Completed
Push — develop-0.9 ( 3c00b3...763dab )
by René
12s
created

ApiController::getSiteUsersAndGroups()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 32
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 22
nc 4
nop 4
dl 0
loc 32
rs 8.6346
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\IUserManager;
35
use OCP\Security\ISecureRandom;
36
37
use OCA\Polls\Db\Event;
38
use OCA\Polls\Db\EventMapper;
39
use OCA\Polls\Db\Options;
40
use OCA\Polls\Db\OptionsMapper;
41
use OCA\Polls\Db\Votes;
42
use OCA\Polls\Db\VotesMapper;
43
use OCA\Polls\Db\Comment;
44
use OCA\Polls\Db\CommentMapper;
45
46
47
48
class ApiController extends Controller {
49
50
	private $eventMapper;
51
	private $optionsMapper;
52
	private $votesMapper;
53
	private $commentMapper;
54
55
	/**
56
	 * PageController constructor.
57
	 * @param string $appName
58
	 * @param IRequest $request
59
	 * @param string $userId
60
	 * @param EventMapper $eventMapper
61
	 * @param OptionsMapper $optionsMapper
62
	 * @param VotesMapper $VotesMapper
63
	 * @param CommentMapper $CommentMapper
64
	 */
65
	public function __construct(
66
		$appName,
67
		IGroupManager $groupManager,
68
		IRequest $request,
69
		IUserManager $userManager,
70
		$userId,
71
		EventMapper $eventMapper,
72
		OptionsMapper $optionsMapper,
73
		VotesMapper $VotesMapper,
74
		CommentMapper $CommentMapper
75
	) {
76
		parent::__construct($appName, $request);
77
		$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...
78
		$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...
79
		$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...
80
		$this->eventMapper = $eventMapper;
81
		$this->optionsMapper = $optionsMapper;
82
		$this->votesMapper = $VotesMapper;
83
		$this->commentMapper = $CommentMapper;
84
	}
85
86
  	/**
87
	* @NoAdminRequired
88
	* @NoCSRFRequired
89
	* @return DataResponse
90
	*/
91
	public function getSiteUsersAndGroups($getGroups = true, $getUsers = true, $skipGroups = array(), $skipUsers = array()) {
92
		$list = array();
93
		$data = array();
94
		if ($getGroups) {
95
			$groups = $this->groupManager->search('');
96
			foreach ($groups as $group) {
97
				if (!in_array($group->getGID(), $skipGroups)) {
98
					$list[] = [
99
						'id' => $group->getGID(),
100
						'type' => 'group',
101
						'displayName' => $group->getGID(),
102
						'avatarURL' => ''
103
					];
104
				}
105
			}
106
		}
107
		if ($getUsers) {
108
			$users = $this->userManager->searchDisplayName('');
109
			foreach ($users as $user) {
110
				if (!in_array($user->getUID(), $skipUsers)) {
111
					$list[] = [
112
						'id' => $user->getUID(),
113
						'type' => 'user',
114
						'displayName' => $user->getDisplayName(),
115
						'avatarURL' => ''
116
					];
117
				}
118
			}
119
		}
120
121
		$data['siteusers'] = $list;
122
		return new DataResponse($data, Http::STATUS_OK);
123
	}
124
  	/**
125
	* @NoAdminRequired
126
	* @NoCSRFRequired
127
	* @return Array
128
	*/	
129
	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...
130
		$split = Array();
131
		if (strpos($item, 'user_') === 0) {
132
			$user = $this->userManager->get(substr($item, 5));
133
			$split = [
134
				'id' => $user->getUID(),
135
				'type' => 'user',
136
				'displayName' => $user->getDisplayName(),
137
				'avatarURL' => ''
138
			];
139
		} elseif (strpos($item, 'group_') === 0) {
140
			$group = substr($item, 6);
141
			$group = $this->groupManager->get($group);
142
			$split = [
143
				'id' => $group->getGID(),
144
				'type' => 'group',
145
				'displayName' => $group->getDisplayName(),
146
				'avatarURL' => '',
147
			];
148
		}
149
		
150
151
		return($split);
152
	}
153
154
  	/**
155
	* @NoAdminRequired
156
	* @NoCSRFRequired
157
	* @PublicPage
158
	* @param string $hash
159
	* @return DataResponse
160
	*/
