// 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) }
// 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 }
//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) }
// 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 }
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 }
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."}) } }
// 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 }
// 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 } }
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) }
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."}) } }
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())) }
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 }
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) } }
func beforeHandler(c context.Context) (err error) { session, _ := session_store.Get(c.HttpRequest(), session_name) session.Save(c.HttpRequest(), c.HttpResponseWriter()) return nil }
// Set the GAEContext member. func (controller *BaseAppengineController) SetGAEContext(ctx context.Context) { if controller.GAEContext == nil { controller.GAEContext = appengine.NewContext(ctx.HttpRequest()) } }
// 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) }
// 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 }
func ApiUrl(ctx context.Context) string { if conf.Conf["api-url"] != "" { return conf.Conf["api-url"] } return "http://" + ctx.HttpRequest().Host }
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."}) } }
func Auth_GetUser(c *context.Context) string { return c.HttpRequest().Header.Get(AuthUserNameHeader) }
// 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 }
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) } }