Completed
Push — master ( d62417...7b2aa5 )
by René
10:14 queued 11s
created

Acl   C

Complexity

Total Complexity 53

Size/Duplication

Total Lines 304
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 4
Bugs 1 Features 0
Metric Value
eloc 108
dl 0
loc 304
ccs 0
cts 155
cp 0
rs 6.96
c 4
b 1
f 0
wmc 53

20 Methods

Rating   Name   Duplication   Size   Complexity  
A getAllowSeeAllVotes() 0 6 2
B getAllowView() 0 7 7
B setToken() 0 29 8
A getIsAdmin() 0 5 2
A getPollId() 0 2 1
A getAllowComment() 0 2 1
A getPersonalShare() 0 6 3
B getAccessLevel() 0 13 8
A __construct() 0 14 1
A getUserId() 0 2 1
A getIsOwner() 0 5 2
A getAllowEdit() 0 2 2
A getFoundByToken() 0 2 1
A setPollId() 0 6 1
A getGroupShare() 0 5 3
A getToken() 0 2 1
A getAllowSeeUsernames() 0 2 3
A setUserId() 0 3 1
A jsonSerialize() 0 17 1
A getAllowVote() 0 5 4

How to fix   Complexity   

Complex Class

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

1
<?php
2
/**
3
 * @copyright Copyright (c) 2017 Vinzenz Rosenkranz <[email protected]>
4
 *
5
 * @author René Gieling <[email protected]>
6
*
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 *  This program is free software: you can redistribute it and/or modify
10
 *  it under the terms of the GNU Affero General Public License as
11
 *  published by the Free Software Foundation, either version 3 of the
12
 *  License, or (at your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU Affero General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU Affero General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
25
namespace OCA\Polls\Model;
26
27
use JsonSerializable;
28
use Exception;
29
use OCP\AppFramework\Db\DoesNotExistException;
30
31
use OCP\IGroupManager;
32
use OCP\ILogger;
33
use OCA\Polls\Db\Event;
34
use OCA\Polls\Db\Share;
35
use OCA\Polls\Db\EventMapper;
36
use OCA\Polls\Db\ShareMapper;
37
38
/**
39
 * Class Acl
40
 *
41
 * @package OCA\Polls\Model\Acl
42
 */
