Completed
Push — master ( 32191e...8fb922 )
by Nate
03:04 queued 11s
created

TokenHelper::parse()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 0
cts 16
cp 0
rs 9.3554
c 0
b 0
f 0
cc 5
nc 4
nop 2
crap 30
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\helpers;
10
11
use Craft;
12
use craft\helpers\User;
13
use flipbox\craft\jwt\Jwt;
14
use Lcobucci\JWT\Token;
15
use yii\web\IdentityInterface;
16
17
/**
18
 * @author Flipbox Factory <[email protected]>
19
 * @since 1.0.0
20
 */
21
class TokenHelper
22
{
23
    /**
24
     * The CSRF claim identifier
25
     */
26
    const CLAIM_CSRF = 'csrf';
27
28
    /**
29
     * The Audience claim identifier
30
     */
31
    const CLAIM_AUDIENCE = 'aud';
32
33
    /**
34
     * The Issuer claim identifier
35
     */
36
    const CLAIM_ISSUER = 'iss';
37
38
    /**
39
     * The Identity claim identifier
40
     */
41
    const CLAIM_IDENTITY = 'jti';
42
43
    /**
44
     * @param $token
45
     * @param bool $validate
46
     * @return Token|null
47
     * @throws \craft\errors\SiteNotFoundException
48
     */
49
    public static function parse(string $token, bool $validate = true)
50
    {
51
        try {
52
            $token = Jwt::getInstance()->getParser()->parse((string)$token);
53
        } catch (\RuntimeException $e) {
54
            Jwt::warning("Invalid JWT provided: " . $e->getMessage());
55
            return null;
56
        } catch (\InvalidArgumentException $e) {
57
            Jwt::warning("Invalid JWT provided: " . $e->getMessage());
58
            return null;
59
        }
60
61
        if ($validate && !Jwt::getInstance()->validateToken($token)) {
62
            return null;
63
        }
64
65
        return $token;
66
    }
67
68
    /**
69
     * @param IdentityInterface $identity
70
     * @return string
71
     */
72
    public static function getSignatureKey(IdentityInterface $identity = null)
73
    {
74
        $result = Jwt::getInstance()->getSettings()->getKey();
75
76
        if ($identity === null) {
77
            return $result;
78
        }
79
80
        return $result . '.' . ($identity instanceof User ? $identity->uid : $identity->getId());
81
    }
82
83
    /**
84
     * @param Token $token
85
     * @return bool
86
     */
87
    public static function verifyTokenCsrfClaim(Token $token): bool
88
    {
89
        $csrf = $token->getClaim(self::CLAIM_CSRF);
90
        if (false === Craft::$app->getRequest()->validateCsrfToken($csrf)) {
91
            Jwt::error(sprintf(
92
                "Unable to verify CSRF Token: %s",
93
                $csrf
94
            ));
95
96
            return false;
97
        }
98
        return true;
99
    }
100
101
    /**
102
     * @param Token $token
103
     * @param IdentityInterface $identity
104
     * @return bool
105
     */
106
    public static function verifyTokenSignature(Token $token, IdentityInterface $identity = null): bool
107
    {
108
        try {
109
            if (false === $token->verify(
110
                Jwt::getInstance()->getSettings()->resolveSigner($token->getHeader('alg')),
111
                TokenHelper::getSignatureKey($identity)
112
            )) {
113
                Jwt::error("Unable to verify token signature");
114
                return false;
115
            }
116
            return true;
117
        } catch (\Exception $e) {
118
            Jwt::error(sprintf(
119
                "Exception caught while trying to verify token signature: %s",
120
                $e->getMessage()
121
            ));
122
        }
123
        return false;
124
    }
125
126
    /**
127
     * @param Token $token
128
     * @return bool
129
     * @throws \craft\errors\SiteNotFoundException
130
     */
131
    public static function verifyAudience(Token $token): bool
132
    {
133
        $audience = $token->getClaim(TokenHelper::CLAIM_AUDIENCE);
134
        if (false === ($audience === Craft::$app->getSites()->getCurrentSite()->getBaseUrl())) {
135
            Jwt::error(sprintf(
136
                "Unable to verify audience: %s",
137
                $audience
138
            ));
139
140
            return false;
141
        }
142
        return true;
143
    }
144
145
    /**
146
     * Verify that the issuer is one we can accept from
147
     *
148
     * @param Token $token
149
     * @param array $issuers
150
     * @return bool
151
     * @throws \craft\errors\SiteNotFoundException
152
     */
153
    public static function verifyIssuer(Token $token, array $issuers): bool
154
    {
155
        $issuer = $token->getClaim(TokenHelper::CLAIM_ISSUER);
156
        if (false === in_array(
157
            $issuer,
158
            $issuers
159
        )) {
160
            Jwt::error(sprintf(
161
                "Unable to verify issuer: %s",
162
                $issuer
163
            ));
164
165
            return false;
166
        }
167
        return true;
168
    }
169
}
170