Completed
Push — master ( d96fc9...95d952 )
by Дмитрий
04:19 queued 34s
created

getAccessTokenByRequestParameters()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 18.42

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 5
cts 13
cp 0.3846
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 13
nc 6
nop 1
crap 18.42
1
<?php
2
/**
3
 * SocialConnect project
4
 * @author: Patsura Dmitry https://github.com/ovr <[email protected]>
5
 */
6
7
namespace SocialConnect\OAuth2;
8
9
use InvalidArgumentException;
10
use SocialConnect\OAuth2\Exception\InvalidState;
11
use SocialConnect\OAuth2\Exception\Unauthorized;
12
use SocialConnect\OAuth2\Exception\UnknownAuthorization;
13
use SocialConnect\OAuth2\Exception\UnknownState;
14
use SocialConnect\Provider\AbstractBaseProvider;
15
use SocialConnect\Provider\Exception\InvalidAccessToken;
16
use SocialConnect\Provider\Exception\InvalidResponse;
17
use SocialConnect\Common\Http\Client\Client;
18
19
abstract class AbstractProvider extends AbstractBaseProvider
20
{
21
    /**
22
     * HTTP method for access token request
23
     *
24
     * @var string
25
     */
26
    protected $requestHttpMethod = Client::POST;
27
28
    /**
29
     * @return string
30
     */
31
    abstract public function getAuthorizeUri();
32
33
    /**
34
     * @return string
35
     */
36
    abstract public function getRequestTokenUri();
37
38
    /**
39
     * Default parameters for auth url, can be redeclared inside implementation of the Provider
40
     *
41
     * @return array
42
     */
43 17
    public function getAuthUrlParameters()
44
    {
45
        return [
46 17
            'client_id' => $this->consumer->getKey(),
47 17
            'redirect_uri' => $this->getRedirectUrl(),
48 17
            'response_type' => 'code',
49 17
        ];
50
    }
51
52
    /**
53
     * @return string
54
     */
55 17
    protected function generateState()
56
    {
57 17
        return md5(
58 17
            time() . mt_rand()
59 17
        );
60
    }
61
62
    /**
63
     * @return string
64
     */
65 17
    public function makeAuthUrl()
66
    {
67 17
        $urlParameters = $this->getAuthUrlParameters();
68
69 17
        $this->session->set(
70 17
            'oauth2_state',
71 17
            $urlParameters['state'] = $this->generateState()
72 17
        );
73
74 17
        if (count($this->scope) > 0) {
75
            $urlParameters['scope'] = $this->getScopeInline();
76
        }
77
78 17
        if (count($this->fields) > 0) {
79
            $urlParameters['fields'] = $this->getFieldsInline();
80
        }
81
82 17
        return $this->getAuthorizeUri() . '?' . http_build_query($urlParameters);
83
    }
84
85
    /**
86
     * Parse access token from response's $body
87
     *
88
     * @param string|bool $body
89
     * @return AccessToken
90
     * @throws InvalidAccessToken
91
     */
92 3
    public function parseToken($body)
93
    {
94 3
        if (empty($body)) {
95
            throw new InvalidAccessToken('Provider response with empty body');
96
        }
97
98 3
        parse_str($body, $token);
99
100 3
        if (!is_array($token) || !isset($token['access_token'])) {
101 2
            throw new InvalidAccessToken('Provider API returned an unexpected response');
102
        }
103
104 1
        return new AccessToken($token);
105
    }
106
107
    /**
108
     * @param string $code
109
     * @return \SocialConnect\Common\Http\Request
110
     */
111 18
    protected function makeAccessTokenRequest($code)
112
    {
113
        $parameters = [
114 18
            'client_id' => $this->consumer->getKey(),
115 18
            'client_secret' => $this->consumer->getSecret(),
116 18
            'code' => $code,
117 18
            'grant_type' => 'authorization_code',
118 18
            'redirect_uri' => $this->getRedirectUrl()
119 18
        ];
120
121 18
        return new \SocialConnect\Common\Http\Request(
122 18
            $this->getRequestTokenUri(),
123 18
            $parameters,
124 18
            $this->requestHttpMethod,
125
            [
126
                'Content-Type' => 'application/x-www-form-urlencoded'
127 18
            ]
128 18
        );
129
    }
130
131
    /**
132
     * @param string $code
133
     * @return AccessToken
134
     * @throws InvalidResponse
135
     */
136 34
    public function getAccessToken($code)
137
    {
138 34
        if (!is_string($code)) {
139 17
            throw new InvalidArgumentException('Parameter $code must be a string');
140
        }
141
142 17
        $response = $this->httpClient->fromRequest(
143 17
            $this->makeAccessTokenRequest($code)
144 17
        );
145
146 17
        if (!$response->isSuccess()) {
147 17
            throw new InvalidResponse(
148 17
                'API response with error code',
149
                $response
150 17
            );
151
        }
152
153
        $body = $response->getBody();
154
        return $this->parseToken($body);
155
    }
156
157
    /**
158
     * @param array $parameters
159
     * @return AccessToken
160
     * @throws \SocialConnect\OAuth2\Exception\InvalidState
161
     * @throws \SocialConnect\OAuth2\Exception\UnknownState
162
     * @throws \SocialConnect\OAuth2\Exception\UnknownAuthorization
163
     */
164 17
    public function getAccessTokenByRequestParameters(array $parameters)
165
    {
166 17
        $state = $this->session->get('oauth2_state');
167 17
        if (!$state) {
168
            throw new UnknownAuthorization();
169
        }
170
171 17
        if (isset($parameters['error']) && $parameters['error'] === 'access_denied') {
172 17
            throw new Unauthorized();
173
        }
174
175
        if (!isset($parameters['state'])) {
176
            throw new UnknownState();
177
        }
178
179
        if ($state !== $parameters['state']) {
180
            throw new InvalidState();
181
        }
182
183
        if (!isset($parameters['code'])) {
184
            throw new Unauthorized('Unknown code');
185
        }
186
187
        return $this->getAccessToken($parameters['code']);
188
    }
189
}
190