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