Files
calypso/backend/internal/iam/group.go
2025-12-27 16:58:19 +00:00

219 lines
4.8 KiB
Go

package iam
import (
"time"
"github.com/atlasos/calypso/internal/common/database"
)
// Group represents a user group
type Group struct {
ID string
Name string
Description string
IsSystem bool
CreatedAt time.Time
UpdatedAt time.Time
UserCount int
RoleCount int
}
// GetGroupByID retrieves a group by ID
func GetGroupByID(db *database.DB, groupID string) (*Group, error) {
query := `
SELECT id, name, description, is_system, created_at, updated_at
FROM groups
WHERE id = $1
`
var group Group
err := db.QueryRow(query, groupID).Scan(
&group.ID, &group.Name, &group.Description, &group.IsSystem,
&group.CreatedAt, &group.UpdatedAt,
)
if err != nil {
return nil, err
}
// Get user count
var userCount int
db.QueryRow("SELECT COUNT(*) FROM user_groups WHERE group_id = $1", groupID).Scan(&userCount)
group.UserCount = userCount
// Get role count
var roleCount int
db.QueryRow("SELECT COUNT(*) FROM group_roles WHERE group_id = $1", groupID).Scan(&roleCount)
group.RoleCount = roleCount
return &group, nil
}
// GetGroupByName retrieves a group by name
func GetGroupByName(db *database.DB, name string) (*Group, error) {
query := `
SELECT id, name, description, is_system, created_at, updated_at
FROM groups
WHERE name = $1
`
var group Group
err := db.QueryRow(query, name).Scan(
&group.ID, &group.Name, &group.Description, &group.IsSystem,
&group.CreatedAt, &group.UpdatedAt,
)
if err != nil {
return nil, err
}
return &group, nil
}
// GetUserGroups retrieves all groups for a user
func GetUserGroups(db *database.DB, userID string) ([]string, error) {
query := `
SELECT g.name
FROM groups g
INNER JOIN user_groups ug ON g.id = ug.group_id
WHERE ug.user_id = $1
ORDER BY g.name
`
rows, err := db.Query(query, userID)
if err != nil {
return nil, err
}
defer rows.Close()
var groups []string
for rows.Next() {
var groupName string
if err := rows.Scan(&groupName); err != nil {
return nil, err
}
groups = append(groups, groupName)
}
return groups, rows.Err()
}
// GetGroupUsers retrieves all users in a group
func GetGroupUsers(db *database.DB, groupID string) ([]string, error) {
query := `
SELECT u.id
FROM users u
INNER JOIN user_groups ug ON u.id = ug.user_id
WHERE ug.group_id = $1
ORDER BY u.username
`
rows, err := db.Query(query, groupID)
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()
}
// GetGroupRoles retrieves all roles for a group
func GetGroupRoles(db *database.DB, groupID string) ([]string, error) {
query := `
SELECT r.name
FROM roles r
INNER JOIN group_roles gr ON r.id = gr.role_id
WHERE gr.group_id = $1
ORDER BY r.name
`
rows, err := db.Query(query, groupID)
if err != nil {
return nil, err
}
defer rows.Close()
var roles []string
for rows.Next() {
var role string
if err := rows.Scan(&role); err != nil {
return nil, err
}
roles = append(roles, role)
}
return roles, rows.Err()
}
// AddUserToGroup adds a user to a group
func AddUserToGroup(db *database.DB, userID, groupID, assignedBy string) error {
query := `
INSERT INTO user_groups (user_id, group_id, assigned_by)
VALUES ($1, $2, $3)
ON CONFLICT (user_id, group_id) DO NOTHING
`
_, err := db.Exec(query, userID, groupID, assignedBy)
return err
}
// RemoveUserFromGroup removes a user from a group
func RemoveUserFromGroup(db *database.DB, userID, groupID string) error {
query := `DELETE FROM user_groups WHERE user_id = $1 AND group_id = $2`
_, err := db.Exec(query, userID, groupID)
return err
}
// AddRoleToGroup adds a role to a group
func AddRoleToGroup(db *database.DB, groupID, roleID string) error {
query := `
INSERT INTO group_roles (group_id, role_id)
VALUES ($1, $2)
ON CONFLICT (group_id, role_id) DO NOTHING
`
_, err := db.Exec(query, groupID, roleID)
return err
}
// RemoveRoleFromGroup removes a role from a group
func RemoveRoleFromGroup(db *database.DB, groupID, roleID string) error {
query := `DELETE FROM group_roles WHERE group_id = $1 AND role_id = $2`
_, err := db.Exec(query, groupID, roleID)
return err
}
// GetUserRolesFromGroups retrieves all roles for a user via groups
func GetUserRolesFromGroups(db *database.DB, userID string) ([]string, error) {
query := `
SELECT DISTINCT r.name
FROM roles r
INNER JOIN group_roles gr ON r.id = gr.role_id
INNER JOIN user_groups ug ON gr.group_id = ug.group_id
WHERE ug.user_id = $1
ORDER BY r.name
`
rows, err := db.Query(query, userID)
if err != nil {
return nil, err
}
defer rows.Close()
var roles []string
for rows.Next() {
var role string
if err := rows.Scan(&role); err != nil {
return nil, err
}
roles = append(roles, role)
}
return roles, rows.Err()
}