Passed
Push — master ( 7b99b1...fbce31 )
by Charles
02:37
created

AuthenticationAction::getVersionedHeaders()   A

Complexity

Conditions 6
Paths 2

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 4
nc 2
nop 1
dl 0
loc 10
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
namespace yrc\actions;
4
5
use app\forms\Login;
0 ignored issues
show
Bug introduced by
The type app\forms\Login 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...
6
use yrc\rest\Action as RestAction;
7
8
use yii\web\UnauthorizedHttpException;
0 ignored issues
show
Bug introduced by
The type yii\web\UnauthorizedHttpException 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 Yii;
0 ignored issues
show
Bug introduced by
The type Yii 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...
10
11
/**
12
 * Handles Authentication and Deauthentication of users
13
 * @class AuthenticationAction
14
 */
15
class AuthenticationAction extends RestAction
16
{
17
    /**
18
     * Authenticates a user using their username and password
19
     * @return mixed
20
     */
21
    public function post($params)
22
    {
23
        $model = new Login;
24
        
25
        if ($model->load(['Login' => Yii::$app->request->post()])) {
26
            $token = $model->authenticate();
27
28
            if ($token === false) {
29
                throw new UnauthorizedHttpException('The credentials you provided are not valid', $model->exitStatus);
30
            } else {
31
                return $token->getAuthResponse();
32
            }
33
        }
34
            
35
        return false;
36
    }
37
38
    /**
39
     * Deauthenticates a user
40
     * @return mixed
41
     */
42
    public function delete($params)
43
    {
44
        $token = self::getAccessTokenFromHeader();
45
        return (bool)$token->delete();
46
    }
47
48
    /**
49
     * Helper method to grab the User Token object from the header
50
     * @return User\Token|bool
0 ignored issues
show
Bug introduced by
The type yrc\actions\User\Token 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...
51
     */
52
    public static function getAccessTokenFromHeader()
53
    {
54
        // Grab the authentication header
55
        $authHeader = Yii::$app->request->getHeaders()->get('Authorization');
56
        
57
        // Pull the accessToken from the Authorization header string
58
        if ($authHeader !== null && preg_match('/^HMAC\s+(.*?)$/', $authHeader, $matches)) {
59
            if (\strpos($matches[1], ',') !== false) {
60
                $data = self::getV1Headers($matches[1]);
61
            } else {
62
                $data = self::getVersionedHeaders($matches[1]);
63
            }
64
65
            // Retrieve the token object
66
            $tokenClass = (Yii::$app->user->identityClass::TOKEN_CLASS);
67
            $token = $tokenClass::find()
68
                ->where([
69
                    'access_token' => $data['access_token'],
70
                    'user_id'      => Yii::$app->user->id
71
                ])
72
                ->one();
73
74
            // Malformed header
75
            if ($token === null || $token->isExpired()) {
76
                throw new UnauthorizedHttpException;
77
            }
78
                
79
            return $token;
80
        }
81
82
        // Header isn't present
83
        throw new UnauthorizedHttpException;
84
    }
85
86
    /**
87
     * Returns the unversioned authorization headers
88
     * @param string $data
89
     * @return array
90
     */
91
    private static function getV1Headers(string $data)
92
    {
93
        $params = explode(',', trim($data[1]));
94
95
        if (count($data) !== 3) {
0 ignored issues
show
Bug introduced by
$data of type string is incompatible with the type Countable|array expected by parameter $var of count(). ( Ignorable by Annotation )

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

95
        if (count(/** @scrutinizer ignore-type */ $data) !== 3) {
Loading history...
96
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array.
Loading history...
97
        }
98
99
        return [
100
            'access_token' => $params[0],
101
            'hmac' => $params[1],
102
            'salt' => $params[2],
103
            'v' => 1,
104
            'date' => null,
105
        ];
106
    }
107
108
    /**
109
     * Returns the versioned authorization headers
110
     * @param string $data
111
     * @return array
112
     */
113
    private static function getVersionedHeaders(string $data)
114
    {
115
        $params = \json_decode(\base64_decode($data), true);
116
117
        // Make sure all the necessary parameters are set
118
        if (!isset($params['access_token']) || !isset($params['hmac']) || !isset($params['salt']) || !isset($params['v']) || !isset($params['date'])) {
119
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array.
Loading history...
120
        }
121
122
        return $params;
123
    }
124
}
125