Passed
Push — master ( 1a2f46...8e46a2 )
by Jens
04:11
created

CmsComponent::checkAutoUpdateSearchIndex()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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