160 lines
4.1 KiB
Go
160 lines
4.1 KiB
Go
package client
|
|
|
|
import (
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
"netidhub-saas-be/app/database/entity"
|
|
)
|
|
|
|
// GetAccessibleClientIDs returns all client IDs that a user has access to
|
|
// This includes:
|
|
// - User's primary client
|
|
// - Clients granted via UserClientAccess
|
|
// - Sub-clients if IncludeSubClients is true
|
|
func GetAccessibleClientIDs(db *gorm.DB, userId uint, isSuperAdmin bool) ([]uuid.UUID, error) {
|
|
if isSuperAdmin {
|
|
// Super admin has access to ALL clients
|
|
return nil, nil // nil means no filter (all clients)
|
|
}
|
|
|
|
var clientIDs []uuid.UUID
|
|
|
|
// Get user's primary client
|
|
var user entity.Users
|
|
if err := db.Select("client_id").Where("id = ?", userId).First(&user).Error; err == nil {
|
|
if user.ClientId != nil {
|
|
clientIDs = append(clientIDs, *user.ClientId)
|
|
}
|
|
}
|
|
|
|
// Get additional client accesses
|
|
var accesses []entity.UserClientAccess
|
|
err := db.Where("user_id = ? AND is_active = ?", userId, true).
|
|
Preload("Client").
|
|
Find(&accesses).Error
|
|
|
|
if err != nil {
|
|
return clientIDs, err
|
|
}
|
|
|
|
for _, access := range accesses {
|
|
clientIDs = append(clientIDs, access.ClientId)
|
|
|
|
// If IncludeSubClients is true, get all sub-clients
|
|
if access.IncludeSubClients != nil && *access.IncludeSubClients {
|
|
subClientIDs, err := GetSubClientIDs(db, access.ClientId)
|
|
if err == nil {
|
|
clientIDs = append(clientIDs, subClientIDs...)
|
|
}
|
|
}
|
|
}
|
|
|
|
return removeDuplicateUUIDs(clientIDs), nil
|
|
}
|
|
|
|
// GetSubClientIDs returns all sub-client IDs for a given parent client (recursive)
|
|
func GetSubClientIDs(db *gorm.DB, parentClientId uuid.UUID) ([]uuid.UUID, error) {
|
|
var clientIDs []uuid.UUID
|
|
var subClients []entity.Clients
|
|
|
|
// Get direct children
|
|
err := db.Where("parent_client_id = ? AND is_active = ?", parentClientId, true).
|
|
Find(&subClients).Error
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, subClient := range subClients {
|
|
clientIDs = append(clientIDs, subClient.ID)
|
|
|
|
// Recursively get sub-clients of sub-clients
|
|
nestedSubClientIDs, err := GetSubClientIDs(db, subClient.ID)
|
|
if err == nil {
|
|
clientIDs = append(clientIDs, nestedSubClientIDs...)
|
|
}
|
|
}
|
|
|
|
return clientIDs, nil
|
|
}
|
|
|
|
// GetClientHierarchy returns the full client hierarchy (parent chain and children)
|
|
func GetClientHierarchy(db *gorm.DB, clientId uuid.UUID) (*entity.Clients, error) {
|
|
var client entity.Clients
|
|
|
|
err := db.Preload("ParentClient").
|
|
Preload("SubClients", "is_active = ?", true).
|
|
Where("id = ?", clientId).
|
|
First(&client).Error
|
|
|
|
return &client, err
|
|
}
|
|
|
|
// HasAccessToClient checks if a user has access to a specific client
|
|
func HasAccessToClient(db *gorm.DB, userId uint, clientId uuid.UUID, isSuperAdmin bool) (bool, error) {
|
|
if isSuperAdmin {
|
|
return true, nil
|
|
}
|
|
|
|
accessibleClientIDs, err := GetAccessibleClientIDs(db, userId, isSuperAdmin)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
// nil means all clients (super admin case)
|
|
if accessibleClientIDs == nil {
|
|
return true, nil
|
|
}
|
|
|
|
for _, id := range accessibleClientIDs {
|
|
if id == clientId {
|
|
return true, nil
|
|
}
|
|
}
|
|
|
|
return false, nil
|
|
}
|
|
|
|
// GetParentClientID returns the root/parent client ID for a given client
|
|
func GetParentClientID(db *gorm.DB, clientId uuid.UUID) (*uuid.UUID, error) {
|
|
var client entity.Clients
|
|
|
|
err := db.Preload("ParentClient").Where("id = ?", clientId).First(&client).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// If has parent, recursively get the root parent
|
|
if client.ParentClientId != nil {
|
|
return GetParentClientID(db, *client.ParentClientId)
|
|
}
|
|
|
|
// This is the root parent
|
|
return &client.ID, nil
|
|
}
|
|
|
|
// IsParentClient checks if a client is a parent client (has sub-clients)
|
|
func IsParentClient(db *gorm.DB, clientId uuid.UUID) (bool, error) {
|
|
var count int64
|
|
err := db.Model(&entity.Clients{}).
|
|
Where("parent_client_id = ? AND is_active = ?", clientId, true).
|
|
Count(&count).Error
|
|
|
|
return count > 0, err
|
|
}
|
|
|
|
// removeDuplicateUUIDs removes duplicate UUIDs from a slice
|
|
func removeDuplicateUUIDs(uuids []uuid.UUID) []uuid.UUID {
|
|
encountered := map[uuid.UUID]bool{}
|
|
result := []uuid.UUID{}
|
|
|
|
for _, uuid := range uuids {
|
|
if !encountered[uuid] {
|
|
encountered[uuid] = true
|
|
result = append(result, uuid)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|