Test Failed
Push — main ( b1977a...e24033 )
by Jean-Christophe
07:23
created

AclManager   F

Complexity

Total Complexity 61

Size/Duplication

Total Lines 350
Duplicated Lines 0 %

Test Coverage

Coverage 88.97%

Importance

Changes 5
Bugs 0 Features 2
Metric Value
eloc 106
dl 0
loc 350
ccs 129
cts 145
cp 0.8897
rs 3.52
c 5
b 0
f 2
wmc 61

36 Methods

Rating   Name   Duplication   Size   Complexity  
A start() 0 3 1
A existPartIn() 0 2 1
A addRole() 0 2 1
A getPermissions() 0 2 1
A getProvider() 0 2 1
A initFromProviders() 0 7 2
A removeResource() 0 2 1
A removeRole() 0 2 1
A getAclList() 0 2 1
A filterProviders() 0 10 3
A setPermissionLevel() 0 2 1
A removePermission() 0 2 1
A allow() 0 2 1
A addAndAllow() 0 2 1
A removefilterProviders() 0 2 1
B isAllowedRoute() 0 22 7
A startWithCacheProvider() 0 3 1
A addResources() 0 3 2
B initCache() 0 28 6
A addPermissions() 0 3 2
A getAcls() 0 2 1
A getModelClassesSwap() 0 9 3
A addRoles() 0 3 2
A isStarted() 0 2 2
A addResource() 0 2 1
A removeAcl() 0 2 1
A reloadFromSelectedProviders() 0 11 5
A getRoles() 0 2 1
A getPermissionMap() 0 6 2
A existAclIn() 0 2 1
A getResources() 0 2 1
A isAllowed() 0 2 1
A registerAnnotations() 0 2 1
A addPermission() 0 2 1
A saveAll() 0 2 1
A associate() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like AclManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AclManager, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace Ubiquity\security\acl;
3
4
use Ubiquity\cache\CacheManager;
5
use Ubiquity\cache\ClassUtils;
6
use Ubiquity\exceptions\AclException;
7
use Ubiquity\security\acl\cache\AclControllerParser;
8
use Ubiquity\security\acl\cache\PermissionsMap;
9
use Ubiquity\security\acl\models\AbstractAclPart;
10
use Ubiquity\security\acl\models\AclElement;
11
use Ubiquity\security\acl\models\AclList;
12
use Ubiquity\security\acl\models\Permission;
13
use Ubiquity\security\acl\models\Resource;
14
use Ubiquity\security\acl\models\Role;
15
use Ubiquity\security\acl\persistence\AclCacheProvider;
16
use Ubiquity\controllers\Router;
17
18
/**
19
 * Ubiquity\security\acl$AclManager
20
 * This class is part of Ubiquity
21
 *
22
 * @author jc
23
 * @version 1.0.0
24
 *
25
 */
