Passed
Pull Request — master (#1470)
by
unknown
33:53
created

AccessTokenTrait::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @author      Alex Bilbie <[email protected]>
5
 * @copyright   Copyright (c) Alex Bilbie
6
 * @license     http://mit-license.org/
7
 *
8
 * @link        https://github.com/thephpleague/oauth2-server
9
 */
10
11
declare(strict_types=1);
12
13
namespace League\OAuth2\Server\Entities\Traits;
14
15
use DateTimeImmutable;
16
use Lcobucci\JWT\Configuration;
17
use Lcobucci\JWT\Signer\Key\InMemory;
18
use Lcobucci\JWT\Signer\Hmac\Sha256 as HS256;
19
use Lcobucci\JWT\Signer\Hmac\Sha384 as HS384;
20
use Lcobucci\JWT\Signer\Hmac\Sha512 as HS512;
21
use Lcobucci\JWT\Signer\Blake2b as BLAKE2B;
22
use Lcobucci\JWT\Signer\Rsa\Sha256 as RS256;
23
use Lcobucci\JWT\Signer\Rsa\Sha384 as RS384;
24
use Lcobucci\JWT\Signer\Rsa\Sha512 as RS512;
25
use Lcobucci\JWT\Signer\Ecdsa\Sha256 as ES256;
26
use Lcobucci\JWT\Signer\Ecdsa\Sha384 as ES384;
27
use Lcobucci\JWT\Signer\Ecdsa\Sha512 as ES512;
28
use Lcobucci\JWT\Signer\Eddsa as EDDSA;
29
use Lcobucci\JWT\Encoding\ChainedFormatter;
30
use Lcobucci\JWT\Encoding\JoseEncoder;
31
use Lcobucci\JWT\Token;
32
use Lcobucci\JWT\Token\Builder;
33
use Lcobucci\JWT\Signer;
34 35
use Lcobucci\JWT\Signer\Key;
35
use League\OAuth2\Server\CryptKeyInterface;
36 35
use League\OAuth2\Server\Entities\ClientEntityInterface;
37
use League\OAuth2\Server\Entities\ScopeEntityInterface;
38
use League\OAuth2\Server\Entities\UserEntityInterface;
39
40
trait AccessTokenTrait
41
{
42 10
    private ?Key $privateKey = null;
43
44 10
    private Signer $signer;
45
46 10
    private Configuration $jwtConfiguration;
47
48
    public function __construct()
49
    {
50 10
        $this->signer = new RS256();
51 10
    }
52 10
53 10
    public function setSigner(string $signerAlgorithm, CryptKeyInterface $privateKey): void
54 10
    {
55
        $this->privateKey = InMemory::plainText($privateKey->getKeyContents(), $privateKey->getPassPhrase() ?? '');
56
57
        switch (strtoupper($signerAlgorithm)) {
58
            case 'HS256': 
59
                $this->signer = new HS256();
60 10
                break;
61
            case 'HS384': 
62 10
                $this->signer = new HS384();
63
                break;
64 10
            case 'HS512': 
65 10
                $this->signer = new HS512();
66 10
                break;
67 10
            case 'BLAKE2B': 
68 10
                $this->signer = new BLAKE2B();
69 10
                break;
70 10
            case 'ES256': 
71 10
                $this->signer = new ES256();
72 10
                break;
73
            case 'ES384': 
74
                $this->signer = new ES384();
75
                break;
76
            case 'ES512': 
77
                $this->signer = new ES512();
78 10
                break;
79
            case 'RS256': 
80 10
                $this->signer = new RS256();
81
                break;
82
            case 'RS384': 
83
                $this->signer = new RS384();
84
                break;
85
            case 'RS512': 
86
                $this->signer = new RS512();
87
                break;
88
            case 'EDDSA': 
89
                $this->signer = new EDDSA();
90
                break;
91
        }
92
    }
93
94
    /**
95
     * Generate a JWT from the access token
96
     */
97
    private function convertToJWT(): Token
98
    {
99
        $tokenBuilder = (new Builder(new JoseEncoder(), ChainedFormatter::default()));
100
101
        return $tokenBuilder
102
            ->permittedFor($this->getClient()->getIdentifier())
103
            ->identifiedBy($this->getIdentifier())
104
            ->issuedAt(new DateTimeImmutable())
105 10
            ->canOnlyBeUsedAfter(new DateTimeImmutable())
106
            ->expiresAt($this->getExpiryDateTime())
107 10
            ->relatedTo($this->getSubjectIdentifier())
108
            ->withClaim('scopes', $this->getScopes())
109
            ->getToken($this->signer, $this->privateKey);
0 ignored issues
show
Bug introduced by
It seems like $this->privateKey can also be of type null; however, parameter $key of Lcobucci\JWT\Token\Builder::getToken() does only seem to accept Lcobucci\JWT\Signer\Key, maybe add an additional type check? ( Ignorable by Annotation )

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

109
            ->getToken($this->signer, /** @scrutinizer ignore-type */ $this->privateKey);
Loading history...
110
    }
111
112
    /**
113
     * Generate a string representation from the access token
114
     */
115
    public function toString(): string
116
    {
117
        if ($this->privateKey === null) {
118
            return $this->getIdentifier();
119
        }
120
        
121
        return $this->convertToJWT()->toString();
122
    }
123
124
    abstract public function getClient(): ClientEntityInterface;
125
126
    abstract public function getExpiryDateTime(): DateTimeImmutable;
127
128
    /**
129
     * Get the token user.
130
     *
131
     * @return ?UserEntityInterface
132
     */
133
    abstract public function getUser(): ?UserEntityInterface;
134
135
    /**
136
     * @return ScopeEntityInterface[]
137
     */
138
    abstract public function getScopes(): array;
139
140
    /**
141
     * @return non-empty-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
142
     */
143
    abstract public function getIdentifier(): string;
144
145
    /**
146
     * @return non-empty-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
147
     */
148
    private function getSubjectIdentifier(): string
149
    {
150
        return $this->getUser()?->getIdentifier() ?? $this->getClient()->getIdentifier();
151
    }
152
}
153