AccessTokenAuthorizationTrait::refreshAndRetry()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 0
cts 15
cp 0
rs 9.6666
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 2
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipboxfactory/patron-salesforce/blob/master/LICENSE
6
 * @link       https://github.com/flipboxfactory/patron-salesforce/
7
 */
8
9
namespace flipbox\patron\salesforce\connections;
10
11
use flipbox\craft\salesforce\helpers\ErrorHelper;
12
use flipbox\patron\records\Token;
13
use Flipbox\Skeleton\Helpers\JsonHelper;
14
use League\OAuth2\Client\Token\AccessTokenInterface;
15
use Psr\Http\Message\RequestInterface;
16
use Psr\Http\Message\ResponseInterface;
17
18
/**
19
 * @author Flipbox Factory <[email protected]>
20
 * @since 1.0.0
21
 */
22
trait AccessTokenAuthorizationTrait
23
{
24
    use AccessTokenTrait;
25
26
    /**
27
     * @param RequestInterface $request
28
     * @return RequestInterface
29
     * @throws \yii\base\InvalidConfigException
30
     */
31
    public function prepareAuthorizationRequest(
32
        RequestInterface $request
33
    ): RequestInterface {
34
        return $this->addAuthorizationHeader($request);
35
    }
36
37
    /**
38
     * @param RequestInterface $request
39
     * @return RequestInterface
40
     * @throws \yii\base\InvalidConfigException
41
     */
42
    protected function addAuthorizationHeader(RequestInterface $request): RequestInterface
43
    {
44
        return $request->withHeader(
45
            'Authorization',
46
            'Bearer ' . (string)$this->getAccessToken()
47
        );
48
    }
49
50
    /**
51
     * @param ResponseInterface $response
52
     * @param RequestInterface $request
53
     * @param callable $runner
54
     * @return ResponseInterface
55
     * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
56
     * @throws \flipbox\craft\ember\exceptions\RecordNotFoundException
57
     * @throws \yii\base\InvalidConfigException
58
     */
59
    public function handleAuthorizationResponse(
60
        ResponseInterface $response,
61
        RequestInterface $request,
62
        callable $runner
63
    ): ResponseInterface {
64
65
        if ($this->responseIsExpiredToken($response)) {
66
            $response = $this->refreshAndRetry(
67
                $request,
68
                $response,
69
                $runner
70
            );
71
        }
72
73
        return $response;
74
    }
75
76
    /**
77
     * @param ResponseInterface $response
78
     * @return bool
79
     */
80
    protected function responseIsExpiredToken(ResponseInterface $response): bool
81
    {
82
        if ($response->getStatusCode() !== 401) {
83
            return false;
84
        }
85
86
        $data = JsonHelper::decodeIfJson(
87
            $response->getBody()->getContents()
88
        );
89
90
        return ErrorHelper::hasSessionExpired($data);
91
    }
92
93
    /**
94
     * @param RequestInterface $request
95
     * @param ResponseInterface $response
96
     * @param callable|null $next
97
     * @return mixed
98
     * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
99
     * @throws \flipbox\craft\ember\exceptions\RecordNotFoundException
100
     * @throws \yii\base\InvalidConfigException
101
     */
102
    protected function refreshAndRetry(RequestInterface $request, ResponseInterface $response, callable $next = null)
103
    {
104
        $refreshToken = $this->getProvider()->getAccessToken('refresh_token', [
105
            'refresh_token' => $this->getAccessToken()->getRefreshToken()
106
        ]);
107
108
        $this->saveRefreshToken(
109
            $this->getAccessToken(),
110
            $refreshToken
111
        );
112
113
        $this->setAccessToken($refreshToken);
114
115
        return $next(
116
            $this->addAuthorizationHeader($request),
117
            $response
118
        );
119
    }
120
121
    /**
122
     * @param AccessTokenInterface $accessToken
123
     * @param AccessTokenInterface $refreshToken
124
     * @return bool
125
     * @throws \flipbox\craft\ember\exceptions\RecordNotFoundException
126
     */
127
    protected function saveRefreshToken(AccessTokenInterface $accessToken, AccessTokenInterface $refreshToken): bool
128
    {
129
        $record = Token::getOne([
130
            'accessToken' => $accessToken->getToken()
131
        ]);
132
        $record->accessToken = $refreshToken->getToken();
133
        return $record->save();
134
    }
135
}
136