161
	
162
	public function getPoll($hash) {
163
		if (!\OC::$server->getUserSession()->getUser() instanceof IUser) {
164
			return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
165
		}
166
		
167
		try {
168
			$poll = $this->eventMapper->findByHash($hash);
169
170
			if ($poll->getExpire() === null) {
0 ignored issues
show
introduced by
The condition $poll->getExpire() === null is always false.
Loading history...
171
				$expired = false;
172
				$expiration = false;
173
			} else {
174
				$expired = time() > strtotime($poll->getExpire());
175
				$expiration = true;
176
			}
177
178
			if ($poll->getType() == 0) {
179
				$pollType = 'datePoll'; 
180
			} else {
181
				$pollType = 'textPoll';
182
			};
183
184
			if ($poll->getOwner() !== \OC::$server->getUserSession()->getUser()->getUID()) {
185
				$mode = 'create';
186
			} else {
187
				$mode = 'edit';
188
			}
189
			$accessList = Array();
190
			$accessType = $poll->getAccess();
191
			if (!strpos('|public|hidden|registered', $accessType)) {
192
				$accessList = explode(';',$accessType);
193
				$accessList = array_filter($accessList);
194
				$accessList = array_map(Array($this,'convertAccessList'), $accessList);
195
				$accessType = 'select';
196
			}
197
				
198
			$data = array();
199
			$commentsList = array();
200
			$optionList = array();
201
			$votesList = array();
202
			
203
		} catch (DoesNotExistException $e) {
204
			return new DataResponse($e, Http::STATUS_NOT_FOUND);
205
		};
206
207
208
		try {
209
			$options = $this->optionsMapper->findByPoll($poll->getId());
210
			foreach ($options as $optionElement) {
211
				$optionList[] = [
212
					'id' => $optionElement->getId(),
213
					'text' => $optionElement->getPollOptionText(),
214
					'timestamp' => $optionElement->getTimestamp()
215
				];
216
			};
217
		} catch (DoesNotExistException $e) {
218
			// ignore
219
		};
220
221
		try {
222
			$votes = $this->votesMapper->findByPoll($poll->getId());
223
			foreach ($votes as $voteElement) {
224
				$votesList[] = [
225
					'id' => $voteElement->getId(),
226
					'userId' => $voteElement->getUserId(),
227
					'voteOptionId' => $voteElement->getVoteOptionId(),
228
					'voteOptionText' => $voteElement->getVoteOptionText(),
229
					'voteAnswer' => $voteElement->getVoteAnswer()
230
				];
231
			};
232
		} catch (DoesNotExistException $e) {
233
			// ignore
234
		};
235
236
		try {
237
			$comments = $this->commentMapper->findByPoll($poll->getId());
238
			foreach ($comments as $commentElement) {
239
				$commentsList[] = [
240
					'id' => $commentElement->getId(),
241
					'userId' => $commentElement->getUserId(),
242
					'date' => $commentElement->getDt() . ' UTC',
243
					'comment' => $commentElement->getComment()
244
				];
245
			};
246
		} catch (DoesNotExistException $e) {
247
			// ignore
248
		};
249
	
250
		$data['poll'] = [
251
			'result' => 'found',
252
			'mode' => $mode,
253
			'comments' => $commentsList,
254
			'votes' => $votesList,
255
			'shares' => $accessList,
256
			'event' => [
257
				'id' => $poll->getId(),
258
				'hash' => $hash,
259
				'type' => $pollType,
260
				'title' => $poll->getTitle(),
261
				'description' => $poll->getDescription(),
262
				'owner' => $poll->getOwner(),
263
				'created' => $poll->getCreated(),
264
				'access' => $accessType,
265
				'expiration' => $expiration,
266
				'expired' => $expired,
267
				'expirationDate' => $poll->getExpire(),
268
				'isAnonymous' => $poll->getIsAnonymous(),
269
				'fullAnonymous' => $poll->getFullAnonymous(),
270
				'disallowMaybe' => $poll->getDisallowMaybe()
271
			],
272
			'options' => [
273
				'pollDates' => [],
274
				'pollTexts' => $optionList
275
			]
276
		];
277
278
		return new DataResponse($data, Http::STATUS_OK);
279
	}
280
	
