package api import ( "context" "git.aiterp.net/stufflog3/stufflog3-api/internal/auth" "git.aiterp.net/stufflog3/stufflog3-api/internal/database" "git.aiterp.net/stufflog3/stufflog3-api/internal/models" "git.aiterp.net/stufflog3/stufflog3-api/internal/slerrors" "github.com/gin-gonic/gin" "net/http" "strconv" "strings" ) func handler(key string, callback func(c *gin.Context) (interface{}, error)) gin.HandlerFunc { return func(c *gin.Context) { res, err := callback(c) if err != nil { slerrors.Respond(c, err) return } resJson := make(map[string]interface{}, 1) if s := getScope(c); s != nil { options := ScopeOptions{ StatusLabels: models.StatusLabels, } if s.Stats != nil && !strings.Contains(c.FullPath(), "/stats/") { options.Stats = make(map[int]models.Stat) for _, stat := range s.Stats { options.Stats[stat.ID] = stat } } options.Members = make(map[string]string) for _, member := range s.Members { options.Members[member.ID] = member.Name } resJson["scopeInfo"] = options } resJson[key] = res c.JSON(200, resJson) } } type ScopeOptions struct { StatusLabels map[models.Status]string `json:"statusLabels"` Stats map[int]models.Stat `json:"stats,omitempty"` Members map[string]string `json:"members,omitempty"` } func reqInt(c *gin.Context, key string) (int, error) { v, err := strconv.Atoi(c.Param(key)) if err != nil { return 0, slerrors.BadRequest(key + " parameter must be a number") } return v, nil } var scopeIdContextKey = struct{ stuff string }{stuff: "Things"} func scopeIDMiddleware(db database.Database) gin.HandlerFunc { return func(c *gin.Context) { scopeID, err := strconv.Atoi(c.Param("scope_id")) if err != nil { c.AbortWithStatusJSON(http.StatusUnauthorized, slerrors.ErrorResponse{ Code: http.StatusBadRequest, Message: "Invalid scope ID in path!", }) return } scope, err := db.Scopes().Find(c.Request.Context(), scopeID, strings.Contains(c.FullPath(), "/stats/") || c.Request.Method != "GET") if err != nil || !scope.HasMember(auth.UserID(c)) { c.AbortWithStatusJSON(http.StatusUnauthorized, slerrors.ErrorResponse{ Code: http.StatusNotFound, Message: "Scope not found or you don't have permission to it!", }) return } c.Request = c.Request.WithContext( context.WithValue(c.Request.Context(), &scopeIdContextKey, scope), ) } } func getScope(c *gin.Context) *models.Scope { scope := c.Request.Context().Value(&scopeIdContextKey) if scope == nil { return nil } return scope.(*models.Scope) }