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) }