// GET /api/session
func (ctrl *SessionController) ReadMany(ctx context.Context) (err error) {
	session, _ := session_store.Get(ctx.HttpRequest(), session_name)
	if session.Values["username"] != nil {
		return goweb.API.RespondWithError(ctx, http.StatusBadRequest, "has session")
	}

	// check form value(not empty?)
	id := ctx.FormValue("id")
	passwd := ctx.FormValue("password")
	if id == "" || passwd == "" {
		return goweb.API.RespondWithError(ctx, http.StatusBadRequest, "not enough query")
	}

	// get userdata from database
	user, err := GetUser(id, passwd)
	if err != nil {
		return goweb.API.RespondWithError(ctx, http.StatusInternalServerError, "error on database")
	}

	if user == nil {
		return goweb.API.RespondWithError(ctx, http.StatusUnauthorized, "user not found")
	}

	session.Values["username"] = user.Name
	session.Save(ctx.HttpRequest(), ctx.HttpResponseWriter())
	return goweb.API.RespondWithData(ctx, nil)
}
Beispiel #2
0
// WriteResponseObject writes the status code and response object to the HttpResponseWriter in
// the specified context, in the format best suited based on the request.
//
// Goweb uses the WebCodecService to decide which codec to use when responding
// see http://godoc.org/github.com/stretchr/codecs/services#WebCodecService for more information.
//
// This method should be used when the Goweb Standard Response Object does not satisfy the needs of
// the API, but other Respond* methods are recommended.
func (a *GowebAPIResponder) WriteResponseObject(ctx context.Context, status int, responseObject interface{}) error {

	service := a.GetCodecService()

	acceptHeader := ctx.HttpRequest().Header.Get("Accept")
	extension := ctx.FileExtension()
	hasCallback := len(ctx.QueryValue(CallbackParameter)) > 0

	codec, codecError := service.GetCodecForResponding(acceptHeader, extension, hasCallback)

	if codecError != nil {
		return codecError
	}

	options := ctx.CodecOptions()

	// do we need to add some options?
	if _, exists := options[constants.OptionKeyClientCallback]; hasCallback && !exists {
		options[constants.OptionKeyClientCallback] = ctx.QueryValue(CallbackParameter)
	}

	output, marshalErr := service.MarshalWithCodec(codec, responseObject, options)

	if marshalErr != nil {
		return marshalErr
	}

	// use the HTTP responder to respond
	ctx.HttpResponseWriter().Header().Set("Content-Type", codec.ContentType()) // TODO: test me
	a.httpResponder.With(ctx, status, output)

	return nil

}
Beispiel #3
0
//helper function to translate args in URL query to samtools args
//manual: http://samtools.sourceforge.net/samtools.shtml
func ParseSamtoolsArgs(ctx context.Context) (argv []string, err error) {

	query := ctx.HttpRequest().URL.Query()
	var (
		filter_options = map[string]string{
			"head":     "-h",
			"headonly": "-H",
			"count":    "-c",
		}
		valued_options = map[string]string{
			"flag":      "-f",
			"lib":       "-l",
			"mapq":      "-q",
			"readgroup": "-r",
		}
	)

	for src, des := range filter_options {
		if _, ok := query[src]; ok {
			argv = append(argv, des)
		}
	}

	for src, des := range valued_options {
		if _, ok := query[src]; ok {
			if val := query.Get(src); val != "" {
				argv = append(argv, des)
				argv = append(argv, val)
			} else {
				return nil, errors.New(fmt.Sprintf("required value not found for query arg: %s ", src))
			}
		}
	}
	return argv, nil
}
func (ctrl *TokenController) ReadMany(ctx context.Context) (err error) {
	t, _ := generateRandomString(tokenlength)
	session, _ := session_store.Get(ctx.HttpRequest(), session_name)
	session.Values["token"] = t

	session.Save(ctx.HttpRequest(), ctx.HttpResponseWriter())
	return goweb.API.RespondWithData(ctx, t)
}
Beispiel #5
0
// Respond performs an API response, adding some additional data to
// the context's CodecOptions to support our custom codecs.  This
// particular function is very specifically for use with the
// github.com/stretchr/goweb web framework.
//
// TODO: Move the with={} parameter to options in the mimetypes in the
// Accept header.
func Respond(ctx context.Context, status int, notifications MessageMap, data interface{}, useFullDomain ...bool) error {
	body, err := web_request_readers.ParseBody(ctx)
	if err != nil {
		return err
	}
	if ctx.QueryParams().Has("joins") {
		if m, ok := body.(objx.Map); ok {
			m.Set("joins", ctx.QueryValue("joins"))
		}
	}

	protocol := "http"
	if ctx.HttpRequest().TLS != nil {
		protocol += "s"
	}

	host := ctx.HttpRequest().Host

	requestDomain := fmt.Sprintf("%s://%s", protocol, host)
	if status == http.StatusOK {
		location := "Error: no location present"
		if locationer, ok := data.(Locationer); ok {
			location = fmt.Sprintf("%s%s", requestDomain, locationer.Location())
		}
		ctx.HttpResponseWriter().Header().Set("Location", location)

		if linker, ok := data.(RelatedLinker); ok {
			linkMap := linker.RelatedLinks()
			links := make([]string, 0, len(linkMap)+1)
			links = append(links, fmt.Sprintf(`<%s>; rel="location"`, location))
			for rel, link := range linkMap {
				link := fmt.Sprintf(`<%s%s>; rel="%s"`, requestDomain, link, rel)
				links = append(links, link)
			}
			ctx.HttpResponseWriter().Header().Set("Link", strings.Join(links, ", "))
		}
	}
	// Transitionary period - don't pass the domain to the codec
	// unless it's requested in the responder
	if len(useFullDomain) == 0 || useFullDomain[0] == false {
		requestDomain = ""
	}

	options := ctx.CodecOptions()
	options.MergeHere(objx.Map{
		"status":        status,
		"input_params":  body,
		"notifications": notifications,
		"domain":        requestDomain,
	})

	// Right now, this line is commented out to support our joins
	// logic.  Unfortunately, that means that codecs other than our
	// custom codecs from this package will not work.  Whoops.
	// data = CreateResponse(data)

	return goweb.API.WriteResponseObject(ctx, status, data)
}
// DELETE /api/session
func (ctrl *SessionController) DeleteMany(ctx context.Context) (err error) {
	session, _ := session_store.Get(ctx.HttpRequest(), session_name)

	// clear user's session data
	session.Values["username"] = nil

	session.Save(ctx.HttpRequest(), ctx.HttpResponseWriter())
	return goweb.API.RespondWithData(ctx, nil)
}
func getUserNameFromCtx(ctx context.Context) (name string) {
	session, _ := session_store.Get(ctx.HttpRequest(), session_name)
	user_raw := session.Values["username"]
	if user_raw == nil {
		return ""
	}
	name = user_raw.(string)
	return
}
Beispiel #8
0
func UploadZip(ctx context.Context) error {
	var currentUser, ok = ctx.Data()["user"].(m.User)
	if ok {

		file, _, err := ctx.HttpRequest().FormFile("file")
		if err != nil {
			log.Error("Error on zip upload FormFile " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the zip."})
		}
		defer file.Close()

		outputZipPath := "../uploads/temp/" + base64.StdEncoding.EncodeToString([]byte(currentUser.Username+time.Now().String()))

		if err := os.MkdirAll("../uploads/temp/", 0777); err != nil {
			log.Error("Error in creating output dir " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the zip."})
		}

		outputZipFile, err := os.Create(outputZipPath)
		if err != nil {
			log.Error("Error in creating output file in zip " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the zip."})
		}
		defer outputZipFile.Close()

		if _, err = io.Copy(outputZipFile, file); err != nil {
			log.Error("Error in copying file " + err.Error())
			os.Remove(outputZipPath)
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the zip."})
		}
		var extention = ""
		if runtime.GOOS == "windows" {
			extention = ".exe"
		}

		extractPath := "../uploads/temp/" + base64.StdEncoding.EncodeToString([]byte(currentUser.Username+time.Now().String()))
		commandString := fmt.Sprintf(`7za%s e %s -o%s -p%s -aoa`, extention, outputZipPath, extractPath, "SuperSecurePassword")
		commandSlice := strings.Fields(commandString)
		commandCall := exec.Command(commandSlice[0], commandSlice[1:]...)
		// err = commandCall.Run()
		value, err := commandCall.Output()
		if err != nil {
			log.Error("in unarchiving zip file: " + err.Error())
			log.Error("Full info about the error: " + string(value))
		}

		go utils.ProcessZip(currentUser, extractPath)

		return goweb.API.Respond(ctx, 200, nil, nil)
	} else {
		return goweb.API.Respond(ctx, 200, nil, []string{"Please log in to upload a zip."})
	}
}
func isSessionValid(ctx context.Context) bool {
	session, _ := session_store.Get(ctx.HttpRequest(), session_name)
	session_token := session.Values["token"]

	session.Values["token"] = ""
	session.Save(ctx.HttpRequest(), ctx.HttpResponseWriter())

	if session_token == "" || session_token != ctx.FormValue("token") {
		return false
	}
	return true
}
Beispiel #10
0
func UploadImgData(ctx context.Context) error {
	var currentUser, ok = ctx.Data()["user"].(m.User)
	if ok {
		file, _, err := ctx.HttpRequest().FormFile("file")
		if err != nil {
			log.Error("Error on image upload FormFile " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the image."})
		}
		defer file.Close()
		utils.ParseImageTable(currentUser, file)
		return goweb.API.Respond(ctx, 200, nil, nil)
	} else {
		return goweb.API.Respond(ctx, 200, nil, []string{"Please log in to upload your images."})
	}
}
Beispiel #11
0
// GET, POST, PUT, DELETE: /node/{nid}/acl/
// GET is the only action implemented here.
func AclRequest(ctx context.Context) {
	nid := ctx.PathValue("nid")

	u, err := request.Authenticate(ctx.HttpRequest())
	if err != nil && err.Error() != e.NoAuth {
		request.AuthError(err, ctx)
		return
	}

	// acl require auth even for public data
	if u == nil {
		responder.RespondWithError(ctx, http.StatusUnauthorized, e.NoAuth)
		return
	}

	// Load node and handle user unauthorized
	n, err := node.Load(nid, u.Uuid)
	if err != nil {
		if err.Error() == e.UnAuth {
			responder.RespondWithError(ctx, http.StatusUnauthorized, e.UnAuth)
			return
		} else if err.Error() == e.MongoDocNotFound {
			responder.RespondWithError(ctx, http.StatusNotFound, "Node not found")
			return
		} else {
			// In theory the db connection could be lost between
			// checking user and load but seems unlikely.
			err_msg := "Err@node_Read:LoadNode: " + err.Error()
			logger.Error(err_msg)
			responder.RespondWithError(ctx, http.StatusInternalServerError, err_msg)
			return
		}
	}

	rights := n.Acl.Check(u.Uuid)
	if ctx.HttpRequest().Method == "GET" {
		if u.Uuid == n.Acl.Owner || rights["read"] {
			responder.RespondWithData(ctx, n.Acl)
		} else {
			responder.RespondWithError(ctx, http.StatusUnauthorized, e.UnAuth)
			return
		}
	} else {
		responder.RespondWithError(ctx, http.StatusNotImplemented, "This request type is not implemented.")
	}
	return
}
Beispiel #12
0
// Searches for an entry in the Accept header that matches
// settings.ApiResponseType.  If a matching entry is found, it is stored
// as BaseRestController.MatchedAccept.
func (controller *BaseRestController) MatchAccept(ctx context.Context) (handlers.MatcherFuncDecision, error) {
	accept := ctx.HttpRequest().Header.Get("Accept")
	matchedAcceptIndex := strings.Index(accept, settings.ApiResponseType)
	switch matchedAcceptIndex {
	case -1:
		return handlers.NoMatch, nil
	default:
		acceptFromMatch := accept[matchedAcceptIndex:]
		var matchedAcceptEnd int
		if matchedAcceptEnd = strings.Index(acceptFromMatch, ","); matchedAcceptEnd == -1 {
			matchedAcceptEnd = len(acceptFromMatch)
		}
		matchedAccept := acceptFromMatch[:matchedAcceptEnd]
		if controller.MatchedAccept != matchedAccept {
			controller.MatchedAccept = matchedAccept
			controller.requestedVersion = ""
		}
		return handlers.DontCare, nil
	}
}
Beispiel #13
0
func (r *IceController) Read(brand string, ctx context.Context) error {

	fmt.Println("already interfacing with cassandra")
	ctx.HttpResponseWriter().Header().Set("Access-Control-Allow-Origin", "*")

	query := ctx.HttpRequest().URL.RawQuery
	id := GetQueryValue("user_id", query)
	column := GetQueryValue("op", query)
	fmt.Println(id)
	newsclusters := db.ReadValue("ice", "user_data", id, column)

	/*for _, cluster := range newsclusters {
	  fmt.Println(cluster)
	}*/
	fmt.Println(column)
	data := new(IceData)
	data.Output = newsclusters
	data.TimeStamp = []string{"testing", "timestamp"}
	return goweb.API.RespondWithData(ctx, data)
}
Beispiel #14
0
func UploadVideo(ctx context.Context) error {
	var currentUser, ok = ctx.Data()["user"].(m.User)
	if ok {
		file, _, err := ctx.HttpRequest().FormFile("file")
		if err != nil {
			log.Error("Error on image upload FormFile " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the image."})
		}
		defer file.Close()

		outputPath := "../uploads/" + currentUser.Username + "/" + base64.StdEncoding.EncodeToString([]byte(currentUser.Username+time.Now().String()))

		if err := os.MkdirAll("../uploads/"+currentUser.Username+"/", 0777); err != nil {
			log.Error("Error in creating output file " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the image."})
		}

		outputFile, err := os.Create(outputPath)
		if err != nil {
			log.Error("Error in creating output file " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the image."})
		}
		defer outputFile.Close()

		if _, err = io.Copy(outputFile, file); err != nil {
			log.Error("Error in copying file " + err.Error())
			os.Remove(outputPath)
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the image."})
		}
		if err = m.GetDB("Video").Insert(&m.Video{currentUser.Id, outputPath, time.Now()}); err != nil {
			log.Error("Error in saving video file to db " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the image."})
		}
		return goweb.API.Respond(ctx, 200, nil, nil)
	} else {
		return goweb.API.Respond(ctx, 200, nil, []string{"Please log in to upload your videos."})
	}
}
Beispiel #15
0
func ConvertHandler(ctx context.Context) (err error) {
	req := ctx.HttpRequest()

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		return
	}
	defer req.Body.Close()

	cvtr := NewConverter(string(buf))
	if cvtr == nil {
		println("a")
		return
	}

	err = cvtr.DoConvert()
	if err != nil {
		println("b")
		return
	}

	return goweb.Respond.With(ctx, 200, []byte(cvtr.GetResult()))
}
Beispiel #16
0
func parseAclRequestTyped(ctx context.Context) (ids []string, err error) {
	var users []string
	query := ctx.HttpRequest().URL.Query()
	params, _, err := request.ParseMultipartForm(ctx.HttpRequest())
	if _, ok := query["users"]; ok && err != nil && err.Error() == "request Content-Type isn't multipart/form-data" {
		users = strings.Split(query.Get("users"), ",")
	} else if params["users"] != "" {
		users = strings.Split(params["users"], ",")
	} else {
		return nil, errors.New("Action requires list of comma separated usernames in 'users' parameter")
	}
	for _, v := range users {
		if uuid.Parse(v) != nil {
			ids = append(ids, v)
		} else {
			u := user.User{Username: v}
			if err := u.SetUuid(); err != nil {
				return nil, err
			}
			ids = append(ids, u.Uuid)
		}
	}
	return ids, nil
}
Beispiel #17
0
func Register(ctx context.Context) error {
	var currentUser, ok = ctx.Data()["user"].(m.User)
	if ok {
		return goweb.API.RespondWithData(ctx, currentUser.Token)
	} else {
		username := ctx.FormValue("username")
		email := ctx.FormValue("email")
		password := ctx.FormValue("password")

		// Check or basic auth header
		authHeader := ctx.HttpRequest().Header.Get("Authorization")
		if len(authHeader) > 0 {
			info, err := base64.StdEncoding.DecodeString(strings.Split(authHeader, " ")[1])
			if err == nil {
				decryptedInfo := strings.Split(string(info), ":")
				username = decryptedInfo[0]
				password = decryptedInfo[1]
				email = decryptedInfo[2]
			}
		}

		if len(username) < 3 {
			return goweb.API.Respond(ctx, 200, nil, []string{"The username has to be at least 4 characters long."})
		}
		if len(email) == 0 {
			return goweb.API.Respond(ctx, 200, nil, []string{"Please supply an email address."})
		}

		err := utils.CheckValidPassword(password)
		if err != nil {
			return goweb.API.Respond(ctx, 200, nil, []string{err.Error()})
		}

		var oldUser m.User
		err = m.GetDB("User").Find(bson.M{"username": username}).One(&oldUser)
		if err == nil {
			log.Debug("Username already taken.")
			return goweb.API.Respond(ctx, 200, nil, []string{"Username already taken."})
		}

		var token = nonce.NewToken()
		nonce.MarkToken(token)
		newUser := m.User{bson.NewObjectId(), username, email, true, token, time.Now()}
		err = m.GetDB("User").Insert(&newUser)
		if err != nil {
			log.Error("Error on local registration, new user: "******"Failed to register."})
		}

		hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), 10)

		err = m.GetDB("Passport").Insert(&m.Passport{bson.NewObjectId(), newUser.Id, string(hashedPassword), "local", "", "", ""})
		if err != nil {
			log.Error("Error on local registration, new user passport: " + err.Error())
			m.GetDB("User").RemoveId(newUser.Id)
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to create your new passport."})
		}
		log.Info("New user registered local")
		return goweb.API.RespondWithData(ctx, newUser.Token)
	}
}
Beispiel #18
0
func beforeHandler(c context.Context) (err error) {
	session, _ := session_store.Get(c.HttpRequest(), session_name)
	session.Save(c.HttpRequest(), c.HttpResponseWriter())
	return nil
}
Beispiel #19
0
// Set the GAEContext member.
func (controller *BaseAppengineController) SetGAEContext(ctx context.Context) {
	if controller.GAEContext == nil {
		controller.GAEContext = appengine.NewContext(ctx.HttpRequest())
	}
}
Beispiel #20
0
// GET: /node
// To do:
// - Iterate node queries
func (cr *NodeController) ReadMany(ctx context.Context) error {
	u, err := request.Authenticate(ctx.HttpRequest())
	if err != nil && err.Error() != e.NoAuth {
		return request.AuthError(err, ctx)
	}

	// Gather query params
	query := ctx.HttpRequest().URL.Query()

	// Setup query and nodes objects
	q := bson.M{}
	nodes := node.Nodes{}

	if u != nil {
		// Admin sees all
		if !u.Admin {
			q["$or"] = []bson.M{bson.M{"acl.read": []string{}}, bson.M{"acl.read": u.Uuid}, bson.M{"acl.owner": u.Uuid}}
		}
	} else {
		if conf.Bool(conf.Conf["anon-read"]) {
			// select on only nodes with no read rights set
			q["acl.read"] = []string{}
		} else {
			return responder.RespondWithError(ctx, http.StatusUnauthorized, e.NoAuth)
		}
	}

	// Gather params to make db query. Do not include the
	// following list.
	paramlist := map[string]int{"limit": 1, "offset": 1, "query": 1, "querynode": 1}
	if _, ok := query["query"]; ok {
		for key := range query {
			if _, found := paramlist[key]; !found {
				q[fmt.Sprintf("attributes.%s", key)] = query.Get(key)
			}
		}
	} else if _, ok := query["querynode"]; ok {
		for key := range query {
			if key == "type" {
				querytypes := strings.Split(query.Get(key), ",")
				q["type"] = bson.M{"$all": querytypes}
			} else {
				if _, found := paramlist[key]; !found {
					q[key] = query.Get(key)
				}
			}
		}
	}

	// defaults
	limit := 25
	offset := 0
	if _, ok := query["limit"]; ok {
		limit = util.ToInt(query.Get("limit"))
	}
	if _, ok := query["offset"]; ok {
		offset = util.ToInt(query.Get("offset"))
	}

	// Get nodes from db
	count, err := nodes.GetPaginated(q, limit, offset)
	if err != nil {
		err_msg := "err " + err.Error()
		logger.Error(err_msg)
		return responder.RespondWithError(ctx, http.StatusBadRequest, err_msg)
	}
	return responder.RespondWithPaginatedData(ctx, nodes, limit, offset, count)
}
Beispiel #21
0
// GET, POST, PUT, DELETE: /node/{nid}/acl/{type}
func AclTypedRequest(ctx context.Context) {
	nid := ctx.PathValue("nid")
	rtype := ctx.PathValue("type")

	u, err := request.Authenticate(ctx.HttpRequest())
	if err != nil && err.Error() != e.NoAuth {
		request.AuthError(err, ctx)
		return
	}

	// acl require auth even for public data
	if u == nil {
		responder.RespondWithError(ctx, http.StatusUnauthorized, e.NoAuth)
		return
	}

	if !validAclTypes[rtype] {
		responder.RespondWithError(ctx, http.StatusBadRequest, "Invalid acl type")
		return
	}

	// Load node and handle user unauthorized
	n, err := node.Load(nid, u.Uuid)
	if err != nil {
		if err.Error() == e.UnAuth {
			responder.RespondWithError(ctx, http.StatusUnauthorized, e.UnAuth)
			return
		} else if err.Error() == e.MongoDocNotFound {
			responder.RespondWithError(ctx, http.StatusNotFound, "Node not found")
			return
		} else {
			// In theory the db connection could be lost between
			// checking user and load but seems unlikely.
			err_msg := "Err@node_Read:LoadNode: " + err.Error()
			logger.Error(err_msg)
			responder.RespondWithError(ctx, http.StatusInternalServerError, err_msg)
			return
		}
	}

	rights := n.Acl.Check(u.Uuid)
	requestMethod := ctx.HttpRequest().Method
	if requestMethod != "GET" {
		ids, err := parseAclRequestTyped(ctx)
		if err != nil {
			responder.RespondWithError(ctx, http.StatusBadRequest, err.Error())
			return
		}
		if (requestMethod == "POST" || requestMethod == "PUT") && (u.Uuid == n.Acl.Owner || rights["write"]) {
			if rtype == "owner" {
				if u.Uuid == n.Acl.Owner {
					if len(ids) == 1 {
						n.Acl.SetOwner(ids[0])
					} else {
						responder.RespondWithError(ctx, http.StatusBadRequest, "Too many users. Nodes may have only one owner.")
						return
					}
				} else {
					responder.RespondWithError(ctx, http.StatusBadRequest, "Only owner can change ownership of Node.")
					return
				}
			} else if rtype == "all" {
				for _, atype := range []string{"read", "write", "delete"} {
					for _, i := range ids {
						n.Acl.Set(i, map[string]bool{atype: true})
					}
				}
			} else {
				for _, i := range ids {
					n.Acl.Set(i, map[string]bool{rtype: true})
				}
			}
			n.Save()
		} else if requestMethod == "DELETE" && (u.Uuid == n.Acl.Owner || rights["delete"]) {
			if rtype == "owner" {
				responder.RespondWithError(ctx, http.StatusBadRequest, "Deleting ownership is not a supported request type.")
				return
			} else if rtype == "all" {
				for _, atype := range []string{"read", "write", "delete"} {
					for _, i := range ids {
						n.Acl.UnSet(i, map[string]bool{atype: true})
					}
				}
			} else {
				for _, i := range ids {
					n.Acl.UnSet(i, map[string]bool{rtype: true})
				}
			}
			n.Save()
		} else {
			responder.RespondWithError(ctx, http.StatusUnauthorized, e.UnAuth)
			return
		}
	}

	if u.Uuid == n.Acl.Owner || rights["read"] {
		switch rtype {
		case "read":
			responder.RespondWithData(ctx, map[string][]string{"read": n.Acl.Read})
		case "write":
			responder.RespondWithData(ctx, map[string][]string{"write": n.Acl.Write})
		case "delete":
			responder.RespondWithData(ctx, map[string][]string{"delete": n.Acl.Delete})
		case "owner":
			responder.RespondWithData(ctx, map[string]string{"owner": n.Acl.Owner})
		case "all":
			responder.RespondWithData(ctx, n.Acl)
		}
	} else {
		responder.RespondWithError(ctx, http.StatusUnauthorized, e.UnAuth)
		return
	}
	return
}
Beispiel #22
0
func ApiUrl(ctx context.Context) string {
	if conf.Conf["api-url"] != "" {
		return conf.Conf["api-url"]
	}
	return "http://" + ctx.HttpRequest().Host
}
Beispiel #23
0
func UploadTrail(ctx context.Context) error {
	var currentUser, ok = ctx.Data()["user"].(m.User)
	if ok {
		// read the file from the request
		file, _, err := ctx.HttpRequest().FormFile("file")
		if err != nil {
			log.Error("Error on gps upload FormFile " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the file."})
		}
		defer file.Close()

		outputPath := "../uploads/" + currentUser.Username + "/gps/" + base64.StdEncoding.EncodeToString([]byte(currentUser.Username+time.Now().String()))

		if err := os.MkdirAll("../uploads/"+currentUser.Username+"/gps/", 0777); err != nil {
			log.Error("Error in creating output dir, gps " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the gps."})
		}

		outputFile, err := os.Create(outputPath)
		if err != nil {
			log.Error("Error in creating output file, gps " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the gps."})
		}
		defer outputFile.Close()

		if _, err = io.Copy(outputFile, file); err != nil {
			log.Error("Error in copying file, gps " + err.Error())
			os.Remove(outputPath)
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the gps."})
		}

		var latIndex int = 4
		var lonIndex int = 6
		var TimeDate bool = true
		//get rid of heading
		scanner := bufio.NewScanner(file)
		if scanner.Scan() {

			line := scanner.Text()
			lineRecords := strings.Split(line, ",")
			if strings.EqualFold(lineRecords[2], "DATE") {
				latIndex++
				lonIndex++
				TimeDate = false
			}
		}

		//initialise vars
		var lastLon string = ""
		var lastLat string = ""

		var track m.Track
		var lastTrackID string = ""
		var LastDateArray []string
		var currDateArray []string
		var date string
		var date2 string

		//first record
		if scanner.Scan() {
			record := scanner.Text()
			recordSlice := strings.Split(record, ",")
			if TimeDate {
				LastDateArray = strings.Split(recordSlice[2], " ")
			} else {
				date = recordSlice[2] + " " + recordSlice[3]
				LastDateArray = strings.Split(date, " ")
			}
			lastTrackID = strconv.FormatInt(utils.GetTrackID(LastDateArray, currDateArray), 10)

			track = m.Track{bson.NewObjectId(), currentUser.Id, lastTrackID, utils.ParseDateFromStrings(LastDateArray[0], LastDateArray[1]), []m.Coordinate{}, time.Now(), time.Now(), time.Now()}
			if strings.EqualFold(recordSlice[latIndex+1], "S") {
				recordSlice[latIndex] = "-" + recordSlice[latIndex]
			}
			if strings.EqualFold(recordSlice[lonIndex+1], "W") {
				recordSlice[lonIndex] = "-" + recordSlice[lonIndex]
			}
			coor := m.Coordinate{recordSlice[latIndex], recordSlice[lonIndex], utils.ParseDateFromStrings(LastDateArray[0], LastDateArray[1])}
			track.Coordinates = append(track.Coordinates, coor)

			lastLat = recordSlice[latIndex]
			lastLon = recordSlice[lonIndex]

		}

		//read records
		for scanner.Scan() { //if there is something left

			line := scanner.Text()        //read one line
			s := strings.Split(line, ",") //split to slice

			if TimeDate {
				currDateArray = strings.Split(s[2], " ")
			} else {
				date2 = s[2] + " " + s[3]
				currDateArray = strings.Split(date2, " ")
			}
			if (strings.EqualFold(lastLat, s[latIndex])) || (strings.EqualFold(lastLon, s[lonIndex])) {

				continue //if same lat or lon as previous row: skip it

			} else {

				lastLat = s[latIndex] //update last record
				lastLon = s[lonIndex]
				trackID := strconv.FormatInt(utils.GetTrackID(LastDateArray, currDateArray), 10)

				if strings.EqualFold(s[latIndex+1], "S") {
					s[latIndex] = "-" + s[latIndex]
				}
				if strings.EqualFold(s[lonIndex+1], "W") {
					s[lonIndex] = "-" + s[lonIndex]
				}

				if strings.EqualFold(lastTrackID, trackID) { //add new coordinate to current track
					track.Coordinates = append(track.Coordinates, m.Coordinate{s[latIndex], s[lonIndex], utils.ParseDateFromStrings(currDateArray[0], currDateArray[1])})
				} else {
					//store track and start a new one!
					min, max := utils.GetMinMaxDateFromCoordinates(track.Coordinates)
					doc := m.Track{Id: bson.NewObjectId(), User: currentUser.Id, TrackID: track.TrackID, Date: track.Date, Coordinates: track.Coordinates, MinDate: min, MaxDate: max, Uploaded: time.Now()}
					err = m.GetDB("Track").Insert(doc)
					if err != nil {
						log.Error("Can't insert track: " + err.Error())
					} else {
						utils.LinkGpsToImages(doc)
					}

					track = m.Track{bson.NewObjectId(), currentUser.Id, trackID, utils.ParseDateFromStrings(currDateArray[0], currDateArray[1]), []m.Coordinate{}, time.Now(), time.Now(), time.Now()}
					track.Coordinates = append(track.Coordinates, m.Coordinate{s[latIndex], s[lonIndex], utils.ParseDateFromStrings(currDateArray[0], currDateArray[1])})
					lastTrackID = trackID

				}
				LastDateArray = currDateArray
			}
		}

		//store last track
		min, max := utils.GetMinMaxDateFromCoordinates(track.Coordinates)
		doc := m.Track{Id: bson.NewObjectId(), User: currentUser.Id, TrackID: track.TrackID, Date: track.Date, Coordinates: track.Coordinates, MinDate: min, MaxDate: max}
		err = m.GetDB("Track").Insert(doc)
		if err != nil {
			log.Error("Can't insert track: " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"Failed to upload the track."})
		}
		utils.LinkGpsToImages(doc)
		return goweb.API.Respond(ctx, 200, nil, nil)
	} else {
		return goweb.API.Respond(ctx, 200, nil, []string{"Please log in to upload your GPS data."})
	}
}
Beispiel #24
0
func Auth_GetUser(c *context.Context) string {
	return c.HttpRequest().Header.Get(AuthUserNameHeader)
}
Beispiel #25
0
// GET: /node/{id}
func (cr *NodeController) Read(id string, ctx context.Context) error {
	u, err := request.Authenticate(ctx.HttpRequest())
	if err != nil && err.Error() != e.NoAuth {
		return request.AuthError(err, ctx)
	}

	// Fake public user
	if u == nil {
		if conf.Bool(conf.Conf["anon-read"]) {
			u = &user.User{Uuid: ""}
		} else {
			return responder.RespondWithError(ctx, http.StatusUnauthorized, e.NoAuth)
		}
	}

	// Gather query params
	query := ctx.HttpRequest().URL.Query()

	var fFunc filter.FilterFunc = nil
	if _, ok := query["filter"]; ok {
		if filter.Has(query.Get("filter")) {
			fFunc = filter.Filter(query.Get("filter"))
		}
	}

	// Load node and handle user unauthorized
	n, err := node.Load(id, u.Uuid)
	if err != nil {
		if err.Error() == e.UnAuth {
			return responder.RespondWithError(ctx, http.StatusUnauthorized, e.UnAuth)
		} else if err.Error() == e.MongoDocNotFound {
			return responder.RespondWithError(ctx, http.StatusNotFound, "Node not found")
		} else {
			// In theory the db connection could be lost between
			// checking user and load but seems unlikely.
			logger.Error("Err@node_Read:LoadNode:" + id + ":" + err.Error())

			n, err = node.LoadFromDisk(id)
			if err != nil {
				err_msg := "Err@node_Read:LoadNodeFromDisk:" + id + ":" + err.Error()
				logger.Error(err_msg)
				return responder.RespondWithError(ctx, http.StatusInternalServerError, err_msg)
			}
		}
	}

	// Switch though param flags
	// ?download=1
	if _, ok := query["download"]; ok {
		if !n.HasFile() {
			return responder.RespondWithError(ctx, http.StatusBadRequest, "Node has no file")
		}
		filename := n.Id
		if _, ok := query["filename"]; ok {
			filename = query.Get("filename")
		}

		if _, ok := query["index"]; ok {
			//handling bam file
			if query.Get("index") == "bai" {
				s := &request.Streamer{R: []file.SectionReader{}, W: ctx.HttpResponseWriter(), ContentType: "application/octet-stream", Filename: filename, Size: n.File.Size, Filter: fFunc}

				var region string

				if _, ok := query["region"]; ok {
					//retrieve alingments overlapped with specified region
					region = query.Get("region")
				}

				argv, err := request.ParseSamtoolsArgs(ctx)
				if err != nil {
					return responder.RespondWithError(ctx, http.StatusBadRequest, "Invaid args in query url")
				}

				err = s.StreamSamtools(n.FilePath(), region, argv...)
				if err != nil {
					return responder.RespondWithError(ctx, http.StatusBadRequest, "error while involking samtools")
				}

				return nil
			}

			// if forgot ?part=N
			if _, ok := query["part"]; !ok {
				return responder.RespondWithError(ctx, http.StatusBadRequest, "Index parameter requires part parameter")
			}
			// open file
			r, err := n.FileReader()
			defer r.Close()
			if err != nil {
				err_msg := "Err@node_Read:Open: " + err.Error()
				logger.Error(err_msg)
				return responder.RespondWithError(ctx, http.StatusInternalServerError, err_msg)
			}
			// load index
			idx, err := n.Index(query.Get("index"))
			if err != nil {
				return responder.RespondWithError(ctx, http.StatusBadRequest, "Invalid index")
			}

			if idx.Type() == "virtual" {
				csize := conf.CHUNK_SIZE
				if _, ok := query["chunk_size"]; ok {
					csize, err = strconv.ParseInt(query.Get("chunk_size"), 10, 64)
					if err != nil {
						return responder.RespondWithError(ctx, http.StatusBadRequest, "Invalid chunk_size")
					}
				}
				idx.Set(map[string]interface{}{"ChunkSize": csize})
			}
			var size int64 = 0
			s := &request.Streamer{R: []file.SectionReader{}, W: ctx.HttpResponseWriter(), ContentType: "application/octet-stream", Filename: filename, Filter: fFunc}
			for _, p := range query["part"] {
				pos, length, err := idx.Part(p)
				if err != nil {
					return responder.RespondWithError(ctx, http.StatusBadRequest, "Invalid index part")
				}
				size += length
				s.R = append(s.R, io.NewSectionReader(r, pos, length))
			}
			s.Size = size
			err = s.Stream()
			if err != nil {
				// causes "multiple response.WriteHeader calls" error but better than no response
				err_msg := "err:@node_Read s.stream: " + err.Error()
				logger.Error(err_msg)
				responder.RespondWithError(ctx, http.StatusBadRequest, err_msg)
			}
		} else {
			nf, err := n.FileReader()
			defer nf.Close()
			if err != nil {
				// File not found or some sort of file read error.
				// Probably deserves more checking
				err_msg := "err:@node_Read node.FileReader: " + err.Error()
				logger.Error(err_msg)
				return responder.RespondWithError(ctx, http.StatusBadRequest, err_msg)
			}
			s := &request.Streamer{R: []file.SectionReader{nf}, W: ctx.HttpResponseWriter(), ContentType: "application/octet-stream", Filename: filename, Size: n.File.Size, Filter: fFunc}
			err = s.Stream()
			if err != nil {
				// causes "multiple response.WriteHeader calls" error but better than no response
				err_msg := "err:@node_Read: s.stream: " + err.Error()
				logger.Error(err_msg)
				responder.RespondWithError(ctx, http.StatusBadRequest, err_msg)
			}
		}
	} else if _, ok := query["download_url"]; ok {
		if !n.HasFile() {
			return responder.RespondWithError(ctx, http.StatusBadRequest, "Node has not file")
		} else if u.Uuid == "" {
			return responder.RespondWithError(ctx, http.StatusUnauthorized, e.NoAuth)
		} else {
			options := map[string]string{}
			if _, ok := query["filename"]; ok {
				options["filename"] = query.Get("filename")
			}
			if p, err := preauth.New(util.RandString(20), "download", n.Id, options); err != nil {
				err_msg := "err:@node_Read download_url: " + err.Error()
				logger.Error(err_msg)
				responder.RespondWithError(ctx, http.StatusInternalServerError, err_msg)
			} else {
				responder.RespondWithData(ctx, util.UrlResponse{Url: util.ApiUrl(ctx) + "/preauth/" + p.Id, ValidTill: p.ValidTill.Format(time.ANSIC)})
			}
		}
	} else {
		// Base case respond with node in json
		responder.RespondWithData(ctx, n)
	}
	return nil
}
// ParseBody will parse a request body, regardless of type.  The body
// could be a json array, and this will return it properly.  All
// map[string]interface{} values are converted to objx.Map before
// returning.
func ParseBody(ctx context.Context) (interface{}, error) {
	if params, ok := ctx.Data()["params"]; ok {
		// We've already parsed this request, so return the cached
		// parameters.
		return params, nil
	}
	request := ctx.HttpRequest()
	var response interface{}
	contentType, _ := codec_services.ParseContentType(request.Header.Get("Content-Type"))
	var mimeType string
	if contentType != nil {
		mimeType = contentType.MimeType
	}
	switch mimeType {
	case "text/json":
		fallthrough
	case "application/json":
		body, err := ioutil.ReadAll(request.Body)
		if err != nil {
			return nil, err
		}
		if err = json.Unmarshal(body, &response); err != nil {
			return nil, err
		}
	default:
		fallthrough
	case "application/x-www-form-urlencoded":
		fallthrough
	case "multipart/form-data":
		params := make(objx.Map)
		request.ParseMultipartForm(MultipartMem())
		if request.MultipartForm != nil {
			params.Set("files", request.MultipartForm.File)
			for key, values := range request.MultipartForm.Value {
				if len(values) == 1 {
					params.Set(key, values[0])
				} else {
					params.Set(key, values)
				}
			}
		}
		for index, values := range request.Form {
			if len(values) == 1 {
				// Okay, so, here's how this works.  I hate just
				// assuming that there's only one value when I'm
				// reading a form, so I always end up testing the
				// length, which adds boilerplate code.  I want my
				// param parser to handle that case, so instead of
				// always adding a slice of values, I'm only adding
				// the single value if the length of the slice is 1.
				params.Set(index, values[0])
			} else {
				params.Set(index, values)
			}
		}
		response = params
	}
	response = ConvertMSIToObjxMap(response)
	ctx.Data().Set("params", response)
	return response, nil
}
Beispiel #27
0
func Login(ctx context.Context) error {
	var currentUser, ok = ctx.Data()["user"].(m.User)
	if ok {
		return goweb.API.RespondWithData(ctx, currentUser.Token)
	} else {
		username := ctx.FormValue("username")
		password := ctx.FormValue("password")

		// Check or basic auth header
		authHeader := ctx.HttpRequest().Header.Get("Authorization")
		if len(authHeader) > 0 {
			info, err := base64.StdEncoding.DecodeString(strings.Split(authHeader, " ")[1])
			if err == nil {
				decryptedInfo := strings.Split(string(info), ":")
				username = decryptedInfo[0]
				password = decryptedInfo[1]
			}
		}

		if len(username) < 3 || len(password) < 6 {
			return goweb.API.Respond(ctx, 200, nil, []string{"Invalid data supplied, please fill all fields."})
		}

		user := m.User{}
		query := bson.M{}
		if strings.Contains(username, "@") {
			query["username"] = username
		} else {
			query["email"] = username
		}
		err := m.GetDB("User").Find(query).One(&user)
		if err != nil {
			log.Error("Error in find user on login " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"No such username, please register."})
		}
		passport := m.Passport{}
		err = m.GetDB("Passport").Find(bson.M{"provider": "local", "user": user.Id}).One(&passport)
		if err != nil {
			log.Error("Error in find user passport on login " + err.Error())
			return goweb.API.Respond(ctx, 200, nil, []string{"You have registered through Facebook."})
		}

		err = bcrypt.CompareHashAndPassword([]byte(passport.Password), []byte(password))
		if err != nil {
			return goweb.API.Respond(ctx, 200, nil, []string{"Incorrect password."})
		}
		log.Info("User found on local login")
		if user.Token == "" || user.TokenUpdate.Before(time.Now().AddDate(0, 0, -1)) {
			var token = nonce.NewToken()
			nonce.MarkToken(token)
			user.Token = token
			user.TokenUpdate = time.Now()

			err := m.GetDB("User").UpdateId(user.Id, user)
			if err != nil {
				log.Error("Failed to update token: " + err.Error())
			}
		}
		ctx.HttpResponseWriter().Header().Add("cookie", "token="+user.Token)
		return goweb.API.RespondWithData(ctx, user.Token)
	}
}