Passed
Push — main ( b3eef2...a44813 )
by Jean-Christophe
02:19
created

AclList   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 224
Duplicated Lines 0 %

Test Coverage

Coverage 95.37%

Importance

Changes 3
Bugs 0 Features 1
Metric Value
eloc 82
c 3
b 0
f 1
dl 0
loc 224
ccs 103
cts 108
cp 0.9537
rs 8.64
wmc 47

25 Methods

Rating   Name   Duplication   Size   Complexity  
A loadAcls() 0 5 2
A getRoles() 0 2 1
A getResources() 0 2 1
A loadPermissions() 0 5 2
A getProviders() 0 2 1
A addRole() 0 3 1
A setProviders() 0 2 1
A allow() 0 5 1
A setPermissionLevel() 0 4 1
A getResourceByName() 0 2 1
A addPermission() 0 3 1
A getAcls() 0 2 1
A getPermissionByName() 0 2 1
A loadRoles() 0 5 2
A addResource() 0 3 1
A getElementByName() 0 7 3
A addProvider() 0 2 1
A getPermissions() 0 2 1
A getRoleByName() 0 2 1
A init() 0 5 1
A loadResources() 0 5 2
A addAndAllow() 0 11 6
B getRolePermissionsOn() 0 17 7
A isAllowed() 0 12 4
A elementExistByName() 0 7 3

How to fix   Complexity   

Complex Class

Complex classes like AclList 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 AclList, and based on these observations, apply Extract Interface, too.

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 19
	protected function getElementByName(string $name, array $inArray, string $type) {
52 19
		foreach ($inArray as $elm) {
53 19
			if ($elm->getName() == $name) {
54 18
				return $elm;
55
			}
56
		}
57 7
		throw new AclException("$name does not exist in $type ACL");
58
	}
59
60 2
	protected function elementExistByName(string $name, array $inArray): bool {
61 2
		foreach ($inArray as $elm) {
62 2
			if ($elm->getName() == $name) {
63 1
				return true;
64
			}
65
		}
66 2
		return false;
67
	}
68
69 19
	public function init() {
70 19
		$this->roles['role_@ALL'] = new Role('@ALL');
71 19
		$this->resources['res_*'] = new Resource('*');
72 19
		$this->permissions['perm_ALL'] = new Permission('ALL', 1000);
73 19
		$this->acls = [];
74 19
	}
75
76 19
	public function getRoleByName(string $name) {
77 19
		return $this->elementsCache["role_$name"] ??= $this->getElementByName($name, $this->roles, 'roles');
78
	}
79
80 11
	public function getResourceByName(string $name) {
81 11
		return $this->elementsCache["res_$name"] ??= $this->getElementByName($name, $this->resources, 'resources');
82
	}
83
84 15
	public function getPermissionByName(string $name) {
85 15
		return $this->elementsCache["perm_$name"] ??= $this->getElementByName($name, $this->permissions, 'permissions');
86
	}
87
88 7
	public function loadAcls(): array {
89 7
		foreach ($this->providers as $provider) {
90 7
			$this->acls += $provider->loadAllAcls();
91
		}
92 7
		return $this->acls;
93
	}
94
95 7
	public function loadRoles(): array {
96 7
		foreach ($this->providers as $provider) {
97 7
			$this->roles += $provider->loadAllRoles();
98
		}
99 7
		return $this->roles;
100
	}
101
102 7
	public function loadResources(): array {
103 7
		foreach ($this->providers as $provider) {
104 7
			$this->resources += $provider->loadAllResources();
105
		}
106 7
		return $this->resources;
107
	}
108
109 7
	public function loadPermissions(): array {
110 7
		foreach ($this->providers as $provider) {
111 7
			$this->permissions += $provider->loadAllPermissions();
112
		}
113 7
		return $this->permissions;
114
	}
115
116
	public function addProvider(AclProviderInterface $provider) {
117
		$this->providers[] = $provider;
118
	}
