1
|
|
|
<?php declare(strict_types=1);
|
2
|
|
|
|
3
|
|
|
namespace jschreuder\MiddleAuth\Acl;
|
4
|
|
|
|
5
|
|
|
use jschreuder\MiddleAuth\AuthorizationHandlerInterface;
|
6
|
|
|
use jschreuder\MiddleAuth\AuthorizationMiddlewareInterface;
|
7
|
|
|
use jschreuder\MiddleAuth\AuthorizationRequestInterface;
|
8
|
|
|
use jschreuder\MiddleAuth\AuthorizationResponseInterface;
|
9
|
|
|
use jschreuder\MiddleAuth\Basic\AuthorizationResponse;
|
10
|
|
|
use jschreuder\MiddleAuth\Util\AuthLoggerInterface;
|
11
|
|
|
use jschreuder\MiddleAuth\Util\NullAuthLogger;
|
12
|
|
|
|
13
|
|
|
final class AclMiddleware implements AuthorizationMiddlewareInterface
|
14
|
|
|
{
|
15
|
|
|
private AuthLoggerInterface $logger;
|
16
|
|
|
|
17
|
11 |
|
public function __construct(
|
18
|
|
|
private AclEntriesCollection $aclEntries,
|
19
|
|
|
?AuthLoggerInterface $logger = null
|
20
|
|
|
)
|
21
|
|
|
{
|
22
|
11 |
|
$this->logger = $logger ?? new NullAuthLogger();
|
23
|
|
|
}
|
24
|
|
|
|
25
|
8 |
|
public function process(
|
26
|
|
|
AuthorizationRequestInterface $request,
|
27
|
|
|
AuthorizationHandlerInterface $handler
|
28
|
|
|
): AuthorizationResponseInterface
|
29
|
|
|
{
|
30
|
8 |
|
$actor = $request->getSubject();
|
31
|
8 |
|
$resource = $request->getResource();
|
32
|
8 |
|
$action = $request->getAction();
|
33
|
|
|
|
34
|
8 |
|
$this->logger->debug('ACL middleware evaluating request', [
|
35
|
8 |
|
'subject_type' => $actor->getType(),
|
36
|
8 |
|
'subject_id' => $actor->getId(),
|
37
|
8 |
|
'resource_type' => $resource->getType(),
|
38
|
8 |
|
'resource_id' => $resource->getId(),
|
39
|
8 |
|
'action' => $action,
|
40
|
8 |
|
'acl_entries_count' => count($this->aclEntries),
|
41
|
8 |
|
]);
|
42
|
|
|
|
43
|
8 |
|
foreach ($this->aclEntries as $index => $aclEntry) {
|
44
|
|
|
if (
|
45
|
7 |
|
$aclEntry->matchesActor($actor)
|
46
|
7 |
|
&& $aclEntry->matchesResource($resource)
|
47
|
7 |
|
&& $aclEntry->matchesAction($action)
|
48
|
|
|
) {
|
49
|
4 |
|
$this->logger->debug('ACL entry matched', [
|
50
|
4 |
|
'entry_index' => $index,
|
51
|
4 |
|
'subject_type' => $actor->getType(),
|
52
|
4 |
|
'subject_id' => $actor->getId(),
|
53
|
4 |
|
'action' => $action,
|
54
|
4 |
|
]);
|
55
|
|
|
|
56
|
4 |
|
return new AuthorizationResponse(
|
57
|
4 |
|
true,
|
58
|
4 |
|
'Access granted by ' . self::class,
|
59
|
4 |
|
self::class
|
60
|
4 |
|
);
|
61
|
|
|
}
|
62
|
|
|
}
|
63
|
|
|
|
64
|
4 |
|
$this->logger->debug('No ACL entries matched, delegating to next handler');
|
65
|
|
|
|
66
|
4 |
|
return $handler->handle($request);
|
67
|
|
|
}
|
68
|
|
|
}
|
69
|
|
|
|