Completed
Push — master ( 8d6a23...e237a8 )
by Michał
02:07
created

Provider::createIdentity()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
1
<?php namespace nyx\auth\id;
2
3
// External dependencies
4
use Psr\Http\Message\ResponseInterface as Response;
5
use GuzzleHttp\Promise\PromiseInterface as Promise;
6
7
// Internal dependencies
8
use nyx\auth;
9
10
/**
11
 * Identity Provider
12
 *
13
 * @package     Nyx\Auth
14
 * @version     0.1.0
15
 * @author      Michal Chojnacki <[email protected]>
16
 * @copyright   2012-2017 Nyx Dev Team
17
 * @link        https://github.com/unyx/nyx
18
 */
19
abstract class Provider implements interfaces\Provider
20
{
21
    /**
22
     * @var credentials\Client  The credentials used to identify this consumer with the provider.
23
     */
24
    protected $consumer;
25
26
    /**
27
     * @var bool    Whether the Provider should attempt to retrieve the email address of an entity when performing
28
     *              identify calls.
29
     *
30
     *              This is kept as a separate, publicly settable behavioural flag because many Providers make
31
     *              the entity's email address(es) available only with special permission scopes and/or at different
32
     *              endpoints, meaning simple identify() calls which do not rely on the email being available
33
     *              can in those cases be simplified by setting this flag to false.
34
     *
35
     *              Some Identity Providers do not provide the entity's email address(es) under any circumstances,
36
     *              in which case this flag will have no effect.
37
     */
38
    protected $shouldProvideEmailAddress = true;
39
40
    /**
41
     * @var \GuzzleHttp\ClientInterface The underlying HTTP Client used for communicating with the provider.
42
     */
43
    protected $httpClient;
44
45
    /**
46
     * Constructs a new Identity Provider instance tied to the given client/consumer/application Credentials.
47
     *
48
     * @param   credentials\Client  $consumer
49
     */
50
    public function __construct(credentials\Client $consumer)
51
    {
52
        $this->consumer = $consumer;
53
    }
54
55
    /**
56
     * {@inheritDoc}
57
     */
58
    public function getAuthorizeUrl(array $parameters = []) : string
59
    {
60
        return $this->buildUrl(static::URL_AUTHORIZE, $parameters);
61
    }
62
63
    /**
64
     * {@inheritDoc}
65
     */
66
    public function getExchangeUrl() : string
67
    {
68
        return static::URL_EXCHANGE;
69
    }
70
71
    /**
72
     * {@inheritDoc}
73
     */
74
    public function getIdentifyUrl() : string
75
    {
76
        return static::URL_IDENTIFY;
77
    }
78
79
    /**
80
     * Checks whether the Provider should attempt to retrieve the email address of an entity when performing
81
     * identify requests.
82
     *
83
     * @see     $shouldProvideEmailAddress
84
     * @return  bool
85
     */
86
    public function shouldProvideEmailAddress() : bool
87
    {
88
        return $this->shouldProvideEmailAddress;
89
    }
90
91
    /**
92
     * Sets whether the Provider should attempt to retrieve the email address of an entity when performing
93
     * identify requests.
94
     *
95
     * @param   bool    $bool
96
     * @return  $this
97
     */
98
    public function setShouldProvideEmailAddress(bool $bool) : Provider
99
    {
100
        $this->shouldProvideEmailAddress = $bool;
101
102
        return $this;
103
    }
104
105
    /**
106
     * {@inheritDoc}
107
     */
108
    public function request(string $method, string $url, auth\interfaces\Token $token = null, array $options = []) : Promise
109
    {
110
        return $this->getHttpClient()->requestAsync($method, $url, array_merge_recursive($this->getDefaultRequestOptions($token), $options))->then(
111
            function (Response $response) use($token) {
112
                return $this->onRequestSuccess($response, $token);
113
            },
114
            function(\Exception $exception) use($token) {
115
                return $this->onRequestError($exception, $token);
116
            });
117
    }
118
119
    /**
120
     * Success callback for self::request().
121
     *
122
     * Note: Some Providers may return valid HTTP response codes for requests that were actually unsuccessful
123
     * and instead provide arbitrary responses like "ok => false" or "errors => []". Those misbehaving cases should
124
     * be caught within specific Providers.
125
     *
126
     * @param   Response                $response   The Response received to the Request made.
127
     * @param   auth\interfaces\Token   $token      The Token that was used to authorize the Request, if applicable.
128
     * @return  mixed
129
     */
130
    protected function onRequestSuccess(Response $response, auth\interfaces\Token $token = null)
131
    {
132
        return json_decode($response->getBody(), true);
133
    }
134
135
    /**
136
     * Failure callback for self::request().
137
     *
138
     * @param   \Exception              $exception  The Exception that occurred during the Request.
139
     * @param   auth\interfaces\Token   $token      The Token that was used to authorize the Request, if applicable.
140
     * @throws  \Exception                          Always re-throws the Exception. Child classes may, however, provide
141
     *                                              recovery paths.
142
     * @return  mixed
143
     */
144
    protected function onRequestError(\Exception $exception, auth\interfaces\Token $token = null)
0 ignored issues
show
Unused Code introduced by
The parameter $token is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
145
    {
146
        throw $exception;
147
    }
148
149
    /**
150
     * Returns the default options (in a format recognized by Guzzle) for requests made by this Provider.
151
     *
152
     * @param   auth\interfaces\Token   $token      The Token that should be used to authorize the Request.
153
     * @return  array
154
     */
155
    protected function getDefaultRequestOptions(auth\interfaces\Token $token = null) : array
156
    {
157
        return [
158
            'headers' => [
159
                'Accept' => 'application/json'
160
            ]
161
        ];
162
    }
163
164
    /**
165
     * Builds an URL string from the given base URL and optional additional query parameters.
166
     *
167
     * @param   string  $base   The base URL.
168
     * @param   array   $query  Additional query parameters.
169
     * @return  string
170
     */
171
    protected function buildUrl(string $base, array $query = []) : string
172
    {
173
        return empty($query) ? $base : $base.'?'.http_build_query($query, null, '&');
174
    }
175
176
    /**
177
     * Returns the underlying HTTP Client used for communicating with the provider. Lazily instantiates
178
     * a HTTP Client if none is set yet.
179
     *
180
     * @return  \GuzzleHttp\ClientInterface
181
     */
182
    protected function getHttpClient() : \GuzzleHttp\ClientInterface
183
    {
184
        return $this->httpClient ?: $this->httpClient = new \GuzzleHttp\Client();
185
    }
186
187
    /**
188
     * Sets the underlying HTTP Client used for communicating with the provider.
189
     *
190
     * @param   \GuzzleHttp\ClientInterface $client
191
     * @return  $this
192
     */
193
    public function setHttpClient(\GuzzleHttp\ClientInterface $client) : Provider
194
    {
195
        $this->httpClient = $client;
196
197
        return $this;
198
    }
199
200
    /**
201
     * Creates an Identity instance of a type specific to the Provider, using a Token and raw data also
202
     * specific to the Provider.
203
     *
204
     * @param   auth\interfaces\Token   $token  The Token that had been used to retrieve the data about the entity.
205
     * @param   array                   $data   The raw data about the entity given by the Provider.
206
     * @return  interfaces\Identity             The resulting Identity instance.
207
     */
208
    protected function createIdentity(auth\interfaces\Token $token, array $data) : interfaces\Identity
209
    {
210
        $class = static::IDENTITY;
211
212
        return new $class($token, $data);
213
    }
214
}
215