Completed
Push — master ( e59634...dafc98 )
by Adeola
02:51
created

AuthController::checkEmptyInput()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.2
cc 4
eloc 4
nc 2
nop 3
1
<?php
2
3
/**
4
 * @author: Raimi Ademola <[email protected]>
5
 * @copyright: 2016 Andela
6
 */
7
namespace Demo;
8
9
use Carbon\Carbon;
10
use Firebase\JWT\JWT;
11
use Psr\Http\Message\ResponseInterface as Response;
12
use Psr\Http\Message\ServerRequestInterface as Request;
13
14
class AuthController
15
{
16
    /**
17
     * Login a user.
18
     *
19
     * @param Slim\Http\Request  $request
20
     * @param Slim\Http\Response $response
21
     *
22
     * @return json response
23
     */
24
    public function login($request, $response)
25
    {
26
        $userData         = $request->getParsedBody();
27
        $validateResponse = $this->validateUserData(['username', 'password'], $userData);
28
29
        if (is_array($validateResponse)) {
30
            return $response->withJson($validateResponse, 400);
31
        }
32
33
        $user = $this->authenticate($userData['username'], $userData['password']);
34
35
        if (!$user) {
36
            return $response->withJson(['message' => 'Username or Password field not valid.'], 400);
37
        }
38
39
        $issTime = $request->getAttribute('issTime') == null ? time() : $request->getAttribute('issTime');
40
        $token   = $this->generateToken($user->id, $issTime);
41
   
42
        return $response->withAddedHeader('HTTP_AUTHORIZATION', $token)->withStatus(200)->write($token);
43
    }
44
45
    /**
46
     * Generate a token for user with passed Id.
47
     *
48
     * @param int $userId
49
     *
50
     * @return string
51
     */
52
    private function generateToken($userId, $time = null)
53
    {
54
        $time         = $time == null ? time() : $time;
55
        $appSecret    = getenv('APP_SECRET');
56
        $jwtAlgorithm = getenv('JWT_ALGORITHM');
57
        $timeIssued   = $time;
58
        $tokenId      = base64_encode($time);
59
        $token = [
60
            'iat'     => $timeIssued,   // Issued at: time when the token was generated
61
            'jti'     => $tokenId,          // Json Token Id: an unique identifier for the token
62
            'nbf'     => $timeIssued, //Not before time
63
            'exp'     => $timeIssued + 60 * 60 * 24 * 30, // expires in 30 days
64
            'data'    => [                  // Data related to the signer user
65
                'userId'  => $userId, // userid from the users tableu;
66
            ],
67
        ];
68
69
        return JWT::encode($token, $appSecret, $jwtAlgorithm);
70
    }
71
72
    /**
73
     * Register a user.
74
     *
75
     * @param Slim\Http\Request  $request
76
     * @param Slim\Http\Response $response
77
     *
78
     * @return json response
79
     */
80
    public function register($request, $response)
81
    {
82
        $requestParams    = $request->getParsedBody();
83
        $validateUserData = $this->validateUserData(['fullname', 'username', 'password'], $requestParams);
84
85
        if (is_array($validateUserData)) {
86
            return $response->withJson($validateUserData, 400);
87
        }
88
89
        $validateEmptyInput = $this->checkEmptyInput($requestParams['fullname'], $requestParams['username'], $requestParams['password']);
90
91
        if (is_array($validateEmptyInput)) {
92
            return $response->withJson($validateEmptyInput, 401);
93
        }
94
95
        if (User::where('username', $requestParams['username'])->first()) {
96
            return $response->withJson(['message' => 'Username already exist.'], 409);
97
        }
98
99
        User::firstOrCreate(
0 ignored issues
show
Bug introduced by
The method firstOrCreate() does not exist on Demo\User. Did you maybe mean create()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
100
            [
101
                'fullname'   => $requestParams['fullname'],
102
                'username'   => strtolower($requestParams['username']),
103
                'password'   => password_hash($requestParams['password'], PASSWORD_DEFAULT),
104
                'created_at' => Carbon::now()->toDateTimeString(),
105
                'updated_at' => Carbon::now()->toDateTimeString(),
106
            ]);
107
108
        return $response->withJson(['message' => 'User successfully created.'], 201);
109
    }
110
111
    /**
112
     * This method logout the user.
113
     *
114
     * @param $args logout
115
     *
116
     * @return json response
117
     */
118
    public function logout(Request $request, Response $response)
119
    {
120
        $request->getAttribute('users');
121
        return $response->withJson(['message' => 'Logout successful'], 200);
122
    }
123
124
    /**
125
     * Authenticate username and password against database.
126
     *
127
     * @param string $username
128
     * @param string $password
129
     *
130
     * @return bool
131
     */
132
    public function authenticate($username, $password)
133
    {
134
        $user = User::where('username', $username)->get();
135
136
        if ($user->isEmpty()) {
137
            return false;
138
        }
139
140
        $user = $user->first();
141
142
        if (password_verify($password, $user->password)) {
143
            return $user;
144
        }
145
146
        return false;
147
    }
148
149
    /**
150
     * Validate user data are correct.
151
     *
152
     * @param $expectedFields
153
     * @param $userData
154
     *
155
     * @return bool
156
     */
157
    public function validateUserData($expectedFields, $userData)
158
    {
159
        $tableFields = [];
160
        $tableValues = [];
161
162
        foreach ($userData as $key => $val) {
163
            $tableFields[] = $key;
164
            $tableValues[] = $val;
165
        }
166
167
        $result = array_diff($expectedFields, $tableFields);
168
169
        if (count($result) > 0 && empty($userData)) {
170
            return ['message' => 'All fields must be provided.'];
171
        }
172
173
        $tableValues = implode('', $tableValues);
174
175
        if (empty($tableValues)) {
176
            return ['message' => 'All fields are required'];
177
        }
178
179
        foreach ($userData as $key => $val) {
180
            if (!in_array($key, $expectedFields)) {
181
                return ['message' => 'Unwanted fields must be removed'];
182
            }
183
        }
184
185
        return true;
186
    }
187
188
    /**
189
     * This method checks for empty input from user.
190
     *
191
     * @param $inputName
192
     * @param $inputChars
193
     * @param $inputCategory
194
     * @param $inputKeywords
195
     *
196
     * @return bool
197
     */
198
    public function checkEmptyInput($inputFullname, $inputUsername, $inputPassword)
199
    {
200
        if (empty($inputFullname) || empty($inputUsername) || empty($inputPassword)) {
201
            return ['message' => 'All fields must be provided.'];
202
        }
203
204
        return true;
205
    }
206
}
207