Completed
Push — develop-0.9 ( 12ab21...4237b7 )
by René
15s queued 10s
created

ApiController::getSystem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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