Passed
Pull Request — master (#948)
by René
04:03
created

Acl::getTokenIsValid()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 2
ccs 0
cts 2
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
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\IUserManager;
32
use OCP\IGroupManager;
33
use OCP\ILogger;
34
use OCP\IUser;
35
use OCA\Polls\Db\Poll;
36
use OCA\Polls\Db\Share;
37
use OCA\Polls\Db\PollMapper;
38
use OCA\Polls\Db\VoteMapper;
39
use OCA\Polls\Db\ShareMapper;
40
41
/**
42
 * Class Acl
43
 *
44
 * @package OCA\Polls\Model\Acl
45
 */
46
class Acl implements JsonSerializable {
47
48
	/** @var int */
49
	private $pollId = 0;
50
51
	/** @var ILogger */
52
	private $logger;
53
54
	/** @var array */
55
	private $shares = [];
56
57
	/** @var string */
58
	private $token = '';
59
60
	/** @var bool */
61
	private $foundByToken = false;
62
63
	/** @var bool */
64
	private $tokenIsValid = false;
65
66
	/** @var string */
67
	private $userId;
68
69
	/** @var IUserManager */
70
	private $userManager;
71
72
	/** @var IGroupManager */
73
	private $groupManager;
74
75
	/** @var PollMapper */
76
	private $pollMapper;
77
78
	/** @var VoteMapper */
79
	private $voteMapper;
80
81
	/** @var ShareMapper */
82
	private $shareMapper;
83
84
	/** @var Poll */
85
	private $poll;
86
87
88
	/**
89
	 * Acl constructor.
90
	 * @param string $appName
91
	 * @param string $userId
92
	 * @param ILogger $logger
93
	 * @param IUserManager $userManager
94
	 * @param IGroupManager $groupManager
95
	 * @param PollMapper $pollMapper
96
	 * @param VoteMapper $voteMapper
97
	 * @param ShareMapper $shareMapper
98
	 * @param Poll $pollMapper
99
	 *
100
	 */
101
	public function __construct(
102
		$userId,
103
		ILogger $logger,
104
		IUserManager $userManager,
105
		IGroupManager $groupManager,
106
		PollMapper $pollMapper,
107
		VoteMapper $voteMapper,
108
		ShareMapper $shareMapper,
109
		Poll $poll
110
	) {
111
		$this->userId = $userId;
112
		$this->logger = $logger;
113
		$this->userManager = $userManager;
114
		$this->groupManager = $groupManager;
115
		$this->pollMapper = $pollMapper;
116
		$this->voteMapper = $voteMapper;
117
		$this->shareMapper = $shareMapper;
118
		$this->poll = $poll;
119
	}
120
121
122
	/**
123
	 * @NoAdminRequired
124
	 * @return int
125
	 */
126
	public function setPollId(int $pollId): Acl {
127
		try {
128
			$this->pollId = $pollId;
129
			$this->poll = $this->pollMapper->find($this->pollId);
130
			$this->shares = $this->shareMapper->findByPoll($this->pollId);
131
		} catch (DoesNotExistException $e) {
132
			$this->poll = new Poll();
133
		}
134
135
		return $this;
136
	}
137
138
	/**
139
	 * @NoAdminRequired
140
	 * @return string
141
	 */
142
	public function setUserId($userId): Acl {
143
		$this->userId = $userId;
144
		return $this;
145
	}
146
147
	/**
148
	 * @NoAdminRequired
149
	 * @return string
150
	 */
151
	public function setToken(string $token): Acl {
152
		try {
153
154
			$this->token = $token;
155
			$share = $this->shareMapper->findByToken($token);
156
			$this->foundByToken = true;
157
			$this->tokenIsValid = true;
158
			$this->setPollId($share->getPollId());
159
160
			if (($share->getType() === 'group' || $share->getType() === 'user') && !\OC::$server->getUserSession()->isLoggedIn()) {
161
				// User must be logged in for shareType user and group
162
				$this->setPollId(0);
163
				$this->setUserId(null);
164
				$this->token = '';
165
				$this->foundByToken = false;
166
				$this->tokenIsValid = false;
167
			} else if (($share->getType() === 'group' || $share->getType() === 'public') && \OC::$server->getUserSession()->isLoggedIn()) {
168
				// Use user name of authorized user shareType public and group if user is logged in
169
				$this->setUserId($this->userId);
170
			} else {
171
				$this->setUserId($share->getUserId());
172
			}
173
174
		} catch (DoesNotExistException $e) {
175
			$this->poll = new Poll();
176
			$this->userId = null;
177
			$this->token = '';
178
			$this->foundByToken = false;
179
			$this->tokenIsValid = false;
180
		}
181
182
		return $this;
183
184
	}
185
186
	/**
187
	 * @NoAdminRequired
188
	 * @return string
189
	 */
190
	 public function getUserId() {
191
		return $this->userId;
192
	}
193
194
	/**
195
	 * @NoAdminRequired
196
	 * @return string
197
	 */
198
	public function getDisplayName() {
199
		if ($this->userManager->get($this->userId) instanceof IUser) {
200
			return $this->userManager->get($this->userId)->getDisplayName();
201
		} else {
202
			return $this->userId;
203
		}
204
	}
205
206
	/**
207
	 * @NoAdminRequired
208
	 * @return string
209
	 */
210
	public function getLoggedIn() {
211
		return \OC::$server->getUserSession()->isLoggedIn();
212
	}
213
214
	/**
215
	 * @NoAdminRequired
216
	 * @return int
217
	 */
218
	public function getPollId(): int {
219
		return $this->pollId;
220
	}
221
222
	/**
223
	 * @NoAdminRequired
224
	 * @return bool
225
	 */
226
	public function getIsOwner(): bool {
227
		if (\OC::$server->getUserSession()->isLoggedIn()) {
228
			return ($this->poll->getOwner() === $this->userId);
229
		} else {
230
			return false;
231
		}
232
	}
233
234
	/**
235
	 * @NoAdminRequired
236
	 * @return bool
237
	 */
238
	public function getIsAdmin(): bool {
239
		if (\OC::$server->getUserSession()->isLoggedIn()) {
240
			return ($this->groupManager->isAdmin($this->userId) && $this->poll->getAdminAccess());
241
		} else {
242
			return false;
243
		}
244
	}
245
246
	/**
247
	 * @NoAdminRequired
248
	 * @return bool
249
	 */
250
	public function getAllowView(): bool {
251
		return (
252
			   $this->getIsOwner()
253
			|| ($this->getIsAdmin() && $this->poll->getAdminAccess())
254
			|| !$this->poll->getDeleted() && (
255
				   $this->getUserHasVoted()
256
				|| $this->getGroupShare()
257
				|| $this->getPersonalShare()
258
				|| $this->getPublicShare()
259
				|| ($this->poll->getAccess() !== 'hidden' && !$this->getPublicShare())
260
			)
261
		);
262
	}
263
264
	/**
265
	 * @NoAdminRequired
266
	 * @return bool
267
	 */
268
	public function getGroupShare(): bool {
269
		return count(
270
			array_filter($this->shareMapper->findByPoll($this->getPollId()), function($item) {
271
				if ($item->getType() === 'group' && $this->groupManager->isInGroup($this->getUserId(), $item->getUserId())) {
272
					return true;
273
				}
274
			})
275
		);
276
	}
277
278
	/**
279
	 * @NoAdminRequired
280
	 * @return bool
281
	 */
282
	public function getUserHasVoted(): bool {
283
		return count(
284
			$this->voteMapper->findParticipantsVotes($this->getPollId(), $this->getUserId())
285
		);
286
	}
287
288
	/**
289
	 * @NoAdminRequired
290
	 * @return bool
291
	 */
292
	public function getPersonalShare(): bool {
293
294
		return count(
295
			array_filter($this->shareMapper->findByPoll($this->getPollId()), function($item) {
296
				if (($item->getType() === 'user' || $item->getType() === 'external' || $item->getType() === 'email' || $item->getType() === 'contact') && $item->getUserId() === $this->getUserId()) {
297
					return true;
298
				}
299
			})
300
		);
301
	}
302
303
	/**
304
	 * @NoAdminRequired
305
	 * @return bool
306
	 */
307
	public function getPublicShare(): bool {
308
309
		return count(
310
			array_filter($this->shareMapper->findByPoll($this->getPollId()), function($item) {
311
				if ($item->getType() === 'public' && $item->getToken() === $this->getToken()) {
312
					return true;
313
				}
314
			})
315
		);
316
	}
317
318
	/**
319
	 * @NoAdminRequired
320
	 * @return bool
321
	 */
322
	public function getExpired(): bool {
323
		return (
324
			   $this->poll->getExpire() > 0
325
			&& $this->poll->getExpire() < time()
326
		);
327
	}
328
329
	/**
330
	 * @NoAdminRequired
331
	 * @return bool
332
	 */
333
	public function getAllowVote(): bool {
334
		if (
335
			   ($this->getAllowView() || $this->getFoundByToken())
336
			&& !$this->getExpired()
337
			&& !$this->poll->getDeleted()
338
			&& $this->userId
339
340
		) {
341
			return true;
342
		} else {
343
			return false;
344
		}
345
	}
346
347
	/**
348
	 * @NoAdminRequired
349
	 * @return bool
350
	 */
351
	public function getAllowComment(): bool {
352
		return !$this->poll->getDeleted() && boolval($this->userId);
353
	}
354
355
	/**
356
	 * @NoAdminRequired
357
	 * @return bool
358
	 */
359
	public function getAllowEdit(): bool {
360
		return ($this->getIsOwner() || $this->getIsAdmin());
361
	}
362
363
	/**
364
	 * @NoAdminRequired
365
	 * @return bool
366
	 */
367
	public function getAllowSeeResults(): bool {
368
		if ($this->poll->getShowResults() === 'always' || $this->getIsOwner()) {
369
			return true;
370
		} elseif ($this->poll->getShowResults() === 'never') {
371
			return false;
372
		} elseif ($this->poll->getShowResults() === 'expired') {
373
			return $this->getExpired();
374
		} else {
375
			return false;
376
		}
377
	}
378
379
	/**
380
	 * @NoAdminRequired
381
	 * @return bool
382
	 */
383
	public function getAllowSeeUsernames(): bool {
384
		return !($this->poll->getAnonymous() && !$this->getIsOwner()); ;
385
	}
386
387
	/**
388
	 * @NoAdminRequired
389
	 * @return bool
390
	 */
391
	public function getAllowSeeAllVotes(): bool {
392
		// TODO: preparation for polls without displaying other votes
393
		if ($this->pollId) {
394
			return true;
395
		} else {
396
			return false;
397
		}
398
	}
399
400
	/**
401
	 * @NoAdminRequired
402
	 * @return bool
403
	 */
404
	public function getFoundByToken(): bool {
405
		return $this->foundByToken;
406
	}
407
408
	/**
409
	 * @NoAdminRequired
410
	 * @return bool
411
	 */
412
	public function getTokenIsValid(): bool {
413
		return $this->tokenIsValid;
414
	}
415
416
	/**
417
	 * @NoAdminRequired
418
	 * @return string
419
	 */
420
	public function getToken(): string {
421
		return $this->token;
422
	}
423
424
	/**
425
	 * @return array
426
	 */
427
	public function jsonSerialize(): array {
428
		return	[
429
			'userId'            => $this->getUserId(),
430
			'displayName'       => $this->getDisplayName(),
431
			'loggedIn'			=> $this->getLoggedIn(),
432
			'pollId'            => $this->getPollId(),
433
			'token'             => $this->getToken(),
434
			'isOwner'           => $this->getIsOwner(),
435
			'isAdmin'           => $this->getIsAdmin(),
436
			'allowView'         => $this->getAllowView(),
437
			'allowVote'         => $this->getAllowVote(),
438
			'allowComment'      => $this->getAllowComment(),
439
			'allowEdit'         => $this->getAllowEdit(),
440
			'allowSeeResults'   => $this->getAllowSeeResults(),
441
			'allowSeeUsernames' => $this->getAllowSeeUsernames(),
442
			'allowSeeAllVotes'  => $this->getAllowSeeAllVotes(),
443
			'userHasVoted'		=> $this->getUserHasVoted(),
444
			'groupShare'        => $this->getGroupShare(),
445
			'personalShare'     => $this->getPersonalShare(),
446
			'publicShare'     	=> $this->getPublicShare(),
447
			'foundByToken'      => $this->getFoundByToken()
448
		];
449
	}
450
}
451