From e6094528b569bf9600e74f536d2a130e0840fe68 Mon Sep 17 00:00:00 2001 From: ragilap Date: Mon, 8 Dec 2025 17:30:11 +0700 Subject: [PATCH] add project flock middleware --- internal/middleware/auth.go | 73 ++++++++++++++- internal/middleware/permissions.go | 91 +++++-------------- .../project-flock-kandangs/route.go | 4 +- .../production/project_flocks/route.go | 18 ++-- internal/modules/users/route.go | 8 +- 5 files changed, 106 insertions(+), 88 deletions(-) diff --git a/internal/middleware/auth.go b/internal/middleware/auth.go index 881c3a67..cf5ce1f3 100644 --- a/internal/middleware/auth.go +++ b/internal/middleware/auth.go @@ -3,14 +3,13 @@ package middleware import ( "strings" - "gitlab.com/mbugroup/lti-api.git/internal/config" + "github.com/gofiber/fiber/v2" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" "gitlab.com/mbugroup/lti-api.git/internal/modules/sso/session" service "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services" "gitlab.com/mbugroup/lti-api.git/internal/sso" "gitlab.com/mbugroup/lti-api.git/internal/utils" - - "github.com/gofiber/fiber/v2" + "gitlab.com/mbugroup/lti-api.git/internal/config" ) const ( @@ -199,3 +198,71 @@ func hasAllScopes(have, required []string) bool { } return true } + +// RequirePermissions ensures the authenticated user possesses all specified permissions. +func RequirePermissions(perms ...string) fiber.Handler { + required := canonicalPermissions(perms) + return func(c *fiber.Ctx) error { + if len(required) == 0 { + return c.Next() + } + + ctx, ok := AuthDetails(c) + if !ok || ctx == nil { + return fiber.NewError(fiber.StatusUnauthorized, "Please authenticate") + } + + userPerms := ctx.permissionSet() + if len(userPerms) == 0 { + return fiber.NewError(fiber.StatusForbidden, "Insufficient permission") + } + + for _, perm := range required { + if _, has := userPerms[perm]; !has { + return fiber.NewError(fiber.StatusForbidden, "Insufficient permission") + } + } + + return c.Next() + } +} + +// HasPermission reports whether the current request context includes the given permission. +func HasPermission(c *fiber.Ctx, perm string) bool { + ctx, ok := AuthDetails(c) + if !ok || ctx == nil { + return false + } + perm = canonicalPermission(perm) + if perm == "" { + return false + } + _, has := ctx.permissionSet()[perm] + return has +} + +func (a *AuthContext) permissionSet() map[string]struct{} { + if a == nil || a.Permissions == nil { + return nil + } + return a.Permissions +} + +func canonicalPermissions(perms []string) []string { + out := make([]string, 0, len(perms)) + seen := make(map[string]struct{}, len(perms)) + for _, perm := range perms { + if canonical := canonicalPermission(perm); canonical != "" { + if _, ok := seen[canonical]; ok { + continue + } + seen[canonical] = struct{}{} + out = append(out, canonical) + } + } + return out +} + +func canonicalPermission(perm string) string { + return strings.ToLower(strings.TrimSpace(perm)) +} \ No newline at end of file diff --git a/internal/middleware/permissions.go b/internal/middleware/permissions.go index 3ebe6866..37e26b47 100644 --- a/internal/middleware/permissions.go +++ b/internal/middleware/permissions.go @@ -1,75 +1,26 @@ package middleware -import ( - "strings" +//project-flock +const ( + P_ProjectFlockKandangsClosing = "lti.production.project_flock_kandangs.closing" + P_ProjectFlockKandangsGetAll = "lti.production.project_flock_kandangs.list" + P_ProjectFlockKandangsGetOne = "lti.production.project_flock_kandangs.detail" - "github.com/gofiber/fiber/v2" + P_ProjectFlockGetAll = "lti.production.project_flocks.list" + P_ProjectFlockCreate = "lti.production.project_flocks.create" + P_ProjectFlockGetOne = "lti.production.project_flocks.detail" + P_ProjectFlockUpdate = "lti.production.project_flocks.update" + P_ProjectFlockDelete = "lti.production.project_flocks.delete" + P_ProjectFlockApprove = "lti.production.project_flocks.approve" + P_ProjectFlockLookup = "lti.production.project_flocks.lookup" + P_ProjectFlockNextPeriod = "lti.production.project_flocks.next_period" + P_ProjectFlockResubmit = "lti.production.project_flocks.resubmit" ) -// RequirePermissions ensures the authenticated user possesses all specified permissions. -func RequirePermissions(perms ...string) fiber.Handler { - required := canonicalPermissions(perms) - return func(c *fiber.Ctx) error { - if len(required) == 0 { - return c.Next() - } - - ctx, ok := AuthDetails(c) - if !ok || ctx == nil { - return fiber.NewError(fiber.StatusUnauthorized, "Please authenticate") - } - - userPerms := ctx.permissionSet() - if len(userPerms) == 0 { - return fiber.NewError(fiber.StatusForbidden, "Insufficient permission") - } - - for _, perm := range required { - if _, has := userPerms[perm]; !has { - return fiber.NewError(fiber.StatusForbidden, "Insufficient permission") - } - } - - return c.Next() - } -} - -// HasPermission reports whether the current request context includes the given permission. -func HasPermission(c *fiber.Ctx, perm string) bool { - ctx, ok := AuthDetails(c) - if !ok || ctx == nil { - return false - } - perm = canonicalPermission(perm) - if perm == "" { - return false - } - _, has := ctx.permissionSet()[perm] - return has -} - -func (a *AuthContext) permissionSet() map[string]struct{} { - if a == nil || a.Permissions == nil { - return nil - } - return a.Permissions -} - -func canonicalPermissions(perms []string) []string { - out := make([]string, 0, len(perms)) - seen := make(map[string]struct{}, len(perms)) - for _, perm := range perms { - if canonical := canonicalPermission(perm); canonical != "" { - if _, ok := seen[canonical]; ok { - continue - } - seen[canonical] = struct{}{} - out = append(out, canonical) - } - } - return out -} - -func canonicalPermission(perm string) string { - return strings.ToLower(strings.TrimSpace(perm)) -} +//recording +const ( + PermissionRecordingRead = "recording.index" + PermissionRecordingCreate = "recording.create" + PermissionRecordingUpdate = "recording.update" + PermissionRecordingDelete = "recording.delete" +) \ No newline at end of file diff --git a/internal/modules/production/project-flock-kandangs/route.go b/internal/modules/production/project-flock-kandangs/route.go index 7bab770e..d4dfec30 100644 --- a/internal/modules/production/project-flock-kandangs/route.go +++ b/internal/modules/production/project-flock-kandangs/route.go @@ -20,7 +20,7 @@ func ProjectFlockKandangRoutes(v1 fiber.Router, u user.UserService, s projectFlo // route.Patch("/:id", m.Auth(u), ctrl.UpdateOne) // route.Delete("/:id", m.Auth(u), ctrl.DeleteOne) - route.Get("/", ctrl.GetAll) - route.Get("/:id", ctrl.GetOne) + route.Get("/",m.RequirePermissions(m.P_ProjectFlockKandangsGetAll), ctrl.GetAll) + route.Get("/:id",m.RequirePermissions(m.P_ProjectFlockKandangsGetOne), ctrl.GetOne) } diff --git a/internal/modules/production/project_flocks/route.go b/internal/modules/production/project_flocks/route.go index 710f5225..a962fd56 100644 --- a/internal/modules/production/project_flocks/route.go +++ b/internal/modules/production/project_flocks/route.go @@ -15,14 +15,14 @@ func ProjectflockRoutes(v1 fiber.Router, u user.UserService, s projectflock.Proj route := v1.Group("/project-flocks") route.Use(m.Auth(u)) - route.Get("/", ctrl.GetAll) - route.Post("/", ctrl.CreateOne) - route.Get("/:id", ctrl.GetOne) - route.Patch("/:id", ctrl.UpdateOne) - route.Delete("/:id", ctrl.DeleteOne) - route.Get("/kandangs/lookup", ctrl.LookupProjectFlockKandang) - route.Post("/approvals", ctrl.Approval) - route.Get("/locations/:location_id/periods", ctrl.GetPeriodSummary) - route.Put("/:id/resubmit", ctrl.Resubmit) + route.Get("/",m.RequirePermissions(m.P_ProjectFlockGetAll),ctrl.GetAll) + route.Post("/",m.RequirePermissions(m.P_ProjectFlockCreate), ctrl.CreateOne) + route.Get("/:id",m.RequirePermissions(m.P_ProjectFlockGetOne), ctrl.GetOne) + route.Patch("/:id",m.RequirePermissions(m.P_ProjectFlockUpdate), ctrl.UpdateOne) + route.Delete("/:id",m.RequirePermissions(m.P_ProjectFlockGetAll), ctrl.DeleteOne) + route.Get("/kandangs/lookup",m.RequirePermissions(m.P_ProjectFlockLookup), ctrl.LookupProjectFlockKandang) + route.Post("/approvals",m.RequirePermissions(m.P_ProjectFlockApprove), ctrl.Approval) + route.Get("/locations/:location_id/periods",m.RequirePermissions(m.P_ProjectFlockNextPeriod), ctrl.GetPeriodSummary) + route.Put("/:id/resubmit",m.RequirePermissions(m.P_ProjectFlockResubmit), ctrl.Resubmit) } diff --git a/internal/modules/users/route.go b/internal/modules/users/route.go index 9ba6bfb3..1093312f 100644 --- a/internal/modules/users/route.go +++ b/internal/modules/users/route.go @@ -3,7 +3,7 @@ package users import ( "github.com/gofiber/fiber/v2" - "gitlab.com/mbugroup/lti-api.git/internal/middleware" + m "gitlab.com/mbugroup/lti-api.git/internal/middleware" controller "gitlab.com/mbugroup/lti-api.git/internal/modules/users/controllers" user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services" ) @@ -12,11 +12,11 @@ func UserRoutes(v1 fiber.Router, s user.UserService) { ctrl := controller.NewUserController(s) route := v1.Group("/users") - route.Use(middleware.Auth(s)) + route.Use(m.Auth(s)) - route.Get("/", ctrl.GetAll) + route.Get("/", m.RequirePermissions("lti.users.list"), ctrl.GetAll) // route.Post("/", ctrl.CreateOne) - route.Get("/:id", ctrl.GetOne) + route.Get("/:id", m.RequirePermissions("lti.users.detail"), ctrl.GetOne) // route.Patch("/:id", ctrl.UpdateOne) // route.Delete("/:id", ctrl.DeleteOne) }