43
class Acl implements JsonSerializable {
44
45
	/** @var int */
46
	private $pollId = 0;
47
	/** @var ILogger */
48
	private $logger;
49
50
	/** @var array */
51
	private $shares = [];
52
53
	/** @var string */
54
	private $token = '';
55
56
	/** @var bool */
57
	private $foundByToken = false;
58
59
	/** @var string */
60
	private $userId;
61
62
	/** @var IGroupManager */
63
	private $groupManager;
64
65
	/** @var EventMapper */
66
	private $eventMapper;
67
68
	/** @var ShareMapper */
69
	private $shareMapper;
70
71
	/** @var Event */
72
	private $event;
73
74
75
	/**
76
	 * Acl constructor.
77
	 * @param string $appName
78
	 * @param string $userId
79
	 * @param ILogger $logger
80
	 * @param IGroupManager $groupManager
81
	 * @param EventMapper $eventMapper
82
	 * @param ShareMapper $shareMapper
83
	 * @param Event $eventMapper
84
	 *
85
	 */
86
	public function __construct(
87
		$userId,
88
		ILogger $logger,
89
		IGroupManager $groupManager,
90
		EventMapper $eventMapper,
91
		ShareMapper $shareMapper,
92
		Event $event
93
	) {
94
		$this->userId = $userId;
95
		$this->logger = $logger;
96
		$this->groupManager = $groupManager;
97
		$this->eventMapper = $eventMapper;
98
		$this->shareMapper = $shareMapper;
99
		$this->event = $event;
100
	}
101
102
103
	/**
104
	 * @NoAdminRequired
105
	 * @return string
106
	 */
107
	 public function getUserId() {
108
		return $this->userId;
109
	}
110
111
	/**
112
	 * @NoAdminRequired
113
	 * @return string
114
	 */
115
	public function setUserId($userId): Acl {
116
		$this->userId = $userId;
117
		return $this;
118
	}
119
120
	/**
121
	 * @NoAdminRequired
122
	 * @return int
123
	 */
124
	public function getPollId(): int {
125
		return $this->pollId;
126
	}
127
128
	/**
129
	 * @NoAdminRequired
130
	 * @return int
131
	 */
132
	public function setPollId(int $pollId): Acl {
133
		$this->pollId = $pollId;
134
		$this->event = $this->eventMapper->find($this->pollId);
135
		$this->shares = $this->shareMapper->findByPoll($this->pollId);
136
137
		return $this;
138
	}
139
140
	/**
141
	 * @NoAdminRequired
142
	 * @return bool
143
	 */
144
	public function getIsOwner(): bool {
145
		if (\OC::$server->getUserSession()->isLoggedIn()) {
146
			return ($this->event->getOwner() === $this->userId);
147
		} else {
148
			return false;
149
		}
150
	}
151
152
	/**
153
	 * @NoAdminRequired
154
	 * @return bool
155
	 */
156
	public function getIsAdmin(): bool {
157
		if (\OC::$server->getUserSession()->isLoggedIn()) {
158
			return $this->groupManager->isAdmin($this->userId);
159
		} else {
160
			return false;
161
		}
162
	}
163
164
	/**
165
	 * @NoAdminRequired
166
	 * @return bool
167
	 */
168
	public function getAllowView(): bool {
169
		return (
170
			   $this->getIsOwner()
171
			|| $this->getIsAdmin()
172
			|| ($this->getGroupShare() && !$this->event->getDeleted())
173
			|| ($this->getPersonalShare() && !$this->event->getDeleted())
174
			|| $this->event->getAccess() !== 'hidden'
175
			);
176
	}
177
178
	/**
179
	 * @NoAdminRequired
180
	 * @return bool
181
	 */
182
	public function getGroupShare(): bool {
183
		return count(
184
			array_filter($this->shareMapper->findByPoll($this->getPollId()), function($item) {
185
				if ($item->getType() === 'group' && $this->groupManager->isInGroup($this->getUserId(),$item->getUserId())) {
186
					return true;
187
				}
188
			})
189
		);
190
	}
191
192
	/**
193
	 * @NoAdminRequired
194
	 * @return bool
195
	 */
196
	public function getPersonalShare(): bool {
197
198
		return count(
199
			array_filter($this->shareMapper->findByPoll($this->getPollId()), function($item) {
200
				if ($item->getType() === 'user' && $item->getUserId() === $this->getUserId()) {
201
					return true;
202
				}
203
			})
204
		);
205
	}
206
207
	/**
208
	 * @NoAdminRequired
209
	 * @return bool
210
	 */
211
	public function getAllowVote(): bool {
212
		if ($this->getAllowView() && !$this->event->getDeleted() && strtotime($this->event->getExpire()) > time()) {
213
			return true;
214
		} else {
215
			return false;
216
		}
217
	}
218
219
	/**
220
	 * @NoAdminRequired
221
	 * @return bool
222
	 */
223
	public function getAllowComment(): bool {
224
		return $this->getAllowVote();
225
	}
226
227
	/**
228
	 * @NoAdminRequired
229
	 * @return bool
230
	 */
231
	public function getAllowEdit(): bool {
232
		return ($this->getIsOwner() || $this->getIsAdmin());
233
	}
234
235
	/**
236
	 * @NoAdminRequired
237
	 * @return bool
238
	 */
239
	public function getAllowSeeUsernames(): bool {
240
		return !(($this->event->getIsAnonymous() && !$this->getIsOwner()) || $this->event->getFullAnonymous());;
241
	}
242
243
	/**
244
	 * @NoAdminRequired
245
	 * @return bool
246
	 */
247
	public function getAllowSeeAllVotes(): bool {
248
		// TODO: preparation for polls without displaying other votes
249
		if ($this->pollId) {
250
			return true;
251
		} else {
252
			return false;
253
		}
254
	}
255
256
	/**
257
	 * @NoAdminRequired
258
	 * @return bool
259
	 */
260
	public function getFoundByToken(): bool {
261
		return $this->foundByToken;
262
	}
263
264
	/**
265
	 * @NoAdminRequired
266
	 * @return string
267
	 */
268
	public function getToken(): string {
269
		return $this->token;
270
	}
271
272
	/**
273
	 * @NoAdminRequired
274
	 * @return string
275
	 */
276
	public function setToken(string $token): Acl {
277
		try {
278
279
			$this->token = $token;
280
			$share = $this->shareMapper->findByToken($token);
281
			$this->foundByToken = true;
282
			$this->setPollId($share->getPollId());
283
284
			if (($share->getType() === 'group' || $share->getType() === 'user')  && !\OC::$server->getUserSession()->isLoggedIn()) {
285
				// User must be logged in for shareType user and group
286
				$this->setPollId(0);
287
				$this->setUserId(null);
288
				$this->token = '';
289
				$this->foundByToken = false;
290
			} else if (($share->getType() === 'group' || $share->getType() === 'public') && \OC::$server->getUserSession()->isLoggedIn()) {
291
				// Use user name of authorized user shareType public and group if user is logged in
292
				$this->setUserId($this->userId);
293
			} else {
294
				$this->setUserId($share->getUserId());
295
			}
296
297
298
		} catch (DoesNotExistException $e) {
299
			$this->setPollId(0);
300
			$this->setUserId(null);
301
			$this->token = '';
302
			$this->foundByToken = false;
303
		}
304
		return $this;
305
	}
306
307
	/**
308
	 * @NoAdminRequired
309
	 * @return string
310
	*/
311
	public function getAccessLevel(): string {
312
		if ($this->getIsOwner()) {
313
			return 'owner';
314
		} elseif ($this->event->getAccess() === 'public') {
315
			return 'public';
316
		} elseif ($this->event->getAccess() === 'registered' && \OC::$server->getUserSession()->getUser()->getUID() === $this->userId) {
317
			return 'registered';
318
		} elseif ($this->event->getAccess() === 'hidden' && $this->getisOwner()) {
319
			return 'hidden';
320
		} elseif ($this->getIsAdmin()) {
321
			return 'admin';
322
		} else {
323
			return 'none';
324
		}
325
	}
326
327
	/**
328
	 * @return array
329
	 */
330
	public function jsonSerialize(): array {
331
		return	[
332
			'userId'            => $this->getUserId(),
333
			'pollId'            => $this->getPollId(),
334
			'token'             => $this->getToken(),
335
			'isOwner'           => $this->getIsOwner(),
336
			'isAdmin'           => $this->getIsAdmin(),
337
			'allowView'         => $this->getAllowView(),
338
			'allowVote'         => $this->getAllowVote(),
339
			'allowComment'      => $this->getAllowComment(),
340
			'allowEdit'         => $this->getAllowEdit(),
341
			'allowSeeUsernames' => $this->getAllowSeeUsernames(),
342
			'allowSeeAllVotes'  => $this->getAllowSeeAllVotes(),
343
			'groupShare'        => $this->getGroupShare(),
344
			'personalShare'     => $this->getPersonalShare(),
345
			'foundByToken'      => $this->getFoundByToken(),
346
			'accessLevel'       => $this->getAccessLevel()
347
		];
348
	}
349
}
350