diff --git a/middleware/jwt.go b/middleware/jwt.go index afc0be0..6ef188b 100644 --- a/middleware/jwt.go +++ b/middleware/jwt.go @@ -14,14 +14,12 @@ func JWTAuth(required bool) gin.HandlerFunc { authtoken := new(authtoken.Token) uid, err := authtoken.HeaderVerify(auth) if err != nil { - c.JSON(401, gin.H{"status": err.Error()}) - c.Abort() + c.AbortWithStatusJSON(401, gin.H{"status": err.Error()}) return } if required == true && uid == "" { - c.JSON(401, gin.H{"status": "unauthorized"}) - c.Abort() + c.AbortWithStatusJSON(401, gin.H{"status": "unauthorized"}) return } diff --git a/middleware/permission.go b/middleware/permission.go new file mode 100644 index 0000000..cdca098 --- /dev/null +++ b/middleware/permission.go @@ -0,0 +1,36 @@ +package middleware + +import ( + "nixcn-cms/data" + + "github.com/gin-gonic/gin" + "github.com/google/uuid" +) + +func Permission(requiredLevel uint) gin.HandlerFunc { + return func(c *gin.Context) { + userIdOrig, ok := c.Get("user_id") + if !ok || userIdOrig.(string) == "" { + c.AbortWithStatusJSON(401, gin.H{"status": "missing user id"}) + return + } + + userId, err := uuid.Parse(userIdOrig.(string)) + if err != nil { + c.AbortWithStatusJSON(500, gin.H{"status": "error parsing user id"}) + return + } + + userData, err := new(data.User).GetByUserId(userId) + if err != nil { + c.AbortWithStatusJSON(404, gin.H{"status": "user not found"}) + return + } + + if userData.PermissionLevel < requiredLevel { + c.AbortWithStatusJSON(403, gin.H{"status": "permission denied"}) + return + } + c.Next() + } +} diff --git a/service/user/checkin.go b/service/user/checkin.go index 73025b2..f2e5ffd 100644 --- a/service/user/checkin.go +++ b/service/user/checkin.go @@ -43,29 +43,13 @@ func Checkin(c *gin.Context) { } func CheckinSubmit(c *gin.Context) { - userIdOrig, ok := c.Get("user_id") - if userIdOrig.(string) == "" || !ok { - c.JSON(401, gin.H{"status": "unauthorized"}) - } - userId, err := uuid.Parse(userIdOrig.(string)) - if err != nil { - c.JSON(500, gin.H{"status": "failed to parse uuid"}) - } - - userData := new(data.User) - userData.GetByUserId(userId) - if userData.PermissionLevel <= 20 { - c.JSON(403, gin.H{"status": "access denied"}) - return - } - var req struct { ChekinCode string `json:"checkin_code"` } c.ShouldBindJSON(&req) attendanceData := new(data.Attendance) - err = attendanceData.VerifyCheckinCode(req.ChekinCode) + err := attendanceData.VerifyCheckinCode(req.ChekinCode) if err != nil { c.JSON(400, gin.H{"status": "error verify checkin code"}) return diff --git a/service/user/full.go b/service/user/full.go index f895b2d..3fd2216 100644 --- a/service/user/full.go +++ b/service/user/full.go @@ -19,18 +19,12 @@ func Full(c *gin.Context) { return } - userData := new(data.User) - user, err := userData.GetByUserId(userId) + userData, err := new(data.User).GetByUserId(userId) if err != nil { c.JSON(404, gin.H{"status": "user not found"}) return } - if user.PermissionLevel < 50 { - c.JSON(403, gin.H{"status": "permission denied"}) - return - } - data, err := userData.GetFullTable() if err != nil { c.JSON(500, gin.H{"status": "database error"}) diff --git a/service/user/handler.go b/service/user/handler.go index 00f5e1e..9438e2a 100644 --- a/service/user/handler.go +++ b/service/user/handler.go @@ -7,12 +7,12 @@ import ( ) func Handler(r *gin.RouterGroup) { - r.Use(middleware.JWTAuth(true)) + r.Use(middleware.JWTAuth(true), middleware.Permission(10)) r.GET("/info", Info) r.GET("/checkin", Checkin) - r.POST("/checkin/submit", CheckinSubmit) + r.POST("/checkin/submit", CheckinSubmit, middleware.Permission(20)) r.PATCH("/update", Update) r.GET("/list", List) r.GET("/query", Query) - r.POST("/full", Full) + r.POST("/full", Full, middleware.Permission(50)) } diff --git a/service/user/list.go b/service/user/list.go index 33dadfa..1564aa5 100644 --- a/service/user/list.go +++ b/service/user/list.go @@ -8,8 +8,6 @@ import ( ) func List(c *gin.Context) { - data := new(data.User) - // Get limit and offset from query limit, ok := c.GetQuery("limit") if !ok { @@ -34,7 +32,7 @@ func List(c *gin.Context) { } // Get user list from search engine - list, err := data.FastListUsers(limitNum, offsetNum) + list, err := new(data.User).FastListUsers(limitNum, offsetNum) if err != nil { c.JSON(500, gin.H{"status": "failed list users from meilisearch"}) } diff --git a/service/user/update.go b/service/user/update.go index 5a37b6b..ea19b61 100644 --- a/service/user/update.go +++ b/service/user/update.go @@ -10,7 +10,6 @@ import ( func Update(c *gin.Context) { // New user model - user := new(data.User) userIdOrig, ok := c.Get("user_id") if !ok { c.JSON(403, gin.H{"status": "userid error"}) @@ -19,34 +18,33 @@ func Update(c *gin.Context) { userId, err := uuid.Parse(userIdOrig.(string)) if err != nil { c.JSON(500, gin.H{"status": "failed to parse uuid"}) + return } var ReqInfo data.User c.BindJSON(&ReqInfo) // Get user info - user.GetByUserId(userId) - - // Reject permission 0 user - if user.PermissionLevel == 0 { - c.JSON(403, gin.H{"status": "premission denied"}) + userData, err := new(data.User).GetByUserId(userId) + if err != nil { + c.JSON(500, gin.H{"status": "failed to find user"}) return } - user.Avatar = ReqInfo.Avatar - user.Email = ReqInfo.Email - user.Nickname = ReqInfo.Nickname - user.Subtitle = ReqInfo.Subtitle + userData.Avatar = ReqInfo.Avatar + userData.Email = ReqInfo.Email + userData.Nickname = ReqInfo.Nickname + userData.Subtitle = ReqInfo.Subtitle if ReqInfo.Bio != "" { if !cryptography.IsBase64Std(ReqInfo.Bio) { c.JSON(400, gin.H{"status": "invalid base64"}) } } - user.Bio = ReqInfo.Bio + userData.Bio = ReqInfo.Bio // Update user info - user.UpdateByUserID(userId) + userData.UpdateByUserID(userId) c.JSON(200, gin.H{"status": "success"}) }