Passed
Push — 3.0 ( 7d7163...f60a73 )
by Jeroen
47:33 queued 11s
created

Gatekeeper::assertAccessibleEntity()   B

Complexity

Conditions 11
Paths 72

Size

Total Lines 56
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 11

Importance

Changes 0
Metric Value
cc 11
eloc 35
nc 72
nop 2
dl 0
loc 56
ccs 34
cts 34
cp 1
crap 11
rs 7.3166
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Elgg;
4
5
use Elgg\Database\AccessCollections;
6
use Elgg\Database\EntityTable;
7
use Elgg\Http\Request as HttpRequest;
8
use Elgg\I18n\Translator;
9
use ElggEntity;
10
use ElggGroup;
11
use ElggSession;
12
use ElggUser;
13
use Exception;
14
use Elgg\Http\Exception\AdminGatekeeperException;
15
use Elgg\Http\Exception\LoggedInGatekeeperException;
16
use Elgg\Http\Exception\LoggedOutGatekeeperException;
17
use Elgg\Http\Exception\AjaxGatekeeperException;
18
19
/**
20
 * Gatekeeper
21
 *
22
 * Use elgg()->gatekeeper
23
 */
24
class Gatekeeper {
25
26
	/**
27
	 * @var ElggSession
28
	 */
29
	protected $session;
30
31
	/**
32
	 * @var \Elgg\Http\Request
33
	 */
34
	protected $request;
35
36
	/**
37
	 * @var RedirectService
38
	 */
39
	protected $redirects;
40
41
	/**
42
	 * @var EntityTable
43
	 */
44
	protected $entities;
45
46
	/**
47
	 * @var AccessCollections
48
	 */
49
	protected $access;
50
51
	/**
52
	 * @var Translator
53
	 */
54
	protected $translator;
55
56
	/**
57
	 * Constructor
58
	 *
59
	 * @param ElggSession       $session    Session
60
	 * @param HttpRequest       $request    HTTP Request
61
	 * @param RedirectService   $redirects  Redirects Service
62
	 * @param EntityTable       $entities   Entity table
63
	 * @param AccessCollections $access     Access collection table
64
	 * @param Translator        $translator Translator
65
	 *
66
	 * @access private
67
	 * @internal
68
	 */
69 108
	public function __construct(
70
		ElggSession $session,
71
		HttpRequest $request,
72
		RedirectService $redirects,
73
		EntityTable $entities,
74
		AccessCollections $access,
75
		Translator $translator
76
	) {
77 108
		$this->session = $session;
78 108
		$this->request = $request;
79 108
		$this->redirects = $redirects;
80 108
		$this->entities = $entities;
81 108
		$this->access = $access;
82 108
		$this->translator = $translator;
83 108
	}
84
85
	/**
86
	 * Require a user to be authenticated to with code execution
87
	 * @return void
88
	 * @throws LoggedInGatekeeperException
89
	 */
90 90
	public function assertAuthenticatedUser() {
91 90
		if ($this->session->isLoggedIn()) {
92 76
			return;
93
		}
94
95 14
		$this->redirects->setLastForwardFrom();
96
97 14
		throw new LoggedInGatekeeperException();
98
	}
99
100
	/**
101
	 * Require a user to be not authenticated (logged out) to with code execution
102
	 * @return void
103
	 * @throws LoggedOutGatekeeperException
104
	 */
105 2
	public function assertUnauthenticatedUser() {
106 2
		if (!$this->session->isLoggedIn()) {
107 1
			return;
108
		}
109
110 1
		$exception = new LoggedOutGatekeeperException();
111 1
		$exception->setRedirectUrl(elgg_get_site_url());
112
		
113 1
		throw $exception;
114
	}
115
116
	/**
117
	 * Require an admin user to be authenticated to proceed with code execution
118
	 * @return void
119
	 * @throws GatekeeperException
120
	 * @throws AdminGatekeeperException
121
	 */
122 15
	public function assertAuthenticatedAdmin() {
123 15
		$this->assertAuthenticatedUser();
124
125 13
		$user = $this->session->getLoggedInUser();
126 13
		if ($user->isAdmin()) {
127 12
			return;
128
		}
129
130 1
		$this->redirects->setLastForwardFrom();
131
132 1
		throw new AdminGatekeeperException();
133
	}
134
135
	/**
136
	 * Require an entity with a given guid, type and subtype to proceed with code execution
137
	 *
138
	 * @warning Returned entity has been retrieved with ignored access, as well including disabled entities.
139
	 *          You must validate entity access on the return of this method.
140
	 *
141
	 * @param int    $guid    GUID of the entity
142
	 * @param string $type    Entity type
143
	 * @param string $subtype Entity subtype
144
	 *
145
	 * @return ElggEntity
146
	 * @throws EntityNotFoundException
147
	 * @throws Exception
148
	 */
149
	public function assertExists($guid, $type = null, $subtype = null) {
150 51
		$entity = elgg_call(ELGG_IGNORE_ACCESS | ELGG_SHOW_DISABLED_ENTITIES, function () use ($guid, $type, $subtype) {
151 51
			return $this->entities->get($guid, $type, $subtype);
152 51
		});
153
154 51
		if (!$entity) {
155 5
			$exception = new EntityNotFoundException();
156 5
			$exception->setParams([
157 5
				'guid' => $guid,
158 5
				'type' => $type,
159 5
				'subtype' => $subtype,
160 5
				'route' => $this->request->get('_route'),
161
			]);
162 5
			throw $exception;
163
		}
164
165 46
		return $entity;
166
	}
167
168
	/**
169
	 * Require that authenticated user has access to entity
170
	 *
171
	 * @param ElggEntity $entity Entity
172
	 * @param ElggUser   $user   User
173
	 *
174
	 * @return void
175
	 * @throws HttpException
176
	 */
177 51
	public function assertAccessibleEntity(ElggEntity $entity, ElggUser $user = null) {
178
179 51
		$result = true;
180
181
		try {
182 51
			if (!$this->session->getIgnoreAccess() && !$this->access->hasAccessToEntity($entity, $user)) {
183
				// user is logged in but still does not have access to it
184 7
				$msg = $this->translator->translate('limited_access');
185 7
				$exception = new EntityPermissionsException($msg);
186 7
				$exception->setParams([
187 7
					'entity' => $entity,
188 7
					'user' => $user,
189 7
					'route' => $this->request->get('_route'),
190
				]);
191 7
				throw $exception;
192
			}
193
194 45
			if (!$entity->isEnabled() && !$this->session->getDisabledEntityVisibility()) {
195
				// entity exists, but is disabled
196 1
				$exception = new EntityNotFoundException();
197 1
				$exception->setParams([
198 1
					'entity' => $entity,
199 1
					'user' => $user,
200 1
					'route' => $this->request->get('_route'),
201
				]);
202 1
				throw $exception;
203
			}
204
205 44
			if ($entity instanceof ElggGroup) {
206 17
				$this->assertAccessibleGroup($entity, $user);
207
			}
208
209 39
			foreach (['owner_guid', 'container_guid'] as $prop) {
210 39
				if (!$entity->$prop) {
211 39
					continue;
212
				}
213
214 27
				$parent = $this->assertExists($entity->$prop);
215 39
				$this->assertAccessibleEntity($parent, $user);
216
			}
217 18
		} catch (HttpException $ex) {
218 18
			$result = $ex;
219
		}
220
221
		$hook_params = [
222 51
			'entity' => $entity,
223 51
			'user' => $user,
224 51
			'route' => $this->request->get('_route'),
225
		];
226
227 51
		$result = _elgg_services()->hooks->trigger('gatekeeper', "{$entity->type}:{$entity->subtype}", $hook_params, $result);
228
229 51
		if ($result instanceof HttpException) {
230 18
			throw $result;
231 34
		} else if ($result === false) {
232 1
			throw new HttpException();
233
		}
234 34
	}
235
236
	/**
237
	 * Validate active user account
238
	 *
239
	 * @param ElggUser $user   User
240
	 * @param ElggUser $viewer Viewing user
241
	 *
242
	 * @return void
243
	 * @throws EntityNotFoundException
244
	 */
245 4
	public function assertAccessibleUser(ElggUser $user, ElggUser $viewer = null) {
246 4
		if (!$user->isBanned()) {
247 1
			return;
248
		}
249
		
250 3
		if (!isset($viewer)) {
251 3
			$viewer = $this->session->getLoggedInUser();
252
		}
253
254 3
		if (!$viewer || !$viewer->isAdmin()) {
255 2
			$exception = new EntityNotFoundException();
256 2
			$exception->setParams([
257 2
				'entity' => $user,
258 2
				'user' => $viewer,
259 2
				'route' => $this->request->get('_route'),
260
			]);
261 2
			throw $exception;
262
		}
263 1
	}
264
265
	/**
266
	 * Validate group content visibility
267
	 *
268
	 * @param ElggGroup $group Group entity
269
	 * @param ElggUser  $user  User entity
270
	 *
271
	 * @return void
272
	 * @throws GroupGatekeeperException
273
	 * @throws GatekeeperException
274
	 */
275 17
	public function assertAccessibleGroup(ElggGroup $group, ElggUser $user = null) {
276 17
		if ($group->canAccessContent($user)) {
277 7
			return;
278
		}
279
		
280 10
		$this->assertAuthenticatedUser();
281
282 10
		$this->redirects->setLastForwardFrom();
283
284 10
		$exception = new GroupGatekeeperException();
285 10
		$exception->setParams([
286 10
			'entity' => $group,
287 10
			'user' => $user,
288 10
			'route' => $this->request->get('_route'),
289
		]);
290 10
		$exception->setRedirectUrl($group->getURL());
291 10
		throw $exception;
292
	}
293
294
	/**
295
	 * Require XmlHttpRequest
296
	 *
297
	 * @return void
298
	 * @throws AjaxGatekeeperException
299
	 */
300 20
	public function assertXmlHttpRequest() {
301 20
		if ($this->request->isXmlHttpRequest()) {
302 18
			return;
303
		}
304
305 2
		throw new AjaxGatekeeperException();
306
	}
307
308
}
309