Passed
Push — master ( 8460a0...9ca045 )
by Maxence
02:13
created

Website::getTemplateSource()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 2
c 0
b 0
f 0
rs 10
cc 1
eloc 1
nc 1
nop 0
1
<?php
2
/**
3
 * CMS Pico - Integration of Pico within your files to create websites.
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2017
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\CMSPico\Model;
28
29
use OC\Files\View;
30
use OCA\CMSPico\AppInfo\Application;
31
use OCA\CMSPico\Exceptions\CheckCharsException;
32
use OCA\CMSPico\Exceptions\ContentDirIsNotLocalException;
33
use OCA\CMSPico\Exceptions\MinCharsException;
34
use OCA\CMSPico\Exceptions\PathContainSpecificFoldersException;
35
use OCA\CMSPico\Exceptions\UserIsNotOwnerException;
36
use OCA\CMSPico\Exceptions\WebpageDoesNotExistException;
37
use OCA\CMSPico\Exceptions\WebsiteIsPrivateException;
38
use OCA\CMSPico\Service\MiscService;
39
use OCP\Files\IRootFolder;
0 ignored issues
show
Bug introduced by
The type OCP\Files\IRootFolder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
40
use OCP\Files\NotFoundException;
0 ignored issues
show
Bug introduced by
The type OCP\Files\NotFoundException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
41
use OCP\IL10N;
42
43
class Website extends WebsiteCore {
44
45
46
	const TYPE_PUBLIC = 1;
47
	const TYPE_PRIVATE = 2;
48
49
	const SITE_LENGTH_MIN = 3;
50
	const NAME_LENGTH_MIN = 5;
51
52
	/** @var IL10N */
53
	private $l10n;
54
55
	/** @var IRootFolder */
56
	private $rootFolder;
57
58
	/** @var View */
59
	private $ownerView;
60
61
62
	public function __construct() {
63
		$this->l10n = \OC::$server->getL10N(Application::APP_NAME);
64
		$this->rootFolder = \OC::$server->getRootFolder();
65
66
		parent::__construct();
67
	}
68
69
70
	private function initSiteOwnerView() {
71
72
		if ($this->ownerView !== null) {
73
			return;
74
		}
75
76
		$this->ownerView = new View($this->getUserId() . '/files/');
77
	}
78
79
80
	/**
81
	 * @return string
82
	 */
83
	public function getAbsolutePath() {
84
85
		$this->initSiteOwnerView();
86
87
		$path = $this->ownerView->getLocalFile($this->getPath());
88
		MiscService::endSlash($path);
89
90
		return $path;
91
	}
92
93
94
	/**
95
	 * @param string $local
96
	 *
97
	 * @return false|\OC\Files\FileInfo
98
	 */
99
	public function isReadableByViewer($local = '') {
100
101
		$fileId = $this->getPageFileId($local);
102
		$viewerFiles = $this->rootFolder->getUserFolder($this->getViewer())
103
										->getById($fileId);
104
105
		foreach ($viewerFiles as $file) {
106
			if ($file->isReadable()) {
107
				return true;
108
			}
109
		}
110
111
		return false;
112
	}
113
114
115
	/**
116
	 * @param string $local
117
	 *
118
	 * @return int
119
	 * @throws WebpageDoesNotExistException
120
	 */
121
	public function getPageFileId($local = '') {
122
123
		try {
124
			$ownerFile = $this->rootFolder->getUserFolder($this->getUserId())
125
										  ->get($this->getPath() . $local);
126
127
			return $ownerFile->getId();
128
		} catch (NotFoundException $e) {
129
			throw new WebpageDoesNotExistException($this->l10n->t('Webpage does not exist'));
130
		}
131
	}
132
133
134
135
	/**
136
	 * @param $userId
137
	 *
138
	 * @throws UserIsNotOwnerException
139
	 */
140
	public function hasToBeOwnedBy($userId) {
141
		if ($this->getUserId() !== $userId) {
142
			throw new UserIsNotOwnerException($this->l10n->t('You are not the owner of this website'));
143
		}
144
	}
145
146
147
	public function contentMustBeLocal($path) {
148
149
		if (strpos($path, $this->getAbsolutePath()) !== 0 || strpos($path, '..') !== false) {
150
			throw new ContentDirIsNotLocalException($this->l10n->t('Content Directory is not valid.'));
151
		}
152
153
	}
154
155
156
	public function getRelativePath($path) {
157
		if (substr($path, 0, 1) !== '/') {
158
			return $path;
159
		}
160
161
		return substr($path, strlen($this->getAbsolutePath()));
162
	}
163
164
	/**
165
	 * @param string $local
166
	 * @param array $meta
167
	 *
168
	 * @throws WebsiteIsPrivateException
169
	 */
170
	public function viewerMustHaveAccess($local, $meta) {
171
172
		$relativePath = $this->getRelativePath($local);
173
		if ($this->pageIsPublic($meta)) {
174
			return;
175
		}
176
177
		if ($this->getViewer() === $this->getUserId()
178
			|| $this->isReadableByViewer($relativePath)) {
179
			return;
180
		}
181
182
		throw new WebsiteIsPrivateException(
183
			$this->l10n->t('Website is private. You do not have access to this website')
184
		);
185
	}
186
187
188
	/**
189
	 * @param array $meta
190
	 *
191
	 * @return bool
192
	 */
193
	private function pageIsPublic($meta) {
194
195
		if (key_exists('access', $meta) && strtolower($meta['access']) === 'private') {
196
			return false;
197
		}
198
199
		if ($this->getOption('private') === '1') {
200
			return false;
201
		}
202
203
		return true;
204
	}
205
206
207
	/**
208
	 * @throws CheckCharsException
209
	 * @throws MinCharsException
210
	 * @throws PathContainSpecificFoldersException
211
	 */
212
	public function hasToBeFilledWithValidEntries() {
213
214
		$this->hasToBeFilledWithNonEmptyValues();
215
		$this->pathCantContainSpecificFolders();
216
217
		if (MiscService::checkChars($this->getSite(), MiscService::ALPHA_NUMERIC_SCORES) === false) {
218
			throw new CheckCharsException(
219
				$this->l10n->t('The address of the website can only contains alpha numeric chars')
220
			);
221
		}
222
	}
223
224
225
	/**
226
	 * @throws MinCharsException
227
	 */
228
	private function hasToBeFilledWithNonEmptyValues() {
229
		if (strlen($this->getSite()) < self::SITE_LENGTH_MIN) {
230
			throw new MinCharsException($this->l10n->t('The address of the website must be longer'));
231
		}
232
233
		if (strlen($this->getName()) < self::NAME_LENGTH_MIN) {
234
			throw new MinCharsException($this->l10n->t('The name of the website must be longer'));
235
		}
236
	}
237
238
239
	/**
240
	 * this is overkill - NC does not allow to create directory outside of the users' filesystem
241
	 * Not sure that there is a single use for this security check
242
	 *
243
	 * @throws PathContainSpecificFoldersException
244
	 */
245
	private function pathCantContainSpecificFolders() {
246
		$limit = ['.', '..'];
247
248
		$folders = explode('/', $this->getPath());
249
		foreach ($folders as $folder) {
250
			if (in_array($folder, $limit)) {
251
				throw new PathContainSpecificFoldersException(
252
					$this->l10n->t('Path is malformed, please check.')
253
				);
254
			}
255
		}
256
	}
257
}