Better handling of permissions

This commit is contained in:
cdricms
2025-01-31 13:07:25 +01:00
parent acfd2c7b14
commit f7dd0c60d6
12 changed files with 45 additions and 57 deletions

View File

@@ -11,13 +11,15 @@ var EventsRoutes = map[string]core.Handler{
Middlewares: []core.Middleware{Methods("GET")}}, Middlewares: []core.Middleware{Methods("GET")}},
"/events/new": { "/events/new": {
Handler: events.HandleNew, Handler: events.HandleNew,
Middlewares: []core.Middleware{Methods("POST"), AuthJWT}}, Middlewares: []core.Middleware{Methods("POST"),
HasPermissions("events", "insert"), AuthJWT}},
"/events/{event_uuid}": { "/events/{event_uuid}": {
Handler: events.HandleEvent, Handler: events.HandleEvent,
Middlewares: []core.Middleware{Methods("GET")}}, Middlewares: []core.Middleware{Methods("GET")}},
"/events/{event_uuid}/delete": { "/events/{event_uuid}/delete": {
Handler: events.HandleDelete, Handler: events.HandleDelete,
Middlewares: []core.Middleware{Methods("DELETE"), AuthJWT}}, Middlewares: []core.Middleware{Methods("DELETE"),
HasPermissions("events", "delete"), AuthJWT}},
"/events/{event_uuid}/update": { "/events/{event_uuid}/update": {
Handler: events.HandleUpdate, Handler: events.HandleUpdate,
Middlewares: []core.Middleware{ Middlewares: []core.Middleware{

View File

@@ -159,24 +159,6 @@ func HasPermissions(resource string, actions ...string) core.Middleware {
return return
} }
// permissions := utils.MergeArrays(
// utils.Map(user.Roles, func(r models.Role) []models.Permission {
// return r.Permissions
// })...)
//
// for _, action := range actions {
// permission := utils.Find(permissions, func(p models.Permission, i int) bool {
// return resource == p.Resource && action == p.Action
// })
// if permission == nil {
// core.JSONError{
// Status: core.Error,
// Message: fmt.Sprintf("The user doesn't have the proper permission %s:%s", resource, action),
// }.Respond(w, http.StatusUnauthorized)
// return
// }
// }
permissionsSet := make(map[string]struct{}) // Set to store unique permissions permissionsSet := make(map[string]struct{}) // Set to store unique permissions
// Populate the set with user's permissions // Populate the set with user's permissions

View File

@@ -9,21 +9,14 @@ import (
) )
func HandlePermission(w http.ResponseWriter, r *http.Request) { func HandlePermission(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("permission_id") resource := r.PathValue("resource")
var permission models.Permission action := r.PathValue("action")
count, err := core.DB.NewSelect(). var permissions models.Permission
Model(&permission). err := core.DB.NewSelect().
Where("id = ?", id). Model(&permissions).
Where("resource = ? AND action = ?", resource, action).
Limit(1). Limit(1).
ScanAndCount(context.Background()) Scan(context.Background())
if count == 0 {
core.JSONSuccess{
Status: core.Success,
Message: "Permission not found.",
}.Respond(w, http.StatusNotFound)
return
}
if err != nil { if err != nil {
core.JSONError{ core.JSONError{
@@ -35,7 +28,7 @@ func HandlePermission(w http.ResponseWriter, r *http.Request) {
core.JSONSuccess{ core.JSONSuccess{
Status: core.Success, Status: core.Success,
Message: "Permission found.", Message: "Permissions found.",
Data: permission, Data: permissions,
}.Respond(w, http.StatusOK) }.Respond(w, http.StatusOK)
} }

View File

@@ -14,12 +14,12 @@ var PermissionsRoutes = map[string]core.Handler{
Handler: permissions.HandleResourceActions, Handler: permissions.HandleResourceActions,
Middlewares: []core.Middleware{Methods("GET"), AuthJWT}, Middlewares: []core.Middleware{Methods("GET"), AuthJWT},
}, },
"/permissions/{permission_id}": {
Handler: permissions.HandlePermission,
Middlewares: []core.Middleware{Methods("GET"), AuthJWT},
},
"/permissions/resources/{resource}": { "/permissions/resources/{resource}": {
Handler: permissions.HandlePermissionsResource, Handler: permissions.HandlePermissionsResource,
Middlewares: []core.Middleware{Methods("GET"), AuthJWT}, Middlewares: []core.Middleware{Methods("GET"), AuthJWT},
}, },
"/permissions/resources/{resource}/{action}": {
Handler: permissions.HandlePermission,
Middlewares: []core.Middleware{Methods("GET"), AuthJWT},
},
} }

View File

@@ -39,7 +39,8 @@ func HandleAddPermission(w http.ResponseWriter, r *http.Request) {
} }
permissionRole := models.PermissionToRole{ permissionRole := models.PermissionToRole{
PermissionID: permission.ID, PermissionResource: permission.Resource,
PermissionAction: permission.Action,
RoleID: role.ID, RoleID: role.ID,
} }
_, err = core.DB.NewInsert().Model(&permissionRole).Ignore(). _, err = core.DB.NewInsert().Model(&permissionRole).Ignore().

View File

@@ -26,7 +26,7 @@ func HandleRemovePermission(w http.ResponseWriter, r *http.Request) {
} }
_, err = core.DB.NewDelete().Model((*models.PermissionToRole)(nil)). _, err = core.DB.NewDelete().Model((*models.PermissionToRole)(nil)).
Where("permission_id = ? AND role_id = ?", permission.ID, role_id). Where("resource = ? AND action = ? AND role_id = ?", permission.Resource, permission.Action, role_id).
Exec(ctx) Exec(ctx)
if err != nil { if err != nil {

View File

@@ -8,8 +8,7 @@ type PermissionConditions struct {
type Permission struct { type Permission struct {
bun.BaseModel `bun:"table:permissions"` bun.BaseModel `bun:"table:permissions"`
ID int `bun:"id,pk,autoincrement" json:"id"` Resource string `bun:"resource,pk" json:"resource"`
Resource string `bun:"resource,notnull,unique:permission" json:"resource"` Action string `bun:"action,pk" json:"action"`
Action string `bun:"action,notnull,unique:permission" json:"action"`
Conditions PermissionConditions `bun:"conditions,type:jsonb" json:"conditions"` Conditions PermissionConditions `bun:"conditions,type:jsonb" json:"conditions"`
} }

View File

@@ -6,11 +6,12 @@ import (
) )
type PermissionToRole struct { type PermissionToRole struct {
bun.BaseModel `bun:"table:permissions_to_users"` bun.BaseModel `bun:"table:permissions_to_roles"`
PermissionID int `bun:"permission_id,pk"` PermissionAction string `bun:"action,pk"`
PermissionResource string `bun:"resource,pk"`
RoleID uuid.UUID `bun:"type:uuid,pk"` RoleID uuid.UUID `bun:"type:uuid,pk"`
Permission *Permission `bun:"rel:belongs-to,join:permission_id=id"` Permission *Permission `bun:"rel:belongs-to,join:resource=resource,action=action"`
Role *Role `bun:"rel:belongs-to,join:role_id=id"` Role *Role `bun:"rel:belongs-to,join:role_id=id"`
} }

View File

@@ -10,5 +10,5 @@ type Role struct {
ID uuid.UUID `bun:"id,pk,type:uuid,default:gen_random_uuid()" json:"id"` ID uuid.UUID `bun:"id,pk,type:uuid,default:gen_random_uuid()" json:"id"`
Name string `bun:"name,unique,notnull" json:"name"` Name string `bun:"name,unique,notnull" json:"name"`
Permissions []Permission `bun:"m2m:permissions_to_users,join:Role=Permission" json:"permissions,omitempty"` Permissions []Permission `bun:"m2m:permissions_to_roles,join:Role=Permission" json:"permissions,omitempty"`
} }

View File

@@ -68,7 +68,7 @@ func main() {
"/": { "/": {
Handler: handler, Handler: handler,
Middlewares: []core.Middleware{api.Methods("GET"), Middlewares: []core.Middleware{api.Methods("GET"),
api.HasPermissions("users", "insert", "jfkdjfdk"), api.HasPermissions("blogs", "insert"),
api.AuthJWT, api.AuthJWT,
}}, }},
"/contact": { "/contact": {

View File

@@ -15,8 +15,19 @@ const geistMono = Geist_Mono({
}); });
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Create Next App", title: "Latosa Escrima France",
description: "Generated by create next app", description: "Site officiel de Latosa Escrima France.",
openGraph: {
title: "Latosa Escrima France",
description: "Site officiel de Latosa Escrima France.",
type: "website",
countryName: "France",
},
applicationName: "Latosa Escrima France",
authors: {
name: "Wing Tsun Picardie",
url: "https://www.youtube.com/@WingTsunPicardie",
},
}; };
export default function RootLayout({ export default function RootLayout({

View File

@@ -18,7 +18,6 @@ const Hero = () => {
alt="logo" alt="logo"
className="h-16" className="h-16"
/> />
<Badge variant="outline">Latosa-Escrima</Badge>
<div> <div>
<h1 className="mb-6 text-pretty text-2xl font-bold text-primary lg:text-5xl"> <h1 className="mb-6 text-pretty text-2xl font-bold text-primary lg:text-5xl">
Trouvez votre équilibre avec Latosa-Escrima Trouvez votre équilibre avec Latosa-Escrima