Passed
Push — master ( 3f6c85...9c6499 )
by Jens
02:40
created

CmsComponent::imageSetRouting()   D

Complexity

Conditions 9
Paths 7

Size

Total Lines 30
Code Lines 25

Duplication

Lines 30
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 25
c 1
b 0
f 0
nc 7
nop 2
dl 30
loc 30
rs 4.909
1
<?php
2
namespace library\components {
3
4
	use library\components\cms\ConfigurationRouting;
5
	use library\components\cms\DocumentRouting;
6
	use library\components\cms\FilesRouting;
7
	use library\components\cms\ImagesRouting;
8
	use library\components\cms\SearchRouting;
9
	use library\components\cms\SitemapRouting;
10
	use library\crypt\Crypt;
11
	use library\storage\Storage;
12
13
	class CmsComponent extends BaseComponent
14
	{
15
        /**
16
		 * @var \library\storage\Storage
17
		 */
18
		public $storage;
19
20
		const INVALID_CREDENTIALS_MESSAGE = 'Invalid username / password combination';
21
22
		const MAIN_NAV_CLASS = 'default';
23
24
		const PARAMETER_APPLICATION_COMPONENT = 'applicationComponent';
25
		const PARAMETER_APPLICATION_COMPONENTS = 'applicationComponents';
26
		const PARAMETER_BLACKLIST_IPS = 'blacklistIps';
27
		const PARAMETER_BODY = 'body';
28
		const PARAMETER_BRICK = 'brick';
29
		const PARAMETER_BRICKS = 'bricks';
30
		const PARAMETER_CMS_PREFIX = 'cmsPrefix';
31
		const PARAMETER_CONFIGURATION = 'configuration';
32
		const PARAMETER_DOCUMENT = 'document';
33
		const PARAMETER_DOCUMENTS = 'documents';
34
		const PARAMETER_DOCUMENT_TYPE = 'documentType';
35
		const PARAMETER_DOCUMENT_TYPES = 'documentTypes';
36
		const PARAMETER_ERROR_MESSAGE = 'errorMsg';
37
		const PARAMETER_FILES = 'files';
38
		const PARAMETER_FOLDER = 'folder';
39
		const PARAMETER_IMAGE = 'image';
40
		const PARAMETER_IMAGES = 'images';
41
		const PARAMETER_IMAGE_SET = 'imageSet';
42
		const PARAMETER_MAIN_NAV_CLASS = 'mainNavClass';
43
		const PARAMETER_MY_BRICK_SLUG = 'myBrickSlug';
44
        const PARAMETER_REDIRECT = 'redirect';
45
        const PARAMETER_REDIRECTS = 'redirects';
46
		const PARAMETER_SEARCH = 'search';
47
		const PARAMETER_SEARCH_LOG = "searchLog";
48
		const PARAMETER_SEARCH_NEEDS_UPDATE = "searchNeedsUpdate";
49
		const PARAMETER_SITEMAP = 'sitemap';
50
		const PARAMETER_SITEMAP_ITEM = 'sitemapItem';
51
		const PARAMETER_SMALLEST_IMAGE = 'smallestImage';
52
		const PARAMETER_STATIC = 'static';
53
		const PARAMETER_USER = 'user';
54
		const PARAMETER_USERS = 'users';
55
		const PARAMETER_USER_RIGHTS = 'userRights';
56
		const PARAMETER_VALUELIST = "valuelist";
57
		const PARAMETER_VALUELISTS = "valuelists";
58
		const PARAMETER_WHITELIST_IPS = 'whitelistIps';
59
60
        const POST_PARAMETER_COMPONENT = 'component';
61
        const POST_PARAMETER_FROM_URL = "fromUrl";
62
        const POST_PARAMETER_PASSWORD = 'password';
63
        const POST_PARAMETER_SAVE = 'save';
64
        const POST_PARAMETER_TEMPLATE = 'template';
65
        const POST_PARAMETER_TITLE = 'title';
66
        const POST_PARAMETER_TO_URL = "toUrl";
67
        const POST_PARAMETER_USERNAME = 'username';
68
69
		const GET_PARAMETER_PATH = 'path';
70
		const GET_PARAMETER_SLUG = 'slug';
71
72
		const FILES_PARAMETER_FILE = 'file';
73
74
		const SESSION_PARAMETER_CLOUD_CONTROL = 'cloudcontrol';
75
76
		const LOGIN_TEMPLATE_PATH = 'cms/login';
77
78
		const CONTENT_TYPE_APPLICATION_JSON = 'Content-type:application/json';
79
80
		public $subTemplate = null;
81
82
83
		/**
84
		 * @param Storage $storage
85
		 *
86
		 * @return void
87
		 */
88
		public function run(Storage $storage)
89
		{
90
			$this->parameters[self::PARAMETER_MAIN_NAV_CLASS] = self::MAIN_NAV_CLASS;
91
			$this->storage = $storage;
92
93
			$remoteAddress = $_SERVER['REMOTE_ADDR'];
94
			$this->checkWhiteList($remoteAddress);
95
			$this->checkBlackList($remoteAddress);
96
97
			$this->checkLogin();
98
99
			$this->parameters[self::PARAMETER_USER_RIGHTS] = $_SESSION[self::SESSION_PARAMETER_CLOUD_CONTROL]->rights;
100
101
			$this->routing();
102
		}
103
104
		/**
105
		 * See if a user is logged or wants to log in and
106
		 * takes appropriate actions.
107
		 *
108
		 * @throws \Exception
109
		 */
110
		protected function checkLogin()
111
		{
112
			$request = $this->request;
113
114
			if (!isset($_SESSION[self::SESSION_PARAMETER_CLOUD_CONTROL])) {
115
				if (isset($request::$post[self::POST_PARAMETER_USERNAME], $request::$post[self::POST_PARAMETER_PASSWORD])) {
116
					$this->checkLoginAttempt($request);
117
				} else {
118
					$this->showLogin();
119
				}
120
			}
121
		}
122
123
		/**
124
		 * Overrides normal behaviour and only renders the
125
		 * login screen
126
		 *
127
		 * @throws \Exception
128
		 */
129
		protected function showLogin()
130
		{
131
			$loginTemplatePath = self::LOGIN_TEMPLATE_PATH;
132
			$this->renderTemplate($loginTemplatePath);
133
			ob_end_flush();
134
			exit;
135
		}
136
137
		/**
138
		 * As an exception, to keep the initial file structure simple
139
		 * the cms implements it's own routing, apart from the regular sitemap functionality
140
		 *
141
		 * @throws \Exception
142
		 */
143
		protected function routing()
144
		{
145
			$relativeCmsUri = $this->getRelativeCmsUri($this->request);
146
147
			$userRights = $_SESSION[self::SESSION_PARAMETER_CLOUD_CONTROL]->rights;
148
149
			$this->dashboardRouting($relativeCmsUri);
150
			$this->logOffRouting($this->request, $relativeCmsUri);
151
			$this->apiRouting($relativeCmsUri);
152
			$this->documentRouting($userRights, $relativeCmsUri);
153
			$this->sitemapRouting($userRights, $relativeCmsUri);
154
			$this->imageRouting($userRights, $relativeCmsUri);
155
			$this->filesRouting($userRights, $relativeCmsUri);
156
			$this->configurationRouting($userRights, $relativeCmsUri);
157
			$this->searchRouting($userRights, $relativeCmsUri);
158
159
			$this->renderBody();
160
		}
161
162
		/**
163
		 * @param $remoteAddress
164
		 *
165
		 * @throws \Exception
166
		 */
167 View Code Duplication
		private function checkWhiteList($remoteAddress)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
168
		{
169
			if (isset($this->parameters[self::PARAMETER_WHITELIST_IPS])) {
170
				$whitelistIps = explode(',', $this->parameters[self::PARAMETER_WHITELIST_IPS]);
171
				$whitelistIps = array_map("trim", $whitelistIps);
172
				if (!in_array($remoteAddress, $whitelistIps)) {
173
					throw new \Exception('Ip address ' . $remoteAddress . ' is not on whitelist');
174
				}
175
			}
176
		}
177
178
		/**
179
		 * @param $remoteAddress
180
		 *
181
		 * @throws \Exception
182
		 */
183 View Code Duplication
		private function checkBlackList($remoteAddress)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
184
		{
185
			if (isset($this->parameters[self::PARAMETER_BLACKLIST_IPS])) {
186
				$blacklistIps = explode(',', $this->parameters[self::PARAMETER_BLACKLIST_IPS]);
187
				$blacklistIps = array_map("trim", $blacklistIps);
188
				if (in_array($remoteAddress, $blacklistIps)) {
189
					throw new \Exception('Ip address ' . $remoteAddress . ' is on blacklist');
190
				}
191
			}
192
		}
193
194
		/**
195
		 * @param $request
196
		 *
197
		 * @return mixed|string
198
		 */
199
		private function getRelativeCmsUri($request)
200
		{
201
			// TODO Use regex match parameter instead of calculating relative uri
202
			$pos = strpos($request::$relativeUri, $this->parameters[self::PARAMETER_CMS_PREFIX]);
203
			$relativeCmsUri = '/';
204
			if ($pos !== false) {
205
				$relativeCmsUri = substr_replace($request::$relativeUri, '', $pos, strlen($this->parameters[self::PARAMETER_CMS_PREFIX]));
206
			}
207
208
			return $relativeCmsUri;
209
		}
210
211
		/**
212
		 * @param $relativeCmsUri
213
		 */
214
		private function apiRouting($relativeCmsUri)
215
		{
216
			if ($relativeCmsUri == '/images.json') {
217
				header(self::CONTENT_TYPE_APPLICATION_JSON);
218
				die(json_encode($this->storage->getImages()->getImages()));
219
			} elseif ($relativeCmsUri == '/files.json') {
220
				header(self::CONTENT_TYPE_APPLICATION_JSON);
221
				die(json_encode($this->storage->getFiles()->getFiles()));
222
			} elseif ($relativeCmsUri == '/documents.json') {
223
				header(self::CONTENT_TYPE_APPLICATION_JSON);
224
				die(json_encode($this->storage->getDocuments()->getDocuments()));
225
			}
226
		}
227
228
		private function logOffRouting($request, $relativeCmsUri)
229
		{
230
			if ($relativeCmsUri == '/log-off') {
231
				$_SESSION[self::SESSION_PARAMETER_CLOUD_CONTROL] = null;
232
				unset($_SESSION[self::SESSION_PARAMETER_CLOUD_CONTROL]);
233
				header('Location: ' . $request::$subfolders . $this->parameters[self::PARAMETER_CMS_PREFIX]);
234
				exit;
235
			}
236
		}
237
238
		public function setParameter($parameterName, $parameterValue)
239
		{
240
			$this->parameters[$parameterName] = $parameterValue;
241
		}
242
243
		public function getParameter($parameterName)
244
		{
245
			return $this->parameters[$parameterName];
246
		}
247
248
		/**
249
		 * @param $relativeCmsUri
250
		 */
251
		protected function dashboardRouting($relativeCmsUri)
252
		{
253
			if ($relativeCmsUri == '' || $relativeCmsUri == '/') {
254
				$this->subTemplate = 'cms/dashboard';
255
			}
256
		}
257
258
		/**
259
		 * @param $userRights
260
		 * @param $relativeCmsUri
261
		 */
262
		protected function documentRouting($userRights, $relativeCmsUri)
263
		{
264
			if (in_array(self::PARAMETER_DOCUMENTS, $userRights)) {
265
				new DocumentRouting($this->request, $relativeCmsUri, $this);
266
			}
267
		}
268
269
		/**
270
		 * @param $userRights
271
		 * @param $relativeCmsUri
272
		 */
273
		protected function sitemapRouting($userRights, $relativeCmsUri)
274
		{
275
			if (in_array(self::PARAMETER_SITEMAP, $userRights)) {
276
				new SitemapRouting($this->request, $relativeCmsUri, $this);
277
			}
278
		}
279
280
		/**
281
		 * @param $userRights
282
		 * @param $relativeCmsUri
283
		 */
284
		protected function imageRouting($userRights, $relativeCmsUri)
285
		{
286
			if (in_array(self::PARAMETER_IMAGES, $userRights)) {
287
				new ImagesRouting($this->request, $relativeCmsUri, $this);
288
			}
289
		}
290
291
		/**
292
		 * @param $userRights
293
		 * @param $relativeCmsUri
294
		 */
295
		protected function filesRouting($userRights, $relativeCmsUri)
296
		{
297
			if (in_array(self::PARAMETER_FILES, $userRights)) {
298
				new FilesRouting($this->request, $relativeCmsUri, $this);
299
			}
300
		}
301
302
		/**
303
		 * @param $userRights
304
		 * @param $relativeCmsUri
305
		 */
306
		protected function configurationRouting($userRights, $relativeCmsUri)
307
		{
308
			if (in_array('configuration', $userRights)) {
309
				new ConfigurationRouting($this->request, $relativeCmsUri, $this);
310
			}
311
		}
312
313
		protected function renderBody()
314
		{
315
			if ($this->subTemplate !== null) {
316
				$this->parameters[self::PARAMETER_BODY] = $this->renderTemplate($this->subTemplate);
317
			}
318
		}
319
320
		/**
321
		 * @param $crypt
322
		 * @param $request
323
		 */
324
		protected function invalidCredentials($crypt, $request)
325
		{
326
			$crypt->encrypt($request::$post[self::POST_PARAMETER_PASSWORD], 16); // Buy time, to avoid brute forcing
327
			$this->parameters[self::PARAMETER_ERROR_MESSAGE] = self::INVALID_CREDENTIALS_MESSAGE;
328
			$this->showLogin();
329
		}
330
331
		/**
332
		 * @param $user
333
		 * @param $crypt
334
		 * @param $request
335
		 */
336
		protected function checkPassword($user, $crypt, $request)
337
		{
338
			$salt = $user->salt;
339
			$password = $user->password;
340
341
			$passwordCorrect = $crypt->compare($request::$post[self::POST_PARAMETER_PASSWORD], $password, $salt);
342
343
			if ($passwordCorrect) {
344
				$_SESSION[self::SESSION_PARAMETER_CLOUD_CONTROL] = $user;
345
			} else {
346
				$this->parameters[self::PARAMETER_ERROR_MESSAGE] = self::INVALID_CREDENTIALS_MESSAGE;
347
				$this->showLogin();
348
			}
349
		}
350
351
		/**
352
		 * @param $request
353
		 */
354
		protected function checkLoginAttempt($request)
355
		{
356
			$user = $this->storage->getUsers()->getUserByUsername($request::$post[self::POST_PARAMETER_USERNAME]);
357
			$crypt = new Crypt();
358
			if (empty($user)) {
359
				$this->invalidCredentials($crypt, $request);
360
			} else {
361
				$this->checkPassword($user, $crypt, $request);
362
			}
363
		}
364
365
		private function searchRouting($userRights, $relativeCmsUri)
366
		{
367
			if (in_array(self::PARAMETER_SEARCH, $userRights)) {
368
				new SearchRouting($this->request, $relativeCmsUri, $this);
369
			}
370
		}
371
	}
372
}