Acl   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 361
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 32
eloc 79
c 2
b 0
f 0
dl 0
loc 361
rs 9.84

26 Methods

Rating   Name   Duplication   Size   Complexity  
A normalizeResourceCollection() 0 8 2
A setRule() 0 16 1
A removeDeny() 0 11 1
A resolveRoleFactory() 0 4 2
A addResource() 0 7 1
A getRole() 0 3 1
A normalizeRoleCollection() 0 8 2
A removeAllRole() 0 7 1
A addRole() 0 7 1
A rules() 0 3 1
A resolveResourceFactory() 0 4 2
A getResource() 0 4 1
A removeAllow() 0 11 1
A removeAllResource() 0 7 1
A removeResource() 0 8 1
A resolveRoleRecorder() 0 4 2
A __construct() 0 15 1
A removeRole() 0 7 1
A deny() 0 11 1
A resolveResourceRecorder() 0 4 2
A hasRole() 0 3 1
A resources() 0 3 1
A allow() 0 11 1
A roles() 0 3 1
A hasResource() 0 3 1
A isAllowed() 0 6 1
1
<?php
2
3
namespace Tleckie\Acl;
4
5
use Tleckie\Acl\Acl\AclInterface;
6
use Tleckie\Acl\Acl\OperationEnum;
7
use Tleckie\Acl\Acl\PermissionTypeEnum;
8
use Tleckie\Acl\Acl\Register;
9
use Tleckie\Acl\Acl\RegisterInterface;
10
use Tleckie\Acl\Resource\ResourceFactory;
11
use Tleckie\Acl\Resource\ResourceFactoryInterface;
12
use Tleckie\Acl\Resource\ResourceInterface;
13
use Tleckie\Acl\Resource\ResourceRecorder;
14
use Tleckie\Acl\Resource\ResourceRecorderInterface;
15
use Tleckie\Acl\Role\RoleFactory;
16
use Tleckie\Acl\Role\RoleFactoryInterface;
17
use Tleckie\Acl\Role\RoleInterface;
18
use Tleckie\Acl\Role\RoleRecorder;
19
use Tleckie\Acl\Role\RoleRecorderInterface;
20
21
/**
22
 * Class Acl
23
 *
24
 * @package Tleckie\Acl
25
 * @author  Teodoro Leckie Westberg <[email protected]>
26
 */
