Completed
Push — master ( 20a8a3...23113a )
by Дмитрий
03:35
created

AbstractProvider   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 66.67%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 8
dl 0
loc 137
ccs 34
cts 51
cp 0.6667
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
getAuthorizeUri() 0 1 ?
getRequestTokenUri() 0 1 ?
A getAuthUrlParameters() 0 8 1
A makeAuthUrl() 0 18 4
A parseToken() 0 14 4
A makeAccessTokenRequest() 0 19 1
A getAccessToken() 0 20 3
A getAccessTokenByRequestParameters() 0 4 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\Provider\AbstractBaseProvider;
11
use SocialConnect\Provider\Exception\InvalidAccessToken;
12
use SocialConnect\Provider\Exception\InvalidResponse;
13
use SocialConnect\Common\Http\Client\Client;
14
15
abstract class AbstractProvider extends AbstractBaseProvider
16
{
17
    /**
18
     * HTTP method for access token request
19
     *
20
     * @var string
21
     */
22
    protected $requestHttpMethod = Client::POST;
23
24
    /**
25
     * @return string
26
     */
27
    abstract public function getAuthorizeUri();
28
29
    /**
30
     * @return string
31
     */
32
    abstract public function getRequestTokenUri();
33
34
    /**
35
     * Default parameters for auth url, can be redeclared inside implementation of the Provider
36
     *
37
     * @return array
38
     */
39 1
    public function getAuthUrlParameters()
40
    {
41
        return [
42 1
            'client_id' => $this->consumer->getKey(),
43 1
            'redirect_uri' => $this->getRedirectUrl(),
44 1
            'response_type' => 'code',
45 1
        ];
46
    }
47
48
    /**
49
     * @return string
50
     */
51 1
    public function makeAuthUrl()
52
    {
53 1
        $urlParameters = $this->getAuthUrlParameters();
54
55 1
        if ($this->state) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->state of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
56
            $urlParameters['state'] = $this->state;
57
        }
58
59 1
        if (count($this->scope) > 0) {
60
            $urlParameters['scope'] = $this->getScopeInline();
61
        }
62
63 1
        if (count($this->fields) > 0) {
64
            $urlParameters['fields'] = $this->getFieldsInline();
65
        }
66
67 1
        return $this->getAuthorizeUri() . '?' . http_build_query($urlParameters);
68
    }
69
70
    /**
71
     * Parse access token from response's $body
72
     *
73
     * @param string|bool $body
74
     * @return AccessToken
75
     * @throws InvalidAccessToken
76
     */
77
    public function parseToken($body)
78
    {
79
        if (empty($body)) {
80
            throw new InvalidAccessToken('Provider response with empty body');
81
        }
82
83
        parse_str($body, $token);
84
85
        if (!is_array($token) || !isset($token['access_token'])) {
86
            throw new InvalidAccessToken('Provider API returned an unexpected response');
87
        }
88
89
        return new AccessToken($token);
90
    }
91
92
    /**
93
     * @param string $code
94
     * @return \SocialConnect\Common\Http\Request
95
     */
96 2
    protected function makeAccessTokenRequest($code)
97
    {
98
        $parameters = [
99 2
            'client_id' => $this->consumer->getKey(),
100 2
            'client_secret' => $this->consumer->getSecret(),
101 2
            'code' => $code,
102 2
            'grant_type' => 'authorization_code',
103 2
            'redirect_uri' => $this->getRedirectUrl()
104 2
        ];
105
106 2
        return new \SocialConnect\Common\Http\Request(
107 2
            $this->getRequestTokenUri(),
108 2
            $parameters,
109 2
            $this->requestHttpMethod,
110
            [
111
                'Content-Type' => 'application/x-www-form-urlencoded'
112 2
            ]
113 2
        );
114
    }
115
116
    /**
117
     * @param string $code
118
     * @return AccessToken
119
     * @throws InvalidResponse
120
     */
121 2
    public function getAccessToken($code)
122
    {
123 2
        if (!is_string($code)) {
124 1
            throw new InvalidArgumentException('Parameter $code must be a string');
125
        }
126
127 1
        $response = $this->httpClient->fromRequest(
128 1
            $this->makeAccessTokenRequest($code)
129 1
        );
130
131 1
        if (!$response->isSuccess()) {
132 1
            throw new InvalidResponse(
133 1
                'API response with error code',
134
                $response
135 1
            );
136
        }
137
138
        $body = $response->getBody();
139
        return $this->parseToken($body);
140
    }
141
142
143
    /**
144
     * @param array $parameters
145
     * @return AccessToken
146
     */
147
    public function getAccessTokenByRequestParameters(array $parameters)
148
    {
149
        return $this->getAccessToken($parameters['code']);
150
    }
151
}
152