Completed
Push — master ( c55ac1...90a3a7 )
by Gabriel
14:46
created

Bearer::renewAccessToken()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
crap 2
1
<?php
2
/*
3
 * The MIT License (MIT)
4
 *
5
 * Copyright (c) 2016 Gabriel Somoza
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in all
15
 * copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * SOFTWARE.
24
 */
25
26
namespace Somoza\Psr7\OAuth2Middleware;
27
28
use League\OAuth2\Client\Provider\AbstractProvider;
29
use League\OAuth2\Client\Token\AccessToken;
30
use Psr\Http\Message\RequestInterface;
31
32
/**
33
 * Bearer PSR7 Middleware
34
 *
35
 * @author Gabriel Somoza <[email protected]>
36
 */
37
final class Bearer
38
{
39
    const HEADER_AUTHENTICATION = 'Authentication';
40
41
    const AUTHENTICATION_SCHEMA = 'Bearer';
42
43
    /** @var AbstractProvider */
44
    private $provider;
45
46
    /** @var AccessToken */
47
    private $accessToken;
48
49
    /** @var callable */
50
    private $tokenCallback;
51
52
    /**
53
     * @param AbstractProvider $provider An OAuth2 Client Provider.
54
     * @param AccessToken $accessToken Provide an initial (e.g. cached) access token.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $accessToken not be null|AccessToken?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
55
     * @param callable $tokenCallback Will be called with a new AccessToken as a parameter if the AcessToken ever
0 ignored issues
show
Documentation introduced by
Should the type for parameter $tokenCallback not be null|callable?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
56
     *                                needs to be renewed.
57
     */
58 13
    public function __construct(
59
        AbstractProvider $provider,
60
        AccessToken $accessToken = null,
61
        callable $tokenCallback = null
62
    ) {
63 13
        $this->provider = $provider;
64 13
        $this->accessToken = $accessToken;
65 13
        $this->tokenCallback = $tokenCallback;
66 13
    }
67
68
    /**
69
     * __invoke
70
     * @param callable $handler
71
     * @return \Closure
72
     */
73
    public function __invoke(callable $handler)
74
    {
75 2
        return function (RequestInterface $request, array $options) use ($handler) {
76 1
            $request = $this->authenticate($request);
77 1
            return $handler($request, $options);
78 2
        };
79
    }
80
81
    /**
82
     * Authenticate
83
     * @param RequestInterface $request
84
     * @return RequestInterface
85
     */
86 9
    protected function authenticate(RequestInterface $request)
87
    {
88 9
        if ($request->getMethod() !== 'GET'
89 9
            || $request->hasHeader('Authentication')
90 8
            || $request->getUri() == $this->provider->getBaseAuthorizationUrl()
91 9
        ) {
92 3
            return $request;
93
        }
94
95 6
        $this->checkAccessToken();
96
97 6
        return $request->withHeader(
98 6
            self::HEADER_AUTHENTICATION,
99 6
            self::AUTHENTICATION_SCHEMA . ' ' . $this->accessToken->getToken()
100 6
        );
101
    }
102
103
    /**
104
     * checkAccessToken
105
     * @return AccessToken
0 ignored issues
show
Documentation introduced by
Should the return type not be AccessToken|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
106
     */
107 7
    private function checkAccessToken()
108
    {
109 7
        $now = time();
110 7
        if (!$this->accessToken
111 7
            || ($this->accessToken->getExpires() !== null
112 3
                && $this->accessToken->getExpires() - $now <= 0)
113 7
        ) {
114 5
            $this->renewAccessToken();
115 5
        }
116 7
    }
117
118
    /**
119
     * renewAccessToken
120
     * @return void
121
     */
122 5
    private function renewAccessToken()
123
    {
124 5
        $this->accessToken = $this->provider->getAccessToken('client_credentials');
125
126 5
        if ($this->tokenCallback) {
127 1
            call_user_func($this->tokenCallback, $this->accessToken);
128 1
        }
129 5
    }
130
}
131