OAuth2Middleware::refreshToken()   A
last analyzed

Complexity

Conditions 5
Paths 1

Size

Total Lines 18
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 7
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 18
ccs 7
cts 7
cp 1
crap 5
rs 9.6111
1
<?php
2
/**
3
 * This file is part of graze/gigya-client
4
 *
5
 * Copyright (c) 2016 Nature Delivered Ltd. <https://www.graze.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md
11
 * @link    https://github.com/graze/gigya-client
12
 */
13
14
namespace Graze\Gigya\Auth\OAuth2;
15
16
use Closure;
17
use Psr\Http\Message\RequestInterface;
18
use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface;
19
20
class OAuth2Middleware
21
{
22
    const AUTH_NAME = 'gigya-oauth2';
23
24
    /** @var GrantInterface */
25
    private $grant;
26
    /** @var string|null */
27
    private $name;
28
    /**
29
     * @var callable
30
     */
31
    private $nextHandler;
32
33
    /**
34
     * @param callable       $nextHandler
35
     * @param GrantInterface $grant
36
     * @param string|null    $name
37
     */
38 6
    public function __construct(callable $nextHandler, GrantInterface $grant, $name = null)
39
    {
40 6
        $this->nextHandler = $nextHandler;
41 6
        $this->grant = $grant;
42 6
        $this->name = $name ?: static::AUTH_NAME;
43 6
    }
44
45
    /**
46
     * @param RequestInterface $request
47
     * @param array            $options
48
     *
49
     * @return mixed
50
     */
51 6
    public function __invoke(RequestInterface $request, array $options)
52
    {
53 6
        if ($request->getUri()->getScheme() == 'https' && $options['auth'] == $this->name) {
54 5
            $token = $this->grant->getToken();
55
56 5
            if (!is_null($token)) {
57 4
                $request = $request->withHeader('Authorization', sprintf('OAuth %s', $token->getToken()));
58
            }
59
        }
60
61 6
        $fn = $this->nextHandler;
62
63 6
        return $fn($request, $options)
64 6
            ->then($this->refreshToken($request, $options));
65
    }
66
67
    /**
68
     * @param RequestInterface $request
69
     * @param array            $options
70
     *
71
     * @return Closure A function taking a response and returning a new response|future
72
     */
73 6
    private function refreshToken(RequestInterface $request, array $options)
74
    {
75
        /**
76
         * Take a response and if it requires authentication, retry the request. Otherwise pass through the response
77
         *
78
         * @param GuzzleResponseInterface $response
79
         *
80
         * @return GuzzleResponseInterface
81
         */
82
        return function (GuzzleResponseInterface $response) use ($request, $options) {
83 4
            if ($response->getStatusCode() == 401
84 4
                && $this->canRetry($request, $options)) {
85 2
                if (!is_null($this->grant->getToken())) {
86 1
                    $options['retries'] = (isset($options['retries'])) ? $options['retries'] + 1 : 1;
87 1
                    return $this($request, $options);
88
                }
89
            }
90 4
            return $response;
91 6
        };
92
    }
93
94
    /**
95
     * @param RequestInterface $request
96
     * @param array            $options
97
     *
98
     * @return bool
99
     */
100 4
    private function canRetry(RequestInterface $request, array $options)
101
    {
102 4
        return ($request->getUri()->getScheme() == 'https'
103 4
            && $options['auth'] == $this->name
104 4
            && (!isset($options['retries']) || $options['retries'] === 0));
105
    }
106
107
    /**
108
     * Return a middleware handler function for OAuth2 Authentication
109
     *
110
     * @param GrantInterface $grant
111
     * @param string|null    $name
112
     *
113
     * @return Closure
114
     */
115
    public static function middleware(GrantInterface $grant, $name = null)
116
    {
117 7
        return function (callable $handler) use ($grant, $name) {
118 6
            return new static($handler, $grant, $name);
119 7
        };
120
    }
121
}
122