Passed
Push — main ( f39298...b455ba )
by Jean-Christophe
02:23
created

AclList::loadResources()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 2
rs 10
c 1
b 0
f 1
1
<?php
2
namespace Ubiquity\security\acl\models;
3
4
use Ubiquity\security\acl\persistence\AclProviderInterface;
5
use Ubiquity\exceptions\AclException;
6
use Ubiquity\security\acl\models\traits\AclListOperationsTrait;
7
8
/**
9
 * Ubiquity\security\acl\models$AclList
10
 * This class is part of Ubiquity
11
 *
12
 * @author jc
13
 * @version 1.0.0
14
 *
15
 */
16
class AclList {
17
	use AclListOperationsTrait;
18
19
	/**
20
	 *
21
	 * @var AclElement[]
22
	 */
23
	protected $acls;
24
25
	/**
26
	 *
27
	 * @var Role[]
28
	 */
29
	protected $roles;
30
31
	/**
32
	 *
33
	 * @var \Ubiquity\security\acl\models\Resource[]
34
	 */
35
	protected $resources;
36
37
	/**
38
	 *
39
	 * @var Permission[]
40
	 */
41
	protected $permissions;
42
43
	/**
44
	 *
45
	 * @var AclProviderInterface[]
46
	 */
47
	protected $providers = [];
48
49
	protected $elementsCache = [];
50
51 21
	protected function getElementByName(string $name, array $inArray, string $type) {
52 21
		foreach ($inArray as $elm) {
53 21
			if ($elm->getName() == $name) {
54 20
				return $elm;
55
			}
56
		}
57 7
		throw new AclException("$name does not exist in $type ACL");
58
	}
59
60 4
	protected function elementExistByName(string $name, array $inArray): bool {
61 4
		foreach ($inArray as $elm) {
62 4
			if ($elm->getName() == $name) {
63 3
				return true;
64
			}
65
		}
66 4
		return false;
67
	}
68
69 21
	public function init() {
70 21
		$this->roles['role_@ALL'] = new Role('@ALL');
71 21
		$this->resources['res_*'] = new Resource('*');
72 21
		$this->permissions['perm_ALL'] = new Permission('ALL', 1000);
73 21
		$this->acls = [];
74 21
	}
75
76 21
	public function getRoleByName(string $name) {
77 21
		return $this->elementsCache["role_$name"] ??= $this->getElementByName($name, $this->roles, 'roles');
78
	}
79
80 13
	public function getResourceByName(string $name) {
81 13
		return $this->elementsCache["res_$name"] ??= $this->getElementByName($name, $this->resources, 'resources');
82
	}
83
84 17
	public function getPermissionByName(string $name) {
85 17
		return $this->elementsCache["perm_$name"] ??= $this->getElementByName($name, $this->permissions, 'permissions');
86
	}
87
88 9
	public function loadAcls(): array {
89 9
		foreach ($this->providers as $provider) {
90 9
			$this->acls += $provider->loadAllAcls();
91
		}
92 9
		return $this->acls;
93
	}
94
95 9
	public function loadRoles(): array {
96 9
		foreach ($this->providers as $provider) {
97 9
			$this->roles += $provider->loadAllRoles();
98
		}
99 9
		return $this->roles;
100
	}
101
102 9
	public function loadResources(): array {
103 9
		foreach ($this->providers as $provider) {
104 9
			$this->resources += $provider->loadAllResources();
105
		}
106 9
		return $this->resources;
107
	}
108
109 9
	public function loadPermissions(): array {
110 9
		foreach ($this->providers as $provider) {
111 9
			$this->permissions += $provider->loadAllPermissions();
112
		}
113 9
		return $this->permissions;
114
	}
115
116
	public function addProvider(AclProviderInterface $provider) {
117
		$this->providers[] = $provider;
118
	}
119
120
	/**
121
	 *
122
	 * @return AclElement[]
123
	 */
124 6
	public function getAcls() {
125 6
		return $this->acls;
126
	}
127
128
	/**
129
	 *
130
	 * @return Role[]
131
	 */
132 9
	public function getRoles() {
133 9
		return $this->roles;
134
	}
135
136
	/**
137
	 *
138
	 * @return \Ubiquity\security\acl\models\Resource[]
139
	 */
140 8
	public function getResources() {
141 8
		return $this->resources;
142
	}
143
144
	/**
145
	 *
146
	 * @return Permission[]
147
	 */
148 12
	public function getPermissions() {
149 12
		return $this->permissions;
150
	}
151
152
	/**
153
	 *
154
	 * @return AclProviderInterface[]
155
	 */
156
	public function getProviders() {
157
		return $this->providers;
158
	}
159
160
	/**
161
	 *
162
	 * @param AclProviderInterface[] $providers
163
	 */
164 10
	public function setProviders($providers) {
165 10
		$this->providers = $providers;
166 10
	}
167
168 11
	public function addRole(Role $role) {
169 11
		$this->roles[$role->getName()] = $role;
170 11
		$this->savePart($role);
171 11
	}
172
173 10
	public function addResource(Resource $resource) {
174 10
		$this->resources[$resource->getName()] = $resource;
175 10
		$this->savePart($resource);
176 10
	}
177
178 12
	public function addPermission(Permission $permission) {
179 12
		$this->permissions[$permission->getName()] = $permission;
180 12
		$this->savePart($permission);
181 12
	}
182
183 3
	public function setPermissionLevel(string $name, int $level) {
184 3
		$perm = $this->getPermissionByName($name);
185 2
		$perm->setLevel($level);
186 2
		$this->updatePart($perm);
187 2
	}
188
189 13
	public function allow(string $roleName, string $resourceName, string $permissionName) {
190 13
		$aclElm = new AclElement();
191 13
		$aclElm->allow($this->getRoleByName($roleName), $this->getResourceByName($resourceName), $this->getPermissionByName($permissionName));
192 13
		$this->acls[] = $aclElm;
193 13
		$this->saveAclElement($aclElm);
194 13
	}
195
196 4
	public function addAndAllow(string $roleName, string $resourceName, string $permissionName) {
197 4
		if (! $this->elementExistByName($roleName, $this->roles)) {
198 4
			$this->addRole(new Role($roleName));
199
		}
200 4
		if ($resourceName !== '*' && ! $this->elementExistByName($resourceName, $this->resources)) {
201 4
			$this->addResource(new Resource($resourceName));
202
		}
203 4
		if ($permissionName !== 'ALL' && ! $this->elementExistByName($permissionName, $this->permissions)) {
204 4
			$this->addPermission(new Permission($permissionName));
205
		}
206 4
		$this->allow($roleName, $resourceName ?? '*', $permissionName ?? 'ALL');
207 4
	}
208
209 20
	public function getRolePermissionsOn(string $roleName, $resourceName = '*'): array {
210 20
		$role = $this->getRoleByName($roleName);
211 19
		$parents = $role->getParentsArray();
212 19
		$result = [];
213 19
		foreach ($this->acls as $aclElement) {
214 16
			$aclRoleName = $aclElement->getRole()->getName();
215 16
			if ($aclRoleName === '@ALL' || $aclRoleName === $roleName) {
216 16
				$aclResourceName = $aclElement->getResource()->getName();
217 16
				if ($aclResourceName === '*' || $aclResourceName === $resourceName) {
218 16
					$result[] = $aclElement;
219
				}
220
			}
221
		}
222 19
		foreach ($parents as $parentElm) {
223 4
			$result += $this->getRolePermissionsOn($parentElm, $resourceName);
224
		}
225 19
		return $result;
226
	}
227
228 20
	public function isAllowed(string $roleName, string $resourceName, string $permissionName) {
229 20
		$acls = $this->getRolePermissionsOn($roleName, $resourceName);
230 19
		if (\count($acls) > 0) {
231 16
			$permissionLevel = $this->getPermissionByName($permissionName)->getLevel();
232 15
			foreach ($acls as $aclElm) {
233 15
				$level = $aclElm->getPermission()->getLevel();
234 15
				if ($level >= $permissionLevel) {
235 15
					return true;
236
				}
237
			}
238
		}
239 14
		return false;
240
	}
241
242
	/**
243
	 *
244
	 * @param string $providerClass
245
	 * @return \Ubiquity\security\acl\persistence\AclProviderInterface|NULL
246
	 */
247 2
	public function getProvider(string $providerClass) {
248 2
		foreach ($this->providers as $prov) {
249 2
			if ($prov instanceof $providerClass) {
250 2
				return $prov;
251
			}
252
		}
253
		return null;
254
	}
255
256
	/**
257
	 *
258
	 * @param AbstractAclPart $part
259
	 * @param string $providerClass
260
	 * @return boolean
261
	 */
262 2
	public function existPartIn(AbstractAclPart $part, string $providerClass) {
263 2
		$prov = $this->getProvider($providerClass);
264 2
		if (isset($prov)) {
265 2
			return $prov->existPart($part);
266
		}
267
		return false;
268
	}
269
270
	/**
271
	 *
272
	 * @param AclElement $elm
273
	 * @param string $providerClass
274
	 * @return boolean
275
	 */
276 2
	public function existAclIn(AclElement $elm, string $providerClass) {
277 2
		$prov = $this->getProvider($providerClass);
278 2
		if (isset($prov)) {
279 2
			return $prov->existAcl($elm);
280
		}
281
		return false;
282
	}
283
}
284
285