123 lines
3.5 KiB
Go
123 lines
3.5 KiB
Go
package rbac
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"tss-rocks-be/ent"
|
|
"tss-rocks-be/ent/permission"
|
|
"tss-rocks-be/ent/role"
|
|
)
|
|
|
|
// DefaultPermissions defines the default permissions for each resource
|
|
var DefaultPermissions = map[string][]string{
|
|
"media": {"create", "read", "update", "delete", "list"},
|
|
"post": {"create", "read", "update", "delete", "list"},
|
|
"daily": {"create", "read", "update", "delete", "list"},
|
|
"user": {"create", "read", "update", "delete", "list"},
|
|
}
|
|
|
|
// DefaultRoles defines the default roles and their permissions
|
|
var DefaultRoles = map[string]map[string][]string{
|
|
"admin": DefaultPermissions,
|
|
"editor": {
|
|
"media": {"create", "read", "update", "list"},
|
|
"post": {"create", "read", "update", "list"},
|
|
"daily": {"create", "read", "update", "list"},
|
|
"user": {"read"},
|
|
},
|
|
"contributor": {
|
|
"media": {"read", "list"},
|
|
"post": {"read", "list"},
|
|
"daily": {"read", "list"},
|
|
},
|
|
}
|
|
|
|
// InitializeRBAC initializes the RBAC system with default roles and permissions
|
|
func InitializeRBAC(ctx context.Context, client *ent.Client) error {
|
|
// Create permissions
|
|
permissionMap := make(map[string]*ent.Permission)
|
|
for resource, actions := range DefaultPermissions {
|
|
for _, action := range actions {
|
|
key := fmt.Sprintf("%s:%s", resource, action)
|
|
permission, err := client.Permission.Query().
|
|
Where(
|
|
permission.ResourceEQ(resource),
|
|
permission.ActionEQ(action),
|
|
).
|
|
Only(ctx)
|
|
if ent.IsNotFound(err) {
|
|
permission, err = client.Permission.Create().
|
|
SetResource(resource).
|
|
SetAction(action).
|
|
SetDescription(fmt.Sprintf("Permission to %s %s", action, resource)).
|
|
Save(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("failed creating permission: %w", err)
|
|
}
|
|
} else if err != nil {
|
|
return fmt.Errorf("failed querying permission: %w", err)
|
|
}
|
|
permissionMap[key] = permission
|
|
}
|
|
}
|
|
|
|
// Create roles with permissions
|
|
for roleName, permissions := range DefaultRoles {
|
|
role, err := client.Role.Query().
|
|
Where(role.NameEQ(roleName)).
|
|
Only(ctx)
|
|
if ent.IsNotFound(err) {
|
|
roleCreate := client.Role.Create().
|
|
SetName(roleName).
|
|
SetDescription(fmt.Sprintf("Role for %s users", roleName))
|
|
|
|
// Add permissions to role
|
|
for resource, actions := range permissions {
|
|
for _, action := range actions {
|
|
key := fmt.Sprintf("%s:%s", resource, action)
|
|
if permission, exists := permissionMap[key]; exists {
|
|
roleCreate.AddPermissions(permission)
|
|
}
|
|
}
|
|
}
|
|
|
|
if _, err := roleCreate.Save(ctx); err != nil {
|
|
return fmt.Errorf("failed creating role %s: %w", roleName, err)
|
|
}
|
|
} else if err != nil {
|
|
return fmt.Errorf("failed querying role: %w", err)
|
|
} else {
|
|
// Update existing role's permissions
|
|
for resource, actions := range permissions {
|
|
for _, action := range actions {
|
|
key := fmt.Sprintf("%s:%s", resource, action)
|
|
if permission, exists := permissionMap[key]; exists {
|
|
err = client.Role.UpdateOne(role).
|
|
AddPermissions(permission).
|
|
Exec(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("failed updating role %s permissions: %w", roleName, err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AssignRoleToUser assigns a role to a user
|
|
func AssignRoleToUser(ctx context.Context, client *ent.Client, userID int, roleName string) error {
|
|
role, err := client.Role.Query().
|
|
Where(role.Name(roleName)).
|
|
Only(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("failed querying role: %w", err)
|
|
}
|
|
|
|
return client.User.UpdateOneID(userID).
|
|
AddRoles(role).
|
|
Exec(ctx)
|
|
}
|