119
120
	/**
121
	 *
122
	 * @return AclElement[]
123
	 */
124 4
	public function getAcls() {
125 4
		return $this->acls;
126
	}
127
128
	/**
129
	 *
130
	 * @return Role[]
131
	 */
132 6
	public function getRoles() {
133 6
		return $this->roles;
134
	}
135
136
	/**
137
	 *
138
	 * @return \Ubiquity\security\acl\models\Resource[]
139
	 */
140 6
	public function getResources() {
141 6
		return $this->resources;
142
	}
143
144
	/**
145
	 *
146
	 * @return Permission[]
147
	 */
148 9
	public function getPermissions() {
149 9
		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 8
	public function setProviders($providers) {
165 8
		$this->providers = $providers;
166 8
	}
167
168 8
	public function addRole(Role $role) {
169 8
		$this->roles[$role->getName()] = $role;
170 8
		$this->savePart($role);
171 8
	}
172
173 8
	public function addResource(Resource $resource) {
174 8
		$this->resources[$resource->getName()] = $resource;
175 8
		$this->savePart($resource);
176 8
	}
177
178 10
	public function addPermission(Permission $permission) {
179 10
		$this->permissions[$permission->getName()] = $permission;
180 10
		$this->savePart($permission);
181 10
	}
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 11
	public function allow(string $roleName, string $resourceName, string $permissionName) {
190 11
		$aclElm = new AclElement();
191 11
		$aclElm->allow($this->getRoleByName($roleName), $this->getResourceByName($resourceName), $this->getPermissionByName($permissionName));
192 11
		$this->acls[] = $aclElm;
193 11
		$this->saveAclElement($aclElm);
194 11
	}
195
196 2
	public function addAndAllow(string $roleName, string $resourceName, string $permissionName) {
197 2
		if (! $this->elementExistByName($roleName, $this->roles)) {
198 1
			$this->addRole(new Role($roleName));
199
		}
200 2
		if ($resourceName !== '*' && ! $this->elementExistByName($resourceName, $this->resources)) {
201 1
			$this->addResource(new Resource($resourceName));
202
		}
203 2
		if ($permissionName !== 'ALL' && ! $this->elementExistByName($permissionName, $this->permissions)) {
204 2
			$this->addPermission(new Permission($permissionName));
205
		}
206 2
		$this->allow($roleName, $resourceName ?? '*', $permissionName ?? 'ALL');
207 2
	}
208
209 18
	public function getRolePermissionsOn(string $roleName, $resourceName = '*'): array {
210 18
		$role = $this->getRoleByName($roleName);
211 17
		$parents = $role->getParentsArray();
212 17
		$result = [];
213 17
		foreach ($this->acls as $aclElement) {
214 14
			$aclRoleName = $aclElement->getRole()->getName();
215 14
			if ($aclRoleName === '@ALL' || $aclRoleName === $roleName) {
216 14
				$aclResourceName = $aclElement->getResource()->getName();
217 14
				if ($aclResourceName === '*' || $aclResourceName === $resourceName) {
218 14
					$result[] = $aclElement;
219
				}
220
			}
221
		}
222 17
		foreach ($parents as $parentElm) {
223 4
			$result += $this->getRolePermissionsOn($parentElm, $resourceName);
224
		}
225 17
		return $result;
226
	}
227
228 18
	public function isAllowed(string $roleName, string $resourceName, string $permissionName) {
229 18
		$acls = $this->getRolePermissionsOn($roleName, $resourceName);
230 17
		if (\count($acls) > 0) {
231 14
			$permissionLevel = $this->getPermissionByName($permissionName)->getLevel();
232 13
			foreach ($acls as $aclElm) {
233 13
				$level = $aclElm->getPermission()->getLevel();
234 13
				if ($level >= $permissionLevel) {
235 13
					return true;
236
				}
237
			}
238
		}
239 12
		return false;
240
	}
241
}
242
243