Passed
Pull Request — master (#77)
by Daniel
24:04
created

WebsitesService::deleteWebsite()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * CMS Pico - Create websites using Pico CMS for Nextcloud.
4
 *
5
 * @copyright Copyright (c) 2017, Maxence Lange (<[email protected]>)
6
 * @copyright Copyright (c) 2019, Daniel Rudolf (<[email protected]>)
7
 *
8
 * @license GNU AGPL version 3 or any later version
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License as
12
 * published by the Free Software Foundation, either version 3 of the
13
 * License, or (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
declare(strict_types=1);
25
26
namespace OCA\CMSPico\Service;
27
28
use OCA\CMSPico\Db\WebsitesRequest;
29
use OCA\CMSPico\Exceptions\AssetInvalidPathException;
30
use OCA\CMSPico\Exceptions\AssetNotFoundException;
31
use OCA\CMSPico\Exceptions\AssetNotPermittedException;
32
use OCA\CMSPico\Exceptions\FilesystemNotLocalException;
33
use OCA\CMSPico\Exceptions\PageInvalidPathException;
34
use OCA\CMSPico\Exceptions\PageNotFoundException;
35
use OCA\CMSPico\Exceptions\PageNotPermittedException;
36
use OCA\CMSPico\Exceptions\PicoRuntimeException;
37
use OCA\CMSPico\Exceptions\TemplateNotFoundException;
38
use OCA\CMSPico\Exceptions\ThemeNotCompatibleException;
39
use OCA\CMSPico\Exceptions\ThemeNotFoundException;
40
use OCA\CMSPico\Exceptions\WebsiteExistsException;
41
use OCA\CMSPico\Exceptions\WebsiteInvalidDataException;
42
use OCA\CMSPico\Exceptions\WebsiteInvalidFilesystemException;
43
use OCA\CMSPico\Exceptions\WebsiteInvalidOwnerException;
44
use OCA\CMSPico\Exceptions\WebsiteNotFoundException;
45
use OCA\CMSPico\Exceptions\WebsiteNotPermittedException;
46
use OCA\CMSPico\Model\PicoAsset;
47
use OCA\CMSPico\Model\PicoPage;
48
use OCA\CMSPico\Model\Website;
49
use OCP\Files\InvalidPathException;
50
use OCP\IGroupManager;
51
52
class WebsitesService
53
{
54
	/** @var int */
55
	const LINK_MODE_LONG = 1;
56
57
	/** @var int */
58
	const LINK_MODE_SHORT = 2;
59
60
	/** @var WebsitesRequest */
61
	private $websiteRequest;
62
63
	/** @var IGroupManager */
64
	private $groupManager;
65
66
	/** @var ConfigService */
67
	private $configService;
68
69
	/** @var TemplatesService */
70
	private $templatesService;
71
72
	/** @var PicoService */
73
	private $picoService;
74
75
	/** @var AssetsService */
76
	private $assetsService;
77
78
	/** @var MiscService */
79
	private $miscService;
80
81
	/**
82
	 * WebsitesService constructor.
83
	 *
84
	 * @param WebsitesRequest  $websiteRequest
85
	 * @param IGroupManager    $groupManager
86
	 * @param ConfigService    $configService
87
	 * @param TemplatesService $templatesService
88
	 * @param PicoService      $picoService
89
	 * @param AssetsService    $assetsService
90
	 * @param MiscService      $miscService
91
	 *
92
	 * @internal param Manager $encryptionManager
93
	 */
94 1
	public function __construct(
95
		WebsitesRequest $websiteRequest,
96
		IGroupManager $groupManager,
97
		ConfigService $configService,
98
		TemplatesService $templatesService,
99
		PicoService $picoService,
100
		AssetsService $assetsService,
101
		MiscService $miscService
102
	) {
103 1
		$this->websiteRequest = $websiteRequest;
104 1
		$this->groupManager = $groupManager;
105 1
		$this->configService = $configService;
106 1
		$this->templatesService = $templatesService;
107 1
		$this->picoService = $picoService;
108 1
		$this->assetsService = $assetsService;
109 1
		$this->miscService = $miscService;
110 1
	}
111
112
	/**
113
	 * Creates a new website.
114
	 *
115
	 * @param Website $website
116
	 *
117
	 * @throws WebsiteExistsException
118
	 * @throws WebsiteInvalidDataException
119
	 * @throws WebsiteInvalidOwnerException
120
	 * @throws ThemeNotFoundException
121
	 * @throws ThemeNotCompatibleException
122
	 * @throws TemplateNotFoundException
123
	 */
124 3
	public function createWebsite(Website $website)
125
	{
126 3
		$website->assertValidOwner();
127 3
		$website->assertValidName();
128 3
		$website->assertValidSite();
129 3
		$website->assertValidPath();
130 3
		$website->assertValidTheme();
131 3
		$website->assertValidTemplate();
132
133
		try {
134 3
			$website = $this->websiteRequest->getWebsiteFromSite($website->getSite());
135 1
			throw new WebsiteExistsException();
136 3
		} catch (WebsiteNotFoundException $e) {
137
			// in fact we want the website not to exist yet
138
		}
139
140 3
		$this->templatesService->installTemplate($website);
141 3
		$this->websiteRequest->create($website);
142 3
	}
143
144
	/**
145
	 * Updates a website.
146
	 *
147
	 * Warning: This method does not check the ownership of the website!
148
	 * Please use {@see Website::assertOwnedBy()} beforehand.
149
	 *
150
	 * @param Website $website
151
	 *
152
	 * @throws WebsiteNotFoundException
153
	 * @throws WebsiteInvalidDataException
154
	 * @throws ThemeNotFoundException
155
	 * @throws ThemeNotCompatibleException
156
	 * @throws TemplateNotFoundException
157
	 */
158 1
	public function updateWebsite(Website $website)
159
	{
160 1
		$originalWebsite = $this->websiteRequest->getWebsiteFromId($website->getId());
161
162 1
		if ($website->getName() !== $originalWebsite->getName()) {
163 1
			$website->assertValidName();
164
		}
165 1
		if ($website->getSite() !== $originalWebsite->getSite()) {
166 1
			$website->assertValidSite();
167
		}
168 1
		if ($website->getPath() !== $originalWebsite->getPath()) {
169
			$website->assertValidPath();
170
		}
171 1
		if ($website->getTheme() !== $originalWebsite->getTheme()) {
172
			$website->assertValidTheme();
173
		}
174 1
		if ($website->getTemplateSource()) {
175
			if ($website->getTemplateSource() !== $originalWebsite->getTemplateSource()) {
176
				$website->assertValidTemplate();
177
			}
178
		}
179
180 1
		$this->websiteRequest->update($website);
181 1
	}
182
183
	/**
184
	 * Deletes a website.
185
	 *
186
	 * Warning: This method does not check the ownership of the website!
187
	 * Please use {@see Website::assertOwnedBy()} beforehand.
188
	 *
189
	 * @param Website $website
190
	 *
191
	 * @throws WebsiteNotFoundException
192
	 */
193 2
	public function deleteWebsite(Website $website)
194
	{
195
		// check whether website actually exists
196 2
		$this->websiteRequest->getWebsiteFromId($website->getId());
197
198 2
		$this->websiteRequest->delete($website);
199 2
	}
200
201
	/**
202
	 * @param string $userId
203
	 */
204 1
	public function onUserRemoved($userId)
205
	{
206 1
		$this->websiteRequest->deleteAllFromUser($userId);
207 1
	}
208
209
	/**
210
	 * @param int $siteId
211
	 *
212
	 * @return Website
213
	 * @throws WebsiteNotFoundException
214
	 */
215
	public function getWebsiteFromId(int $siteId): Website
216
	{
217
		return $this->websiteRequest->getWebsiteFromId($siteId);
218
	}
219
220
	/**
221
	 * @param string $site
222
	 *
223
	 * @return Website
224
	 * @throws WebsiteNotFoundException
225
	 */
226 4
	public function getWebsiteFromSite(string $site): Website
227
	{
228 4
		return $this->websiteRequest->getWebsiteFromSite($site);
229
	}
230
231
	/**
232
	 * @param string $userId
233
	 *
234
	 * @return Website[]
235
	 */
236 4
	public function getWebsitesFromUser(string $userId): array
237
	{
238 4
		return $this->websiteRequest->getWebsitesFromUserId($userId);
239
	}
240
241
	/**
242
	 * @param string      $site
243
	 * @param string      $page
244
	 * @param string|null $viewer
245
	 * @param bool        $proxyRequest
246
	 *
247
	 * @return PicoPage
248
	 * @throws WebsiteNotFoundException
249
	 * @throws WebsiteInvalidOwnerException
250
	 * @throws WebsiteInvalidFilesystemException
251
	 * @throws WebsiteNotPermittedException
252
	 * @throws FilesystemNotLocalException
253
	 * @throws PageInvalidPathException
254
	 * @throws PageNotFoundException
255
	 * @throws PageNotPermittedException
256
	 * @throws ThemeNotFoundException
257
	 * @throws ThemeNotCompatibleException
258
	 * @throws PicoRuntimeException
259
	 */
260 2
	public function getPage(string $site, string $page, string $viewer = null, bool $proxyRequest = false): PicoPage
261
	{
262
		try {
263 2
			$page = $this->miscService->normalizePath($page);
264
		} catch (InvalidPathException $e) {
265
			throw new PageInvalidPathException($e);
266
		}
267
268 2
		$website = $this->getWebsiteFromSite($site);
269 2
		$website->setProxyRequest($proxyRequest);
270 2
		$website->setViewer($viewer ?: '');
271 2
		$website->setPage($page);
272
273 2
		$website->assertValidOwner();
274
275 2
		if (!$website->getWebsiteFolder()->isLocal()) {
276
			throw new FilesystemNotLocalException();
277
		}
278
279 2
		return $this->picoService->getPage($website);
280
	}
281
282
	/**
283
	 * @param string      $site
284
	 * @param string      $asset
285
	 * @param string|null $viewer
286
	 *
287
	 * @return PicoAsset
288
	 * @throws WebsiteNotFoundException
289
	 * @throws WebsiteInvalidOwnerException
290
	 * @throws WebsiteInvalidFilesystemException
291
	 * @throws WebsiteNotPermittedException
292
	 * @throws FilesystemNotLocalException
293
	 * @throws AssetInvalidPathException
294
	 * @throws AssetNotFoundException
295
	 * @throws AssetNotPermittedException
296
	 */
297
	public function getAsset(string $site, string $asset, string $viewer = null): PicoAsset
298
	{
299
		try {
300
			$asset = $this->miscService->normalizePath($asset);
301
			if ($asset === '') {
302
				throw new InvalidPathException();
303
			}
304
		} catch (InvalidPathException $e) {
305
			throw new AssetInvalidPathException($e);
306
		}
307
308
		$website = $this->getWebsiteFromSite($site);
309
		$website->setViewer($viewer ?: '');
310
		$website->setPage(PicoService::DIR_ASSETS . '/' . $asset);
311
312
		$website->assertValidOwner();
313
314
		if (!$website->getWebsiteFolder()->isLocal()) {
315
			throw new FilesystemNotLocalException();
316
		}
317
318
		return $this->assetsService->getAsset($website);
319
	}
320
321
	/**
322
	 * @param string[] $limitGroups
323
	 *
324
	 * @throws \UnexpectedValueException
325
	 */
326
	public function setLimitGroups(array $limitGroups)
327
	{
328
		foreach ($limitGroups as $group) {
329
			if (!$this->groupManager->groupExists($group)) {
330
				throw new \UnexpectedValueException();
331
			}
332
		}
333
334
		$this->configService->setAppValue(ConfigService::LIMIT_GROUPS, json_encode($limitGroups));
335
	}
336
337
	/**
338
	 * @return string[]
339
	 */
340 5
	public function getLimitGroups(): array
341
	{
342 5
		$json = $this->configService->getAppValue(ConfigService::LIMIT_GROUPS);
343 5
		return $json ? json_decode($json, true) : [];
344
	}
345
346
	/**
347
	 * @param string|null $userId
348
	 *
349
	 * @return bool
350
	 */
351 5
	public function isUserAllowed(string $userId = null)
352
	{
353 5
		if (!$userId) {
354
			return false;
355
		}
356
357 5
		$limitGroups = $this->getLimitGroups();
358 5
		if (empty($limitGroups)) {
359 5
			return true;
360
		}
361
362
		foreach ($this->getLimitGroups() as $group) {
363
			if ($this->groupManager->isInGroup($userId, $group)) {
364
				return true;
365
			}
366
		}
367
368
		return false;
369
	}
370
371
	/**
372
	 * @param int $linkMode
373
	 *
374
	 * @throws \UnexpectedValueException
375
	 */
376
	public function setLinkMode(int $linkMode)
377
	{
378
		if (($linkMode !== self::LINK_MODE_LONG) && ($linkMode !== self::LINK_MODE_SHORT)) {
379
			throw new \UnexpectedValueException();
380
		}
381
382
		$this->configService->setAppValue(ConfigService::LINK_MODE, $linkMode);
383
	}
384
385
	/**
386
	 * @return int
387
	 */
388
	public function getLinkMode(): int
389
	{
390
		return (int) $this->configService->getAppValue(ConfigService::LINK_MODE);
391
	}
392
}
393