Files
server/core/lib/Security/Authorization/PermissionChecker.php
2026-02-10 18:46:11 -05:00

125 lines
3.4 KiB
PHP

<?php
namespace KTXC\Security\Authorization;
use KTXC\SessionIdentity;
/**
* Permission Checker
* Provides granular permission checking with support for wildcards
*/
class PermissionChecker
{
public function __construct(
private readonly SessionIdentity $sessionIdentity
) {}
/**
* Check if user has a specific permission
* Supports wildcards: user_manager.users.* matches all user actions
*
* @param string $permission Permission to check (e.g., "user_manager.users.create")
* @param mixed $resource Optional resource for resource-based permissions
* @return bool
*/
public function can(string $permission, mixed $resource = null): bool
{
$identity = $this->sessionIdentity->identity();
if (!$identity) {
return false;
}
// Get user permissions from identity
$userPermissions = $identity->getPermissions() ?? [];
// Super admin bypass - check for admin role
$roles = $identity->getRoles() ?? [];
if (in_array('admin', $roles) || in_array('system.admin', $roles)) {
return true;
}
// Exact match
if (in_array($permission, $userPermissions)) {
return true;
}
// Wildcard match: user_manager.users.* allows user_manager.users.create
foreach ($userPermissions as $userPerm) {
if (str_ends_with($userPerm, '.*')) {
$prefix = substr($userPerm, 0, -2);
if (str_starts_with($permission, $prefix . '.')) {
return true;
}
}
}
// Full wildcard: * grants all permissions
if (in_array('*', $userPermissions)) {
return true;
}
return false;
}
/**
* Check if user has ANY of the permissions (OR logic)
*
* @param array $permissions Array of permissions to check
* @param mixed $resource Optional resource for resource-based permissions
* @return bool
*/
public function canAny(array $permissions, mixed $resource = null): bool
{
if (empty($permissions)) {
return true; // No permissions required
}
foreach ($permissions as $permission) {
if ($this->can($permission, $resource)) {
return true;
}
}
return false;
}
/**
* Check if user has ALL permissions (AND logic)
*
* @param array $permissions Array of permissions to check
* @param mixed $resource Optional resource for resource-based permissions
* @return bool
*/
public function canAll(array $permissions, mixed $resource = null): bool
{
if (empty($permissions)) {
return true; // No permissions required
}
foreach ($permissions as $permission) {
if (!$this->can($permission, $resource)) {
return false;
}
}
return true;
}
/**
* Get all permissions for the current user
*
* @return array
*/
public function getUserPermissions(): array
{
$identity = $this->sessionIdentity->identity();
if (!$identity) {
return [];
}
return $identity->getPermissions() ?? [];
}
}