Passed
Push — develop ( adb2d3...61a548 )
by Jens
04:06
created

CmsComponent::checkAutoUpdateSearchIndex()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
c 0
b 0
f 0
nc 3
nop 0
dl 0
loc 9
rs 9.6666
1
<?php
2
3
namespace CloudControl\Cms\components {
4
5
    use CloudControl\Cms\components\cms\BaseRouting;
6
    use CloudControl\Cms\components\cms\CmsConstants;
7
    use CloudControl\Cms\crypt\Crypt;
8
    use CloudControl\Cms\storage\Storage;
9
10
    class CmsComponent extends BaseComponent
11
    {
12
        /**
13
         * @var \CloudControl\Cms\storage\Storage
14
         */
15
        public $storage;
16
17
        public $subTemplate;
18
19
        public $autoUpdateSearchIndex = true;
20
21
22
        /**
23
         * @param Storage $storage
24
         *
25
         * @return void
26
         * @throws \Exception
27
         */
28
        public function run(Storage $storage)
29
        {
30
            $this->setParameter(CmsConstants::PARAMETER_MAIN_NAV_CLASS, CmsConstants::MAIN_NAV_CLASS);
31
            $this->storage = $storage;
32
33
            $remoteAddress = $_SERVER['REMOTE_ADDR'];
34
            $this->checkWhiteList($remoteAddress);
35
            $this->checkBlackList($remoteAddress);
36
37
            $this->checkAutoUpdateSearchIndex();
38
39
            $this->checkLogin();
40
41
            $this->setParameter(CmsConstants::PARAMETER_USER_RIGHTS, $_SESSION[CmsConstants::SESSION_PARAMETER_CLOUD_CONTROL]->rights);
42
43
            $this->routing();
44
45
            $this->renderBody();
46
        }
47
48
        /**
49
         * See if a user is logged or wants to log in and
50
         * takes appropriate actions.
51
         *
52
         * @throws \Exception
53
         */
54
        protected function checkLogin()
55
        {
56
            $request = $this->request;
57
58
            if (!isset($_SESSION[CmsConstants::SESSION_PARAMETER_CLOUD_CONTROL])) {
59
                if (isset($request::$post[CmsConstants::POST_PARAMETER_USERNAME], $request::$post[CmsConstants::POST_PARAMETER_PASSWORD])) {
60
                    $this->checkLoginAttempt($request);
61
                } else {
62
                    $this->showLogin();
63
                }
64
            }
65
        }
66
67
        /**
68
         * Overrides normal behaviour and only renders the
69
         * login screen
70
         *
71
         * @throws \Exception
72
         */
73
        protected function showLogin()
74
        {
75
            $loginTemplatePath = CmsConstants::LOGIN_TEMPLATE_PATH;
76
            $this->renderTemplate($loginTemplatePath);
77
            ob_end_flush();
78
            exit;
79
        }
80
81
        /**
82
         * As an exception, to keep the initial file structure simple
83
         * the cms implements it's own routing, apart from the regular sitemap functionality
84
         *
85
         * @throws \Exception
86
         */
87
        protected function routing()
88
        {
89
            $relativeCmsUri = $this->getRelativeCmsUri($this->request);
90
            $userRights = $_SESSION[CmsConstants::SESSION_PARAMETER_CLOUD_CONTROL]->rights;
91
92
            $baseRouting = new BaseRouting($this->request, $relativeCmsUri, $this);
93
            $baseRouting->setUserRights($userRights);
94
            $baseRouting->route();
95
        }
96
97
        /**
98
         * @param $remoteAddress
99
         *
100
         * @throws \Exception
101
         */
102 View Code Duplication
        protected 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...
103
        {
104
            if (isset($this->parameters[CmsConstants::PARAMETER_WHITELIST_IPS])) {
105
                $whitelistIps = explode(',', $this->parameters[CmsConstants::PARAMETER_WHITELIST_IPS]);
106
                $whitelistIps = array_map("trim", $whitelistIps);
107
                if (!in_array($remoteAddress, $whitelistIps)) {
108
                    throw new \Exception('Ip address ' . $remoteAddress . ' is not on whitelist');
109
                }
110
            }
111
        }
112
113
        /**
114
         * @param $remoteAddress
115
         *
116
         * @throws \Exception
117
         */
118 View Code Duplication
        protected 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...
119
        {
120
            if (isset($this->parameters[CmsConstants::PARAMETER_BLACKLIST_IPS])) {
121
                $blacklistIps = explode(',', $this->parameters[CmsConstants::PARAMETER_BLACKLIST_IPS]);
122
                $blacklistIps = array_map("trim", $blacklistIps);
123
                if (in_array($remoteAddress, $blacklistIps)) {
124
                    throw new \Exception('Ip address ' . $remoteAddress . ' is on blacklist');
125
                }
126
            }
127
        }
128
129
        /**
130
         * @param $request
131
         *
132
         * @return mixed|string
133
         */
134
        protected function getRelativeCmsUri($request)
135
        {
136
            // TODO Use regex match parameter instead of calculating relative uri
137
            $pos = strpos($request::$relativeUri, $this->parameters[CmsConstants::PARAMETER_CMS_PREFIX]);
138
            $relativeCmsUri = '/';
139
            if ($pos !== false) {
140
                $relativeCmsUri = substr_replace($request::$relativeUri, '', $pos, strlen($this->parameters[CmsConstants::PARAMETER_CMS_PREFIX]));
141
            }
142
143
            return $relativeCmsUri;
144
        }
145
146
        /**
147
         * @param $parameterName
148
         * @param $parameterValue
149
         */
150
        public function setParameter($parameterName, $parameterValue)
151
        {
152
            $this->parameters[$parameterName] = $parameterValue;
153
        }
154
155
        /**
156
         * @param $parameterName
157
         * @return mixed
158
         */
159
        public function getParameter($parameterName)
160
        {
161
            return $this->parameters[$parameterName];
162
        }
163
164
        /**
165
         * @throws \Exception
166
         */
167
        protected function renderBody()
168
        {
169
            if ($this->subTemplate !== null) {
170
                $this->parameters[CmsConstants::PARAMETER_BODY] = $this->renderTemplate($this->subTemplate);
171
            }
172
        }
173
174
        /**
175
         * @param Crypt $crypt
176
         * @param Request $request
177
         * @throws \Exception
178
         */
179
        protected function invalidCredentials($crypt, $request)
180
        {
181
            $crypt->encrypt($request::$post[CmsConstants::POST_PARAMETER_PASSWORD], 16); // Buy time, to avoid brute forcing
182
            $this->parameters[CmsConstants::PARAMETER_ERROR_MESSAGE] = CmsConstants::INVALID_CREDENTIALS_MESSAGE;
183
            $this->showLogin();
184
        }
185
186
        /**
187
         * @param $user
188
         * @param Crypt $crypt
189
         * @param Request $request
190
         * @throws \Exception
191
         */
192
        protected function checkPassword($user, $crypt, $request)
193
        {
194
            $salt = $user->salt;
195
            $password = $user->password;
196
197
            $passwordCorrect = $crypt->compare($request::$post[CmsConstants::POST_PARAMETER_PASSWORD], $password, $salt);
198
199
            if ($passwordCorrect) {
200
                $_SESSION[CmsConstants::SESSION_PARAMETER_CLOUD_CONTROL] = $user;
201
                $this->storage->getActivityLog()->add('logged in', 'user');
202
            } else {
203
                $this->parameters[CmsConstants::PARAMETER_ERROR_MESSAGE] = CmsConstants::INVALID_CREDENTIALS_MESSAGE;
204
                $this->showLogin();
205
            }
206
        }
207
208
        /**
209
         * @param $request
210
         * @throws \Exception
211
         */
212
        protected function checkLoginAttempt($request)
213
        {
214
            $user = $this->storage->getUsers()->getUserByUsername($request::$post[CmsConstants::POST_PARAMETER_USERNAME]);
215
            $crypt = new Crypt();
216
            if (empty($user)) {
217
                $this->invalidCredentials($crypt, $request);
218
            } else {
219
                $this->checkPassword($user, $crypt, $request);
220
            }
221
        }
222
223
        /**
224
         * @param $template
225
         * @param null $application
226
         * @return string
227
         */
228
        protected function getTemplateDir($template, $application = null)
229
        {
230
            return __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . $template . '.php';
231
        }
232
233
        private function checkAutoUpdateSearchIndex()
234
        {
235
            if (isset($this->parameters[CmsConstants::PARAMETER_AUTO_UPDATE_SEARCH_INDEX])) {
236
                $param = $this->parameters[CmsConstants::PARAMETER_AUTO_UPDATE_SEARCH_INDEX];
237
                if ($param === 'false') {
238
                    $this->autoUpdateSearchIndex = false;
239
                }
240
            }
241
        }
242
243
    public static function isCmsLoggedIn()
244
    {
245
        return isset($_SESSION[CmsConstants::SESSION_PARAMETER_CLOUD_CONTROL]);
246
    }
247
248
}
249
}