Completed
Push — master ( 85e40f...7b165f )
by Pavel
13s
created

TokenController::failUnknownUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace App\Controller;
4
5
use App\Requests\GetTokenRequest;
6
use App\Requests\RefreshTokenRequest;
7
use App\Model\User;
8
use App\Model\AccessToken;
9
use App\Model\RefreshToken;
10
11
use Slim\Http\Request;
12
use Slim\Http\Response;
13
14
use App\Common\JsonException;
15
16
class TokenController extends BaseController
17
{
18
    const TOKEN_TYPE = 'Bearer';
19
20
    /**
21
     * @api {post} /token Получение токена
22
     * @apiName CreateToken
23
     * @apiGroup Token
24
     *
25
     * @apiDescription Метод для получения авторизационного токена. Токен необходим для выполнения запросов к АПИ.
26
     * Полученный токен отправляется в заголовке запроса:
27
     * <br/>
28
     * <strong>Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxx</strong>
29
     *
30
     * @apiHeader {String} Content-Type application/vnd.api+json <br/> application/json
31
     *
32
     * @apiParam {String} username Логин
33
     * @apiParam {String} password Пароль
34
     *
35
     * @apiParamExample {json} Пример запроса:
36
     *    {
37
     *      "data":{
38
     *        "attributes":{
39
     *          "username":"[email protected]",
40
     *          "password": "qwerty"
41
     *        }
42
     *      }
43
     *    }
44
     *
45
     * @apiSuccessExample {json} Успешно (200)
46
     *     HTTP/1.1 200 OK
47
     *     {
48
     *       "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOmZhbHNlLCJhdWQiOiJza2VsZXRvbi5kZXYiLCJpYXQiOjE0NzY0Mjk4NjksImV4cCI6MTQ3NjQzMzQ2OX0.NJn_-lK28kEZyZqygLr6B-FZ2zC2-1unStayTGicP5g",
49
     *       "expires_in": 3600,
50
     *       "token_type": "Bearer",
51
     *       "refresh_token": "092ea7e36f6b9bf462cb3ca1f6f86b80"
52
     *     }
53
     *
54
     * @apiUse StandardErrors
55
     */
56
    /**
57
     * @param Request  $request
58
     * @param Response $response
59
     *
60
     * @return \Psr\Http\Message\ResponseInterface
61
     * @throws JsonException
62
     */
63
    public function getToken(Request $request, Response $response)
64
    {
65
        $params = $request->getParsedBody();
66
67
        $this->validateRequestParams($params, 'token', new GetTokenRequest());
68
69
        $user = User::findUserByEmail($params['data']['attributes']['username']);
70
        // ensure user and password are good
71
        if (!$user || !password_verify($params['data']['attributes']['password'], $user->password)) {
72
            $this->failUnknownUser();
73
        }
74
75
        return $this->buildTokens($request, $response, $user);
0 ignored issues
show
Bug introduced by
It seems like $user defined by \App\Model\User::findUse...tributes']['username']) on line 69 can be null; however, App\Controller\TokenController::buildTokens() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
76
    }
77
78
    /**
79
     * @api {post} /refresh-token Обновление токена
80
     * @apiName RefreshToken
81
     * @apiGroup Token
82
     *
83
     * @apiDescription Метод для обновления access_token по refresh_token
84
     *
85
     * @apiHeader {String} Content-Type application/vnd.api+json <br/> application/json
86
     *
87
     * @apiParam {String} refresh_token Токен для обновления
88
     *
89
     * @apiParamExample {json} Пример запроса:
90
     *    {
91
     *      "data":{
92
     *        "attributes":{
93
     *          "refresh_token":"092ea7e36f6b9bf462cb3ca1f6f86b80"
94
     *        }
95
     *      }
96
     *    }
97
     *
98
     * @apiSuccessExample {json} Успешно (200)
99
     *     HTTP/1.1 200 OK
100
     *     {
101
     *       "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOmZhbHNlLCJhdWQiOiJza2VsZXRvbi5kZXYiLCJpYXQiOjE0NzY0Mjk4NjksImV4cCI6MTQ3NjQzMzQ2OX0.NJn_-lK28kEZyZqygLr6B-FZ2zC2-1unStayTGicP5g",
102
     *       "expires_in": 3600,
103
     *       "token_type": "Bearer",
104
     *       "refresh_token": "092ea7e36f6b9bf462cb3ca1f6f86b80"
105
     *     }
106
     *
107
     * @apiUse StandardErrors
108
     */
109
110
    /**
111
     * @param Request  $request
112
     * @param Response $response
113
     *
114
     * @return \Psr\Http\Message\ResponseInterface
115
     * @throws JsonException
116
     */
117
    public function refreshToken(Request $request, Response $response)
118
    {
119
        $params = $request->getParsedBody();
120
121
        $this->validateRequestParams($params, 'token', new RefreshTokenRequest());
122
123
        $user = RefreshToken::getUserByToken($params['data']['attributes']['refresh_token']);
124
        // ensure user is good
125
        if (!$user) {
126
            $this->failUnknownToken();
127
        }
128
129
        return $this->buildTokens($request, $response, $user);
0 ignored issues
show
Bug introduced by
It seems like $user defined by \App\Model\RefreshToken:...tes']['refresh_token']) on line 123 can be null; however, App\Controller\TokenController::buildTokens() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
130
    }
131
132
    /**
133
     * @param Request $request
134
     * @param Response $response
135
     * @param User $user
136
     * @return \Psr\Http\Message\ResponseInterface
137
     */
138
    protected function buildTokens(Request $request, Response $response, User $user)
139
    {
140
        // build tokens
141
        $accessToken = AccessToken::createToken(
142
            $user,
143
            $request->getUri()->getHost(),
144
            $this->settings['accessToken']
145
        );
146
        $refreshToken = RefreshToken::createToken($user);
147
148
        // prepare response structure
149
        $result = [
150
            'token_type'    => self::TOKEN_TYPE,
151
            'access_token'  => $accessToken,
152
            'refresh_token' => $refreshToken,
153
            'expires_in'    => $this->settings['accessToken']['ttl'],
154
        ];
155
156
        // render response
157
        return $this->apiRenderer->jsonResponse($response, 200, json_encode($result));
158
    }
159
160
    /**
161
     * @throws JsonException
162
     */
163
    protected function failUnknownUser()
164
    {
165
        throw new JsonException('token', 400, 'Invalid Attribute', 'Invalid password or username');
166
    }
167
168
    /**
169
     * @throws JsonException
170
     */
171
    protected function failUnknownToken()
172
    {
173
        throw new JsonException('token', 400, 'Invalid Attribute', 'Invalid refresh_token');
174
    }
175
}
176