Passed
Pull Request — master (#415)
by René
05:28
created

ApiController::convertAccessList()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 31
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 25
nc 3
nop 1
dl 0
loc 31
ccs 0
cts 29
cp 0
crap 12
rs 9.52
c 0
b 0
f 0
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
namespace OCA\Polls\Controller;
25
26
use OCP\AppFramework\Controller;
27
use OCP\AppFramework\Http;
28
use OCP\AppFramework\Http\DataResponse;
29
use OCP\AppFramework\Db\DoesNotExistException;
30
31
use OCP\IGroupManager;
32
use OCP\IRequest;
33
use OCP\IUser;
34
use OCP\IConfig;
35
use OCP\IUserManager;
36
use OCP\Security\ISecureRandom;
37
38
use OCA\Polls\Db\Event;
39
use OCA\Polls\Db\EventMapper;
40
use OCA\Polls\Db\Options;
41
use OCA\Polls\Db\OptionsMapper;
42
use OCA\Polls\Db\Votes;
43
use OCA\Polls\Db\VotesMapper;
44
use OCA\Polls\Db\Comment;
45
use OCA\Polls\Db\CommentMapper;
46
47
48
49
class ApiController extends Controller {
50
51
	private $eventMapper;
52
	private $optionsMapper;
53
	private $votesMapper;
54
	private $commentMapper;
55
	private $systemConfig;
56
57
	/**
58
	 * PageController constructor.
59
	 * @param string $appName
60
	 * @param IRequest $request
61
	 * @param string $userId
62
	 * @param EventMapper $eventMapper
63
	 * @param OptionsMapper $optionsMapper
64
	 * @param VotesMapper $VotesMapper
65
	 * @param CommentMapper $CommentMapper
66
	 */
67
	public function __construct(
68
		$appName,
69
		IConfig $systemConfig,
70
		IGroupManager $groupManager,
71
		IRequest $request,
72
		IUserManager $userManager,
73
		$userId,
74
		EventMapper $eventMapper,
75
		OptionsMapper $optionsMapper,
76
		VotesMapper $VotesMapper,
77
		CommentMapper $CommentMapper
78
	) {
79
		parent::__construct($appName, $request);
80
		$this->userId = $userId;
0 ignored issues
show
Bug Best Practice introduced by
The property userId does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
81
		$this->groupManager = $groupManager;
0 ignored issues
show
Bug Best Practice introduced by
The property groupManager does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
82
		$this->systemConfig = $systemConfig;
83
		$this->userManager = $userManager;
0 ignored issues
show
Bug Best Practice introduced by
The property userManager does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
84
		$this->eventMapper = $eventMapper;
85
		$this->optionsMapper = $optionsMapper;
86
		$this->votesMapper = $VotesMapper;
87
		$this->commentMapper = $CommentMapper;
88
	}
89
90
  	/**
91
	* @NoAdminRequired
92
	* @NoCSRFRequired
93
	* @return DataResponse
94
	*/
95
	public function getSiteUsersAndGroups($query = '', $getGroups = true, $getUsers = true, $skipGroups = array(), $skipUsers = array()) {
96
		$list = array();
97
		$data = array();
98
		if ($getGroups) {
99
			$groups = $this->groupManager->search($query);
100
			foreach ($groups as $group) {
101
				if (!in_array($group->getGID(), $skipGroups)) {
102
					$list[] = [
103
						'id' => $group->getGID(),
104
						'user' => $group->getGID(),
105
						'type' => 'group',
106
						'desc' => 'group',
107
						'icon' => 'icon-group',
108
						'displayName' => $group->getGID(),
109
						'avatarURL' => ''
110
					];
111
				}
112
			}
113
		}
114
		if ($getUsers) {
115
			$users = $this->userManager->searchDisplayName($query);
116
			foreach ($users as $user) {
117
				if (!in_array($user->getUID(), $skipUsers)) {
118
					$list[] = [
119
						'id' => $user->getUID(),
120
						'user' => $user->getUID(),
121
						'type' => 'user',
122
						'desc' => 'user',
123
						'icon' => 'icon-user',
124
						'displayName' => $user->getDisplayName(),
125
						'avatarURL' => '',
126
						'lastLogin' => $user->getLastLogin(),
127
						'cloudId' => $user->getCloudId()
128
					];
129
				}
130
			}
131
		}
132
133
		$data['siteusers'] = $list;
134
		return new DataResponse($data, Http::STATUS_OK);
135
	}
136
  	/**
137
	* @NoAdminRequired
138
	* @NoCSRFRequired
139
	* @return Array
140
	*/
141
	function convertAccessList($item) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
142
		$split = Array();
143
		if (strpos($item, 'user_') === 0) {
144
			$user = $this->userManager->get(substr($item, 5));
145
			$split = [
146
				'id' => $user->getUID(),
147
				'user' => $user->getUID(),
148
				'type' => 'user',
149
				'desc' => 'user',
150
				'icon' => 'icon-user',
151
				'displayName' => $user->getDisplayName(),
152
				'avatarURL' => '',
153
				'lastLogin' => $user->getLastLogin(),
154
				'cloudId' => $user->getCloudId()
155
			];
156
		} elseif (strpos($item, 'group_') === 0) {
157
			$group = substr($item, 6);
158
			$group = $this->groupManager->get($group);
159
			$split = [
160
				'id' => $group->getGID(),
161
				'user' => $group->getGID(),
162
				'type' => 'group',
163
				'desc' => 'group',
164
				'icon' => 'icon-group',
165
				'displayName' => $group->getDisplayName(),
166
				'avatarURL' => '',
167
			];
168
		}
169
170
171
		return($split);
172
	}
173
174
  	/**
175
	* @NoAdminRequired
176
	* @NoCSRFRequired
177
	* @PublicPage
178
	* @param string $hash
179
	* @return DataResponse
180
	*/
181
182
	public function getPoll($hash) {
183
		if (!\OC::$server->getUserSession()->getUser() instanceof IUser) {
184
			return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
185
		} else {
186
			$currentUser = \OC::$server->getUserSession()->getUser()->getUID();
187
			$AdminAccess = $this->groupManager->isAdmin($currentUser);
188
		}
189
190
		try {
191
			$poll = $this->eventMapper->findByHash($hash);
192
193
			if ($poll->getExpire() === null) {
0 ignored issues
show
introduced by
The condition $poll->getExpire() === null is always false.
Loading history...
194
				$expired = false;
195
				$expiration = false;
196
			} else {
197
				$expired = time() > strtotime($poll->getExpire());
198
				$expiration = true;
199
			}
200
201
			if ($poll->getType() == 0) {
202
				$pollType = 'datePoll';
203
			} else {
204
				$pollType = 'textPoll';
205
			};
206
207
			if ($poll->getOwner() !== $currentUser && !$AdminAccess) {
208
				$mode = 'create';
209
			} else {
210
				$mode = 'edit';
211
			}
212
			$accessList = Array();
213
			$accessType = $poll->getAccess();
214
			if (!strpos('|public|hidden|registered', $accessType)) {
215
				$accessList = explode(';',$accessType);
216
				$accessList = array_filter($accessList);
217
				$accessList = array_map(Array($this,'convertAccessList'), $accessList);
218
				$accessType = 'select';
219
			}
220
221
			$data = array();
222
			$commentsList = array();
223
			$optionList = array();
224
			$votesList = array();
225
226
		} catch (DoesNotExistException $e) {
227
			return new DataResponse($e, Http::STATUS_NOT_FOUND);
228
		};
229
230
231
		try {
232
			$options = $this->optionsMapper->findByPoll($poll->getId());
233
			foreach ($options as $optionElement) {
234
				$optionList[] = [
235
					'id' => $optionElement->getId(),
236
					'text' => $optionElement->getPollOptionText(),
237
					'timestamp' => $optionElement->getTimestamp()
238
				];
239
			};
240
		} catch (DoesNotExistException $e) {
241
			// ignore
242
		};
243
244
		try {
245
			$votes = $this->votesMapper->findByPoll($poll->getId());
246
			foreach ($votes as $voteElement) {
247
				$votesList[] = [
248
					'id' => $voteElement->getId(),
249
					'userId' => $voteElement->getUserId(),
250
					'voteOptionId' => $voteElement->getVoteOptionId(),
251
					'voteOptionText' => $voteElement->getVoteOptionText(),
252
					'voteAnswer' => $voteElement->getVoteAnswer()
253
				];
254
			};
255
		} catch (DoesNotExistException $e) {
256
			// ignore
257
		};
258
259
		try {
260
			$comments = $this->commentMapper->findByPoll($poll->getId());
261
			foreach ($comments as $commentElement) {
262
				$commentsList[] = [
263
					'id' => $commentElement->getId(),
264
					'userId' => $commentElement->getUserId(),
265
					'date' => $commentElement->getDt() . ' UTC',
266
					'comment' => $commentElement->getComment()
267
				];
268
			};
269
		} catch (DoesNotExistException $e) {
270
			// ignore
271
		};
272
273
		$data['poll'] = [
274
			'result' => 'found',
275
			'mode' => $mode,
276
			'comments' => $commentsList,
277
			'votes' => $votesList,
278
			'shares' => $accessList,
279
			'event' => [
280
				'id' => $poll->getId(),
281
				'hash' => $hash,
282
				'type' => $pollType,
283
				'title' => $poll->getTitle(),
284
				'description' => $poll->getDescription(),
285
				'owner' => $poll->getOwner(),
286
				'created' => $poll->getCreated(),
287
				'access' => $accessType,
288
				'expiration' => $expiration,
289
				'expired' => $expired,
290
				'expirationDate' => $poll->getExpire(),
291
				'isAnonymous' => $poll->getIsAnonymous(),
292
				'fullAnonymous' => $poll->getFullAnonymous(),
293
				'disallowMaybe' => $poll->getDisallowMaybe()
294
			],
295
			'options' => [
296
				'pollDates' => [],
297
				'pollTexts' => $optionList
298
			]
299
		];
300
301
		return new DataResponse($data, Http::STATUS_OK);
302
	}
303
304
	/**
305
	 * @NoAdminRequired
306
	 * @NoCSRFRequired
307
	 * @param string $poll
308
	 * @return DataResponse
309
	 */
310
	public function writePoll($event, $options, $shares, $mode) {
311
		if (!\OC::$server->getUserSession()->getUser() instanceof IUser) {
312
			return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
313
		} else {
314
			$currentUser = \OC::$server->getUserSession()->getUser()->getUID();
315
			$AdminAccess = $this->groupManager->isAdmin($currentUser);
316
		}
317
318
		$newEvent = new Event();
319
320
		// Set the configuration options entered by the user
321
		$newEvent->setTitle($event['title']);
322
		$newEvent->setDescription($event['description']);
323
324
		$newEvent->setType($event['type']);
325
		$newEvent->setIsAnonymous($event['isAnonymous']);
326
		$newEvent->setFullAnonymous($event['fullAnonymous']);
327
		$newEvent->setDisallowMaybe($event['disallowMaybe']);
328
329
		if ($event['access'] === 'select') {
330
			$shareAccess = '';
331
			foreach ($shares as $shareElement) {
332
				if ($shareElement['type'] === 'user') {
333
					$shareAccess = $shareAccess . 'user_' . $shareElement['id'] . ';';
334
				} elseif ($shareElement['type'] === 'group') {
335
					$shareAccess = $shareAccess . 'group_' . $shareElement['id'] . ';';
336
				}
337
			}
338
			$newEvent->setAccess(rtrim($shareAccess, ';'));
339
		} else {
340
			$newEvent->setAccess($event['access']);
341
		}
342
343
		if ($event['expiration']) {
344
			$newEvent->setExpire($event['expirationDate']);
345
		} else {
346
			$newEvent->setExpire(null);
347
		}
348
349
		if ($event['type'] === 'datePoll') {
350
			$newEvent->setType(0);
351
		} elseif ($event['type'] === 'textPoll') {
352
			$newEvent->setType(1);
353
		}
354
355
		if ($mode === 'edit') {
356
			// Edit existing poll
357
			$oldPoll = $this->eventMapper->findByHash($event['hash']);
358
359
			// Check if current user is allowed to edit existing poll
360
			if ($oldPoll->getOwner() !== $currentUser && !$AdminAccess) {
361
				// If current user is not owner of existing poll deny access
362
				return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
363
			}
364
365
			// else take owner, hash and id of existing poll
366
			$newEvent->setOwner($oldPoll->getOwner());
367
			$newEvent->setHash($oldPoll->getHash());
368
			$newEvent->setId($oldPoll->getId());
369
			$this->eventMapper->update($newEvent);
370
			$this->optionsMapper->deleteByPoll($newEvent->getId());
371
372
		} elseif ($mode === 'create') {
373
			// Create new poll
374
			// Define current user as owner, set new creation date and create a new hash
375
			$newEvent->setOwner($currentUser);
376
			$newEvent->setCreated(date('Y-m-d H:i:s'));
377
			$newEvent->setHash(\OC::$server->getSecureRandom()->generate(
378
				16,
379
				ISecureRandom::CHAR_DIGITS .
380
				ISecureRandom::CHAR_LOWER .
381
				ISecureRandom::CHAR_UPPER
382
			));
383
			$newEvent = $this->eventMapper->insert($newEvent);
384
		}
385
386
		// Update options
387
		if ($event['type'] === 'datePoll') {
388
			foreach ($options['pollDates'] as $optionElement) {
389
				$newOption = new Options();
390
391
				$newOption->setPollId($newEvent->getId());
392
				$newOption->setPollOptionText(date('Y-m-d H:i:s', $optionElement['timestamp']));
393
				$newOption->setTimestamp($optionElement['timestamp']);
394
395
				$this->optionsMapper->insert($newOption);
396
			}
397
		} elseif ($event['type'] === "textPoll") {
398
			foreach ($options['pollTexts'] as $optionElement) {
399
				$newOption = new Options();
400
401
				$newOption->setPollId($newEvent->getId());
402
				$newOption->setpollOptionText(htmlspecialchars($optionElement['text']));
403
404
				$this->optionsMapper->insert($newOption);
405
			}
406
		}
407
		return new DataResponse(array(
408
			'id' => $newEvent->getId(),
409
			'hash' => $newEvent->getHash()
410
		), Http::STATUS_OK);
411
412
	}
413
414
	private function getVendor() {
415
		// this should really be a JSON file
416
		require \OC::$SERVERROOT . '/version.php';
417
		/** @var string $vendor */
418
		return (string) $vendor;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $vendor seems to be never defined.
Loading history...
419
	}
420
421
	/**
422
	 * @NoAdminRequired
423
	 * @NoCSRFRequired
424
	 * @return DataResponse
425
	 */
426
	public function getSystem() {
427
		$userId = \OC::$server->getUserSession()->getUser()->getUID();
428
		$data['system'] = [
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
429
			'versionArray' => \OCP\Util::getVersion(),
430
			'version' => implode('.', \OCP\Util::getVersion()),
431
			'vendor' => $this->getVendor(),
432
			'language' => $this->systemConfig->getUserValue($userId, 'core', 'lang')
433
		];
434
		return new DataResponse($data, Http::STATUS_OK);
435
	}
436
}
437