Passed
Push — master ( db71b9...272130 )
by Darío
04:27
created

module/Auth/source/Controller/LogIn.php (4 issues)

1
<?php
2
3
namespace Auth\Controller;
4
5
use Auth\Model\User;
6
use Auth\Model\UserRole;
7
use Auth\Model\DbUserRole;
8
use Auth\Model\Authentication;
0 ignored issues
show
The type Auth\Model\Authentication 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...
9
use Drone\Db\TableGateway\EntityAdapter;
10
use Drone\Db\TableGateway\TableGateway;
11
use Drone\Dom\Element\Form;
12
use Drone\Mvc\AbstractionController;
13
use Drone\Network\Http;
14
use Drone\Validator\FormValidator;
15
use Zend\Crypt\Password\Bcrypt;
16
use Drone\Error\Errno;
17
18
class LogIn extends AbstractionController
19
{
20
    use \Drone\Error\ErrorTrait;
21
22
    /**
23
     * @var EntityAdapter
24
     */
25
    private $userAdapter;
26
27
    /**
28
     * @var EntityAdapter
29
     */
30
    private $userRoleAdapter;
31
32
    /**
33
     * @var EntityAdapter
34
     */
35
    private $dbUserRoleAdapter;
36
37
    /**
38
     * @return EntityAdapter
39
     */
40
    private function getUserAdapter()
41
    {
42
        if (!is_null($this->userAdapter))
43
            return $this->userAdapter;
44
45
        $this->userAdapter = new EntityAdapter(new TableGateway(new User()));
46
47
        return $this->userAdapter;
48
    }
49
50
    /**
51
     * @return EntityAdapter
52
     */
53
    private function getUserRoleAdapter()
54
    {
55
        if (!is_null($this->userRoleAdapter))
56
            return $this->userRoleAdapter;
57
58
        $this->userRoleAdapter = new EntityAdapter(new TableGateway(new UserRole()));
59
60
        return $this->userRoleAdapter;
61
    }
62
63
    /**
64
     * @return EntityAdapter
65
     */
66
    private function getDbUserRoleAdapter()
0 ignored issues
show
The method getDbUserRoleAdapter() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
67
    {
68
        if (!is_null($this->dbUserRoleAdapter))
69
            return $this->dbUserRoleAdapter;
70
71
        $this->dbUserRoleAdapter = new EntityAdapter(new TableGateway(new DbUserRole()));
72
73
        return $this->dbUserRoleAdapter;
74
    }
75
76
    /**
77
     * Checks user session and redirect to other module if exists any active session
78
     *
79
     * @return null
80
     */
81
    private function checkSession()
82
    {
83
        $config = include 'module/Auth/config/user.config.php';
84
        $method = $config["authentication"]["method"];
85
        $key    = $config["authentication"]["key"];
86
87
        $global_config = include 'config/global.config.php';
88
89
        /** URL TO REDIRECT:
90
         *
91
         * By default if there isn't a session active, it will be redirected to the module in the user config file ($config["redirect"]).
92
         * If a last URI requested exists, it will be redirecto to it.
93
         *
94
         * Other modules must have the following line of code inside init method to ensure last uri redirection.
95
         * $_SESSION["last_uri_" . $global_config["project"]["id"]] = $_SERVER["REQUEST_URI"];
96
         * It should be an unique session id for the app to prevent bad redirections with other projects.
97
         */
98
        if (array_key_exists("last_uri_" . $global_config["project"]["id"], $_SESSION) || !empty($_SESSION["last_uri_" . $global_config["project"]["id"]]))
99
            $location = $_SESSION["last_uri_" . $global_config["project"]["id"]];
100
        else
101
            $location = $this->getBasePath() . "/public/" . $config["redirect"];
102
103
        switch ($method)
104
        {
105
            case '_COOKIE':
106
107
                if (array_key_exists($key, $_COOKIE) || !empty($_COOKIE[$key]))
108
                    header("location: " . $location);
109
110
                break;
111
112
            case '_SESSION':
113
114
                if (array_key_exists($key, $_SESSION) || !empty($_SESSION[$key]))
115
                    header("location: " . $location);
116
117
                break;
118
        }
119
    }
120
121
    /**
122
     * Shows login form
123
     *
124
     * @return array
125
     */
126
    public function index()
127
    {
128
        # STANDARD VALIDATIONS [check method]
129
        if (!$this->isGet())
130
        {
131
            $http = new Http();
132
            $http->writeStatus($http::HTTP_METHOD_NOT_ALLOWED);
133
134
            die('Error ' . $http::HTTP_METHOD_NOT_ALLOWED .' (' . $http->getStatusText($http::HTTP_METHOD_NOT_ALLOWED) . ')!!');
135
        }
136
137
        $this->checkSession();
138
139
        return [];
140
    }
141
142
    /**
143
     * Checks user credentials
144
     *
145
     * @return array
146
     */
147
    public function attemp()
148
    {
149
        # data to send
150
        $data = [];
151
152
        $post = $this->getPost();
153
        $this->setTerminal(true);
154
155
        # TRY-CATCH-BLOCK
156
        try {
157
158
            # STANDARD VALIDATIONS [check method]
159
            if (!$this->isPost())
160
            {
161
                $http = new Http();
162
                $http->writeStatus($http::HTTP_METHOD_NOT_ALLOWED);
163
164
                die('Error ' . $http::HTTP_METHOD_NOT_ALLOWED .' (' . $http->getStatusText($http::HTTP_METHOD_NOT_ALLOWED) . ')!!');
165
            }
166
167
            # STANDARD VALIDATIONS [check needed arguments]
168
            $needles = ['username', 'password'];
169
170
            array_walk($needles, function(&$item) use ($post) {
171
                if (!array_key_exists($item, $post))
172
                {
173
                    $http = new Http();
174
                    $http->writeStatus($http::HTTP_BAD_REQUEST);
175
176
                    die('Error ' . $http::HTTP_BAD_REQUEST .' (' . $http->getStatusText($http::HTTP_BAD_REQUEST) . ')!!');
177
                }
178
            });
179
180
            $this->checkSession();
181
182
            $components = [
183
                "attributes" => [
184
                    "username" => [
185
                        "required"  => true,
186
                        "type"      => "text",
187
                        "minlength" => 4,
188
                        "maxlength" => 20
189
                    ],
190
                    "password" => [
191
                        "required"  => true,
192
                        "type"      => "text",
193
                        "minlength" => 4,
194
                        "maxlength" => 20
195
                    ]
196
                ],
197
            ];
198
199
            $options = [
200
                "username" => [
201
                    "label" => "Username",
202
                    "validators" => [
203
                        "Alnum"  => ["allowWhiteSpace" => false]
204
                    ]
205
                ],
206
                "password" => [
207
                    "label"      => "Password"
208
                ]
209
            ];
210
211
            $form = new Form($components);
212
            $form->fill($post);
213
214
            $validator = new FormValidator($form, $options);
215
            $validator->validate();
216
217
            $data["validator"] = $validator;
218
219
            # STANDARD VALIDATIONS [check argument constraints]
220
            if (!$validator->isValid())
221
            {
222
                $data["messages"] = $validator->getMessages();
223
                throw new \Drone\Exception\Exception("Form validation errors!");
224
            }
225
226
            $config = include 'module/Auth/config/user.config.php';
227
228
            $authorization = $config["authorization"];
229
            $username_str  = $config["authentication"]["gateway"]["credentials"]["username"];
230
            $password_str  = $config["authentication"]["gateway"]["credentials"]["password"];
231
232
            switch ($config["authentication"]["type"])
233
            {
234
                case 'db_user':
235
236
                    try
237
                    {
238
                        if ($authorization["enabled"])
239
                        {
240
                            $rowset = $this->getDbUserAdapter()->select([
0 ignored issues
show
The method getDbUserAdapter() does not exist on Auth\Controller\LogIn. Did you maybe mean getUserAdapter()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

240
                            $rowset = $this->/** @scrutinizer ignore-call */ getDbUserAdapter()->select([

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
241
                                $username_str => strtoupper($post["username"])
242
                            ]);
243
244
                            if (!count($rowset))
245
                                throw new \Drone\Exception\Exception("Your user is not authorized to use this application!");
246
                        }
247
248
                        $auth = new Authentication("default", false);
249
                        $result = $auth->authenticate($post["username"], $post["password"]);
250
                    }
251
                    catch (\Drone\Db\Driver\Exception\ConnectionException $e)
252
                    {
253
                        throw new \Drone\Exception\Exception("Wrong user or password");
254
                    }
255
256
                    break;
257
258
                case 'db_table':
259
260
                    $rowset = $this->getUserAdapter()->select([
261
                        $username_str => $post["username"]
262
                    ]);
263
264
                    if (!count($rowset))
265
                        throw new \Drone\Exception\Exception("Username or password are incorrect");
266
267
                    $user = array_shift($rowset);
268
269
                    if ($authorization["enabled"] == "Y")
270
                    {
271
                        $id_field = $config["authentication"]["gateway"]["table_info"]["columns"]["id_field"];
272
273
                        $rowset = $this->getUserRoleAdapter()->select([
274
                            $id_field => $user->{$id_field}
275
                        ]);
276
277
                        if (!count($rowset))
278
                            throw new \Drone\Exception\Exception("Your user is not authorized to use this application!");
279
                    }
280
281
                    $state_field = $config["authentication"]["gateway"]["table_info"]["columns"]["state_field"];
282
                    $state_pending_value = $config["authentication"]["gateway"]["table_info"]["column_values"]["state_field"]["pending_email"];
283
284
                    if ($user->{$state_field} == $state_pending_value)
285
                        throw new \Drone\Exception\Exception("User pending of email checking");
286
287
                    $securePass = $user->{$password_str};
288
                    $password = $post["password"];
289
290
                    $bcrypt = new Bcrypt();
291
292
                    if (!$bcrypt->verify($password, $securePass))
293
                        throw new \Drone\Exception\Exception("Username or password are incorrect");
294
295
                    break;
296
297
                default:
298
                    # code...
299
                    break;
300
            }
301
302
            $key    = $config["authentication"]["key"];
303
            $method = $config["authentication"]["method"];
304
305
            switch ($method)
306
            {
307
                case '_COOKIE':
308
                    setcookie($key, $post["username"], time() + 2000000000, '/');
309
                    break;
310
311
                case '_SESSION':
312
                    $_SESSION[$key] = $post["username"];
313
                    break;
314
            }
315
316
            # SUCCESS-MESSAGE
317
            $data["process"] = "success";
318
        }
319
        catch (\Drone\Exception\Exception $e)
320
        {
321
            # ERROR-MESSAGE
322
            $data["process"] = "warning";
323
            $data["message"] = $e->getMessage();
324
        }
325
        catch (\Exception $e)
326
        {
327
            $file = str_replace('\\', '', __CLASS__);
328
            $storage = new \Drone\Exception\Storage("cache/$file.json");
329
330
            # stores the error code
331
            if (($errorCode = $storage->store($e)) === false)
0 ignored issues
show
The condition $errorCode = $storage->store($e) === false is always true.
Loading history...
332
            {
333
                $errors = $storage->getErrors();
334
335
                # if error storing is not possible, handle it (internal app error)
336
                $this->handleErrors($errors, __METHOD__);
337
            }
338
339
            # errors retrived by the use of ErrorTrait
340
            if (count($this->getErrors()))
341
                $this->handleErrors($this->getErrors(), __METHOD__);
342
343
            $data["code"]    = $errorCode;
344
            $data["message"] = $e->getMessage();
345
346
            $config = include 'config/application.config.php';
347
            $data["dev_mode"] = $config["environment"]["dev_mode"];
348
349
            # redirect view
350
            $this->setMethod('error');
351
352
            return $data;
353
        }
354
355
        return $data;
356
    }
357
358
    private function handleErrors(Array $errors, $method)
359
    {
360
        if (count($errors))
361
        {
362
            $errorInformation = "";
363
364
            foreach ($errors as $errno => $error)
365
            {
366
                $errorInformation .=
367
                    "<strong style='color: #a94442'>".
368
                        $method
369
                            . "</strong>: <span style='color: #e24f4c'>{$error}</span> \n<br />";
370
            }
371
372
            $hd = @fopen('cache/errors.txt', "a");
373
374
            if (!$hd || !@fwrite($hd, $errorInformation))
375
            {
376
                # error storing are not mandatory!
377
            }
378
            else
379
                @fclose($hd);
380
381
            $config = include 'config/application.config.php';
382
            $dev = $config["environment"]["dev_mode"];
383
384
            if ($dev)
385
                echo $errorInformation;
386
        }
387
    }
388
}