281
	/**
282
	 * @NoAdminRequired
283
	 * @NoCSRFRequired
284
	 * @param string $poll
285
	 * @return DataResponse
286
	 */
287
	public function writePoll($event, $options, $shares, $mode) {
288
		$user = \OC::$server->getUserSession()->getUser();
289
290
		if (!$user instanceof IUser) {
291
			return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
292
		}
293
		$userId = \OC::$server->getUserSession()->getUser()->getUID();
294
295
		$newEvent = new Event();
296
297
		// Set the configuration options entered by the user
298
		$newEvent->setTitle($event['title']);
299
		$newEvent->setDescription($event['description']);
300
301
		$newEvent->setType($event['type']);
302
		$newEvent->setIsAnonymous($event['isAnonymous']);
303
		$newEvent->setFullAnonymous($event['fullAnonymous']);
304
		$newEvent->setDisallowMaybe($event['disallowMaybe']);
305
	
306
		if ($event['access'] === 'select') {
307
			$shareAccess = '';
308
			foreach ($shares as $shareElement) {
309
				if ($shareElement['type'] === 'user') {
310
					$shareAccess = $shareAccess . 'user_' . $shareElement['id'] . ';';
311
				} elseif ($shareElement['type'] === 'group') {
312
					$shareAccess = $shareAccess . 'group_' . $shareElement['id'] . ';';
313
				}
314
			}
315
			$newEvent->setAccess(rtrim($shareAccess, ';'));
316
		} else {
317
			$newEvent->setAccess($event['access']);
318
		}
319
320
		if ($event['expiration']) {
321
			$newEvent->setExpire($event['expirationDate']);
322
		} else {
323
			$newEvent->setExpire(null);
324
		}
325
		
326
		if ($event['type'] === 'datePoll') {
327
			$newEvent->setType(0);
328
		} elseif ($event['type'] === 'textPoll') {
329
			$newEvent->setType(1);
330
		}
331
332
		if ($mode === 'edit') {
333
			// Edit existing poll
334
			$oldPoll = $this->eventMapper->findByHash($event['hash']);
335
336
			// Check if current user is allowed to edit existing poll
337
			if ($oldPoll->getOwner() !== $userId) {
338
				// If current user is not owner of existing poll deny access
339
				return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
340
			} 
341
342
			// else take owner, hash and id of existing poll
343
			$newEvent->setOwner($oldPoll->getOwner());
344
			$newEvent->setHash($oldPoll->getHash());
345
			$newEvent->setId($oldPoll->getId());
346
			$this->eventMapper->update($newEvent);
347
			$this->optionsMapper->deleteByPoll($newEvent->getId());
348
					
349
		} elseif ($mode === 'create') {
350
			// Create new poll
351
			// Define current user as owner, set new creation date and create a new hash
352
			$newEvent->setOwner($userId);
353
			$newEvent->setCreated(date('Y-m-d H:i:s'));
354
			$newEvent->setHash(\OC::$server->getSecureRandom()->generate(
355
				16,
356
				ISecureRandom::CHAR_DIGITS .
357
				ISecureRandom::CHAR_LOWER .
358
				ISecureRandom::CHAR_UPPER
359
			));
360
			$newEvent = $this->eventMapper->insert($newEvent);
361
		}
362
		
363
		// Update options
364
		if ($event['type'] === 'datePoll') {
365
			foreach ($options['pollDates'] as $optionElement) {
366
				$newOption = new Options();
367
				
368
				$newOption->setPollId($newEvent->getId());
369
				$newOption->setPollOptionText(date('Y-m-d H:i:s', $optionElement['timestamp']));
370
				$newOption->setTimestamp($optionElement['timestamp']);
371
				
372
				$this->optionsMapper->insert($newOption);
373
			}
374
		} elseif ($event['type'] === "textPoll") {
375
			foreach ($options['pollTexts'] as $optionElement) {
376
				$newOption = new Options();
377
				
378
				$newOption->setPollId($newEvent->getId());
379
				$newOption->setpollOptionText(htmlspecialchars($optionElement['text']));
380
				
381
				$this->optionsMapper->insert($newOption);
382
			}
383
		}
384
		return new DataResponse(array(
385
			'id' => $newEvent->getId(),
386
			'hash' => $newEvent->getHash()
387
		), Http::STATUS_OK);
388
389
	}
390
}
391