rosavox/lib/alveolata/accesscontrol/functions.php
2025-05-23 07:33:29 +00:00

87 lines
1.4 KiB
PHP

<?php
namespace alveolata\accesscontrol;
require_once(DIR_ALVEOLATA . '/list/functions.php');
/**
*/
class struct_subject
{
/**
* @var array {map<string,function<tuple<any,any>,bool>>}
*/
public $getters;
/**
* @var array {record<default:list<list<record<type:string,?parameters:any>>>,concrete:map<string,list<list<record<type:string,?parameters:any>>>>>}
*/
public $acl;
/**
*/
public function __construct(
array $getters,
array $acl
)
{
$this->getters = $getters;
$this->acl = $acl;
}
}
/**
*/
function make(
array $getters,
array $acl
)
{
return (
new struct_subject(
$getters,
$acl
)
);
}
/**
*/
function check(
struct_subject $subject,
string $action,
$state = null
) : bool
{
$acl_section = (
$subject->acl['concrete'][$action]
?? $subject->acl['default']
?? []
);
return \alveolata\list_\some(
$acl_section,
function (array $acl_section_sub) use ($subject, $state) : bool {
return \alveolata\list_\every(
$acl_section_sub,
function (array $entry) use ($subject, $state) : bool {
if (! array_key_exists($entry['type'], $subject->getters)) {
throw (new \Exception('unhandled ACL check type: ' . $entry['type']));
}
else {
$getter = $subject->getters[$entry['type']];
return $getter($entry['parameters'] ?? null, $state);
}
}
);
}
);
}
?>