package iam import ( "time" "github.com/atlasos/calypso/internal/common/database" ) // Role represents a system role type Role struct { ID string Name string Description string IsSystem bool CreatedAt time.Time UpdatedAt time.Time } // GetRoleByID retrieves a role by ID func GetRoleByID(db *database.DB, roleID string) (*Role, error) { query := ` SELECT id, name, description, is_system, created_at, updated_at FROM roles WHERE id = $1 ` var role Role err := db.QueryRow(query, roleID).Scan( &role.ID, &role.Name, &role.Description, &role.IsSystem, &role.CreatedAt, &role.UpdatedAt, ) if err != nil { return nil, err } return &role, nil } // GetRoleByName retrieves a role by name func GetRoleByName(db *database.DB, name string) (*Role, error) { query := ` SELECT id, name, description, is_system, created_at, updated_at FROM roles WHERE name = $1 ` var role Role err := db.QueryRow(query, name).Scan( &role.ID, &role.Name, &role.Description, &role.IsSystem, &role.CreatedAt, &role.UpdatedAt, ) if err != nil { return nil, err } return &role, nil } // ListRoles retrieves all roles func ListRoles(db *database.DB) ([]*Role, error) { query := ` SELECT id, name, description, is_system, created_at, updated_at FROM roles ORDER BY name ` rows, err := db.Query(query) if err != nil { return nil, err } defer rows.Close() var roles []*Role for rows.Next() { var role Role if err := rows.Scan( &role.ID, &role.Name, &role.Description, &role.IsSystem, &role.CreatedAt, &role.UpdatedAt, ); err != nil { return nil, err } roles = append(roles, &role) } return roles, rows.Err() } // CreateRole creates a new role func CreateRole(db *database.DB, name, description string) (*Role, error) { query := ` INSERT INTO roles (name, description) VALUES ($1, $2) RETURNING id, name, description, is_system, created_at, updated_at ` var role Role err := db.QueryRow(query, name, description).Scan( &role.ID, &role.Name, &role.Description, &role.IsSystem, &role.CreatedAt, &role.UpdatedAt, ) if err != nil { return nil, err } return &role, nil } // UpdateRole updates an existing role func UpdateRole(db *database.DB, roleID, name, description string) error { query := ` UPDATE roles SET name = $1, description = $2, updated_at = NOW() WHERE id = $3 ` _, err := db.Exec(query, name, description, roleID) return err } // DeleteRole deletes a role func DeleteRole(db *database.DB, roleID string) error { query := `DELETE FROM roles WHERE id = $1` _, err := db.Exec(query, roleID) return err } // GetRoleUsers retrieves all users with a specific role func GetRoleUsers(db *database.DB, roleID string) ([]string, error) { query := ` SELECT u.id FROM users u INNER JOIN user_roles ur ON u.id = ur.user_id WHERE ur.role_id = $1 ORDER BY u.username ` rows, err := db.Query(query, roleID) if err != nil { return nil, err } defer rows.Close() var userIDs []string for rows.Next() { var userID string if err := rows.Scan(&userID); err != nil { return nil, err } userIDs = append(userIDs, userID) } return userIDs, rows.Err() } // GetRolePermissions retrieves all permissions for a role func GetRolePermissions(db *database.DB, roleID string) ([]string, error) { query := ` SELECT p.name FROM permissions p INNER JOIN role_permissions rp ON p.id = rp.permission_id WHERE rp.role_id = $1 ORDER BY p.name ` rows, err := db.Query(query, roleID) if err != nil { return nil, err } defer rows.Close() var permissions []string for rows.Next() { var perm string if err := rows.Scan(&perm); err != nil { return nil, err } permissions = append(permissions, perm) } return permissions, rows.Err() } // AddPermissionToRole assigns a permission to a role func AddPermissionToRole(db *database.DB, roleID, permissionID string) error { query := ` INSERT INTO role_permissions (role_id, permission_id) VALUES ($1, $2) ON CONFLICT (role_id, permission_id) DO NOTHING ` _, err := db.Exec(query, roleID, permissionID) return err } // RemovePermissionFromRole removes a permission from a role func RemovePermissionFromRole(db *database.DB, roleID, permissionID string) error { query := `DELETE FROM role_permissions WHERE role_id = $1 AND permission_id = $2` _, err := db.Exec(query, roleID, permissionID) return err } // GetPermissionIDByName retrieves a permission ID by name func GetPermissionIDByName(db *database.DB, permissionName string) (string, error) { var permissionID string err := db.QueryRow("SELECT id FROM permissions WHERE name = $1", permissionName).Scan(&permissionID) return permissionID, err } // ListPermissions retrieves all permissions func ListPermissions(db *database.DB) ([]map[string]interface{}, error) { query := ` SELECT id, name, resource, action, description FROM permissions ORDER BY resource, action ` rows, err := db.Query(query) if err != nil { return nil, err } defer rows.Close() var permissions []map[string]interface{} for rows.Next() { var id, name, resource, action, description string if err := rows.Scan(&id, &name, &resource, &action, &description); err != nil { return nil, err } permissions = append(permissions, map[string]interface{}{ "id": id, "name": name, "resource": resource, "action": action, "description": description, }) } return permissions, rows.Err() }