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