26
class AclManager {
27
28
	/**
29
	 *
30
	 * @var AclList
31
	 */
32
	protected static $aclList;
33
34
	/**
35
	 *
36
	 * @var PermissionsMap
37
	 */
38
	protected static $permissionMap;
39
40
	protected static $providersPersistence;
41
42
	/**
43
	 * Create AclList with default roles and resources.
44 22
	 */
45 22
	public static function start(): void {
46 22
		self::$aclList = new AclList();
47 22
		self::$aclList->init();
48
	}
49
	
50
	/**
51
	 * Start the Acls with AclCacheProvider (for attributes or annotations).
52 6
	 */
53 6
	public static function startWithCacheProvider(): void {
54 6
		self::start();
55 6
		self::initFromProviders([new AclCacheProvider()]);
56
	}
57
58
	/**
59
	 * Check whether the Acl service is started.
60
	 *
61
	 * @return bool
62 2
	 */
63 2
	public static function isStarted(): bool {
64
		return self::$aclList !== NULL && (self::$aclList instanceof AclList);
65
	}
66
67
	/**
68
	 * Load acls, roles, resources and permissions from providers.
69
	 *
70
	 * @param AclProviderInterface[] $providers
71 11
	 */
72 11
	public static function initFromProviders(?array $providers = []): void {
73 11
		self::$aclList->setProviders($providers);
74 10
		if (\count($providers) > 0) {
75 10
			self::$aclList->loadAcls();
76 10
			self::$aclList->loadRoles();
77 10
			self::$aclList->loadResources();
78
			self::$aclList->loadPermissions();
79 11
		}
80
	}
81
82
	/**
83
	 *
84
	 * @param array|string $selectedProviders
85 3
	 */
86 3
	public static function reloadFromSelectedProviders($selectedProviders = '*') {
87 3
		$sProviders = self::$aclList->getProviders();
88 3
		self::$aclList->clear();
89 3
		$providers = [];
90 3
		foreach ($sProviders as $prov) {
91 3
			if ($selectedProviders === '*' || (\is_array($selectedProviders) && \array_search(\get_class($prov), $selectedProviders) !== false)) {
92
				$providers[] = $prov;
93
			}
94 3
		}
95 3
		self::initFromProviders($providers);
96 3
		self::$aclList->setProviders($sProviders);
97
	}
98 8
99 8
	public static function addRole(string $name, ?array $parents = []) {
100 8
		self::$aclList->addRole(new Role($name, $parents));
101
	}
102 1
103 1
	public static function addRoles(array $nameParents) {
104 1
		foreach ($nameParents as $name => $parents) {
105
			self::$aclList->addRole(new Role($name, $parents));
106 1
		}
107
	}
108 7
109 7
	public static function addResource(string $name, ?string $value = null) {
110 7
		self::$aclList->addResource(new Resource($name, $value));
111
	}
112 1
113 1
	public static function addResources(array $nameValue) {
114 1
		foreach ($nameValue as $name => $value) {
115
			self::$aclList->addResource(new Resource($name, $value));
116 1
		}
117
	}
118 9
119 9
	public static function addPermission(string $name, int $level = 0) {
120 9
		self::$aclList->addPermission(new Permission($name, $level));
121
	}
122 1
123 1
	public static function addPermissions(array $nameLevel) {
124 1
		foreach ($nameLevel as $name => $level) {
125
			self::$aclList->addPermission(new Permission($name, $level));
126 1
		}
127
	}
128 3
129 3
	public static function setPermissionLevel(string $name, int $level) {
130 2
		self::$aclList->setPermissionLevel($name, $level);
131
	}
132 8
133 8
	public static function getRoles() {
134
		return self::$aclList->getRoles();
135
	}
136 7
137 7
	public static function getResources() {
138
		return self::$aclList->getResources();
139
	}
140
141
	/**
142
	 *
143
	 * @return \Ubiquity\security\acl\models\AclList
144 3
	 */
145 3
	public static function getAclList() {
146
		return AclManager::$aclList;
147
	}
148 11
149 11
	public static function getPermissions() {
150
		return self::$aclList->getPermissions();
151
	}
152 6
153 6
	public static function getAcls() {
154
		return self::$aclList->getAcls();
155
	}
156
157
	/**
158
	 * Allow role to access to resource with the permission.
159
	 *
160
	 * @param string $role
161
	 * @param string $resource
162
	 * @param string $permission
163 10
	 */
164 10
	public static function allow(string $role, ?string $resource = '*', ?string $permission = 'ALL') {
165 10
		self::$aclList->allow($role, $resource ?? '*', $permission ?? 'ALL');
166
	}
167
168
	/**
169
	 * Add role, resource and permission and allow this role to access to resource with the permission.
170
	 *
171
	 * @param string $role
172
	 * @param string $resource
173
	 * @param string $permission
174 3
	 */
175 3
	public static function addAndAllow(string $role, ?string $resource = '*', ?string $permission = 'ALL') {
176 3
		self::$aclList->addAndAllow($role, $resource ?? '*', $permission ?? 'ALL');
177
	}
178
179
	/**
180
	 * Check if access to resource is allowed for role with the permission.
181
	 *
182
	 * @param string $role
183
	 * @param string $resource
184
	 * @param string $permission
185
	 * @return bool
186 20
	 */
187 20
	public static function isAllowed(string $role, ?string $resource = '*', ?string $permission = 'ALL'): bool {
188
		return self::$aclList->isAllowed($role, $resource ?? '*', $permission ?? 'ALL');
189
	}
190
	
191
	public static function isAllowedRoute(string $role,string $routeName){
0 ignored issues
show
Unused Code introduced by
The parameter $routeName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

191
	public static function isAllowedRoute(string $role,/** @scrutinizer ignore-unused */ string $routeName){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
192
		$routeInfo=Router::getRouteInfoByName($name);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $name seems to be never defined.
Loading history...
193 4
		if (!isset ( $routeDetails ['controller'] )) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $routeDetails seems to never exist and therefore isset should always be false.
Loading history...
194 4
			$routeInfo=current($routeInfo);
0 ignored issues
show
Bug introduced by
It seems like $routeInfo can also be of type false; however, parameter $array of current() does only seem to accept array|object, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

194
			$routeInfo=current(/** @scrutinizer ignore-type */ $routeInfo);
Loading history...
195 4
		}
196
		$controller=$routeInfo['controller']??null;
197
		$action=$routeInfo['action']??null;
198
		if(isset($controller) && isset($action)){
199
			$resourceController = self::getPermissionMap ()->getRessourcePermission ( $controller, $action );
200
			if (isset ( $resourceController )) {
201 2
				try{
202 2
					if (self::isAllowed ( $role, $resourceController ['resource'], $resourceController ['permission'] )) {
203 2
						return true;
204
					}
205
				}
206
				catch(AclException $e){
207
					//Nothing to do
208
				}
209 2
			}
210 2
			return false;
211 2
		}
212
		return false;
213
	}
214
215
	/**
216
	 * Save all acls,roles, resources and permissions for AclProviders with no autoSave.
217
	 */
218
	public static function saveAll() {
219
		self::$aclList->saveAll();
220
	}
221
222
	/**
223
	 *
224
	 * @param string $role
225
	 */
226
	public static function removeRole(string $role) {
227 2
		self::$aclList->removeRole($role);
228 2
	}
229 2
230
	/**
231
	 *
232
	 * @param string $permission
233
	 */
234
	public static function removePermission(string $permission) {
235
		self::$aclList->removePermission($permission);
236
	}
237
238 2
	/**
239 2
	 *
240
	 * @param string $resource
241
	 */
242
	public static function removeResource(string $resource) {
243
		self::$aclList->removeResource($resource);
244
	}
245 2
246 2
	/**
247 2
	 *
248 2
	 * @param string $role
249 2
	 * @param string $resource
250 2
	 * @param string $permission
251 2
	 */
252 2
	public static function removeAcl(string $role, string $resource, string $permission = null) {
253 2
		self::$aclList->removeAcl($role, $resource, $permission);
254
	}
255 2
256
	/**
257
	 * Initialize acls cache with controllers annotations.
258
	 * Do not execute at runtime
259
	 *
260
	 * @param array $config
261
	 * @throws \Ubiquity\exceptions\AclException
262
	 */
263 2
	public static function initCache(&$config) {
264 2
		if(!self::isStarted()){
265 2
			self::start();
266 2
			self::initFromProviders([
267
				new AclCacheProvider()
268 2
			]);
269 2
		}
270 2
		self::filterProviders(AclCacheProvider::class);
271
		self::reloadFromSelectedProviders([]);
272
		self::registerAnnotations();
273
		$files = \Ubiquity\cache\CacheManager::getControllersFiles($config, true);
274
		$parser = new AclControllerParser();
275
		$parser->init();
276 1
		foreach ($files as $file) {
277 1
			if (\is_file($file)) {
278 1
				$controller = ClassUtils::getClassFullNameFromFile($file);
279 1
				try {
280
					$parser->parse($controller);
281 1
				} catch (\Exception $e) {
282
					if ($e instanceof AclException) {
283
						throw $e;
284
					}
285
				}
286
			}
287
		}
288
		$parser->save();
289
		self::removefilterProviders();
290
		self::reloadFromSelectedProviders();
291 1
	}
292 1
293 1
	protected static function registerAnnotations() {
294 1
		CacheManager::getAnnotationsEngineInstance()->registerAcls();
295 1
	}
296
297
	/**
298
	 *
299
	 * @return \Ubiquity\security\acl\cache\PermissionsMap
300
	 */
301
	public static function getPermissionMap() {
302
		if (! isset(self::$permissionMap)) {
303 2
			self::$permissionMap = new PermissionsMap();
304 2
			self::$permissionMap->load();
305
		}
306
		return self::$permissionMap;
307
	}
308
309
	/**
310
	 *
311
	 * @param string $controller
312
	 * @param string $action
313 2
	 * @param string $resource
314 2
	 * @param string $permission
315
	 */
316
	public static function associate(string $controller, string $action, string $resource, string $permission = 'ALL') {
317
		self::$aclList->getResourceByName($resource);
318
		self::$aclList->getPermissionByName($permission);
319
		self::$permissionMap->addAction($controller, $action, $resource, $permission);
320
	}
321
322 2
	/**
323 2
	 *
324
	 * @param AbstractAclPart $part
325
	 * @param string $providerClass
326
	 * @return boolean
327
	 */
328
	public static function existPartIn(AbstractAclPart $part, string $providerClass) {
329
		return self::$aclList->existPartIn($part, $providerClass);
330
	}
331
332
	/**
333
	 *
334
	 * @param AclElement $elm
335
	 * @param string $providerClass
336
	 * @return boolean
337 2
	 */
338 2
	public static function existAclIn(AclElement $elm, string $providerClass) {
339 2
		return self::$aclList->existAclIn($elm, $providerClass);
340 2
	}
341 2
342 2
	/**
343
	 *
344
	 * @param string $providerClass
345 2
	 * @return \Ubiquity\security\acl\persistence\AclProviderInterface|NULL
346 2
	 */
347 2
	public static function getProvider(string $providerClass) {
348
		return self::$aclList->getProvider($providerClass);
349 2
	}
350 2
351 2
	public static function getModelClassesSwap(): array {
352
		$result = [];
353
		$aclList = self::getAclList();
354
		if (isset($aclList)) {
355
			foreach ($aclList->getProviders() as $prov) {
356
				$result += $prov->getModelClassesSwap();
357
			}
358
		}
359
		return $result;
360
	}
361
362
	public static function filterProviders(string $providerClass) {
363
		$providers = self::$aclList->getProviders();
364
		$filter = [];
365
		foreach ($providers as $prov) {
366
			if ($prov instanceof $providerClass) {
367
				$filter[] = $prov;
368
			}
369
		}
370
		self::$aclList->setProviders($filter);
371
		self::$providersPersistence = $providers;
372
	}
373
374
	public static function removefilterProviders() {
375
		self::$aclList->setProviders(self::$providersPersistence);
376
	}
377
}
378
379