Loggest thy stuff
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.6 KiB

3 years ago
3 years ago
3 years ago
  1. package api
  2. import (
  3. "context"
  4. "git.aiterp.net/stufflog3/stufflog3-api/internal/auth"
  5. "git.aiterp.net/stufflog3/stufflog3-api/internal/database"
  6. "git.aiterp.net/stufflog3/stufflog3-api/internal/models"
  7. "git.aiterp.net/stufflog3/stufflog3-api/internal/slerrors"
  8. "github.com/gin-gonic/gin"
  9. "net/http"
  10. "strconv"
  11. "strings"
  12. )
  13. func handler(key string, callback func(c *gin.Context) (interface{}, error)) gin.HandlerFunc {
  14. return func(c *gin.Context) {
  15. res, err := callback(c)
  16. if err != nil {
  17. slerrors.Respond(c, err)
  18. return
  19. }
  20. resJson := make(map[string]interface{}, 1)
  21. if s := getScope(c); s != nil {
  22. options := ScopeOptions{
  23. StatusLabels: models.StatusLabels,
  24. }
  25. if s.Stats != nil && !strings.Contains(c.FullPath(), "/stats/") {
  26. options.Stats = make(map[int]models.Stat)
  27. for _, stat := range s.Stats {
  28. options.Stats[stat.ID] = stat
  29. }
  30. }
  31. options.Members = make(map[string]string)
  32. for _, member := range s.Members {
  33. options.Members[member.ID] = member.Name
  34. }
  35. resJson["scopeInfo"] = options
  36. }
  37. resJson[key] = res
  38. c.JSON(200, resJson)
  39. }
  40. }
  41. type ScopeOptions struct {
  42. StatusLabels map[models.Status]string `json:"statusLabels"`
  43. Stats map[int]models.Stat `json:"stats,omitempty"`
  44. Members map[string]string `json:"members,omitempty"`
  45. }
  46. func reqInt(c *gin.Context, key string) (int, error) {
  47. v, err := strconv.Atoi(c.Param(key))
  48. if err != nil {
  49. return 0, slerrors.BadRequest(key + " parameter must be a number")
  50. }
  51. return v, nil
  52. }
  53. var scopeIdContextKey = struct{ stuff string }{stuff: "Things"}
  54. func scopeIDMiddleware(db database.Database) gin.HandlerFunc {
  55. return func(c *gin.Context) {
  56. scopeID, err := strconv.Atoi(c.Param("scope_id"))
  57. if err != nil {
  58. c.AbortWithStatusJSON(http.StatusUnauthorized, slerrors.ErrorResponse{
  59. Code: http.StatusBadRequest,
  60. Message: "Invalid scope ID in path!",
  61. })
  62. return
  63. }
  64. scope, err := db.Scopes().Find(c.Request.Context(), scopeID, strings.Contains(c.FullPath(), "/stats/") || c.Request.Method != "GET")
  65. if err != nil || !scope.HasMember(auth.UserID(c)) {
  66. c.AbortWithStatusJSON(http.StatusUnauthorized, slerrors.ErrorResponse{
  67. Code: http.StatusNotFound,
  68. Message: "Scope not found or you don't have permission to it!",
  69. })
  70. return
  71. }
  72. c.Request = c.Request.WithContext(
  73. context.WithValue(c.Request.Context(), &scopeIdContextKey, scope),
  74. )
  75. }
  76. }
  77. func getScope(c *gin.Context) *models.Scope {
  78. scope := c.Request.Context().Value(&scopeIdContextKey)
  79. if scope == nil {
  80. return nil
  81. }
  82. return scope.(*models.Scope)
  83. }