ReauthenticateMiddleware   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 91.18%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 4
dl 0
loc 118
ccs 31
cts 34
cp 0.9118
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A __invoke() 0 10 1
A isUnauthenticatedResponse() 0 4 1
A reauthenticate() 0 4 1
A handleUnauthenticatedResponse() 0 11 2
A onFulfilled() 0 10 2
A onRejected() 0 16 3
1
<?php
2
3
namespace TreeHouse\Keystone\Client\Middleware;
4
5
use GuzzleHttp\Exception\ClientException;
6
use GuzzleHttp\Promise\PromiseInterface;
7
use GuzzleHttp\Promise\RejectedPromise;
8
use Psr\Http\Message\RequestInterface;
9
use Psr\Http\Message\ResponseInterface;
10
use TreeHouse\Keystone\Client\RequestSigner;
11
12
class ReauthenticateMiddleware
13
{
14
    /**
15
     * @var callable
16
     */
17
    protected $handler;
18
19
    /**
20
     * @var RequestSigner
21
     */
22
    protected $signer;
23
24
    /**
25
     * @param callable      $handler
26
     * @param RequestSigner $signer
27
     */
28 7
    public function __construct(callable $handler, RequestSigner $signer)
29
    {
30 7
        $this->handler = $handler;
31 7
        $this->signer = $signer;
32 7
    }
33
34
    /**
35
     * @param RequestInterface $request
36
     * @param array            $options
37
     *
38
     * @return PromiseInterface
39
     */
40 6
    public function __invoke(RequestInterface $request, array $options)
41
    {
42 6
        $fn = $this->handler;
43
44 6
        return $fn($request, $options)
45 6
            ->then(
46 6
                $this->onFulfilled($request, $options),
47 6
                $this->onRejected($request, $options)
48 6
            );
49
    }
50
51
    /**
52
     * @param ResponseInterface $response
53
     *
54
     * @return bool
55
     */
56 5
    protected function isUnauthenticatedResponse(ResponseInterface $response)
57
    {
58 5
        return in_array($response->getStatusCode(), [401, 403]);
59
    }
60
61
    /**
62
     * @param RequestInterface $request
63
     *
64
     * @return bool
65
     */
66 3
    protected function reauthenticate(RequestInterface $request)
67
    {
68 3
        return $this->signer->signRequest($request, true);
69
    }
70
71
    /**
72
     * @param RequestInterface  $request
73
     * @param ResponseInterface $response
74
     * @param array             $options
75
     *
76
     * @return mixed
77
     */
78 5
    private function handleUnauthenticatedResponse(RequestInterface $request, ResponseInterface $response, array $options)
79
    {
80 5
        if (!$this->isUnauthenticatedResponse($response)) {
81 2
            return null;
82
        }
83
84 3
        $handler = $this->handler;
85 3
        $newRequest = $this->reauthenticate($request);
86
87 2
        return $handler($newRequest, $options);
88
    }
89
90
    /**
91
     * @param RequestInterface $request
92
     * @param array            $options
93
     *
94
     * @return \Closure
95
     */
96 6
    private function onFulfilled(RequestInterface $request, array $options)
97
    {
98
        return function (ResponseInterface $response) use ($request, $options) {
99 2
            if ($next = $this->handleUnauthenticatedResponse($request, $response, $options)) {
100
                return $next;
101
            }
102
103 2
            return $response;
104 6
        };
105
    }
106
107
    /**
108
     * @param RequestInterface $request
109
     * @param array            $options
110
     *
111
     * @return \Closure
112
     */
113
    private function onRejected(RequestInterface $request, array $options)
114
    {
115 6
        return function ($reason) use ($request, $options) {
116 3
            if (!$reason instanceof ClientException) {
117
                return new RejectedPromise($reason);
118
            }
119
120 3
            $response = $reason->getResponse();
121
122 3
            if ($next = $this->handleUnauthenticatedResponse($request, $response, $options)) {
0 ignored issues
show
Bug introduced by
It seems like $response defined by $reason->getResponse() on line 120 can be null; however, TreeHouse\Keystone\Clien...authenticatedResponse() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
123 2
                return $next;
124
            }
125
126
            return new RejectedPromise($reason);
127 6
        };
128
    }
129
}
130