JwtHttpBearerAuth::validIdentity()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 7
cp 0
rs 10
c 0
b 0
f 0
cc 4
nc 3
nop 1
crap 20
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://flipboxfactory.com/software/jwt/license
6
 * @link       https://www.flipboxfactory.com/jwt/organization/
7
 */
8
9
namespace flipbox\craft\jwt\filters;
10
11
use Craft;
12
use craft\elements\User;
13
use flipbox\craft\jwt\Jwt;
14
use yii\filters\auth\AuthMethod;
15
use yii\web\IdentityInterface;
16
17
/**
18
 * @author Flipbox Factory <[email protected]>
19
 * @since 1.0.0
20
 */
21
class JwtHttpBearerAuth extends AuthMethod
22
{
23
    /**
24
     * @var string A "realm" attribute MAY be included to indicate the scope
25
     * of protection in the manner described in HTTP/1.1 [RFC2617].  The "realm"
26
     * attribute MUST NOT appear more than once.
27
     */
28
    public $realm = 'api';
29
30
    /**
31
     * @var string Authorization header schema, default 'Bearer'
32
     */
33
    public $schema = 'Bearer';
34
35
    /**
36
     * @var bool Perform a full login operation, default `false`
37
     */
38
    public $login = false;
39
40
    /**
41
     * @inheritdoc
42
     *
43
     * @throws \craft\errors\SiteNotFoundException
44
     * @throws \yii\web\UnauthorizedHttpException
45
     */
46
    public function authenticate($user, $request, $response)
47
    {
48
        $authHeader = $request->getHeaders()->get('Authorization');
49
        if ($authHeader === null || preg_match('/^' . $this->schema . '\s+(.*?)$/', $authHeader, $matches) === false) {
50
            return null;
51
        }
52
53
        // Header does not match schema
54
        if (empty($matches)) {
55
            return null;
56
        }
57
58
        // Header schema is a match, but no token
59
        if (!isset($matches[1])) {
60
            $this->handleFailure($response);
61
        }
62
63
        // JWT token could not be claimed
64
        if (false === ($identity = Jwt::getInstance()->getIdentity()->claim($matches[1]))) {
65
            $this->handleFailure($response);
66
        }
67
68
        if ($this->validIdentity($identity)) {
69
            if ($this->login === true) {
70
                $user->login($identity);
71
            } else {
72
                Craft::$app->getUser()->setIdentity($identity);
73
            }
74
        }
75
76
        return $identity instanceof IdentityInterface ? $identity : true;
0 ignored issues
show
Bug Compatibility introduced by
The expression $identity instanceof \yi...ace ? $identity : true; of type yii\web\IdentityInterface|boolean adds the type boolean to the return on line 76 which is incompatible with the return type declared by the interface yii\filters\auth\AuthInterface::authenticate of type yii\web\IdentityInterface.
Loading history...
77
    }
78
79
    /**
80
     * @param IdentityInterface $identity
81
     * @return bool
82
     *
83
     * @deprecated
84
     */
85
    protected function canLogin(IdentityInterface $identity = null): bool
86
    {
87
        return $this->validIdentity($identity);
88
    }
89
90
    /**
91
     * @param IdentityInterface $identity
92
     * @return bool
93
     */
94
    protected function validIdentity(IdentityInterface $identity = null): bool
95
    {
96
        if ($identity === null || empty($identity->getId())) {
97
            return false;
98
        }
99
100
        return $identity instanceof User && $identity->getStatus() === User::STATUS_ACTIVE;
101
    }
102
103
    /**
104
     * @inheritdoc
105
     */
106
    public function challenge($response)
107
    {
108
        $response->getHeaders()->set(
109
            'WWW-Authenticate',
110
            "{$this->schema} realm=\"{$this->realm}\", error=\"invalid_token\"," .
111
            " error_description=\"The access token invalid or expired\""
112
        );
113
    }
114
}
115