Passed
Push — master ( e6c475...db71b9 )
by Darío
04:47
created

module/Auth/source/Controller/LogIn.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Auth\Controller;
4
5
use Auth\Model\User;
6
use Drone\Db\TableGateway\EntityAdapter;
7
use Drone\Db\TableGateway\TableGateway;
8
use Drone\Dom\Element\Form;
9
use Drone\Mvc\AbstractionController;
10
use Drone\Network\Http;
11
use Drone\Validator\FormValidator;
12
use Zend\Crypt\Password\Bcrypt;
13
use Drone\Error\Errno;
14
15
class LogIn extends AbstractionController
16
{
17
    use \Drone\Error\ErrorTrait;
18
19
    /**
20
     * @var EntityAdapter
21
     */
22
    private $usersAdapter;
23
24
    /**
25
     * @return EntityAdapter
26
     */
27
    private function getUsersAdapter()
28
    {
29
        if (!is_null($this->usersAdapter))
30
            return $this->usersAdapter;
31
32
        $this->usersAdapter = new EntityAdapter(new TableGateway(new User()));
33
34
        return $this->usersAdapter;
35
    }
36
37
    /**
38
     * Checks user session and redirect to other module if exists any active session
39
     *
40
     * @return null
41
     */
42
    private function checkSession()
43
    {
44
        $config = include 'module/Auth/config/user.config.php';
45
        $method = $config["authentication"]["method"];
46
        $key    = $config["authentication"]["key"];
47
48
        switch ($method)
49
        {
50
            case '_COOKIE':
51
52
                if (array_key_exists($key, $_COOKIE) || !empty($_COOKIE[$key]))
53
                {
54
                    if (array_key_exists("CR_VAR_URL_REJECTED", $_SESSION) || !empty($_SESSION["CR_VAR_URL_REJECTED"]))
55
                        header("location: " . $_SESSION["CR_VAR_URL_REJECTED"]);
56
                    else
57
                        header("location: " . $this->basePath . "/public/" . $config["redirect"]);
0 ignored issues
show
The property basePath is declared private in Drone\Mvc\AbstractionController and cannot be accessed from this context.
Loading history...
58
                }
59
60
                break;
61
62
            case '_SESSION':
63
64
                if (array_key_exists($key, $_SESSION) || !empty($_SESSION[$key]))
65
                {
66
                    if (array_key_exists("CR_VAR_URL_REJECTED", $_SESSION) || !empty($_SESSION["CR_VAR_URL_REJECTED"]))
67
                        header("location: " . $_SESSION["CR_VAR_URL_REJECTED"]);
68
                    else
69
                        header("location: " . $this->basePath . "/public/" . $config["redirect"]);
70
                }
71
72
                break;
73
        }
74
    }
75
76
    /**
77
     * Shows login form
78
     *
79
     * @return array
80
     */
81
    public function index()
82
    {
83
        # STANDARD VALIDATIONS [check method]
84
        if (!$this->isGet())
85
        {
86
            $http = new Http();
87
            $http->writeStatus($http::HTTP_METHOD_NOT_ALLOWED);
88
89
            die('Error ' . $http::HTTP_METHOD_NOT_ALLOWED .' (' . $http->getStatusText($http::HTTP_METHOD_NOT_ALLOWED) . ')!!');
90
        }
91
92
        $this->checkSession();
93
94
        return [];
95
    }
96
97
    /**
98
     * Checks user credentials
99
     *
100
     * @return array
101
     */
102
    public function attemp()
103
    {
104
        # data to send
105
        $data = [];
106
107
        $post = $this->getPost();
108
        $this->setTerminal(true);
109
110
        # TRY-CATCH-BLOCK
111
        try {
112
113
            # STANDARD VALIDATIONS [check method]
114
            if (!$this->isPost())
115
            {
116
                $http = new Http();
117
                $http->writeStatus($http::HTTP_METHOD_NOT_ALLOWED);
118
119
                die('Error ' . $http::HTTP_METHOD_NOT_ALLOWED .' (' . $http->getStatusText($http::HTTP_METHOD_NOT_ALLOWED) . ')!!');
120
            }
121
122
            # STANDARD VALIDATIONS [check needed arguments]
123
            $needles = ['username', 'password'];
124
125
            array_walk($needles, function(&$item) use ($post) {
126
                if (!array_key_exists($item, $post))
127
                {
128
                    $http = new Http();
129
                    $http->writeStatus($http::HTTP_BAD_REQUEST);
130
131
                    die('Error ' . $http::HTTP_BAD_REQUEST .' (' . $http->getStatusText($http::HTTP_BAD_REQUEST) . ')!!');
132
                }
133
            });
134
135
            $this->checkSession();
136
137
            $components = [
138
                "attributes" => [
139
                    "username" => [
140
                        "required"  => true,
141
                        "type"      => "text",
142
                        "minlength" => 4,
143
                        "maxlength" => 20
144
                    ],
145
                    "password" => [
146
                        "required"  => true,
147
                        "type"      => "text",
148
                        "minlength" => 4,
149
                        "maxlength" => 20
150
                    ]
151
                ],
152
            ];
153
154
            $options = [
155
                "username" => [
156
                    "label" => "Username",
157
                    "validators" => [
158
                        "Alnum"  => ["allowWhiteSpace" => false]
159
                    ]
160
                ],
161
                "password" => [
162
                    "label"      => "Password"
163
                ]
164
            ];
165
166
            $form = new Form($components);
167
            $form->fill($post);
168
169
            $validator = new FormValidator($form, $options);
170
            $validator->validate();
171
172
            $data["validator"] = $validator;
173
174
            # STANDARD VALIDATIONS [check argument constraints]
175
            if (!$validator->isValid())
176
            {
177
                $data["messages"] = $validator->getMessages();
178
                throw new \Drone\Exception\Exception("Form validation errors!");
179
            }
180
181
            $config = include 'module/Auth/config/user.config.php';
182
183
            $username_str = $config["authentication"]["gateway"]["credentials"]["username"];
184
            $password_str = $config["authentication"]["gateway"]["credentials"]["password"];
185
186
            $row = $this->getUsersAdapter()->select([
187
                "$username_str" => $post["username"]
188
            ]);
189
190
            if (!count($row))
191
                throw new \Drone\Exception\Exception("Username or password are incorrect");
192
193
            $user = array_shift($row);
194
195
            $securePass = $user->{$password_str};
196
            $password = $post["password"];
197
198
            if ($user->USER_STATE_ID == 1)
199
                throw new \Drone\Exception\Exception("User pending of email checking!");
200
201
            $bcrypt = new Bcrypt();
202
203
            if (!$bcrypt->verify($password, $securePass))
204
                throw new \Drone\Exception\Exception("Username or password are incorrect");
205
206
            $key    = $config["authentication"]["key"];
207
            $method = $config["authentication"]["method"];
208
209
            switch ($method)
210
            {
211
                case '_COOKIE':
212
                    setcookie($key, $user->USERNAME, time() + 2000000000, '/');
213
                    break;
214
215
                case '_SESSION':
216
                    $_SESSION[$key] = $user->USERNAME;
217
                    break;
218
            }
219
220
            # SUCCESS-MESSAGE
221
            $data["process"] = "success";
222
        }
223
        catch (\Drone\Exception\Exception $e)
224
        {
225
            # ERROR-MESSAGE
226
            $data["process"] = "warning";
227
            $data["message"] = $e->getMessage();
228
        }
229
        catch (\Exception $e)
230
        {
231
            $file = str_replace('\\', '', __CLASS__);
232
            $storage = new \Drone\Exception\Storage("cache/$file.json");
233
234
            # stores the error code
235
            if (($errorCode = $storage->store($e)) === false)
236
            {
237
                $errors = $storage->getErrors();
238
239
                # if error storing is not possible, handle it (internal app error)
240
                $this->handleErrors($errors, __METHOD__);
241
            }
242
243
            # errors retrived by the use of ErrorTrait
244
            if (count($this->getErrors()))
245
                $this->handleErrors($this->getErrors(), __METHOD__);
246
247
            $data["code"]    = $errorCode;
248
            $data["message"] = $e->getMessage();
249
250
            $config = include 'config/application.config.php';
251
            $data["dev_mode"] = $config["environment"]["dev_mode"];
252
253
            # redirect view
254
            $this->setMethod('error');
255
256
            return $data;
257
        }
258
259
        return $data;
260
    }
261
262
    private function handleErrors(Array $errors, $method)
263
    {
264
        if (count($errors))
265
        {
266
            $errorInformation = "";
267
268
            foreach ($errors as $errno => $error)
269
            {
270
                $errorInformation .=
271
                    "<strong style='color: #a94442'>".
272
                        $method
273
                            . "</strong>: <span style='color: #e24f4c'>{$error}</span> \n<br />";
274
            }
275
276
            $hd = @fopen('cache/errors.txt', "a");
277
278
            if (!$hd || !@fwrite($hd, $errorInformation))
279
            {
280
                # error storing are not mandatory!
281
            }
282
            else
283
                @fclose($hd);
284
285
            $config = include 'config/application.config.php';
286
            $dev = $config["environment"]["dev_mode"];
287
288
            if ($dev)
289
                echo $errorInformation;
290
        }
291
    }
292
}