Completed
Push — master ( 7dd2dd...7e98b2 )
by Adam
03:24 queued 01:04
created

LatteChecker   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 192
Duplicated Lines 45.31 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 6.45%

Importance

Changes 0
Metric Value
wmc 38
lcom 1
cbo 6
dl 87
loc 192
ccs 4
cts 62
cp 0.0645
rs 8.3999
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B isAllowed() 0 16 6
C checkUser() 28 28 8
D checkResources() 14 31 9
B checkPrivileges() 21 21 6
B checkPermission() 24 24 4
A checkRoles() 0 17 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * LatteChecker.php
4
 *
5
 * @copyright      More in license.md
6
 * @license        http://www.ipublikuj.eu
7
 * @author         Adam Kadlec http://www.ipublikuj.eu
8
 * @package        iPublikuj:Permissions!
9
 * @subpackage     Access
10
 * @since          1.0.0
11
 *
12
 * @date           14.10.14
13
 */
14
15
declare(strict_types = 1);
16
17
namespace IPub\Permissions\Access;
18
19
use Nette;
20
use Nette\Utils;
21
use Nette\Security as NS;
22
23
use IPub;
24
use IPub\Permissions\Entities;
25
use IPub\Permissions\Exceptions;
26
use IPub\Permissions\Security;
27
28
/**
29
 * Latte helper for access checking
30
 *
31
 * @package        iPublikuj:Permissions!
32
 * @subpackage     Access
33
 *
34
 * @author         Adam Kadlec <[email protected]>
35
 */
36 1
final class LatteChecker extends Nette\Object implements IChecker
37
{
38
	/**
39
	 * @var NS\User
40
	 */
41
	private $user;
42
43
	/**
44
	 * @param NS\User $user
45
	 */
46
	public function __construct(NS\User $user)
47
	{
48 1
		$this->user = $user;
49 1
	}
50
51
	/**
52
	 * {@inheritdoc}
53
	 */
54
	public function isAllowed($element) : bool
55
	{
56
		// Check annotations only if element have to be secured
57
		if (is_array($element)) {
58
			$element = Utils\ArrayHash::from($element);
59
60
			return $this->checkUser($element)
61
			&& $this->checkResources($element)
62
			&& $this->checkPrivileges($element)
63
			&& $this->checkPermission($element)
64
			&& $this->checkRoles($element);
65
66
		} else {
67
			return TRUE;
68
		}
69
	}
70
71
	/**
72
	 * @param Utils\ArrayHash $element
73
	 *
74
	 * @return bool
75
	 *
76
	 * @throws Exceptions\InvalidArgumentException
77
	 */
78 View Code Duplication
	private function checkUser(Utils\ArrayHash $element) : bool
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
79
	{
80
		// Check if element has user parameter
81
		if ($element->offsetExists('user')) {
82
			// Get user parameter
83
			$user = $element->offsetGet('user');
84
85
			// Parameter is single string
86
			if (is_string($user) && in_array($user, ['loggedIn', 'guest'], TRUE)) {
87
				// User have to be logged in and is not
88
				if ($user === 'loggedIn' && $this->user->isLoggedIn() === FALSE) {
89
					return FALSE;
90
91
				// User have to be logged out and is logged in
92
				} elseif ($user === 'guest' && $this->user->isLoggedIn() === TRUE) {
93
					return FALSE;
94
				}
95
96
			// Parameter have multiple definitions
97
			} else {
98
				throw new Exceptions\InvalidArgumentException('In parameter \'user\' is allowed only one from two strings: \'loggedIn\' & \'guest\'');
99
			}
100
101
			return TRUE;
102
		}
103
104
		return TRUE;
105
	}
106
107
	/**
108
	 * @param Utils\ArrayHash $element
109
	 *
110
	 * @return bool
111
	 *
112
	 * @throws Exceptions\InvalidStateException
113
	 */
114
	protected function checkResources(Utils\ArrayHash $element) : bool
115
	{
116
		// Check if element has resource parameter & privilege parameter
117
		if ($element->offsetExists('resource')) {
118
			$resources = (array) $element->offsetGet('resource');
119
			$privileges = $element->offsetExists('privilege') ? (array) $element->offsetGet('privilege') : [];
120
121
			if (count($resources) != 1) {
122
				throw new Exceptions\InvalidStateException('Invalid resources count in \'resource\' parameter!');
123
			}
124
125 View Code Duplication
			foreach ($resources as $resource) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
				if (count($privileges)) {
127
					foreach ($privileges as $privilege) {
128
						if ($this->user->isAllowed($resource, $privilege)) {
129
							return TRUE;
130
						}
131
					}
132
133
				} else {
134
					if ($this->user->isAllowed($resource)) {
135
						return TRUE;
136
					}
137
				}
138
			}
139
140
			return FALSE;
141
		}
142
143
		return TRUE;
144
	}
145
146
	/**
147
	 * @param Utils\ArrayHash $element
148
	 *
149
	 * @return bool
150
	 *
151
	 * @throws Exceptions\InvalidStateException
152
	 */
153 View Code Duplication
	protected function checkPrivileges(Utils\ArrayHash $element) : bool
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
154
	{
155
		// Check if element has privilege parameter & hasn't resource parameter
156
		if (!$element->offsetExists('resource') && $element->offsetExists('privilege')) {
157
			$privileges = (array) $element->offsetGet('privilege');
158
159
			if (count($privileges) != 1) {
160
				throw new Exceptions\InvalidStateException('Invalid privileges count in \'privilege\' parameter!');
161
			}
162
163
			foreach ($privileges as $privilege) {
164
				if ($this->user->isAllowed(NS\IAuthorizator::ALL, $privilege)) {
165
					return TRUE;
166
				}
167
			}
168
169
			return FALSE;
170
		}
171
172
		return TRUE;
173
	}
174
175
	/**
176
	 * @param Utils\ArrayHash $element
177
	 *
178
	 * @return bool
179
	 */
180 View Code Duplication
	protected function checkPermission(Utils\ArrayHash $element) : bool
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
181
	{
182
		// Check if element has permission parameter
183
		if ($element->offsetExists('permission')) {
184
			$permissions = (array) $element->offsetGet('permission');
185
186
			foreach ($permissions as $permission) {
187
				// Parse resource & privilege from permission
188
				list($resource, $privilege) = explode(Entities\IPermission::DELIMITER, $permission);
189
190
				// Remove white spaces
191
				$resource = Utils\Strings::trim($resource);
192
				$privilege = Utils\Strings::trim($privilege);
193
194
				if ($this->user->isAllowed($resource, $privilege)) {
195
					return TRUE;
196
				}
197
			}
198
199
			return FALSE;
200
		}
201
202
		return TRUE;
203
	}
204
205
	/**
206
	 * @param Utils\ArrayHash $element
207
	 *
208
	 * @return bool
209
	 */
210
	protected function checkRoles(Utils\ArrayHash $element) : bool
211
	{
212
		// Check if element has role parameter
213
		if ($element->offsetExists('role')) {
214
			$roles = (array) $element->offsetGet('role');
215
216
			foreach ($roles as $role) {
217
				if ($this->user->isInRole($role)) {
218
					return TRUE;
219
				}
220
			}
221
222
			return FALSE;
223
		}
224
225
		return TRUE;
226
	}
227
}
228