Passed
Pull Request — master (#1128)
by René
06:43
created

ShareService::add()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 43
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 5
Bugs 0 Features 1
Metric Value
eloc 36
c 5
b 0
f 1
dl 0
loc 43
ccs 0
cts 24
cp 0
rs 8.0995
cc 8
nc 8
nop 4
crap 72
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\Service;
25
26
use OCA\Polls\Exceptions\NotAuthorizedException;
27
use OCA\Polls\Exceptions\InvalidShareType;
28
29
use OCP\Security\ISecureRandom;
30
31
use OCA\Polls\Db\ShareMapper;
32
use OCA\Polls\Db\Share;
33
use OCA\Polls\Model\Acl;
34
use OCA\Polls\Model\Circle;
35
use OCA\Polls\Model\Contact;
36
use OCA\Polls\Model\ContactGroup;
37
use OCA\Polls\Model\Email;
38
use OCA\Polls\Model\Group;
39
use OCA\Polls\Model\User;
40
41
class ShareService {
42
43
	/** @var SystemService */
44
	private $systemService;
45
46
	/** @var ShareMapper */
47
	private $shareMapper;
48
49
	/** @var Share */
50
	private $share;
51
52
	/** @var MailService */
53
	private $mailService;
54
55
	/** @var Acl */
56
	private $acl;
57
58
	/**
59
	 * ShareController constructor.
60
	 * @param SystemService $systemService
61
	 * @param ShareMapper $shareMapper
62
	 * @param Share $share
63
	 * @param MailService $mailService
64
	 * @param Acl $acl
65
	 */
66
	public function __construct(
67
		SystemService $systemService,
68
		ShareMapper $shareMapper,
69
		Share $share,
70
		MailService $mailService,
71
		Acl $acl
72
	) {
73
		$this->systemService = $systemService;
74
		$this->shareMapper = $shareMapper;
75
		$this->share = $share;
76
		$this->mailService = $mailService;
77
		$this->acl = $acl;
78
	}
79
80
	/**
81
	 * Read all shares of a poll based on the poll id and return list as array
82
	 * @NoAdminRequired
83
	 * @param int $pollId
84
	 * @return array array of Share
85
	 * @throws NotAuthorizedException
86
	 */
87
	public function list($pollId, $token) {
88
		if ($token) {
89
			return [$this->get($token)];
90
		}
91
92
		if (!$this->acl->set($pollId)->getAllowEdit()) {
93
			throw new NotAuthorizedException;
94
		}
95
96
		return $this->shareMapper->findByPoll($pollId);
97
	}
98
99
	/**
100
	 * Get share by token
101
	 * @NoAdminRequired
102
	 * @param string $token
103
	 * @return Share
104
	 */
105
	public function get($token) {
106
		$this->share = $this->shareMapper->findByToken($token);
107
		return $this->share;
108
	}
109
110
	/**
111
	 * Add share
112
	 * @NoAdminRequired
113
	 * @param int $pollId
114
	 * @param array $user
115
	 * @return Share
116
	 * @throws NotAuthorizedException
117
	 * @throws InvalidShareType
118
	 */
119
	public function add($pollId, $type, $userId, $emailAddress = '') {
120
		if (!$this->acl->set($pollId)->getAllowEdit()) {
121
			throw new NotAuthorizedException;
122
		}
123
124
		switch ($type) {
125
			case Group::TYPE:
126
				$share = new Group($userId);
127
				break;
128
			case Circle::TYPE:
129
				$share = new Circle($userId);
130
				break;
131
			case Contact::TYPE:
132
				$share = new Contact($userId);
133
				break;
134
			case ContactGroup::TYPE:
135
				$share = new ContactGroup($userId);
136
				break;
137
			case User::TYPE:
138
				$share = new User($userId);
139
				break;
140
			case Email::TYPE:
141
				$share = new Email($userId, $emailAddress);
142
				break;
143
			default:
144
				throw new InvalidShareType('Invalid share type (' . $type . ')');
145
		}
146
147
		$this->share = new Share();
148
		$this->share->setPollId($pollId);
149
		$this->share->setType($share->getType());
150
		$this->share->setUserId($share->getId());
151
		$this->share->setDisplayName($share->getDisplayName());
152
		$this->share->setUserEmail($share->getEmailAddress());
153
		$this->share->setInvitationSent(0);
154
		$this->share->setToken(\OC::$server->getSecureRandom()->generate(
155
			16,
156
			ISecureRandom::CHAR_DIGITS .
157
			ISecureRandom::CHAR_LOWER .
158
			ISecureRandom::CHAR_UPPER
159
		));
160
161
		return $this->shareMapper->insert($this->share);
162
	}
163
164
	/**
165
	 * Set emailAddress to personal share
166
	 * or update an email share with the username
167
	 * @NoAdminRequired
168
	 * @param string $token
169
	 * @param string $emailAddress
170
	 * @return Share
171
	 * @throws InvalidShareType
172
	 */
173
	public function setEmailAddress($token, $emailAddress) {
174
		$this->share = $this->shareMapper->findByToken($token);
175
		if ($this->share->getType() === Share::TYPE_EXTERNAL) {
176
			$this->systemService->validateEmailAddress($emailAddress);
177
			$this->share->setUserEmail($emailAddress);
178
			// TODO: Send confirmation
179
			return $this->shareMapper->update($this->share);
180
		} else {
181
			throw new InvalidShareType('Email address can only be set in external shares.');
182
		}
183
	}
184
185
	/**
186
	 * Create a personal share from a public share
187
	 * or update an email share with the username
188
	 * @NoAdminRequired
189
	 * @param string $token
190
	 * @param string $userName
191
	 * @return Share
192
	 * @throws NotAuthorizedException
193
	 */
194
	public function personal($token, $userName, $emailAddress = '') {
195
		$this->share = $this->shareMapper->findByToken($token);
196
197
		$this->systemService->validatePublicUsername($this->share->getPollId(), $userName, $token);
198
199
		if ($emailAddress) {
200
			$this->systemService->validateEmailAddress($emailAddress);
201
		}
202
203
		if ($this->share->getType() === Share::TYPE_PUBLIC) {
204
			$pollId = $this->share->getPollId();
205
			$this->share = new Share();
206
			$this->share->setToken(\OC::$server->getSecureRandom()->generate(
207
				16,
208
				ISecureRandom::CHAR_DIGITS .
209
				ISecureRandom::CHAR_LOWER .
210
				ISecureRandom::CHAR_UPPER
211
			));
212
			$this->share->setType(Share::TYPE_EXTERNAL);
213
			$this->share->setPollId($pollId);
214
			$this->share->setUserId($userName);
215
			$this->share->setUserEmail($emailAddress);
216
			$this->share->setInvitationSent(time());
217
			$this->shareMapper->insert($this->share);
218
219
			if ($emailAddress) {
220
				$this->mailService->sendInvitationMail($this->share->getToken());
221
			}
222
223
			return $this->share;
224
		} elseif ($this->share->getType() === Share::TYPE_EMAIL) {
225
			$this->share->setType(Share::TYPE_EXTERNAL);
226
			$this->share->setUserId($userName);
227
			$this->share->setUserEmail($emailAddress);
228
			return $this->shareMapper->update($this->share);
229
		} else {
230
			throw new NotAuthorizedException;
231
		}
232
	}
233
234
	/**
235
	 * Delete share
236
	 * remove share
237
	 * @NoAdminRequired
238
	 * @param string $token
239
	 * @return Share
240
	 * @throws NotAuthorizedException
241
	 */
242
243
	public function delete($token) {
244
		$this->share = $this->shareMapper->findByToken($token);
245
		if (!$this->acl->set($this->share->getPollId())->getAllowEdit()) {
246
			throw new NotAuthorizedException;
247
		}
248
249
		$this->shareMapper->delete($this->share);
250
251
		return $this->share;
252
	}
253
}
254