Passed
Push — main ( c291e2...a2634b )
by Jean-Christophe
02:27
created

AclManager::getPermissions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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
use Ubiquity\security\acl\persistence\AclDAOProvider;
18
use Ubiquity\security\acl\persistence\AclProviderInterface;
19
20
/**
21
 * Ubiquity\security\acl$AclManager
22
 * This class is part of Ubiquity
23
 *
24
 * @author jc
25
 * @version 1.0.1
26
 *
27
 */
28
class AclManager {
29
30
	protected static ?AclList $aclList=null;
31
32
	protected static PermissionsMap $permissionMap;
33
34
	protected static array $providersPersistence;
35
36
	/**
37
	 * Create AclList with default roles and resources.
38
	 */
39 22
	public static function start(): void {
40 22
		self::$aclList = new AclList();
41 22
		self::$aclList->init();
42
	}
43
44
	/**
45
	 * Start the Acls with AclCacheProvider (for attributes or annotations).
46
	 */
47 6
	public static function startWithCacheProvider(): void {
48 6
		self::start();
49 6
		self::initFromProviders([new AclCacheProvider()]);
50
	}
51
52
	/**
53
	 * Check whether the Acl service is started.
54
	 *
55
	 * @return bool
56
	 */
57 2
	public static function isStarted(): bool {
58 2
		return isset(self::$aclList) && (self::$aclList instanceof AclList);
59
	}
60
61
	/**
62
	 * Load acls, roles, resources and permissions from providers.
63
	 *
64
	 * @param AclProviderInterface[] $providers
65
	 */
66 11
	public static function initFromProviders(?array $providers = []): void {
67 11
		self::$aclList->setProviders($providers);
68 11
		if (\count($providers) > 0) {
69 10
			self::$aclList->loadAcls();
70 10
			self::$aclList->loadRoles();
71 10
			self::$aclList->loadResources();
72 10
			self::$aclList->loadPermissions();
73
		}
74
	}
75
76
	/**
77
	 *
78
	 * @param array|string $selectedProviders
79
	 */
80 3
	public static function reloadFromSelectedProviders($selectedProviders = '*') {
81 3
		$sProviders = self::$aclList->getProviders();
82 3
		self::$aclList->clear();
83 3
		$providers = [];
84 3
		foreach ($sProviders as $prov) {
85 3
			if ($selectedProviders === '*' || (\is_array($selectedProviders) && \array_search(\get_class($prov), $selectedProviders) !== false)) {
86 3
				$providers[] = $prov;
87
			}
88
		}
89 3
		self::initFromProviders($providers);
90 3
		self::$aclList->setProviders($sProviders);
91
	}
92
93 8
	public static function addRole(string $name, ?array $parents = []) {
94 8
		self::$aclList->addRole(new Role($name, $parents));
95
	}
96
97 1
	public static function addRoles(array $nameParents) {
98 1
		foreach ($nameParents as $name => $parents) {
99 1
			self::$aclList->addRole(new Role($name, $parents));
100
		}
101
	}
102
103 7
	public static function addResource(string $name, ?string $value = null) {
104 7
		self::$aclList->addResource(new Resource($name, $value));
105
	}
106
107 1
	public static function addResources(array $nameValue) {
108 1
		foreach ($nameValue as $name => $value) {
109 1
			self::$aclList->addResource(new Resource($name, $value));
110
		}
111
	}
112
113 9
	public static function addPermission(string $name, int $level = 0) {
114 9
		self::$aclList->addPermission(new Permission($name, $level));
115
	}
116
117 1
	public static function addPermissions(array $nameLevel) {
118 1
		foreach ($nameLevel as $name => $level) {
119 1
			self::$aclList->addPermission(new Permission($name, $level));
120
		}
121
	}
122
123 3
	public static function setPermissionLevel(string $name, int $level) {
124 3
		self::$aclList->setPermissionLevel($name, $level);
125
	}
126
127 8
	public static function getRoles() {
128 8
		return self::$aclList->getRoles();
129
	}
130
131 7
	public static function getResources() {
132 7
		return self::$aclList->getResources();
133
	}
134
135
	/**
136
	 *
137
	 * @return \Ubiquity\security\acl\models\AclList
138
	 */
139 3
	public static function getAclList() {
140 3
		return AclManager::$aclList;
141
	}
142
143 11
	public static function getPermissions():array {
144 11
		return self::$aclList->getPermissions();
145
	}
146
147 6
	public static function getAcls() {
148 6
		return self::$aclList->getAcls();
149
	}
150
151
	/**
152
	 * Allow role to access to resource with the permission.
153
	 *
154
	 * @param string $role
155
	 * @param ?string $resource
156
	 * @param ?string $permission
157
	 */
158 10
	public static function allow(string $role, ?string $resource = '*', ?string $permission = 'ALL') {
159 10
		self::$aclList->allow($role, $resource ?? '*', $permission ?? 'ALL');
160
	}
161
162
	/**
163
	 * Add role, resource and permission and allow this role to access to resource with the permission.
164
	 *
165
	 * @param string $role
166
	 * @param ?string $resource
167
	 * @param ?string $permission
168
	 */
169 3
	public static function addAndAllow(string $role, ?string $resource = '*', ?string $permission = 'ALL') {
170 3
		self::$aclList->addAndAllow($role, $resource ?? '*', $permission ?? 'ALL');
171
	}
172
173
	/**
174
	 * Check if access to resource is allowed for role with the permission.
175
	 *
176
	 * @param string $role
177
	 * @param ?string $resource
178
	 * @param ?string $permission
179
	 * @return bool
180
	 */
181 20
	public static function isAllowed(string $role, ?string $resource = '*', ?string $permission = 'ALL'): bool {
182 20
		return self::$aclList->isAllowed($role, $resource ?? '*', $permission ?? 'ALL');
183
	}
184
185
	public static function isAllowedRoute(string $role,string $routeName): bool {
186
		$routeInfo=Router::getRouteInfoByName($routeName);
187
		if (!isset ( $routeInfo ['controller'] )) {
188
			$routeInfo=\current($routeInfo);
189
		}
190
		$controller=$routeInfo['controller']??null;
191
		$action=$routeInfo['action']??null;
192
		if(isset($controller) && isset($action)){
193
			$resourceController = self::getPermissionMap ()->getRessourcePermission ( $controller, $action );
194
			if (isset ( $resourceController )) {
195
				try{
196
					if (self::isAllowed ( $role, $resourceController ['resource'], $resourceController ['permission'] )) {
197
						return true;
198
					}
199
				}
200
				catch(AclException $e){
201
					//Nothing to do
202
				}
203
			}
204
			return false;
205
		}
206
		return false;
207
	}
208
209
	/**
210
	 * Save all acls,roles, resources and permissions for AclProviders with no autoSave.
211
	 */
212 4
	public static function saveAll(): void {
213 4
		self::$aclList->saveAll();
214
	}
215
216
	/**
217
	 *
218
	 * @param string $role
219
	 */
220 2
	public static function removeRole(string $role) {
221 2
		self::$aclList->removeRole($role);
222
	}
223
224
	/**
225
	 *
226
	 * @param string $permission
227
	 */
228 2
	public static function removePermission(string $permission) {
229 2
		self::$aclList->removePermission($permission);
230
	}
231
232
	/**
233
	 *
234
	 * @param string $resource
235
	 */
236
	public static function removeResource(string $resource) {
237
		self::$aclList->removeResource($resource);
238
	}
239
240
	/**
241
	 *
242
	 * @param string $role
243
	 * @param string $resource
244
	 * @param ?string $permission
245
	 */
246 2
	public static function removeAcl(string $role, string $resource, ?string $permission = null) {
247 2
		self::$aclList->removeAcl($role, $resource, $permission);
248
	}
249
250
	/**
251
	 * Initialize acls cache with controllers annotations.
252
	 * Do not execute at runtime
253
	 *
254
	 * @param array $config
255
	 * @throws \Ubiquity\exceptions\AclException
256
	 */
257 2
	public static function initCache(&$config) {
258 2
		if(!self::isStarted()){
259
			self::start();
260
			self::initFromProviders([
261
				new AclCacheProvider()
262
			]);
263
		}
264 2
		self::filterProviders(AclCacheProvider::class);
265 2
		self::reloadFromSelectedProviders([]);
266 2
		self::registerAnnotations();
267 2
		$files = \Ubiquity\cache\CacheManager::getControllersFiles($config, true);
268 2
		$parser = new AclControllerParser();
269 2
		$parser->init();
270 2
		foreach ($files as $file) {
271 2
			if (\is_file($file)) {
272 2
				$controller = ClassUtils::getClassFullNameFromFile($file);
273
				try {
274 2
					$parser->parse($controller);
275
				} catch (\Exception $e) {
276
					if ($e instanceof AclException) {
277
						throw $e;
278
					}
279
				}
280
			}
281
		}
282 2
		$parser->save();
283 2
		self::removefilterProviders();
284 2
		self::reloadFromSelectedProviders();
285
	}
286
287 2
	protected static function registerAnnotations() {
288 2
		CacheManager::getAnnotationsEngineInstance()->registerAcls();
289
	}
290
291
	/**
292
	 *
293
	 * @return \Ubiquity\security\acl\cache\PermissionsMap
294
	 */
295 1
	public static function getPermissionMap():PermissionsMap {
296 1
		if (! isset(self::$permissionMap)) {
297 1
			self::$permissionMap = new PermissionsMap();
298 1
			self::$permissionMap->load();
299
		}
300 1
		return self::$permissionMap;
301
	}
302
303
	/**
304
	 *
305
	 * @param string $controller
306
	 * @param string $action
307
	 * @param string $resource
308
	 * @param string $permission
309
	 */
310 1
	public static function associate(string $controller, string $action, string $resource, string $permission = 'ALL'):void {
311 1
		self::$aclList->getResourceByName($resource);
312 1
		self::$aclList->getPermissionByName($permission);
313 1
		self::$permissionMap->addAction($controller, $action, $resource, $permission);
314
	}
315
316
	/**
317
	 *
318
	 * @param AbstractAclPart $part
319
	 * @param string $providerClass
320
	 * @return boolean
321
	 */
322 2
	public static function existPartIn(AbstractAclPart $part, string $providerClass):bool {
323 2
		return self::$aclList->existPartIn($part, $providerClass);
324
	}
325
326
	/**
327
	 *
328
	 * @param AclElement $elm
329
	 * @param string $providerClass
330
	 * @return boolean
331
	 */
332 2
	public static function existAclIn(AclElement $elm, string $providerClass):bool {
333 2
		return self::$aclList->existAclIn($elm, $providerClass);
334
	}
335
336
	/**
337
	 *
338
	 * @param string $providerClass
339
	 * @return AclProviderInterface|NULL
340
	 */
341 2
	public static function getProvider(string $providerClass):?AclProviderInterface {
342 2
		return self::$aclList->getProvider($providerClass);
343
	}
344
345
	public static function getModelClassesSwap(): array {
346
		$result = [];
347
		$aclList = self::getAclList();
348
		if (isset($aclList)) {
349
			foreach ($aclList->getProviders() as $prov) {
350
				$result += $prov->getModelClassesSwap();
351
			}
352
		}
353
		return $result;
354
	}
355
356 2
	public static function filterProviders(string $providerClass):void {
357 2
		$providers = self::$aclList->getProviders();
358 2
		$filter = [];
359 2
		foreach ($providers as $prov) {
360 2
			if ($prov instanceof $providerClass) {
361 2
				$filter[] = $prov;
362
			}
363
		}
364 2
		self::$aclList->setProviders($filter);
365 2
		self::$providersPersistence = $providers;
366
	}
367
368 2
	public static function removefilterProviders():void {
369 2
		self::$aclList->setProviders(self::$providersPersistence);
370
	}
371
372
	/**
373
	 * Initializes AclDAOProvider and creates ACL tables in the specified dbOffset.
374
	 * Do not use in production
375
	 * @param array $config
376
	 * @param string $dbOffset
377
	 * @param array $classes
378
	 *        	associative array['acl'=>'','role'=>'','resource'=>'','permission'=>'']
379
	 * @return AclDAOProvider
380
	 * @throws AclException
381
	 */
382
	public static function initializeDAOProvider(array &$config, string $dbOffset='default', array $classes=[]): AclDAOProvider {
383
		self::start();
384
		return AclDAOProvider::initializeProvider($config,$dbOffset,$classes);
385
	}
386
}
387