238 lines
5.4 KiB
Go
238 lines
5.4 KiB
Go
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()
|
|
}
|