add project flock middleware

This commit is contained in:
ragilap
2025-12-08 17:30:11 +07:00
parent 89b23b0653
commit e6094528b5
5 changed files with 106 additions and 88 deletions
+70 -3
View File
@@ -3,14 +3,13 @@ package middleware
import ( import (
"strings" "strings"
"gitlab.com/mbugroup/lti-api.git/internal/config" "github.com/gofiber/fiber/v2"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities" entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
"gitlab.com/mbugroup/lti-api.git/internal/modules/sso/session" "gitlab.com/mbugroup/lti-api.git/internal/modules/sso/session"
service "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services" 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/sso"
"gitlab.com/mbugroup/lti-api.git/internal/utils" "gitlab.com/mbugroup/lti-api.git/internal/utils"
"gitlab.com/mbugroup/lti-api.git/internal/config"
"github.com/gofiber/fiber/v2"
) )
const ( const (
@@ -199,3 +198,71 @@ func hasAllScopes(have, required []string) bool {
} }
return true 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))
}
+21 -70
View File
@@ -1,75 +1,26 @@
package middleware package middleware
import ( //project-flock
"strings" 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. //recording
func RequirePermissions(perms ...string) fiber.Handler { const (
required := canonicalPermissions(perms) PermissionRecordingRead = "recording.index"
return func(c *fiber.Ctx) error { PermissionRecordingCreate = "recording.create"
if len(required) == 0 { PermissionRecordingUpdate = "recording.update"
return c.Next() PermissionRecordingDelete = "recording.delete"
} )
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))
}
@@ -20,7 +20,7 @@ func ProjectFlockKandangRoutes(v1 fiber.Router, u user.UserService, s projectFlo
// route.Patch("/:id", m.Auth(u), ctrl.UpdateOne) // route.Patch("/:id", m.Auth(u), ctrl.UpdateOne)
// route.Delete("/:id", m.Auth(u), ctrl.DeleteOne) // route.Delete("/:id", m.Auth(u), ctrl.DeleteOne)
route.Get("/", ctrl.GetAll) route.Get("/",m.RequirePermissions(m.P_ProjectFlockKandangsGetAll), ctrl.GetAll)
route.Get("/:id", ctrl.GetOne) route.Get("/:id",m.RequirePermissions(m.P_ProjectFlockKandangsGetOne), ctrl.GetOne)
} }
@@ -15,14 +15,14 @@ func ProjectflockRoutes(v1 fiber.Router, u user.UserService, s projectflock.Proj
route := v1.Group("/project-flocks") route := v1.Group("/project-flocks")
route.Use(m.Auth(u)) route.Use(m.Auth(u))
route.Get("/", ctrl.GetAll) route.Get("/",m.RequirePermissions(m.P_ProjectFlockGetAll),ctrl.GetAll)
route.Post("/", ctrl.CreateOne) route.Post("/",m.RequirePermissions(m.P_ProjectFlockCreate), ctrl.CreateOne)
route.Get("/:id", ctrl.GetOne) route.Get("/:id",m.RequirePermissions(m.P_ProjectFlockGetOne), ctrl.GetOne)
route.Patch("/:id", ctrl.UpdateOne) route.Patch("/:id",m.RequirePermissions(m.P_ProjectFlockUpdate), ctrl.UpdateOne)
route.Delete("/:id", ctrl.DeleteOne) route.Delete("/:id",m.RequirePermissions(m.P_ProjectFlockGetAll), ctrl.DeleteOne)
route.Get("/kandangs/lookup", ctrl.LookupProjectFlockKandang) route.Get("/kandangs/lookup",m.RequirePermissions(m.P_ProjectFlockLookup), ctrl.LookupProjectFlockKandang)
route.Post("/approvals", ctrl.Approval) route.Post("/approvals",m.RequirePermissions(m.P_ProjectFlockApprove), ctrl.Approval)
route.Get("/locations/:location_id/periods", ctrl.GetPeriodSummary) route.Get("/locations/:location_id/periods",m.RequirePermissions(m.P_ProjectFlockNextPeriod), ctrl.GetPeriodSummary)
route.Put("/:id/resubmit", ctrl.Resubmit) route.Put("/:id/resubmit",m.RequirePermissions(m.P_ProjectFlockResubmit), ctrl.Resubmit)
} }
+4 -4
View File
@@ -3,7 +3,7 @@ package users
import ( import (
"github.com/gofiber/fiber/v2" "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" controller "gitlab.com/mbugroup/lti-api.git/internal/modules/users/controllers"
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services" 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) ctrl := controller.NewUserController(s)
route := v1.Group("/users") 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.Post("/", ctrl.CreateOne)
route.Get("/:id", ctrl.GetOne) route.Get("/:id", m.RequirePermissions("lti.users.detail"), ctrl.GetOne)
// route.Patch("/:id", ctrl.UpdateOne) // route.Patch("/:id", ctrl.UpdateOne)
// route.Delete("/:id", ctrl.DeleteOne) // route.Delete("/:id", ctrl.DeleteOne)
} }