Passed
Push — master ( f61691...1918f3 )
by Jens
07:18
created

CmsComponent   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 217
Duplicated Lines 9.22 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
dl 20
loc 217
rs 10
c 0
b 0
f 0
wmc 24
lcom 1
cbo 7

14 Methods

Rating   Name   Duplication   Size   Complexity  
A run() 0 17 1
A checkLogin() 0 12 3
A showLogin() 0 7 1
A routing() 0 9 1
A checkWhiteList() 10 10 3
A checkBlackList() 10 10 3
A getRelativeCmsUri() 0 11 2
A setParameter() 0 4 1
A getParameter() 0 4 1
A renderBody() 0 6 2
A invalidCredentials() 0 6 1
A checkPassword() 0 15 2
A checkLoginAttempt() 0 10 2
A getTemplateDir() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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