From 01da5ec2ee6268aa06996e5f60dfbc6929c85cc9 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 15 Nov 2024 01:04:48 +0300 Subject: [PATCH] Massive rework has been started --- enshi_back/ABAC/globalRules/authorizedRule.go | 24 +++++++++ enshi_back/ABAC/postsPolicies/postPolicy.go | 50 +++++++++++++++++++ .../postsPolicies/postRules/createRule.go | 10 ++++ .../postsPolicies/postRules/deleteRule.go | 22 ++++++++ .../ABAC/postsPolicies/postRules/readRule.go | 10 ++++ .../postsPolicies/postRules/updateRule.go | 17 +++++++ enshi_back/middleware/adminMiddleware.go | 10 +--- enshi_back/middleware/checkRole/isAdmin.go | 11 +++- .../{isOwner.go => isOwnerOfThePost.go} | 17 ++++++- enshi_back/middleware/getters/getIntParam.go | 17 +++++++ enshi_back/middleware/postsMiddleware.go | 41 +++++++++++++++ enshi_back/routes/changeUserProfile.go | 17 ------- enshi_back/routes/postsRoutes/deletePost.go | 11 ++-- enshi_back/routes/postsRoutes/getPost.go | 9 ++-- enshi_back/routes/postsRoutes/updatePost.go | 18 +++---- enshi_back/utils/routesSetup.go | 37 ++++++++++---- 16 files changed, 263 insertions(+), 58 deletions(-) create mode 100644 enshi_back/ABAC/globalRules/authorizedRule.go create mode 100644 enshi_back/ABAC/postsPolicies/postPolicy.go create mode 100644 enshi_back/ABAC/postsPolicies/postRules/createRule.go create mode 100644 enshi_back/ABAC/postsPolicies/postRules/deleteRule.go create mode 100644 enshi_back/ABAC/postsPolicies/postRules/readRule.go create mode 100644 enshi_back/ABAC/postsPolicies/postRules/updateRule.go rename enshi_back/middleware/checkRole/{isOwner.go => isOwnerOfThePost.go} (51%) create mode 100644 enshi_back/middleware/getters/getIntParam.go create mode 100644 enshi_back/middleware/postsMiddleware.go delete mode 100644 enshi_back/routes/changeUserProfile.go diff --git a/enshi_back/ABAC/globalRules/authorizedRule.go b/enshi_back/ABAC/globalRules/authorizedRule.go new file mode 100644 index 0000000..0aa714a --- /dev/null +++ b/enshi_back/ABAC/globalRules/authorizedRule.go @@ -0,0 +1,24 @@ +package globalrules + +import ( + "enshi/auth" + "enshi/global" + "net/http" + + "github.com/gin-gonic/gin" +) + +func AuthorizedRule(c *gin.Context) (bool, error) { + tokenFromCookies := c.Request.CookiesNamed("auth_cookie")[0].Value + cookieClimes, err := auth.ValidateToken(tokenFromCookies) + if err != nil { + c.IndentedJSON(http.StatusUnauthorized, gin.H{"error auth": err.Error()}) + c.Abort() + return false, err + } else { + c.Set(global.ContextUserId, cookieClimes["id"]) + c.Set(global.ContextTokenData, cookieClimes) + } + + return true, nil +} diff --git a/enshi_back/ABAC/postsPolicies/postPolicy.go b/enshi_back/ABAC/postsPolicies/postPolicy.go new file mode 100644 index 0000000..7d16b81 --- /dev/null +++ b/enshi_back/ABAC/postsPolicies/postPolicy.go @@ -0,0 +1,50 @@ +package postspolicies + +import ( + postRules "enshi/ABAC/postsPolicies/postRules" + + "github.com/gin-gonic/gin" +) + +const ( + DELETE_POST = "delete_post" + UPDATE_POST = "update_post" + CREATE_POST = "create_post" + GET_POST = "get_post" +) + +func checkRule( + c *gin.Context, + ruleChecker func(*gin.Context) (bool, error), +) (bool, error) { + IsAllowed, err := ruleChecker(c) + if err != nil { + return false, err + } + + return IsAllowed, nil +} + +func PostsPolicies(c *gin.Context) (bool, error) { + target, exists := c.Get("target") + if !exists { + return false, nil + } + + switch target { + case DELETE_POST: + return checkRule(c, postRules.DeleteRule) + + case UPDATE_POST: + return checkRule(c, postRules.PostUpdateRule) + + case GET_POST: + return checkRule(c, postRules.PostReadRule) + + case CREATE_POST: + return checkRule(c, postRules.PostCreateRule) + + } + + return false, nil +} diff --git a/enshi_back/ABAC/postsPolicies/postRules/createRule.go b/enshi_back/ABAC/postsPolicies/postRules/createRule.go new file mode 100644 index 0000000..81026fd --- /dev/null +++ b/enshi_back/ABAC/postsPolicies/postRules/createRule.go @@ -0,0 +1,10 @@ +package postRules + +import ( + "github.com/gin-gonic/gin" +) + +// Only owner of the post can change it +func PostCreateRule(c *gin.Context) (bool, error) { + return true, nil +} diff --git a/enshi_back/ABAC/postsPolicies/postRules/deleteRule.go b/enshi_back/ABAC/postsPolicies/postRules/deleteRule.go new file mode 100644 index 0000000..4e2cfec --- /dev/null +++ b/enshi_back/ABAC/postsPolicies/postRules/deleteRule.go @@ -0,0 +1,22 @@ +package postRules + +import ( + "enshi/middleware/checkRole" + + "github.com/gin-gonic/gin" +) + +// Only owner or admin can delete post +func DeleteRule(c *gin.Context) (bool, error) { + isOwner, err := checkRole.IsOwnerOfThePost(c) + if err != nil { + return false, err + } + + isAdmin, err := checkRole.IsAdmin(c) + if err != nil { + return false, err + } + + return isAdmin || isOwner, err +} diff --git a/enshi_back/ABAC/postsPolicies/postRules/readRule.go b/enshi_back/ABAC/postsPolicies/postRules/readRule.go new file mode 100644 index 0000000..df83bc5 --- /dev/null +++ b/enshi_back/ABAC/postsPolicies/postRules/readRule.go @@ -0,0 +1,10 @@ +package postRules + +import ( + "github.com/gin-gonic/gin" +) + +// Only owner of the post can change it +func PostReadRule(c *gin.Context) (bool, error) { + return true, nil +} diff --git a/enshi_back/ABAC/postsPolicies/postRules/updateRule.go b/enshi_back/ABAC/postsPolicies/postRules/updateRule.go new file mode 100644 index 0000000..7a1200c --- /dev/null +++ b/enshi_back/ABAC/postsPolicies/postRules/updateRule.go @@ -0,0 +1,17 @@ +package postRules + +import ( + "enshi/middleware/checkRole" + + "github.com/gin-gonic/gin" +) + +// Only owner of the post can change it +func PostUpdateRule(c *gin.Context) (bool, error) { + isOwner, err := checkRole.IsOwnerOfThePost(c) + if err != nil { + return false, err + } + + return isOwner, nil +} diff --git a/enshi_back/middleware/adminMiddleware.go b/enshi_back/middleware/adminMiddleware.go index 3d35800..0ddf300 100644 --- a/enshi_back/middleware/adminMiddleware.go +++ b/enshi_back/middleware/adminMiddleware.go @@ -3,7 +3,6 @@ package middleware import ( rest_api_stuff "enshi/REST_API_stuff" "enshi/middleware/checkRole" - "enshi/middleware/getters" "fmt" "github.com/gin-gonic/gin" @@ -12,14 +11,7 @@ import ( func AdminMiddleware() gin.HandlerFunc { return func(c *gin.Context) { - userId, err := getters.GetUserIdFromContext(c) - - if err != nil || userId == 0 { - rest_api_stuff.BadRequestAnswer(c, err) - c.Abort() - } - - isAdmin, err := checkRole.IsAdmin(userId) + isAdmin, err := checkRole.IsAdmin(c) if err != nil { rest_api_stuff.BadRequestAnswer(c, err) diff --git a/enshi_back/middleware/checkRole/isAdmin.go b/enshi_back/middleware/checkRole/isAdmin.go index 93a356e..4e16a59 100644 --- a/enshi_back/middleware/checkRole/isAdmin.go +++ b/enshi_back/middleware/checkRole/isAdmin.go @@ -4,9 +4,18 @@ import ( "context" db_repo "enshi/db/go_queries" "enshi/db_connection" + "enshi/middleware/getters" + + "github.com/gin-gonic/gin" ) -func IsAdmin(userId int64) (bool, error) { +func IsAdmin(c *gin.Context) (bool, error) { + userId, err := getters.GetUserIdFromContext(c) + + if err != nil { + return false, err + } + user, err := db_repo.New(db_connection.Dbx). GetUserById(context.Background(), userId) diff --git a/enshi_back/middleware/checkRole/isOwner.go b/enshi_back/middleware/checkRole/isOwnerOfThePost.go similarity index 51% rename from enshi_back/middleware/checkRole/isOwner.go rename to enshi_back/middleware/checkRole/isOwnerOfThePost.go index 5f046e9..58cc5b5 100644 --- a/enshi_back/middleware/checkRole/isOwner.go +++ b/enshi_back/middleware/checkRole/isOwnerOfThePost.go @@ -4,9 +4,24 @@ import ( "context" db_repo "enshi/db/go_queries" "enshi/db_connection" + "enshi/middleware/getters" + + "github.com/gin-gonic/gin" ) -func IsOwnerOfThePost(userId int64, postId int64) (bool, error) { +func IsOwnerOfThePost(c *gin.Context) (bool, error) { + postId, err := getters.GetInt64Param(c, "post-id") + + if err != nil { + return false, err + } + + userId, err := getters.GetUserIdFromContext(c) + + if err != nil { + return false, err + } + post, err := db_repo.New(db_connection.Dbx). GetPostsByPostId(context.Background(), postId) diff --git a/enshi_back/middleware/getters/getIntParam.go b/enshi_back/middleware/getters/getIntParam.go new file mode 100644 index 0000000..f5ddd57 --- /dev/null +++ b/enshi_back/middleware/getters/getIntParam.go @@ -0,0 +1,17 @@ +package getters + +import ( + "strconv" + + "github.com/gin-gonic/gin" +) + +func GetInt64Param(c *gin.Context, paramName string) (int64, error) { + int64ParamValue, err := strconv.ParseInt(c.Param(paramName), 10, 64) + + if err != nil { + return -1, err + } + + return int64ParamValue, nil +} diff --git a/enshi_back/middleware/postsMiddleware.go b/enshi_back/middleware/postsMiddleware.go new file mode 100644 index 0000000..fc2ee21 --- /dev/null +++ b/enshi_back/middleware/postsMiddleware.go @@ -0,0 +1,41 @@ +package middleware + +import ( + postspolicies "enshi/ABAC/postsPolicies" + rest_api_stuff "enshi/REST_API_stuff" + "fmt" + + "github.com/gin-gonic/gin" +) + +func PostsMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + + switch c.Request.Method { + case "DELETE": + c.Set("target", postspolicies.DELETE_POST) + case "PUT": + c.Set("target", postspolicies.UPDATE_POST) + case "POST": + c.Set("target", postspolicies.CREATE_POST) + case "GET": + c.Set("target", postspolicies.GET_POST) + } + + isAllowed, err := postspolicies.PostsPolicies(c) + + if err != nil { + rest_api_stuff.InternalErrorAnswer(c, err) + c.Abort() + return + } + + if !isAllowed { + rest_api_stuff.UnauthorizedAnswer(c, fmt.Errorf("you have no permission")) + c.Abort() + return + } + + c.Next() + } +} diff --git a/enshi_back/routes/changeUserProfile.go b/enshi_back/routes/changeUserProfile.go deleted file mode 100644 index f4fd3e5..0000000 --- a/enshi_back/routes/changeUserProfile.go +++ /dev/null @@ -1,17 +0,0 @@ -package routes - -import ( - rest_api_stuff "enshi/REST_API_stuff" - db_repo "enshi/db/go_queries" - - "github.com/gin-gonic/gin" -) - -func ChangeUserProfile(c *gin.Context) { - var userProfileParams db_repo.UpdateProfileByUserIdParams - - if err := c.BindJSON(&userProfileParams); err != nil { - rest_api_stuff.BadRequestAnswer(c, err) - } - -} diff --git a/enshi_back/routes/postsRoutes/deletePost.go b/enshi_back/routes/postsRoutes/deletePost.go index 52c6e1b..b0e3388 100644 --- a/enshi_back/routes/postsRoutes/deletePost.go +++ b/enshi_back/routes/postsRoutes/deletePost.go @@ -7,16 +7,15 @@ import ( "enshi/db_connection" "enshi/middleware/getters" "fmt" + "strconv" "github.com/gin-gonic/gin" ) func DeletePost(c *gin.Context) { - var deletePostId struct { - PostId int64 `json:"post_id"` - } + postId, err := strconv.ParseInt(c.Param("post-id"), 10, 64) - if err := c.BindJSON(&deletePostId); err != nil { + if err != nil { rest_api_stuff.BadRequestAnswer(c, err) return } @@ -28,7 +27,7 @@ func DeletePost(c *gin.Context) { } query := db_repo.New(db_connection.Dbx) - post, err := query.GetPostsByPostId(context.Background(), deletePostId.PostId) + post, err := query.GetPostsByPostId(context.Background(), postId) if err != nil { rest_api_stuff.InternalErrorAnswer(c, err) return @@ -41,7 +40,7 @@ func DeletePost(c *gin.Context) { // TODO: Add block of code, so admin could delete anything - err = query.DeletePostByPostId(context.Background(), deletePostId.PostId) + err = query.DeletePostByPostId(context.Background(), postId) if err != nil { rest_api_stuff.InternalErrorAnswer(c, err) return diff --git a/enshi_back/routes/postsRoutes/getPost.go b/enshi_back/routes/postsRoutes/getPost.go index 2f9e8b2..f05cc2c 100644 --- a/enshi_back/routes/postsRoutes/getPost.go +++ b/enshi_back/routes/postsRoutes/getPost.go @@ -5,24 +5,23 @@ import ( rest_api_stuff "enshi/REST_API_stuff" db_repo "enshi/db/go_queries" "enshi/db_connection" + "enshi/middleware/getters" "net/http" "github.com/gin-gonic/gin" ) func GetPost(c *gin.Context) { - var postParams struct { - PostId int64 `json:"post_id"` - } + postId, err := getters.GetInt64Param(c, "post-id") - if err := c.BindJSON(&postParams); err != nil { + if err != nil { rest_api_stuff.BadRequestAnswer(c, err) return } postData, err := db_repo.New(db_connection.Dbx). - GetPostsByPostId(context.Background(), postParams.PostId) + GetPostsByPostId(context.Background(), postId) if err != nil { rest_api_stuff.InternalErrorAnswer(c, err) diff --git a/enshi_back/routes/postsRoutes/updatePost.go b/enshi_back/routes/postsRoutes/updatePost.go index d1cfd45..8568897 100644 --- a/enshi_back/routes/postsRoutes/updatePost.go +++ b/enshi_back/routes/postsRoutes/updatePost.go @@ -5,9 +5,7 @@ import ( rest_api_stuff "enshi/REST_API_stuff" db_repo "enshi/db/go_queries" "enshi/db_connection" - "enshi/middleware/checkRole" "enshi/middleware/getters" - "fmt" "github.com/gin-gonic/gin" ) @@ -20,20 +18,20 @@ func UpdatePost(c *gin.Context) { return } - userId, err := getters.GetUserIdFromContext(c) + _, err := getters.GetUserIdFromContext(c) if err != nil { rest_api_stuff.InternalErrorAnswer(c, err) return } - if isOwner, _ := checkRole.IsOwnerOfThePost( - userId, - UpdatedPostParams.PostID, - ); !isOwner { - rest_api_stuff.UnauthorizedAnswer(c, fmt.Errorf("you are now allowed to change this")) - return - } + // if isOwner, _ := checkRole.IsOwnerOfThePost( + // userId, + // UpdatedPostParams.PostID, + // ); !isOwner { + // rest_api_stuff.UnauthorizedAnswer(c, fmt.Errorf("you are now allowed to change this")) + // return + // } _, err = db_repo.New( db_connection.Dbx, diff --git a/enshi_back/utils/routesSetup.go b/enshi_back/utils/routesSetup.go index 832273e..3cc9f15 100644 --- a/enshi_back/utils/routesSetup.go +++ b/enshi_back/utils/routesSetup.go @@ -2,7 +2,6 @@ package utils import ( "enshi/middleware" - "enshi/routes" "enshi/routes/authRoutes" "enshi/routes/postsRoutes" "enshi/routes/userProfileRoutes" @@ -29,20 +28,40 @@ func SetupRotes(g *gin.Engine) error { freeGroup.GET("getCookie", testCookie) - freeGroup.POST("login", authRoutes.Login) - freeGroup.POST("registerUser", authRoutes.RegisterUser) - freeGroup.GET("getPost", postsRoutes.GetPost) + freeGroup.POST( + "login", + authRoutes.Login, + ) + freeGroup.POST( + "users", + authRoutes.RegisterUser, + ) + freeGroup.GET( + "posts/:post-id", + postsRoutes.GetPost, + ) // Auth group routes authGroup := g.Group("/") authGroup.Use(middleware.AuthMiddleware()) - authGroup.POST("updatePost", postsRoutes.UpdatePost) - authGroup.POST("createPost", postsRoutes.CreatePost) - authGroup.POST("changeUserProfile", routes.ChangeUserProfile) - authGroup.POST("updateProfile", userProfileRoutes.UpdateUserProfile) + authGroup.PUT( + "posts/:post-id", + postsRoutes.UpdatePost, + ) + authGroup.POST( + "posts", + postsRoutes.CreatePost, + ) + authGroup.DELETE( + "posts/:post-id", + postsRoutes.DeletePost, + ) - authGroup.DELETE("deletePost", postsRoutes.DeletePost) + authGroup.PUT( + "user-profiles", + userProfileRoutes.UpdateUserProfile, + ) // Admin group routes adminGroup := authGroup.Group("/admin/")