Another bunch of improvements

This commit is contained in:
Max 2024-11-16 18:04:33 +03:00
parent b454f7a50f
commit cc0caf2ab0
24 changed files with 215 additions and 18 deletions

View File

@ -1,7 +1,7 @@
package postspolicies
import (
postRules "enshi/ABAC/postsPolicies/postRules"
"enshi/ABAC/PostsPolicies/postRules"
"enshi/ABAC/rules"
"github.com/gin-gonic/gin"

View File

@ -1,7 +1,7 @@
package postRules
import (
globalrules "enshi/ABAC/globalRules"
globalrules "enshi/ABAC/GlobalRules"
"enshi/ABAC/rules"
"github.com/gin-gonic/gin"

View File

@ -1,7 +1,7 @@
package postRules
import (
globalrules "enshi/ABAC/globalRules"
globalrules "enshi/ABAC/GlobalRules"
"enshi/ABAC/rules"
"github.com/gin-gonic/gin"

View File

@ -1,7 +1,7 @@
package postRules
import (
globalrules "enshi/ABAC/globalRules"
globalrules "enshi/ABAC/GlobalRules"
"enshi/ABAC/rules"
"github.com/gin-gonic/gin"
@ -11,7 +11,6 @@ import (
func PostUpdateRule(c *gin.Context) (bool, []error) {
rulesToCheck := []rules.RuleFunction{
globalrules.AuthorizedRule,
globalrules.IsOwnerOfThePostRule,
}
isAllowed, errors := rules.CheckRules(

View File

@ -0,0 +1,31 @@
package profilepolicies
import (
profilesrules "enshi/ABAC/ProfilePolicies/ProfilesRules"
"enshi/ABAC/rules"
"github.com/gin-gonic/gin"
)
const (
RESET_PROFILE = "reset_profile"
UPDATE_PROFILE = "update_profile"
CREATE_PROFILE = "create_profile"
GET_PROFILE = "get_profile"
)
func ProfilePolicies(c *gin.Context) (bool, []error) {
target, exists := c.Get("target")
if !exists {
return false, nil
}
// Permit if one permit
switch target {
case UPDATE_PROFILE:
return rules.CheckRule(c, profilesrules.UpdateProfileRule)
}
return false, nil
}

View File

@ -0,0 +1,22 @@
package profilesrules
import (
globalrules "enshi/ABAC/GlobalRules"
"enshi/ABAC/rules"
"github.com/gin-gonic/gin"
)
func UpdateProfileRule(c *gin.Context) (bool, []error) {
rulesToCheck := []rules.RuleFunction{
globalrules.AuthorizedRule,
}
isAllowed, errors := rules.CheckRules(
c,
rulesToCheck,
rules.ALL_RULES_MUST_BE_COMPLETED,
)
return isAllowed, errors
}

View File

@ -1,7 +1,7 @@
package blogrules
import (
globalrules "enshi/ABAC/globalRules"
globalrules "enshi/ABAC/GlobalRules"
"enshi/ABAC/rules"
"github.com/gin-gonic/gin"

View File

@ -1,7 +1,7 @@
package blogrules
import (
globalrules "enshi/ABAC/globalRules"
globalrules "enshi/ABAC/GlobalRules"
"enshi/ABAC/rules"
"github.com/gin-gonic/gin"

View File

@ -1,7 +1,7 @@
package blogrules
import (
globalrules "enshi/ABAC/globalRules"
globalrules "enshi/ABAC/GlobalRules"
"enshi/ABAC/rules"
"github.com/gin-gonic/gin"

View File

@ -21,7 +21,7 @@ RETURNING blog_id, user_id, title, description, category_id, created_at
type CreateBlogByUserIdParams struct {
BlogID int64 `json:"blog_id"`
UserID int64 `json:"user_id"`
Title pgtype.Text `json:"title"`
Title pgtype.Text `json:"title" validate:"required"`
Description pgtype.Text `json:"description"`
CategoryID pgtype.Int4 `json:"category_id"`
}
@ -117,7 +117,7 @@ RETURNING blog_id, user_id, title, description, category_id, created_at
`
type UpdateBlogInfoByBlogIdParams struct {
Title pgtype.Text `json:"title"`
Title pgtype.Text `json:"title" validate:"required"`
Description pgtype.Text `json:"description"`
CategoryID pgtype.Int4 `json:"category_id"`
BlogID int64 `json:"blog_id"`

View File

@ -11,7 +11,7 @@ import (
type Blog struct {
BlogID int64 `json:"blog_id"`
UserID int64 `json:"user_id"`
Title pgtype.Text `json:"title"`
Title pgtype.Text `json:"title" validate:"required"`
Description pgtype.Text `json:"description"`
CategoryID pgtype.Int4 `json:"category_id"`
CreatedAt pgtype.Timestamp `json:"created_at"`

View File

@ -18,6 +18,9 @@ sql:
- column: users.email
go_struct_tag: validate:"required,email"
- column: blogs.title
go_struct_tag: validate:"required"
- db_type: "uuid"
go_type:
import: 'github.com/google/uuid'

View File

@ -0,0 +1,40 @@
package middleware
import (
profilepolicies "enshi/ABAC/ProfilePolicies"
rest_api_stuff "enshi/REST_API_stuff"
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
func ProfileMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
switch c.Request.Method {
case "PUT":
c.Set("target", profilepolicies.UPDATE_PROFILE)
}
isAllowed, errors := profilepolicies.ProfilePolicies(c)
var errorsMap = map[int]string{}
for i, error := range errors {
errorsMap[i] = error.Error()
}
if errors != nil {
c.IndentedJSON(http.StatusUnauthorized, errorsMap)
c.Abort()
return
}
if !isAllowed {
rest_api_stuff.UnauthorizedAnswer(c, fmt.Errorf("you have no permission"))
c.Abort()
return
}
c.Next()
}
}

View File

@ -1,7 +1,7 @@
package middleware
import (
postspolicies "enshi/ABAC/postsPolicies"
postspolicies "enshi/ABAC/PostsPolicies"
rest_api_stuff "enshi/REST_API_stuff"
"fmt"
"net/http"

View File

@ -0,0 +1,48 @@
package blogRoutes
import (
"context"
rest_api_stuff "enshi/REST_API_stuff"
db_repo "enshi/db/go_queries"
"enshi/db_connection"
"enshi/middleware/getters"
"enshi/utils"
"github.com/gin-gonic/gin"
)
func CreateBlog(c *gin.Context) {
blogParams, err := utils.GetContextPayload[db_repo.CreateBlogByUserIdParams](c)
if err != nil {
rest_api_stuff.BadRequestAnswer(c, err)
return
}
userId, err := getters.GetUserIdFromContext(c)
if err != nil {
rest_api_stuff.BadRequestAnswer(c, err)
return
}
blogId, err := utils.GetUUIDv7AsInt64()
if err != nil {
rest_api_stuff.InternalErrorAnswer(c, err)
return
}
blogParams.UserID = userId
blogParams.BlogID = blogId
_, err = db_repo.
New(db_connection.Dbx).
CreateBlogByUserId(
context.Background(),
blogParams,
)
if err != nil {
rest_api_stuff.InternalErrorAnswer(c, err)
return
}
rest_api_stuff.OkAnswer(c, "blog has been created")
}

View File

@ -3,6 +3,7 @@ package routes
import (
"enshi/middleware"
"enshi/routes/authRoutes"
"enshi/routes/blogRoutes"
"enshi/routes/postsRoutes"
"enshi/routes/userProfileRoutes"
"net/http"
@ -57,13 +58,25 @@ func SetupRotes(g *gin.Engine) error {
postsRoutes.DeletePost,
)
blogGroup := g.Group("/")
blogGroup.Use(middleware.BlogsMiddleware())
blogGroup.POST(
"blogs",
blogRoutes.CreateBlog,
)
profilesGroup := g.Group("/")
profilesGroup.Use(middleware.ProfileMiddleware())
profilesGroup.PUT(
"profiles",
userProfileRoutes.UpdateUserProfile,
)
// Auth group routes
authGroup := g.Group("/")
authGroup.Use(middleware.AuthMiddleware())
authGroup.PUT(
"user-profiles",
userProfileRoutes.UpdateUserProfile,
)
// Admin group routes
adminGroup := authGroup.Group("/admin/")

View File

@ -6,14 +6,16 @@ import (
db_repo "enshi/db/go_queries"
"enshi/db_connection"
"enshi/middleware/getters"
"enshi/utils"
"github.com/gin-gonic/gin"
)
func UpdateUserProfile(c *gin.Context) {
var newProfile db_repo.UpdateProfileByUserIdParams
newProfile, err :=
utils.GetContextPayload[db_repo.UpdateProfileByUserIdParams](c)
if err := c.BindJSON(&newProfile); err != nil {
if err != nil {
rest_api_stuff.BadRequestAnswer(c, err)
return
}

View File

@ -0,0 +1,21 @@
package utils
import (
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
)
func GetContextPayload[T any](c *gin.Context) (T, error) {
var params T
if err := c.BindJSON(&params); err != nil {
return params, err
}
validate := validator.New(validator.WithRequiredStructEnabled())
if err := validate.Struct(params); err != nil {
return params, err
}
return params, nil
}

View File

@ -0,0 +1,18 @@
package utils
import (
"encoding/binary"
"github.com/google/uuid"
)
func GetUUIDv7AsInt64() (int64, error) {
uuid, err := uuid.NewV7()
if err != nil {
return -1, err
}
return -int64(
binary.BigEndian.Uint64(uuid[8:]),
), nil
}