144 lines
4.1 KiB
PHP
144 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace KTXC\Service;
|
|
|
|
use KTXC\SessionTenant;
|
|
use KTXC\Stores\UserRolesStore;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
/**
|
|
* User Roles Service - Business logic for user role management
|
|
*/
|
|
class UserRolesService
|
|
{
|
|
public function __construct(
|
|
private readonly SessionTenant $tenantIdentity,
|
|
private readonly UserRolesStore $roleStore,
|
|
private readonly LoggerInterface $logger
|
|
) {}
|
|
|
|
// =========================================================================
|
|
// Role Operations
|
|
// =========================================================================
|
|
|
|
/**
|
|
* List all roles for current tenant
|
|
*/
|
|
public function listRoles(): array
|
|
{
|
|
return $this->roleStore->listRoles($this->tenantIdentity->identifier());
|
|
}
|
|
|
|
/**
|
|
* Get role by ID
|
|
*/
|
|
public function getRole(string $rid): ?array
|
|
{
|
|
return $this->roleStore->fetchByRid($this->tenantIdentity->identifier(), $rid);
|
|
}
|
|
|
|
/**
|
|
* Create a new role
|
|
*/
|
|
public function createRole(array $roleData): array
|
|
{
|
|
$this->validateRoleData($roleData);
|
|
|
|
$this->logger->info('Creating role', [
|
|
'tenant' => $this->tenantIdentity->identifier(),
|
|
'label' => $roleData['label'] ?? 'Unnamed'
|
|
]);
|
|
|
|
return $this->roleStore->createRole($this->tenantIdentity->identifier(), $roleData);
|
|
}
|
|
|
|
/**
|
|
* Update existing role
|
|
*/
|
|
public function updateRole(string $rid, array $updates): bool
|
|
{
|
|
// Verify role exists and is not system role
|
|
$role = $this->getRole($rid);
|
|
if (!$role) {
|
|
throw new \InvalidArgumentException('Role not found');
|
|
}
|
|
|
|
if ($role['system'] ?? false) {
|
|
throw new \InvalidArgumentException('Cannot modify system roles');
|
|
}
|
|
|
|
$this->validateRoleData($updates, false);
|
|
|
|
$this->logger->info('Updating role', [
|
|
'tenant' => $this->tenantIdentity->identifier(),
|
|
'rid' => $rid
|
|
]);
|
|
|
|
return $this->roleStore->updateRole($this->tenantIdentity->identifier(), $rid, $updates);
|
|
}
|
|
|
|
/**
|
|
* Delete a role
|
|
*/
|
|
public function deleteRole(string $rid): bool
|
|
{
|
|
// Verify role exists and is not system role
|
|
$role = $this->getRole($rid);
|
|
if (!$role) {
|
|
throw new \InvalidArgumentException('Role not found');
|
|
}
|
|
|
|
if ($role['system'] ?? false) {
|
|
throw new \InvalidArgumentException('Cannot delete system roles');
|
|
}
|
|
|
|
// Check if role is assigned to users
|
|
$userCount = $this->roleStore->countUsersInRole($this->tenantIdentity->identifier(), $rid);
|
|
if ($userCount > 0) {
|
|
throw new \InvalidArgumentException("Cannot delete role assigned to {$userCount} user(s)");
|
|
}
|
|
|
|
$this->logger->info('Deleting role', [
|
|
'tenant' => $this->tenantIdentity->identifier(),
|
|
'rid' => $rid
|
|
]);
|
|
|
|
return $this->roleStore->deleteRole($this->tenantIdentity->identifier(), $rid);
|
|
}
|
|
|
|
/**
|
|
* Get user count for a role
|
|
*/
|
|
public function getRoleUserCount(string $rid): int
|
|
{
|
|
return $this->roleStore->countUsersInRole($this->tenantIdentity->identifier(), $rid);
|
|
}
|
|
|
|
/**
|
|
* Get all available permissions from modules
|
|
* Grouped by category with metadata
|
|
*/
|
|
public function availablePermissions(): array
|
|
{
|
|
return $this->roleStore->availablePermissions();
|
|
}
|
|
|
|
// =========================================================================
|
|
// Validation
|
|
// =========================================================================
|
|
|
|
/**
|
|
* Validate role data
|
|
*/
|
|
private function validateRoleData(array $data, bool $isCreate = true): void
|
|
{
|
|
if ($isCreate && empty($data['label'])) {
|
|
throw new \InvalidArgumentException('Role label is required');
|
|
}
|
|
|
|
if (isset($data['permissions']) && !is_array($data['permissions'])) {
|
|
throw new \InvalidArgumentException('Permissions must be an array');
|
|
}
|
|
}
|
|
}
|