Files
server/core/lib/Stores/UserRolesStore.php
2026-02-10 18:46:11 -05:00

143 lines
3.8 KiB
PHP

<?php
namespace KTXC\Stores;
use KTXC\Db\DataStore;
use KTXC\Module\ModuleManager;
use KTXF\Utile\UUID;
/**
* Role Store - Database operations for user roles
*/
class UserRolesStore
{
protected const COLLECTION_NAME = 'user_roles';
public function __construct(
protected readonly DataStore $store,
protected readonly ModuleManager $moduleManager
) {}
// =========================================================================
// Role Operations
// =========================================================================
/**
* List all roles for a tenant
*/
public function listRoles(string $tenant): array
{
$cursor = $this->store->selectCollection(self::COLLECTION_NAME)->find(
['tid' => $tenant],
['sort' => ['label' => 1]]
);
$roles = [];
foreach ($cursor as $entry) {
$role = (array)$entry;
// Ensure permissions is an array
if (isset($role['permissions'])) {
$role['permissions'] = (array)$role['permissions'];
}
$roles[] = $role;
}
return $roles;
}
/**
* Fetch role by tenant and role ID
*/
public function fetchByRid(string $tenant, string $rid): ?array
{
$entry = $this->store->selectCollection(self::COLLECTION_NAME)->findOne([
'tid' => $tenant,
'rid' => $rid
]);
if (!$entry) {
return null;
}
return (array)$entry;
}
/**
* Create a new role
*/
public function createRole(string $tenant, array $roleData): array
{
$roleData['tid'] = $tenant;
$roleData['rid'] = $roleData['rid'] ?? UUID::v4();
$roleData['label'] = $roleData['label'] ?? 'Unnamed Role';
$roleData['description'] = $roleData['description'] ?? '';
$roleData['permissions'] = $roleData['permissions'] ?? [];
$roleData['system'] = $roleData['system'] ?? false;
$this->store->selectCollection(self::COLLECTION_NAME)->insertOne($roleData);
return $this->fetchByRid($tenant, $roleData['rid']);
}
/**
* Update an existing role
*/
public function updateRole(string $tenant, string $rid, array $updates): bool
{
// Prevent updating system flag
unset($updates['tid'], $updates['rid'], $updates['system']);
if (empty($updates)) {
return false;
}
$result = $this->store->selectCollection(self::COLLECTION_NAME)->updateOne(
['tid' => $tenant, 'rid' => $rid],
['$set' => $updates]
);
return $result->getModifiedCount() > 0;
}
/**
* Delete a role
*/
public function deleteRole(string $tenant, string $rid): bool
{
// Check if role is system role
$role = $this->fetchByRid($tenant, $rid);
if (!$role || ($role['system'] ?? false)) {
return false; // Cannot delete system roles
}
$result = $this->store->selectCollection(self::COLLECTION_NAME)->deleteOne([
'tid' => $tenant,
'rid' => $rid
]);
return $result->getDeletedCount() > 0;
}
/**
* Count users assigned to a role
*/
public function countUsersInRole(string $tenant, string $rid): int
{
$count = $this->store->selectCollection('user_accounts')->countDocuments([
'tid' => $tenant,
'roles' => $rid
]);
return (int)$count;
}
/**
* Get all available permissions from modules
* Grouped by category with metadata
*/
public function availablePermissions(): array
{
return $this->moduleManager->availablePermissions();
}
}