func (a *API) getAccountResources(c *gin.Context) { // Token and account from context var ( ownAccount = c.MustGet("account").(*models.Account) token = c.MustGet("token").(*models.Token) ) // Resolve the ID from the URL id := c.Param("id") if id == "me" { id = ownAccount.ID } // Check the scope if id == ownAccount.ID { if !models.InScope(token.Scope, []string{"resources:read"}) { c.JSON(403, &gin.H{ "code": 0, "error": "Your token has insufficient scope", }) return } } else { if !models.InScope(token.Scope, []string{"admin"}) { c.JSON(403, &gin.H{ "code": 0, "error": "Your token has insufficient scope", }) return } } // 1. Owner filter query := r.Table("resources").GetAllByIndex("owner", id) // 2. Tag filter if tagstr := c.Query("tags"); tagstr != "" { tags := strings.Split(tagstr, ",") // Cast to []interface{} tagsi := []interface{}{} for _, tag := range tags { tagsi = append(tagsi, tag) } query = query.Filter(func(row r.Term) r.Term { return row.Field("tags").Contains(tagsi...) }) } // 3. Meta filter // not needed right now // 4. Date created and date modified ts := func(field string) error { if dm := c.Query(field); dm != "" { dmp := strings.Split(dm, ",") if len(dmp) == 1 || dmp[1] == "" { // parse dmp[0] d0, err := time.Parse(time.RFC3339, dmp[0]) if err != nil { return err } // after dmp[0] query = query.Filter(func(row r.Term) r.Term { return row.Field(field).Ge(d0) }) } else { // parse dmp[1] d1, err := time.Parse(time.RFC3339, dmp[1]) if err != nil { return err } if dmp[0] == "" { // until dmp[1] query = query.Filter(func(row r.Term) r.Term { return row.Field(field).Le(d1) }) } else { // parse dmp[0] d0, err := time.Parse(time.RFC3339, dmp[0]) if err != nil { return err } // between dmp[0] and dmp[1] query = query.Filter(func(row r.Term) r.Term { return row.Field(field).Ge(d0).And(row.Field(field).Le(d1)) }) } } } return nil } if err := ts("date_modified"); err != nil { c.JSON(500, &gin.H{ "code": 0, "error": err.Error(), }) return } if err := ts("date_created"); err != nil { c.JSON(500, &gin.H{ "code": 0, "error": err.Error(), }) return } // 5. Pluck / Without if pls := c.Query("pluck"); pls != "" { pl := strings.Split(pls, ",") // Cast to []interface{} pli := []interface{}{} for _, field := range pl { pli = append(pli, field) } query = query.Pluck(pli...) } else if wos := c.Query("wo"); wos != "" { wo := strings.Split(wos, ",") // Cast to []interface{} woi := []interface{}{} for _, field := range wo { woi = append(woi, field) } query = query.Pluck(woi...) } // 6. Ordering if obs := c.Query("order_by"); obs != "" { ob := strings.Split(obs, ",") fields := []interface{}{} for _, fi := range ob { asc := true if fi[0] == '-' { asc = false fi = fi[1:] } else if fi[0] == '+' || fi[0] == ' ' { fi = fi[1:] } field := r.Row.Field(fi) if path := strings.Split(fi, "."); len(path) > 1 { field = r.Row.Field(path[0]) for i := 1; i < len(path); i++ { field = field.Field(path[i]) } } if !asc { field = r.Desc(field) } fields = append(fields, field) } query = query.OrderBy(fields...) } // 7. Limiting var ( sks = c.Query("skip") lms = c.Query("limit") err error skip, limit int ) if sks != "" { skip, err = strconv.Atoi(sks) if err != nil { c.JSON(400, &gin.H{ "code": 0, "error": err.Error(), }) return } } if lms != "" { limit, err = strconv.Atoi(lms) if err != nil { c.JSON(400, &gin.H{ "code": 0, "error": err.Error(), }) return } } if skip != 0 && limit != 0 { query = query.Slice(skip, skip+limit) } else if skip == 0 && limit != 0 { query = query.Limit(limit) } else if skip != 0 && limit == 0 { query = query.Skip(skip) } // Get resources from database without bodies cursor, err := query.Run(a.Rethink) if err != nil { c.JSON(500, &gin.H{ "code": 0, "error": err.Error(), }) return } defer cursor.Close() var resources []*models.Resource if err := cursor.All(&resources); err != nil { c.JSON(500, &gin.H{ "code": 0, "error": err.Error(), }) return } // Write the response c.JSON(200, resources) return }
func (a *API) getLabelThreads(c *gin.Context) { // Token and account from context var ( account = c.MustGet("account").(*models.Account) token = c.MustGet("token").(*models.Token) ) // Resolve the ID from the URL id := c.Param("id") // Get label from the database cursor, err := r.Table("labels").Get(id).Run(a.Rethink) if err != nil { c.JSON(500, &gin.H{ "code": 0, "error": err.Error(), }) return } var label *models.Label if err := cursor.One(&label); err != nil { c.JSON(500, &gin.H{ "code": 0, "error": err.Error(), }) return } // Check the ownership and scope if label.Owner == account.ID { if !models.InScope(token.Scope, []string{"labels:read"}) { c.JSON(403, &gin.H{ "code": 0, "error": "Your token has insufficient scope", }) return } } else { if !models.InScope(token.Scope, []string{"admin"}) { c.JSON(403, &gin.H{ "code": 0, "error": "Your token has insufficient scope", }) return } } // Get threads from the database cursor, err = r.Table("threads").GetAllByIndex("labels", label.ID).OrderBy(r.Desc("date_modified")).Map(func(thread r.Term) r.Term { return thread.Merge(map[string]interface{}{ "manifest": r.Table("emails").GetAllByIndex("thread", thread.Field("id")).OrderBy("date_modified").CoerceTo("array"), }).Do(func(thread r.Term) r.Term { return r.Branch( thread.Field("manifest").Count().Gt(0), thread.Merge(map[string]interface{}{ "manifest": thread.Field("manifest").Nth(0).Field("manifest"), }), thread.Without("manifest"), ) }) }).Run(a.Rethink) if err != nil { c.JSON(500, &gin.H{ "code": 0, "error": err.Error(), }) return } var threads []*extendedThread if err := cursor.All(&threads); err != nil { c.JSON(500, &gin.H{ "code": 0, "error": err.Error(), }) return } if threads == nil { threads = []*extendedThread{} } // Write the response c.JSON(200, threads) return }