Oauth2Subscriber::getAccessToken()   B
last analyzed

Complexity

Conditions 5
Paths 6

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 17
ccs 11
cts 11
cp 1
rs 8.8571
cc 5
eloc 8
nc 6
nop 0
crap 5
1
<?php
2
3
namespace CommerceGuys\Guzzle\Oauth2;
4
5
use CommerceGuys\Guzzle\Oauth2\GrantType\GrantTypeInterface;
6
use CommerceGuys\Guzzle\Oauth2\GrantType\RefreshTokenGrantTypeInterface;
7
use GuzzleHttp\Event\BeforeEvent;
8
use GuzzleHttp\Event\ErrorEvent;
9
use GuzzleHttp\Event\RequestEvents;
10
use GuzzleHttp\Event\SubscriberInterface;
11
12
class Oauth2Subscriber implements SubscriberInterface
13
{
14
15
    /** @var AccessToken|null */
16
    protected $accessToken;
17
    /** @var AccessToken|null */
18
    protected $refreshToken;
19
20
    /** @var GrantTypeInterface */
21
    protected $grantType;
22
    /** @var RefreshTokenGrantTypeInterface */
23
    protected $refreshTokenGrantType;
24
25
    /**
26
     * Create a new Oauth2 subscriber.
27
     *
28
     * @param GrantTypeInterface             $grantType
29
     * @param RefreshTokenGrantTypeInterface $refreshTokenGrantType
30
     */
31 5
    public function __construct(GrantTypeInterface $grantType = null, RefreshTokenGrantTypeInterface $refreshTokenGrantType = null)
32
    {
33 5
        $this->grantType = $grantType;
34 5
        $this->refreshTokenGrantType = $refreshTokenGrantType;
35 5
    }
36
37
    /**
38
     * @inheritdoc
39
     */
40 4
    public function getEvents()
41
    {
42
        return [
43 4
            'before' => ['onBefore', RequestEvents::SIGN_REQUEST],
44 4
            'error' => ['onError', RequestEvents::EARLY],
45 4
        ];
46
    }
47
48
    /**
49
     * @inheritdoc
50
     */
51 1
    public function onError(ErrorEvent $event)
52
    {
53 1
        $response = $event->getResponse();
54 1
        if ($response && 401 == $response->getStatusCode()) {
55 1
            $request = $event->getRequest();
56 1
            if ($request->getConfig()->get('auth') == 'oauth2' && !$request->getConfig()->get('retried')) {
57 1
                if ($token = $this->acquireAccessToken()) {
58 1
                    $this->accessToken = $token;
59 1
                    $this->refreshToken = $token->getRefreshToken();
60 1
                    $request->getConfig()->set('retried', true);
61 1
                    $event->intercept($event->getClient()->send($request));
62 1
                }
63 1
            }
64 1
        }
65 1
    }
66
67
    /**
68
     * Get a new access token.
69
     *
70
     * @return AccessToken|null
71
     */
72 4
    protected function acquireAccessToken()
73
    {
74 4
        $accessToken = null;
75
76 4
        if ($this->refreshTokenGrantType) {
77
            // Get an access token using the stored refresh token.
78 2
            if ($this->refreshToken) {
79 2
                $this->refreshTokenGrantType->setRefreshToken($this->refreshToken->getToken());
80 2
            }
81 2
            if ($this->refreshTokenGrantType->hasRefreshToken()) {
82 2
                $accessToken = $this->refreshTokenGrantType->getToken();
83 2
            }
84 2
        }
85
86 4
        if (!$accessToken && $this->grantType) {
87
            // Get a new access token.
88 1
            $accessToken = $this->grantType->getToken();
89 1
        }
90
91 4
        return $accessToken ?: null;
92
    }
93
94
    /**
95
     * Add the Authorization header to requests.
96
     *
97
     * @param BeforeEvent $event Event received
98
     */
99 4
    public function onBefore(BeforeEvent $event)
100
    {
101 4
        $request = $event->getRequest();
102 4
        if ($request->getConfig()->get('auth') == 'oauth2') {
103 4
            $token = $this->getAccessToken();
104 4
            if ($token !== null) {
105 4
                $request->setHeader('Authorization', 'Bearer ' . $token->getToken());
106 4
            }
107 4
        }
108 4
    }
109
110
    /**
111
     * Get the access token.
112
     *
113
     * @return AccessToken|null Oauth2 access token
114
     */
115 4
    public function getAccessToken()
116
    {
117 4
        if ($this->accessToken && $this->accessToken->isExpired()) {
118
            // The access token has expired.
119 1
            $this->accessToken = null;
120 1
        }
121
122 4
        if (null === $this->accessToken) {
123
            // Try to acquire a new access token from the server.
124 3
            $this->accessToken = $this->acquireAccessToken();
125 3
            if ($this->accessToken) {
126 2
                $this->refreshToken = $this->accessToken->getRefreshToken();
127 2
            }
128 3
        }
129
130 4
        return $this->accessToken;
131
    }
132
133
    /**
134
     * Get the refresh token.
135
     *
136
     * @return AccessToken|null
137
     */
138 3
    public function getRefreshToken()
139
    {
140 3
        return $this->refreshToken;
141
    }
142
143
    /**
144
     * Set the access token.
145
     *
146
     * @param AccessToken|string $accessToken
147
     * @param string             $type
148
     * @param int                $expires
149
     */
150 2
    public function setAccessToken($accessToken, $type = null, $expires = null)
151
    {
152 2
        if (is_string($accessToken)) {
153 2
            $accessToken = new AccessToken($accessToken, $type, ['expires' => $expires]);
154 2
        } elseif (!$accessToken instanceof AccessToken) {
155
            throw new \InvalidArgumentException('Invalid access token');
156
        }
157 2
        $this->accessToken = $accessToken;
158 2
        $this->refreshToken = $accessToken->getRefreshToken();
159 2
    }
160
161
    /**
162
     * Set the refresh token.
163
     *
164
     * @param AccessToken|string $refreshToken The refresh token
165
     */
166 3
    public function setRefreshToken($refreshToken)
167
    {
168 3
        if (is_string($refreshToken)) {
169 3
            $refreshToken = new AccessToken($refreshToken, 'refresh_token');
170 3
        } elseif (!$refreshToken instanceof AccessToken) {
171
            throw new \InvalidArgumentException('Invalid refresh token');
172
        }
173 3
        $this->refreshToken = $refreshToken;
174 3
    }
175
}
176