TokenStorage   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 16
eloc 21
c 1
b 0
f 0
dl 0
loc 92
ccs 27
cts 27
cp 1
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A clear() 0 3 1
A onIntrospection() 0 8 3
A token() 0 3 2
A onUserinfo() 0 3 2
A onRevocation() 0 5 2
A expired() 0 4 2
A onEndSession() 0 9 3
A onToken() 0 4 1
1
<?php
2
3
namespace Parroauth2\Client\Extension;
4
5
use Parroauth2\Client\EndPoint\EndPointTransformerTrait;
6
use Parroauth2\Client\EndPoint\Introspection\IntrospectionEndPoint;
7
use Parroauth2\Client\EndPoint\Introspection\IntrospectionResponse;
8
use Parroauth2\Client\EndPoint\Token\RevocationEndPoint;
9
use Parroauth2\Client\EndPoint\Token\TokenEndPoint;
10
use Parroauth2\Client\EndPoint\Token\TokenResponse;
11
use Parroauth2\Client\OpenID\EndPoint\EndSessionEndPoint;
12
use Parroauth2\Client\OpenID\EndPoint\Token\TokenResponse as OpenIdTokenResponse;
13
use Parroauth2\Client\OpenID\EndPoint\Userinfo\UserinfoEndPoint;
14
15
/**
16
 * Extension for store and use access tokens
17
 *
18
 * Listen for the token endpoint response for store and update the token
19
 *
20
 * Add the access token on endpoints :
21
 * - userinfo
22
 * - introspection
23
 * - revocation
24
 */
25
final class TokenStorage extends AbstractEndPointTransformerExtension
26
{
27
    use EndPointTransformerTrait;
28
29
    /**
30
     * {@inheritdoc}
31
     */
32 6
    public function onToken(TokenEndPoint $endPoint): TokenEndPoint
33
    {
34
        return $endPoint->onResponse(function (TokenResponse $response) {
35 6
            $this->client()->storage()->store(self::class, $response);
36 6
        });
37
    }
38
39
    /**
40
     * {@inheritdoc}
41
     */
42 3
    public function onUserinfo(UserinfoEndPoint $endPoint): UserinfoEndPoint
43
    {
44 3
        return $this->expired() ? $endPoint : $endPoint->token($this->token()->accessToken());
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 3
    public function onIntrospection(IntrospectionEndPoint $endPoint): IntrospectionEndPoint
51
    {
52 3
        return $this->expired()
53 1
            ? $endPoint
54 2
            : $endPoint->accessToken($this->token()->accessToken())
55
                ->onResponse(function (IntrospectionResponse $response) {
56 2
                    if (!$response->active()) {
57 1
                        $this->clear();
58
                    }
59 3
                })
60
        ;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 2
    public function onRevocation(RevocationEndPoint $endPoint): RevocationEndPoint
67
    {
68 2
        return $this->expired()
69 1
            ? $endPoint
70 2
            : $endPoint->accessToken($this->token()->accessToken())->onResponse([$this, 'clear'])
71
        ;
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77 2
    public function onEndSession(EndSessionEndPoint $endPoint): EndSessionEndPoint
78
    {
79 2
        $token = $this->token();
80
81 2
        if (!$token instanceof OpenIdTokenResponse || !$token->idToken()) {
82 1
            return $endPoint;
83
        }
84
85 1
        return $endPoint->idToken($token->idToken());
86
    }
87
88
    /**
89
     * Get the stored token
90
     *
91
     * @return TokenResponse|null
92
     */
93 7
    public function token(): ?TokenResponse
94
    {
95 7
        return $this->client()->storage()->has(self::class) ? $this->client()->storage()->retrieve(self::class) : null;
96
    }
97
98
    /**
99
     * Check if the stored token is not available or expired
100
     *
101
     * @return bool
102
     *
103
     * @psalm-assert-if-false TokenResponse $this->token()
104
     */
105 8
    public function expired(): bool
106
    {
107
        /** @psalm-suppress PossiblyNullReference */
108 8
        return !$this->client()->storage()->has(self::class) || $this->token()->expired();
109
    }
110
111
    /**
112
     * Remove the stored token
113
     */
114 3
    public function clear(): void
115
    {
116 3
        $this->client()->storage()->remove(self::class);
117 3
    }
118
}
119