27
class Acl implements AclInterface
28
{
29
    /** @var RegisterInterface */
30
    protected RegisterInterface $register;
31
32
    /** @var ResourceFactoryInterface */
33
    private ResourceFactoryInterface $resourceFactory;
34
35
    /** @var RoleFactoryInterface */
36
    private RoleFactoryInterface $roleFactory;
37
38
    /** @var ResourceRecorderInterface */
39
    private ResourceRecorderInterface $resourceRecorder;
40
41
    /** @var RoleRecorderInterface */
42
    private RoleRecorderInterface $roleRecorder;
43
44
    /**
45
     * Acl constructor.
46
     *
47
     * @param ResourceFactoryInterface|null  $resourceFactory
48
     * @param RoleFactoryInterface|null      $roleFactory
49
     * @param ResourceRecorderInterface|null $resourceRecorder
50
     * @param RoleRecorderInterface|null     $roleRecorder
51
     */
52
    public function __construct(
53
        ResourceFactoryInterface $resourceFactory = null,
54
        RoleFactoryInterface $roleFactory = null,
55
        ResourceRecorderInterface $resourceRecorder = null,
56
        RoleRecorderInterface $roleRecorder = null,
57
    ) {
58
        $this->resourceFactory = $this->resolveResourceFactory($resourceFactory);
59
60
        $this->roleFactory = $this->resolveRoleFactory($roleFactory);
61
62
        $this->resourceRecorder = $this->resolveResourceRecorder($resourceRecorder);
63
64
        $this->roleRecorder = $this->resolveRoleRecorder($roleRecorder);
65
66
        $this->register = new Register($this->roleRecorder);
67
    }
68
69
    /**
70
     * @param ResourceFactoryInterface|null $resourceFactory
71
     * @return ResourceFactoryInterface
72
     */
73
    private function resolveResourceFactory(
74
        ResourceFactoryInterface|null $resourceFactory
75
    ): ResourceFactoryInterface {
76
        return ($resourceFactory) ?: new ResourceFactory();
77
    }
78
79
    /**
80
     * @param RoleFactoryInterface|null $roleFactory
81
     * @return RoleFactoryInterface
82
     */
83
    private function resolveRoleFactory(
84
        RoleFactoryInterface|null $roleFactory
85
    ): RoleFactoryInterface {
86
        return ($roleFactory) ?: new RoleFactory();
87
    }
88
89
    /**
90
     * @param ResourceRecorderInterface|null $resourceRecorder
91
     * @return ResourceRecorderInterface
92
     */
93
    private function resolveResourceRecorder(
94
        ResourceRecorderInterface|null $resourceRecorder
95
    ): ResourceRecorderInterface {
96
        return ($resourceRecorder) ?: new ResourceRecorder($this->resourceFactory);
97
    }
98
99
    /**
100
     * @param RoleRecorderInterface|null $roleRecorder
101
     * @return RoleRecorderInterface
102
     */
103
    private function resolveRoleRecorder(
104
        RoleRecorderInterface|null $roleRecorder
105
    ): RoleRecorderInterface {
106
        return ($roleRecorder) ?: new RoleRecorder($this->roleFactory);
107
    }
108
109
    /**
110
     * @param RoleInterface|string $role
111
     * @param array                $parents
112
     * @return AclInterface
113
     */
114
    public function addRole(RoleInterface|string $role, array $parents = []): AclInterface
115
    {
116
        $this->roleRecorder->addRole($role, $parents);
117
118
        $this->register->addRole($role, $parents);
119
120
        return $this;
121
    }
122
123
    /**
124
     * @inheritdoc
125
     */
126
    public function getRole(RoleInterface|string $role): RoleInterface
127
    {
128
        return $this->roleRecorder->getRole($role);
129
    }
130
131
    /**
132
     * @inheritdoc
133
     */
134
    public function hasRole(RoleInterface|string $role): bool
135
    {
136
        return $this->roleRecorder->hasRole($role);
137
    }
138
139
    /**
140
     * @param RoleInterface|string $role
141
     * @return AclInterface
142
     */
143
    public function removeRole(RoleInterface|string $role): AclInterface
144
    {
145
        $this->roleRecorder->removeRole($role);
146
147
        $this->register->removeRole($role);
148
149
        return $this;
150
    }
151
152
    /**
153
     * @return AclInterface
154
     */
155
    public function removeAllRole(): AclInterface
156
    {
157
        $this->roleRecorder->removeAllRole();
158
159
        $this->register->removeAllRole();
160
161
        return $this;
162
    }
163
164
    /**
165
     * @param string|ResourceInterface $resource
166
     * @param ResourceInterface[]      $parents
167
     * @return AclInterface
168
     */
169
    public function addResource(
170
        string|ResourceInterface $resource,
171
        array $parents = []
172
    ): AclInterface {
173
        $this->resourceRecorder->addResource($resource, $parents);
174
175
        return $this;
176
    }
177
178
    /**
179
     * @inheritdoc
180
     */
181
    public function getResource(
182
        ResourceInterface|string $resource
183
    ): ResourceInterface {
184
        return $this->resourceRecorder->getResource($resource);
185
    }
186
187
    /**
188
     * @inheritdoc
189
     */
190
    public function hasResource(ResourceInterface|string $resource): bool
191
    {
192
        return $this->resourceRecorder->hasResource($resource);
193
    }
194
195
    /**
196
     * @param ResourceInterface|string $resource
197
     * @return AclInterface
198
     */
199
    public function removeResource(
200
        ResourceInterface|string $resource
201
    ): AclInterface {
202
        $this->resourceRecorder->removeResource($resource);
203
204
        $this->register->removeResource($resource);
205
206
        return $this;
207
    }
208
209
    /**
210
     * @return AclInterface
211
     */
212
    public function removeAllResource(): AclInterface
213
    {
214
        $this->resourceRecorder->removeAllResource();
215
216
        $this->register->removeAllResource();
217
218
        return $this;
219
    }
220
221
    /**
222
     * @param array $roles
223
     * @param array $resources
224
     * @param array $privileges
225
     * @return AclInterface
226
     */
227
    public function removeDeny(
228
        array $roles = [],
229
        array $resources = [],
230
        array $privileges = []
231
    ): AclInterface {
232
        return $this->setRule(
233
            OperationEnum::REMOVE(),
234
            PermissionTypeEnum::DENY(),
235
            $roles,
236
            $resources,
237
            $privileges
238
        );
239
    }
240
241
    /**
242
     * @param OperationEnum      $operation
243
     * @param PermissionTypeEnum $type
244
     * @param array              $roles
245
     * @param array              $resources
246
     * @param array              $privileges
247
     * @return AclInterface
248
     */
249
    public function setRule(
250
        OperationEnum $operation,
251
        PermissionTypeEnum $type,
252
        array $roles = [],
253
        array $resources = [],
254
        array $privileges = []
255
    ): AclInterface {
256
        $this->register->setRule(
257
            $operation,
258
            $type,
259
            $this->normalizeRoleCollection($roles),
260
            $this->normalizeResourceCollection($resources),
261
            $privileges
262
        );
263
264
        return $this;
265
    }
266
267
    /**
268
     * @param RoleInterface[] $roles
269
     * @return array
270
     */
271
    private function normalizeRoleCollection(array $roles): array
272
    {
273
        $collection = [];
274
        foreach ($roles as $role) {
275
            $collection[] = $this->roleRecorder->getRole($role);
276
        }
277
278
        return $collection;
279
    }
280
281
    /**
282
     * @param array $resources
283
     * @return ResourceInterface[]
284
     */
285
    private function normalizeResourceCollection(array $resources): array
286
    {
287
        $collection = [];
288
        foreach ($resources as $resource) {
289
            $collection[] = $this->resourceRecorder->getResource($resource);
290
        }
291
292
        return $collection;
293
    }
294
295
    /**
296
     * @param array $roles
297
     * @param array $resources
298
     * @param array $privileges
299
     * @return AclInterface
300
     */
301
    public function removeAllow(
302
        array $roles = [],
303
        array $resources = [],
304
        array $privileges = []
305
    ): AclInterface {
306
        return $this->setRule(
307
            OperationEnum::REMOVE(),
308
            PermissionTypeEnum::ALLOW(),
309
            $roles,
310
            $resources,
311
            $privileges
312
        );
313
    }
314
315
    /**
316
     * @param array $roles
317
     * @param array $resources
318
     * @param array $privileges
319
     * @return AclInterface
320
     */
321
    public function allow(
322
        array $roles = [],
323
        array $resources = [],
324
        array $privileges = []
325
    ): AclInterface {
326
        return $this->setRule(
327
            OperationEnum::ADD(),
328
            PermissionTypeEnum::ALLOW(),
329
            $roles,
330
            $resources,
331
            $privileges
332
        );
333
    }
334
335
    /**
336
     * @param array $roles
337
     * @param array $resources
338
     * @param array $privileges
339
     * @return AclInterface
340
     */
341
    public function deny(
342
        array $roles = [],
343
        array $resources = [],
344
        array $privileges = []
345
    ): AclInterface {
346
        return $this->setRule(
347
            OperationEnum::ADD(),
348
            PermissionTypeEnum::DENY(),
349
            $roles,
350
            $resources,
351
            $privileges
352
        );
353
    }
354
355
    /**
356
     * @inheritdoc
357
     */
358
    public function isAllowed(
359
        RoleInterface|string $role = null,
360
        ResourceInterface|string $resource = null,
361
        string $privilege = null
362
    ): bool {
363
        return $this->register->isAllowed($role, $resource, $privilege);
364
    }
365
366
    /**
367
     * @inheritdoc
368
     */
369
    public function roles(): array
370
    {
371
        return $this->roleRecorder->roles();
372
    }
373
374
    /**
375
     * @inheritdoc
376
     */
377
    public function resources(): array
378
    {
379
        return $this->resourceRecorder->resources();
380
    }
381
382
    /**
383
     * @return array
384
     */
385
    public function rules(): array
386
    {
387
        return $this->register->rules();
388
    }
389
}
390