Completed
Push — master ( 483eda...cb59ac )
by Дмитрий
03:04
created

AbstractProvider::getAccessToken()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 33
rs 8.8571
cc 3
eloc 20
nc 3
nop 1
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\Auth\AbstractBaseProvider;
11
use SocialConnect\Auth\Provider\Exception\InvalidAccessToken;
12
use SocialConnect\Auth\Provider\Exception\InvalidResponse;
13
use SocialConnect\Common\Entity\User;
14
use SocialConnect\Common\Http\Client\Client;
15
16
abstract class AbstractProvider extends AbstractBaseProvider
17
{
18
    /**
19
     * HTTP method for access token request
20
     *
21
     * @var string
22
     */
23
    protected $requestHttpMethod = Client::POST;
24
25
    /**
26
     * @return string
27
     */
28
    abstract public function getAuthorizeUri();
29
30
    /**
31
     * @return string
32
     */
33
    abstract public function getRequestTokenUri();
34
35
    /**
36
     * Default parameters for auth url, can be redeclared inside implementation of the Provider
37
     *
38
     * @return array
39
     */
40
    public function getAuthUrlParameters()
41
    {
42
        return array(
43
            'client_id' => $this->consumer->getKey(),
44
            'redirect_uri' => $this->getRedirectUrl(),
45
            'response_type' => 'code',
46
        );
47
    }
48
49
    /**
50
     * @return string
51
     */
52
    public function makeAuthUrl()
53
    {
54
        $urlParameters = $this->getAuthUrlParameters();
55
56
        if (count($this->scope) > 0) {
57
            $urlParameters['scope'] = $this->getScopeInline();
58
        }
59
60
        if (count($this->fields) > 0) {
61
            $urlParameters['fields'] = $this->getFieldsInline();
62
        }
63
64
        return $this->getAuthorizeUri() . '?' . http_build_query($urlParameters);
65
    }
66
67
    /**
68
     * Parse access token from response's $body
69
     *
70
     * @param string|bool $body
71
     * @return AccessToken
72
     * @throws InvalidAccessToken
73
     */
74
    public function parseToken($body)
75
    {
76
        if (empty($body)) {
77
            throw new InvalidAccessToken('Provider response with empty body');
78
        }
79
80
        parse_str($body, $token);
81
82
        if (!is_array($token) || !isset($token['access_token'])) {
83
            throw new InvalidAccessToken('Provider API returned an unexpected response');
84
        }
85
86
        return new AccessToken($token['access_token']);
87
    }
88
89
    /**
90
     * @param string $code
91
     * @return AccessToken
92
     * @throws InvalidResponse
93
     */
94
    public function getAccessToken($code)
95
    {
96
        if (!is_string($code)) {
97
            throw new InvalidArgumentException('Parameter $code must be a string');
98
        }
99
100
        $parameters = array(
101
            'client_id' => $this->consumer->getKey(),
102
            'client_secret' => $this->consumer->getSecret(),
103
            'code' => $code,
104
            'grant_type' => 'authorization_code',
105
            'redirect_uri' => $this->getRedirectUrl()
106
        );
107
108
        $response = $this->service->getHttpClient()->request(
109
            $this->getRequestTokenUri(),
110
            $parameters,
111
            $this->requestHttpMethod,
112
            [
113
                'Content-Type' => 'application/x-www-form-urlencoded'
114
            ]
115
        );
116
117
        if (!$response->isSuccess()) {
118
            throw new InvalidResponse(
119
                'API response with error code',
120
                $response
121
            );
122
        }
123
124
        $body = $response->getBody();
125
        return $this->parseToken($body);
126
    }
127
128
129
    /**
130
     * @param array $parameters
131
     * @return AccessToken
132
     */
133
    public function getAccessTokenByRequestParameters(array $parameters)
134
    {
135
        return $this->getAccessToken($parameters['code']);
136
    }
137
138
    /**
139
     * Get current user identity from social network by $accessToken
140
     *
141
     * @param AccessToken $accessToken
142
     * @return User
143
     *
144
     * @throws InvalidResponse
145
     */
146
    abstract public function getIdentity(AccessToken $accessToken);
147
}
148