Passed
Push — master ( bd5724...8a312b )
by
unknown
01:47
created
src/Provider/Twitter.php 2 patches
Indentation   +221 added lines, -221 removed lines patch added patch discarded remove patch
@@ -40,225 +40,225 @@
 block discarded – undo
40 40
  */
41 41
 class Twitter extends OAuth1
42 42
 {
43
-    /**
44
-     * {@inheritdoc}
45
-     */
46
-    protected $apiBaseUrl = 'https://api.twitter.com/1.1/';
47
-
48
-    /**
49
-     * {@inheritdoc}
50
-     */
51
-    protected $authorizeUrl = 'https://api.twitter.com/oauth/authenticate';
52
-
53
-    /**
54
-     * {@inheritdoc}
55
-     */
56
-    protected $requestTokenUrl = 'https://api.twitter.com/oauth/request_token';
57
-
58
-    /**
59
-     * {@inheritdoc}
60
-     */
61
-    protected $accessTokenUrl = 'https://api.twitter.com/oauth/access_token';
62
-
63
-    /**
64
-     * {@inheritdoc}
65
-     */
66
-    protected $apiDocumentation = 'https://dev.twitter.com/web/sign-in/implementing';
67
-
68
-    /**
69
-     * {@inheritdoc}
70
-     */
71
-    protected function getAuthorizeUrl($parameters = [])
72
-    {
73
-        if ($this->config->get('authorize') === true) {
74
-            $this->authorizeUrl = 'https://api.twitter.com/oauth/authorize';
75
-        }
76
-
77
-        return parent::getAuthorizeUrl($parameters);
78
-    }
79
-
80
-    /**
81
-     * {@inheritdoc}
82
-     */
83
-    public function getUserProfile()
84
-    {
85
-        $response = $this->apiRequest('account/verify_credentials.json', 'GET', [
86
-            'include_email' => $this->config->get('include_email') === false ? 'false' : 'true',
87
-        ]);
88
-
89
-        $data = new Data\Collection($response);
90
-
91
-        if (!$data->exists('id_str')) {
92
-            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
93
-        }
94
-
95
-        $userProfile = new User\Profile();
96
-
97
-        $userProfile->identifier = $data->get('id_str');
98
-        $userProfile->displayName = $data->get('screen_name');
99
-        $userProfile->description = $data->get('description');
100
-        $userProfile->firstName = $data->get('name');
101
-        $userProfile->email = $data->get('email');
102
-        $userProfile->emailVerified = $data->get('email');
103
-        $userProfile->webSiteURL = $data->get('url');
104
-        $userProfile->region = $data->get('location');
105
-
106
-        $userProfile->profileURL = $data->exists('screen_name')
107
-            ? ('https://twitter.com/' . $data->get('screen_name'))
108
-            : '';
109
-
110
-        $photoSize = $this->config->get('photo_size') ?: 'original';
111
-        $photoSize = $photoSize === 'original' ? '' : "_{$photoSize}";
112
-        $userProfile->photoURL = $data->exists('profile_image_url_https')
113
-            ? str_replace('_normal', $photoSize, $data->get('profile_image_url_https'))
114
-            : '';
115
-
116
-        $userProfile->data = [
117
-            'followed_by' => $data->get('followers_count'),
118
-            'follows' => $data->get('friends_count'),
119
-        ];
120
-
121
-        return $userProfile;
122
-    }
123
-
124
-    /**
125
-     * {@inheritdoc}
126
-     */
127
-    public function getUserContacts($parameters = [])
128
-    {
129
-        $parameters = ['cursor' => '-1'] + $parameters;
130
-
131
-        $response = $this->apiRequest('friends/ids.json', 'GET', $parameters);
132
-
133
-        $data = new Data\Collection($response);
134
-
135
-        if (!$data->exists('ids')) {
136
-            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
137
-        }
138
-
139
-        if ($data->filter('ids')->isEmpty()) {
140
-            return [];
141
-        }
142
-
143
-        $contacts = [];
144
-
145
-        // 75 id per time should be okey
146
-        $contactsIds = array_chunk((array)$data->get('ids'), 75);
147
-
148
-        foreach ($contactsIds as $chunk) {
149
-            $parameters = ['user_id' => implode(',', $chunk)];
150
-
151
-            try {
152
-                $response = $this->apiRequest('users/lookup.json', 'GET', $parameters);
153
-
154
-                if ($response && count($response)) {
155
-                    foreach ($response as $item) {
156
-                        $contacts[] = $this->fetchUserContact($item);
157
-                    }
158
-                }
159
-            } catch (\Exception $e) {
160
-                continue;
161
-            }
162
-        }
163
-
164
-        return $contacts;
165
-    }
166
-
167
-    /**
168
-     * @param $item
169
-     *
170
-     * @return User\Contact
171
-     */
172
-    protected function fetchUserContact($item)
173
-    {
174
-        $item = new Data\Collection($item);
175
-
176
-        $userContact = new User\Contact();
177
-
178
-        $userContact->identifier = $item->get('id_str');
179
-        $userContact->displayName = $item->get('name');
180
-        $userContact->photoURL = $item->get('profile_image_url');
181
-        $userContact->description = $item->get('description');
182
-
183
-        $userContact->profileURL = $item->exists('screen_name')
184
-            ? ('https://twitter.com/' . $item->get('screen_name'))
185
-            : '';
186
-
187
-        return $userContact;
188
-    }
189
-
190
-    /**
191
-     * {@inheritdoc}
192
-     */
193
-    public function setUserStatus($status)
194
-    {
195
-        if (is_string($status)) {
196
-            $status = ['status' => $status];
197
-        }
198
-
199
-        // Prepare request parameters.
200
-        $params = [];
201
-        if (isset($status['status'])) {
202
-            $params['status'] = $status['status'];
203
-        }
204
-        if (isset($status['picture'])) {
205
-            $media = $this->apiRequest('https://upload.twitter.com/1.1/media/upload.json', 'POST', [
206
-                'media' => base64_encode(file_get_contents($status['picture'])),
207
-            ]);
208
-            $params['media_ids'] = $media->media_id;
209
-        }
210
-
211
-        $response = $this->apiRequest('statuses/update.json', 'POST', $params);
212
-
213
-        return $response;
214
-    }
215
-
216
-    /**
217
-     * {@inheritdoc}
218
-     */
219
-    public function getUserActivity($stream = 'me')
220
-    {
221
-        $apiUrl = ($stream == 'me')
222
-            ? 'statuses/user_timeline.json'
223
-            : 'statuses/home_timeline.json';
224
-
225
-        $response = $this->apiRequest($apiUrl);
226
-
227
-        if (!$response) {
228
-            return [];
229
-        }
230
-
231
-        $activities = [];
232
-
233
-        foreach ($response as $item) {
234
-            $activities[] = $this->fetchUserActivity($item);
235
-        }
236
-
237
-        return $activities;
238
-    }
239
-
240
-    /**
241
-     * @param $item
242
-     * @return User\Activity
243
-     */
244
-    protected function fetchUserActivity($item)
245
-    {
246
-        $item = new Data\Collection($item);
247
-
248
-        $userActivity = new User\Activity();
249
-
250
-        $userActivity->id = $item->get('id_str');
251
-        $userActivity->date = $item->get('created_at');
252
-        $userActivity->text = $item->get('text');
253
-
254
-        $userActivity->user->identifier = $item->filter('user')->get('id_str');
255
-        $userActivity->user->displayName = $item->filter('user')->get('name');
256
-        $userActivity->user->photoURL = $item->filter('user')->get('profile_image_url');
257
-
258
-        $userActivity->user->profileURL = $item->filter('user')->get('screen_name')
259
-            ? ('https://twitter.com/' . $item->filter('user')->get('screen_name'))
260
-            : '';
261
-
262
-        return $userActivity;
263
-    }
43
+	/**
44
+	 * {@inheritdoc}
45
+	 */
46
+	protected $apiBaseUrl = 'https://api.twitter.com/1.1/';
47
+
48
+	/**
49
+	 * {@inheritdoc}
50
+	 */
51
+	protected $authorizeUrl = 'https://api.twitter.com/oauth/authenticate';
52
+
53
+	/**
54
+	 * {@inheritdoc}
55
+	 */
56
+	protected $requestTokenUrl = 'https://api.twitter.com/oauth/request_token';
57
+
58
+	/**
59
+	 * {@inheritdoc}
60
+	 */
61
+	protected $accessTokenUrl = 'https://api.twitter.com/oauth/access_token';
62
+
63
+	/**
64
+	 * {@inheritdoc}
65
+	 */
66
+	protected $apiDocumentation = 'https://dev.twitter.com/web/sign-in/implementing';
67
+
68
+	/**
69
+	 * {@inheritdoc}
70
+	 */
71
+	protected function getAuthorizeUrl($parameters = [])
72
+	{
73
+		if ($this->config->get('authorize') === true) {
74
+			$this->authorizeUrl = 'https://api.twitter.com/oauth/authorize';
75
+		}
76
+
77
+		return parent::getAuthorizeUrl($parameters);
78
+	}
79
+
80
+	/**
81
+	 * {@inheritdoc}
82
+	 */
83
+	public function getUserProfile()
84
+	{
85
+		$response = $this->apiRequest('account/verify_credentials.json', 'GET', [
86
+			'include_email' => $this->config->get('include_email') === false ? 'false' : 'true',
87
+		]);
88
+
89
+		$data = new Data\Collection($response);
90
+
91
+		if (!$data->exists('id_str')) {
92
+			throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
93
+		}
94
+
95
+		$userProfile = new User\Profile();
96
+
97
+		$userProfile->identifier = $data->get('id_str');
98
+		$userProfile->displayName = $data->get('screen_name');
99
+		$userProfile->description = $data->get('description');
100
+		$userProfile->firstName = $data->get('name');
101
+		$userProfile->email = $data->get('email');
102
+		$userProfile->emailVerified = $data->get('email');
103
+		$userProfile->webSiteURL = $data->get('url');
104
+		$userProfile->region = $data->get('location');
105
+
106
+		$userProfile->profileURL = $data->exists('screen_name')
107
+			? ('https://twitter.com/' . $data->get('screen_name'))
108
+			: '';
109
+
110
+		$photoSize = $this->config->get('photo_size') ?: 'original';
111
+		$photoSize = $photoSize === 'original' ? '' : "_{$photoSize}";
112
+		$userProfile->photoURL = $data->exists('profile_image_url_https')
113
+			? str_replace('_normal', $photoSize, $data->get('profile_image_url_https'))
114
+			: '';
115
+
116
+		$userProfile->data = [
117
+			'followed_by' => $data->get('followers_count'),
118
+			'follows' => $data->get('friends_count'),
119
+		];
120
+
121
+		return $userProfile;
122
+	}
123
+
124
+	/**
125
+	 * {@inheritdoc}
126
+	 */
127
+	public function getUserContacts($parameters = [])
128
+	{
129
+		$parameters = ['cursor' => '-1'] + $parameters;
130
+
131
+		$response = $this->apiRequest('friends/ids.json', 'GET', $parameters);
132
+
133
+		$data = new Data\Collection($response);
134
+
135
+		if (!$data->exists('ids')) {
136
+			throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
137
+		}
138
+
139
+		if ($data->filter('ids')->isEmpty()) {
140
+			return [];
141
+		}
142
+
143
+		$contacts = [];
144
+
145
+		// 75 id per time should be okey
146
+		$contactsIds = array_chunk((array)$data->get('ids'), 75);
147
+
148
+		foreach ($contactsIds as $chunk) {
149
+			$parameters = ['user_id' => implode(',', $chunk)];
150
+
151
+			try {
152
+				$response = $this->apiRequest('users/lookup.json', 'GET', $parameters);
153
+
154
+				if ($response && count($response)) {
155
+					foreach ($response as $item) {
156
+						$contacts[] = $this->fetchUserContact($item);
157
+					}
158
+				}
159
+			} catch (\Exception $e) {
160
+				continue;
161
+			}
162
+		}
163
+
164
+		return $contacts;
165
+	}
166
+
167
+	/**
168
+	 * @param $item
169
+	 *
170
+	 * @return User\Contact
171
+	 */
172
+	protected function fetchUserContact($item)
173
+	{
174
+		$item = new Data\Collection($item);
175
+
176
+		$userContact = new User\Contact();
177
+
178
+		$userContact->identifier = $item->get('id_str');
179
+		$userContact->displayName = $item->get('name');
180
+		$userContact->photoURL = $item->get('profile_image_url');
181
+		$userContact->description = $item->get('description');
182
+
183
+		$userContact->profileURL = $item->exists('screen_name')
184
+			? ('https://twitter.com/' . $item->get('screen_name'))
185
+			: '';
186
+
187
+		return $userContact;
188
+	}
189
+
190
+	/**
191
+	 * {@inheritdoc}
192
+	 */
193
+	public function setUserStatus($status)
194
+	{
195
+		if (is_string($status)) {
196
+			$status = ['status' => $status];
197
+		}
198
+
199
+		// Prepare request parameters.
200
+		$params = [];
201
+		if (isset($status['status'])) {
202
+			$params['status'] = $status['status'];
203
+		}
204
+		if (isset($status['picture'])) {
205
+			$media = $this->apiRequest('https://upload.twitter.com/1.1/media/upload.json', 'POST', [
206
+				'media' => base64_encode(file_get_contents($status['picture'])),
207
+			]);
208
+			$params['media_ids'] = $media->media_id;
209
+		}
210
+
211
+		$response = $this->apiRequest('statuses/update.json', 'POST', $params);
212
+
213
+		return $response;
214
+	}
215
+
216
+	/**
217
+	 * {@inheritdoc}
218
+	 */
219
+	public function getUserActivity($stream = 'me')
220
+	{
221
+		$apiUrl = ($stream == 'me')
222
+			? 'statuses/user_timeline.json'
223
+			: 'statuses/home_timeline.json';
224
+
225
+		$response = $this->apiRequest($apiUrl);
226
+
227
+		if (!$response) {
228
+			return [];
229
+		}
230
+
231
+		$activities = [];
232
+
233
+		foreach ($response as $item) {
234
+			$activities[] = $this->fetchUserActivity($item);
235
+		}
236
+
237
+		return $activities;
238
+	}
239
+
240
+	/**
241
+	 * @param $item
242
+	 * @return User\Activity
243
+	 */
244
+	protected function fetchUserActivity($item)
245
+	{
246
+		$item = new Data\Collection($item);
247
+
248
+		$userActivity = new User\Activity();
249
+
250
+		$userActivity->id = $item->get('id_str');
251
+		$userActivity->date = $item->get('created_at');
252
+		$userActivity->text = $item->get('text');
253
+
254
+		$userActivity->user->identifier = $item->filter('user')->get('id_str');
255
+		$userActivity->user->displayName = $item->filter('user')->get('name');
256
+		$userActivity->user->photoURL = $item->filter('user')->get('profile_image_url');
257
+
258
+		$userActivity->user->profileURL = $item->filter('user')->get('screen_name')
259
+			? ('https://twitter.com/' . $item->filter('user')->get('screen_name'))
260
+			: '';
261
+
262
+		return $userActivity;
263
+	}
264 264
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -88,7 +88,7 @@  discard block
 block discarded – undo
88 88
 
89 89
         $data = new Data\Collection($response);
90 90
 
91
-        if (!$data->exists('id_str')) {
91
+        if ( ! $data->exists('id_str')) {
92 92
             throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
93 93
         }
94 94
 
@@ -104,7 +104,7 @@  discard block
 block discarded – undo
104 104
         $userProfile->region = $data->get('location');
105 105
 
106 106
         $userProfile->profileURL = $data->exists('screen_name')
107
-            ? ('https://twitter.com/' . $data->get('screen_name'))
107
+            ? ('https://twitter.com/'.$data->get('screen_name'))
108 108
             : '';
109 109
 
110 110
         $photoSize = $this->config->get('photo_size') ?: 'original';
@@ -132,7 +132,7 @@  discard block
 block discarded – undo
132 132
 
133 133
         $data = new Data\Collection($response);
134 134
 
135
-        if (!$data->exists('ids')) {
135
+        if ( ! $data->exists('ids')) {
136 136
             throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
137 137
         }
138 138
 
@@ -143,7 +143,7 @@  discard block
 block discarded – undo
143 143
         $contacts = [];
144 144
 
145 145
         // 75 id per time should be okey
146
-        $contactsIds = array_chunk((array)$data->get('ids'), 75);
146
+        $contactsIds = array_chunk((array) $data->get('ids'), 75);
147 147
 
148 148
         foreach ($contactsIds as $chunk) {
149 149
             $parameters = ['user_id' => implode(',', $chunk)];
@@ -181,7 +181,7 @@  discard block
 block discarded – undo
181 181
         $userContact->description = $item->get('description');
182 182
 
183 183
         $userContact->profileURL = $item->exists('screen_name')
184
-            ? ('https://twitter.com/' . $item->get('screen_name'))
184
+            ? ('https://twitter.com/'.$item->get('screen_name'))
185 185
             : '';
186 186
 
187 187
         return $userContact;
@@ -224,7 +224,7 @@  discard block
 block discarded – undo
224 224
 
225 225
         $response = $this->apiRequest($apiUrl);
226 226
 
227
-        if (!$response) {
227
+        if ( ! $response) {
228 228
             return [];
229 229
         }
230 230
 
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
         $userActivity->user->photoURL = $item->filter('user')->get('profile_image_url');
257 257
 
258 258
         $userActivity->user->profileURL = $item->filter('user')->get('screen_name')
259
-            ? ('https://twitter.com/' . $item->filter('user')->get('screen_name'))
259
+            ? ('https://twitter.com/'.$item->filter('user')->get('screen_name'))
260 260
             : '';
261 261
 
262 262
         return $userActivity;
Please login to merge, or discard this patch.
src/Provider/Keycloak.php 2 patches
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -48,24 +48,24 @@  discard block
 block discarded – undo
48 48
     {
49 49
         parent::configure();
50 50
 
51
-        if (!$this->config->exists('url')) {
51
+        if ( ! $this->config->exists('url')) {
52 52
             throw new InvalidApplicationCredentialsException(
53 53
                 'You must define a provider url'
54 54
             );
55 55
         }
56 56
         $url = $this->config->get('url');
57 57
 
58
-        if (!$this->config->exists('realm')) {
58
+        if ( ! $this->config->exists('realm')) {
59 59
             throw new InvalidApplicationCredentialsException(
60 60
                 'You must define a realm'
61 61
             );
62 62
         }
63 63
         $realm = $this->config->get('realm');
64 64
 
65
-        $this->apiBaseUrl = $url . '/realms/' . $realm . '/protocol/openid-connect/';
65
+        $this->apiBaseUrl = $url.'/realms/'.$realm.'/protocol/openid-connect/';
66 66
 
67
-        $this->authorizeUrl = $this->apiBaseUrl . 'auth';
68
-        $this->accessTokenUrl = $this->apiBaseUrl . 'token';
67
+        $this->authorizeUrl = $this->apiBaseUrl.'auth';
68
+        $this->accessTokenUrl = $this->apiBaseUrl.'token';
69 69
 
70 70
     }
71 71
 
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
 
79 79
         $data = new Data\Collection($response);
80 80
 
81
-        if (!$data->exists('sub')) {
81
+        if ( ! $data->exists('sub')) {
82 82
             throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
83 83
         }
84 84
 
Please login to merge, or discard this patch.
Indentation   +68 added lines, -68 removed lines patch added patch discarded remove patch
@@ -31,72 +31,72 @@
 block discarded – undo
31 31
 class Keycloak extends OAuth2
32 32
 {
33 33
 
34
-    /**
35
-     * {@inheritdoc}
36
-     */
37
-    public $scope = 'openid profile email';
38
-
39
-    /**
40
-     * {@inheritdoc}
41
-     */
42
-    protected $apiDocumentation = 'https://www.keycloak.org/docs/latest/securing_apps/#_oidc';
43
-
44
-    /**
45
-     * {@inheritdoc}
46
-     */
47
-    protected function configure()
48
-    {
49
-        parent::configure();
50
-
51
-        if (!$this->config->exists('url')) {
52
-            throw new InvalidApplicationCredentialsException(
53
-                'You must define a provider url'
54
-            );
55
-        }
56
-        $url = $this->config->get('url');
57
-
58
-        if (!$this->config->exists('realm')) {
59
-            throw new InvalidApplicationCredentialsException(
60
-                'You must define a realm'
61
-            );
62
-        }
63
-        $realm = $this->config->get('realm');
64
-
65
-        $this->apiBaseUrl = $url . '/realms/' . $realm . '/protocol/openid-connect/';
66
-
67
-        $this->authorizeUrl = $this->apiBaseUrl . 'auth';
68
-        $this->accessTokenUrl = $this->apiBaseUrl . 'token';
69
-
70
-    }
71
-
72
-    /**
73
-     * {@inheritdoc}
74
-     */
75
-    public function getUserProfile()
76
-    {
77
-        $response = $this->apiRequest('userinfo');
78
-
79
-        $data = new Data\Collection($response);
80
-
81
-        if (!$data->exists('sub')) {
82
-            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
83
-        }
84
-
85
-        $userProfile = new User\Profile();
86
-
87
-        $userProfile->identifier = $data->get('sub');
88
-        $userProfile->displayName = $data->get('preferred_username');
89
-        $userProfile->email = $data->get('email');
90
-        $userProfile->firstName = $data->get('given_name');
91
-        $userProfile->lastName = $data->get('family_name');
92
-        $userProfile->emailVerified = $data->get('email_verified');
93
-
94
-        // Collect organization claim if provided in the IDToken
95
-        if ($data->exists('organization')) {
96
-            $kc_orgs = array_keys((array) $data->get('organization'));
97
-            $userProfile->data['organization'] = array_shift($kc_orgs); //Get the first key
98
-        }
99
-
100
-        return $userProfile;
101
-    }
34
+	/**
35
+	 * {@inheritdoc}
36
+	 */
37
+	public $scope = 'openid profile email';
38
+
39
+	/**
40
+	 * {@inheritdoc}
41
+	 */
42
+	protected $apiDocumentation = 'https://www.keycloak.org/docs/latest/securing_apps/#_oidc';
43
+
44
+	/**
45
+	 * {@inheritdoc}
46
+	 */
47
+	protected function configure()
48
+	{
49
+		parent::configure();
50
+
51
+		if (!$this->config->exists('url')) {
52
+			throw new InvalidApplicationCredentialsException(
53
+				'You must define a provider url'
54
+			);
55
+		}
56
+		$url = $this->config->get('url');
57
+
58
+		if (!$this->config->exists('realm')) {
59
+			throw new InvalidApplicationCredentialsException(
60
+				'You must define a realm'
61
+			);
62
+		}
63
+		$realm = $this->config->get('realm');
64
+
65
+		$this->apiBaseUrl = $url . '/realms/' . $realm . '/protocol/openid-connect/';
66
+
67
+		$this->authorizeUrl = $this->apiBaseUrl . 'auth';
68
+		$this->accessTokenUrl = $this->apiBaseUrl . 'token';
69
+
70
+	}
71
+
72
+	/**
73
+	 * {@inheritdoc}
74
+	 */
75
+	public function getUserProfile()
76
+	{
77
+		$response = $this->apiRequest('userinfo');
78
+
79
+		$data = new Data\Collection($response);
80
+
81
+		if (!$data->exists('sub')) {
82
+			throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
83
+		}
84
+
85
+		$userProfile = new User\Profile();
86
+
87
+		$userProfile->identifier = $data->get('sub');
88
+		$userProfile->displayName = $data->get('preferred_username');
89
+		$userProfile->email = $data->get('email');
90
+		$userProfile->firstName = $data->get('given_name');
91
+		$userProfile->lastName = $data->get('family_name');
92
+		$userProfile->emailVerified = $data->get('email_verified');
93
+
94
+		// Collect organization claim if provided in the IDToken
95
+		if ($data->exists('organization')) {
96
+			$kc_orgs = array_keys((array) $data->get('organization'));
97
+			$userProfile->data['organization'] = array_shift($kc_orgs); //Get the first key
98
+		}
99
+
100
+		return $userProfile;
101
+	}
102 102
 }
Please login to merge, or discard this patch.
src/Data/Collection.php 2 patches
Indentation   +139 added lines, -139 removed lines patch added patch discarded remove patch
@@ -12,143 +12,143 @@
 block discarded – undo
12 12
  */
13 13
 final class Collection
14 14
 {
15
-    /**
16
-     * Data collection
17
-     *
18
-     * @var mixed
19
-     */
20
-    protected $collection = null;
21
-
22
-    /**
23
-     * @param mixed $data
24
-     */
25
-    public function __construct($data = null)
26
-    {
27
-        $this->collection = (object)$data;
28
-    }
29
-
30
-    /**
31
-     * Retrieves the whole collection as array
32
-     *
33
-     * @return mixed
34
-     */
35
-    public function toArray()
36
-    {
37
-        return (array)$this->collection;
38
-    }
39
-
40
-    /**
41
-     * Retrieves an item
42
-     *
43
-     * @param $property
44
-     *
45
-     * @return mixed
46
-     */
47
-    public function get($property)
48
-    {
49
-        if ($this->exists($property)) {
50
-            return $this->collection->$property;
51
-        }
52
-
53
-        return null;
54
-    }
55
-
56
-    /**
57
-     * Add or update an item
58
-     *
59
-     * @param $property
60
-     * @param mixed $value
61
-     */
62
-    public function set($property, $value)
63
-    {
64
-        if ($property) {
65
-            $this->collection->$property = $value;
66
-        }
67
-    }
68
-
69
-    /**
70
-     * .. until I come with a better name..
71
-     *
72
-     * @param $property
73
-     *
74
-     * @return Collection
75
-     */
76
-    public function filter($property)
77
-    {
78
-        if ($this->exists($property)) {
79
-            $data = $this->get($property);
80
-
81
-            if (!is_a($data, 'Collection')) {
82
-                $data = new Collection($data);
83
-            }
84
-
85
-            return $data;
86
-        }
87
-
88
-        return new Collection([]);
89
-    }
90
-
91
-    /**
92
-     * Checks whether an item within the collection
93
-     *
94
-     * @param $property
95
-     *
96
-     * @return bool
97
-     */
98
-    public function exists($property)
99
-    {
100
-        return property_exists($this->collection, $property);
101
-    }
102
-
103
-    /**
104
-     * Finds whether the collection is empty
105
-     *
106
-     * @return bool
107
-     */
108
-    public function isEmpty()
109
-    {
110
-        return !(bool)$this->count();
111
-    }
112
-
113
-    /**
114
-     * Count all items in collection
115
-     *
116
-     * @return int
117
-     */
118
-    public function count()
119
-    {
120
-        return count($this->properties());
121
-    }
122
-
123
-    /**
124
-     * Returns all items properties names
125
-     *
126
-     * @return array
127
-     */
128
-    public function properties()
129
-    {
130
-        $properties = [];
131
-
132
-        foreach ($this->collection as $key => $value) {
133
-            $properties[] = $key;
134
-        }
135
-
136
-        return $properties;
137
-    }
138
-
139
-    /**
140
-     * Returns all items values
141
-     *
142
-     * @return array
143
-     */
144
-    public function values()
145
-    {
146
-        $values = [];
147
-
148
-        foreach ($this->collection as $value) {
149
-            $values[] = $value;
150
-        }
151
-
152
-        return $values;
153
-    }
15
+	/**
16
+	 * Data collection
17
+	 *
18
+	 * @var mixed
19
+	 */
20
+	protected $collection = null;
21
+
22
+	/**
23
+	 * @param mixed $data
24
+	 */
25
+	public function __construct($data = null)
26
+	{
27
+		$this->collection = (object)$data;
28
+	}
29
+
30
+	/**
31
+	 * Retrieves the whole collection as array
32
+	 *
33
+	 * @return mixed
34
+	 */
35
+	public function toArray()
36
+	{
37
+		return (array)$this->collection;
38
+	}
39
+
40
+	/**
41
+	 * Retrieves an item
42
+	 *
43
+	 * @param $property
44
+	 *
45
+	 * @return mixed
46
+	 */
47
+	public function get($property)
48
+	{
49
+		if ($this->exists($property)) {
50
+			return $this->collection->$property;
51
+		}
52
+
53
+		return null;
54
+	}
55
+
56
+	/**
57
+	 * Add or update an item
58
+	 *
59
+	 * @param $property
60
+	 * @param mixed $value
61
+	 */
62
+	public function set($property, $value)
63
+	{
64
+		if ($property) {
65
+			$this->collection->$property = $value;
66
+		}
67
+	}
68
+
69
+	/**
70
+	 * .. until I come with a better name..
71
+	 *
72
+	 * @param $property
73
+	 *
74
+	 * @return Collection
75
+	 */
76
+	public function filter($property)
77
+	{
78
+		if ($this->exists($property)) {
79
+			$data = $this->get($property);
80
+
81
+			if (!is_a($data, 'Collection')) {
82
+				$data = new Collection($data);
83
+			}
84
+
85
+			return $data;
86
+		}
87
+
88
+		return new Collection([]);
89
+	}
90
+
91
+	/**
92
+	 * Checks whether an item within the collection
93
+	 *
94
+	 * @param $property
95
+	 *
96
+	 * @return bool
97
+	 */
98
+	public function exists($property)
99
+	{
100
+		return property_exists($this->collection, $property);
101
+	}
102
+
103
+	/**
104
+	 * Finds whether the collection is empty
105
+	 *
106
+	 * @return bool
107
+	 */
108
+	public function isEmpty()
109
+	{
110
+		return !(bool)$this->count();
111
+	}
112
+
113
+	/**
114
+	 * Count all items in collection
115
+	 *
116
+	 * @return int
117
+	 */
118
+	public function count()
119
+	{
120
+		return count($this->properties());
121
+	}
122
+
123
+	/**
124
+	 * Returns all items properties names
125
+	 *
126
+	 * @return array
127
+	 */
128
+	public function properties()
129
+	{
130
+		$properties = [];
131
+
132
+		foreach ($this->collection as $key => $value) {
133
+			$properties[] = $key;
134
+		}
135
+
136
+		return $properties;
137
+	}
138
+
139
+	/**
140
+	 * Returns all items values
141
+	 *
142
+	 * @return array
143
+	 */
144
+	public function values()
145
+	{
146
+		$values = [];
147
+
148
+		foreach ($this->collection as $value) {
149
+			$values[] = $value;
150
+		}
151
+
152
+		return $values;
153
+	}
154 154
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -24,7 +24,7 @@  discard block
 block discarded – undo
24 24
      */
25 25
     public function __construct($data = null)
26 26
     {
27
-        $this->collection = (object)$data;
27
+        $this->collection = (object) $data;
28 28
     }
29 29
 
30 30
     /**
@@ -34,7 +34,7 @@  discard block
 block discarded – undo
34 34
      */
35 35
     public function toArray()
36 36
     {
37
-        return (array)$this->collection;
37
+        return (array) $this->collection;
38 38
     }
39 39
 
40 40
     /**
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
         if ($this->exists($property)) {
79 79
             $data = $this->get($property);
80 80
 
81
-            if (!is_a($data, 'Collection')) {
81
+            if ( ! is_a($data, 'Collection')) {
82 82
                 $data = new Collection($data);
83 83
             }
84 84
 
@@ -107,7 +107,7 @@  discard block
 block discarded – undo
107 107
      */
108 108
     public function isEmpty()
109 109
     {
110
-        return !(bool)$this->count();
110
+        return ! (bool) $this->count();
111 111
     }
112 112
 
113 113
     /**
Please login to merge, or discard this patch.
src/Provider/Spotify.php 2 patches
Indentation   +73 added lines, -73 removed lines patch added patch discarded remove patch
@@ -17,77 +17,77 @@
 block discarded – undo
17 17
  */
18 18
 class Spotify extends OAuth2
19 19
 {
20
-    /**
21
-     * {@inheritdoc}
22
-     */
23
-    protected $scope = 'user-read-email';
24
-
25
-    /**
26
-     * {@inheritdoc}
27
-     */
28
-    public $apiBaseUrl = 'https://api.spotify.com/v1/';
29
-
30
-    /**
31
-     * {@inheritdoc}
32
-     */
33
-    public $authorizeUrl = 'https://accounts.spotify.com/authorize';
34
-
35
-    /**
36
-     * {@inheritdoc}
37
-     */
38
-    protected $accessTokenUrl = 'https://accounts.spotify.com/api/token';
39
-
40
-    /**
41
-     * {@inheritdoc}
42
-     */
43
-    protected $apiDocumentation = 'https://developer.spotify.com/documentation/general/guides/authorization-guide/';
44
-
45
-    /**
46
-     * {@inheritdoc}
47
-     */
48
-    public function getUserProfile()
49
-    {
50
-        $response = $this->apiRequest('me');
51
-
52
-        $data = new Data\Collection($response);
53
-
54
-        if (!$data->exists('id')) {
55
-            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
56
-        }
57
-
58
-        $userProfile = new User\Profile();
59
-
60
-        $userProfile->identifier = $data->get('id');
61
-        $userProfile->displayName = $data->get('display_name');
62
-        $userProfile->email = $data->get('email');
63
-        $userProfile->emailVerified = $data->get('email');
64
-        $userProfile->profileURL = $data->filter('external_urls')->get('spotify');
65
-        $userProfile->photoURL = $data->filter('images')->get('url');
66
-        $userProfile->country = $data->get('country');
67
-
68
-        if ($data->exists('birthdate')) {
69
-            $this->fetchBirthday($userProfile, $data->get('birthdate'));
70
-        }
71
-
72
-        return $userProfile;
73
-    }
74
-
75
-    /**
76
-     * Fetch use birthday
77
-     *
78
-     * @param User\Profile $userProfile
79
-     * @param              $birthday
80
-     *
81
-     * @return User\Profile
82
-     */
83
-    protected function fetchBirthday(User\Profile $userProfile, $birthday)
84
-    {
85
-        $result = (new Data\Parser())->parseBirthday($birthday);
86
-
87
-        $userProfile->birthDay = (int)$result[0];
88
-        $userProfile->birthMonth = (int)$result[1];
89
-        $userProfile->birthYear = (int)$result[2];
90
-
91
-        return $userProfile;
92
-    }
20
+	/**
21
+	 * {@inheritdoc}
22
+	 */
23
+	protected $scope = 'user-read-email';
24
+
25
+	/**
26
+	 * {@inheritdoc}
27
+	 */
28
+	public $apiBaseUrl = 'https://api.spotify.com/v1/';
29
+
30
+	/**
31
+	 * {@inheritdoc}
32
+	 */
33
+	public $authorizeUrl = 'https://accounts.spotify.com/authorize';
34
+
35
+	/**
36
+	 * {@inheritdoc}
37
+	 */
38
+	protected $accessTokenUrl = 'https://accounts.spotify.com/api/token';
39
+
40
+	/**
41
+	 * {@inheritdoc}
42
+	 */
43
+	protected $apiDocumentation = 'https://developer.spotify.com/documentation/general/guides/authorization-guide/';
44
+
45
+	/**
46
+	 * {@inheritdoc}
47
+	 */
48
+	public function getUserProfile()
49
+	{
50
+		$response = $this->apiRequest('me');
51
+
52
+		$data = new Data\Collection($response);
53
+
54
+		if (!$data->exists('id')) {
55
+			throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
56
+		}
57
+
58
+		$userProfile = new User\Profile();
59
+
60
+		$userProfile->identifier = $data->get('id');
61
+		$userProfile->displayName = $data->get('display_name');
62
+		$userProfile->email = $data->get('email');
63
+		$userProfile->emailVerified = $data->get('email');
64
+		$userProfile->profileURL = $data->filter('external_urls')->get('spotify');
65
+		$userProfile->photoURL = $data->filter('images')->get('url');
66
+		$userProfile->country = $data->get('country');
67
+
68
+		if ($data->exists('birthdate')) {
69
+			$this->fetchBirthday($userProfile, $data->get('birthdate'));
70
+		}
71
+
72
+		return $userProfile;
73
+	}
74
+
75
+	/**
76
+	 * Fetch use birthday
77
+	 *
78
+	 * @param User\Profile $userProfile
79
+	 * @param              $birthday
80
+	 *
81
+	 * @return User\Profile
82
+	 */
83
+	protected function fetchBirthday(User\Profile $userProfile, $birthday)
84
+	{
85
+		$result = (new Data\Parser())->parseBirthday($birthday);
86
+
87
+		$userProfile->birthDay = (int)$result[0];
88
+		$userProfile->birthMonth = (int)$result[1];
89
+		$userProfile->birthYear = (int)$result[2];
90
+
91
+		return $userProfile;
92
+	}
93 93
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -51,7 +51,7 @@  discard block
 block discarded – undo
51 51
 
52 52
         $data = new Data\Collection($response);
53 53
 
54
-        if (!$data->exists('id')) {
54
+        if ( ! $data->exists('id')) {
55 55
             throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
56 56
         }
57 57
 
@@ -84,9 +84,9 @@  discard block
 block discarded – undo
84 84
     {
85 85
         $result = (new Data\Parser())->parseBirthday($birthday);
86 86
 
87
-        $userProfile->birthDay = (int)$result[0];
88
-        $userProfile->birthMonth = (int)$result[1];
89
-        $userProfile->birthYear = (int)$result[2];
87
+        $userProfile->birthDay = (int) $result[0];
88
+        $userProfile->birthMonth = (int) $result[1];
89
+        $userProfile->birthYear = (int) $result[2];
90 90
 
91 91
         return $userProfile;
92 92
     }
Please login to merge, or discard this patch.
src/Provider/Seznam.php 2 patches
Indentation   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -17,47 +17,47 @@
 block discarded – undo
17 17
  */
18 18
 class Seznam extends OAuth2
19 19
 {
20
-    /**
21
-     * {@inheritdoc}
22
-     */
23
-    protected $apiBaseUrl = 'https://login.szn.cz/';
24
-
25
-    /**
26
-     * {@inheritdoc}
27
-     */
28
-    protected $authorizeUrl = 'https://login.szn.cz/api/v1/oauth/auth';
29
-
30
-    /**
31
-     * {@inheritdoc}
32
-     */
33
-    protected $accessTokenUrl = 'https://login.szn.cz/api/v1/oauth/token';
34
-
35
-    /**
36
-     * {@inheritdoc}
37
-     */
38
-    protected $apiDocumentation = 'https://vyvojari.seznam.cz/oauth/doc';
39
-
40
-    /**
41
-     * {@inheritdoc}
42
-     */
43
-    public function getUserProfile()
44
-    {
45
-        $response = $this->apiRequest('api/v1/user', 'GET', ['format' => 'json']);
46
-
47
-        $data = new Data\Collection($response);
48
-
49
-        if (!$data->exists('oauth_user_id')) {
50
-            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
51
-        }
52
-
53
-        $userProfile = new User\Profile();
54
-
55
-        $userProfile->identifier = $data->get('oauth_user_id');
56
-        $userProfile->email = $data->get('account_name');
57
-        $userProfile->firstName = $data->get('firstname');
58
-        $userProfile->lastName = $data->get('lastname');
59
-        $userProfile->photoURL = $data->get('avatar_url');
60
-
61
-        return $userProfile;
62
-    }
20
+	/**
21
+	 * {@inheritdoc}
22
+	 */
23
+	protected $apiBaseUrl = 'https://login.szn.cz/';
24
+
25
+	/**
26
+	 * {@inheritdoc}
27
+	 */
28
+	protected $authorizeUrl = 'https://login.szn.cz/api/v1/oauth/auth';
29
+
30
+	/**
31
+	 * {@inheritdoc}
32
+	 */
33
+	protected $accessTokenUrl = 'https://login.szn.cz/api/v1/oauth/token';
34
+
35
+	/**
36
+	 * {@inheritdoc}
37
+	 */
38
+	protected $apiDocumentation = 'https://vyvojari.seznam.cz/oauth/doc';
39
+
40
+	/**
41
+	 * {@inheritdoc}
42
+	 */
43
+	public function getUserProfile()
44
+	{
45
+		$response = $this->apiRequest('api/v1/user', 'GET', ['format' => 'json']);
46
+
47
+		$data = new Data\Collection($response);
48
+
49
+		if (!$data->exists('oauth_user_id')) {
50
+			throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
51
+		}
52
+
53
+		$userProfile = new User\Profile();
54
+
55
+		$userProfile->identifier = $data->get('oauth_user_id');
56
+		$userProfile->email = $data->get('account_name');
57
+		$userProfile->firstName = $data->get('firstname');
58
+		$userProfile->lastName = $data->get('lastname');
59
+		$userProfile->photoURL = $data->get('avatar_url');
60
+
61
+		return $userProfile;
62
+	}
63 63
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -46,7 +46,7 @@
 block discarded – undo
46 46
 
47 47
         $data = new Data\Collection($response);
48 48
 
49
-        if (!$data->exists('oauth_user_id')) {
49
+        if ( ! $data->exists('oauth_user_id')) {
50 50
             throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
51 51
         }
52 52
 
Please login to merge, or discard this patch.
src/Adapter/OpenID.php 2 patches
Indentation   +257 added lines, -257 removed lines patch added patch discarded remove patch
@@ -23,261 +23,261 @@
 block discarded – undo
23 23
  */
24 24
 abstract class OpenID extends AbstractAdapter implements AdapterInterface
25 25
 {
26
-    /**
27
-     * LightOpenID instance
28
-     *
29
-     * @var object
30
-     */
31
-    protected $openIdClient = null;
32
-
33
-    /**
34
-     * Openid provider identifier
35
-     *
36
-     * @var string
37
-     */
38
-    protected $openidIdentifier = '';
39
-
40
-    /**
41
-     * IPD API Documentation
42
-     *
43
-     * OPTIONAL.
44
-     *
45
-     * @var string
46
-     */
47
-    protected $apiDocumentation = '';
48
-
49
-    /**
50
-     * {@inheritdoc}
51
-     */
52
-    protected function configure()
53
-    {
54
-        if ($this->config->exists('openid_identifier')) {
55
-            $this->openidIdentifier = $this->config->get('openid_identifier');
56
-        }
57
-
58
-        if (empty($this->openidIdentifier)) {
59
-            throw new InvalidOpenidIdentifierException('OpenID adapter requires an openid_identifier.', 4);
60
-        }
61
-
62
-        $this->setCallback($this->config->get('callback'));
63
-        $this->setApiEndpoints($this->config->get('endpoints'));
64
-    }
65
-
66
-    /**
67
-     * {@inheritdoc}
68
-     */
69
-    protected function initialize()
70
-    {
71
-        $hostPort = parse_url($this->callback, PHP_URL_PORT);
72
-        $hostUrl = parse_url($this->callback, PHP_URL_HOST);
73
-
74
-        if ($hostPort) {
75
-            $hostUrl .= ':' . $hostPort;
76
-        }
77
-
78
-        // @fixme: add proxy
79
-        $this->openIdClient = new LightOpenID($hostUrl, null);
80
-    }
81
-
82
-    /**
83
-     * {@inheritdoc}
84
-     */
85
-    public function authenticate()
86
-    {
87
-        $this->logger->info(sprintf('%s::authenticate()', get_class($this)));
88
-
89
-        if ($this->isConnected()) {
90
-            return true;
91
-        }
92
-
93
-        if (empty($_REQUEST['openid_mode'])) {
94
-            $this->authenticateBegin();
95
-        } else {
96
-            return $this->authenticateFinish();
97
-        }
98
-
99
-        return null;
100
-    }
101
-
102
-    /**
103
-     * {@inheritdoc}
104
-     */
105
-    public function isConnected()
106
-    {
107
-        return (bool)$this->storage->get($this->providerId . '.user');
108
-    }
109
-
110
-    /**
111
-     * {@inheritdoc}
112
-     */
113
-    public function disconnect()
114
-    {
115
-        $this->storage->delete($this->providerId . '.user');
116
-
117
-        return true;
118
-    }
119
-
120
-    /**
121
-     * Initiate the authorization protocol
122
-     *
123
-     * Include and instantiate LightOpenID
124
-     */
125
-    protected function authenticateBegin()
126
-    {
127
-        $this->openIdClient->identity = $this->openidIdentifier;
128
-        $this->openIdClient->returnUrl = $this->callback;
129
-        $this->openIdClient->required = [
130
-            'namePerson/first',
131
-            'namePerson/last',
132
-            'namePerson/friendly',
133
-            'namePerson',
134
-            'contact/email',
135
-            'birthDate',
136
-            'birthDate/birthDay',
137
-            'birthDate/birthMonth',
138
-            'birthDate/birthYear',
139
-            'person/gender',
140
-            'pref/language',
141
-            'contact/postalCode/home',
142
-            'contact/city/home',
143
-            'contact/country/home',
144
-
145
-            'media/image/default',
146
-        ];
147
-
148
-        $authUrl = $this->openIdClient->authUrl();
149
-
150
-        $this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]);
151
-
152
-        HttpClient\Util::redirect($authUrl);
153
-    }
154
-
155
-    /**
156
-     * Finalize the authorization process.
157
-     *
158
-     * @throws AuthorizationDeniedException
159
-     * @throws UnexpectedApiResponseException
160
-     */
161
-    protected function authenticateFinish()
162
-    {
163
-        $this->logger->debug(
164
-            sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
165
-            [HttpClient\Util::getCurrentUrl(true)]
166
-        );
167
-
168
-        if ($this->openIdClient->mode == 'cancel') {
169
-            throw new AuthorizationDeniedException('User has cancelled the authentication.');
170
-        }
171
-
172
-        if (!$this->openIdClient->validate()) {
173
-            throw new UnexpectedApiResponseException('Invalid response received.');
174
-        }
175
-
176
-        $openidAttributes = $this->openIdClient->getAttributes();
177
-
178
-        if (!$this->openIdClient->identity) {
179
-            throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
180
-        }
181
-
182
-        $userProfile = $this->fetchUserProfile($openidAttributes);
183
-
184
-        /* with openid providers we only get user profiles once, so we store it */
185
-        $this->storage->set($this->providerId . '.user', $userProfile);
186
-    }
187
-
188
-    /**
189
-     * Fetch user profile from received openid attributes
190
-     *
191
-     * @param array $openidAttributes
192
-     *
193
-     * @return User\Profile
194
-     */
195
-    protected function fetchUserProfile($openidAttributes)
196
-    {
197
-        $data = new Data\Collection($openidAttributes);
198
-
199
-        $userProfile = new User\Profile();
200
-
201
-        $userProfile->identifier = $this->openIdClient->identity;
202
-
203
-        $userProfile->firstName = $data->get('namePerson/first');
204
-        $userProfile->lastName = $data->get('namePerson/last');
205
-        $userProfile->email = $data->get('contact/email');
206
-        $userProfile->language = $data->get('pref/language');
207
-        $userProfile->country = $data->get('contact/country/home');
208
-        $userProfile->zip = $data->get('contact/postalCode/home');
209
-        $userProfile->gender = $data->get('person/gender');
210
-        $userProfile->photoURL = $data->get('media/image/default');
211
-        $userProfile->birthDay = $data->get('birthDate/birthDay');
212
-        $userProfile->birthMonth = $data->get('birthDate/birthMonth');
213
-        $userProfile->birthYear = $data->get('birthDate/birthDate');
214
-
215
-        $userProfile = $this->fetchUserGender($userProfile, $data->get('person/gender'));
216
-
217
-        $userProfile = $this->fetchUserDisplayName($userProfile, $data);
218
-
219
-        return $userProfile;
220
-    }
221
-
222
-    /**
223
-     * Extract users display names
224
-     *
225
-     * @param User\Profile $userProfile
226
-     * @param Data\Collection $data
227
-     *
228
-     * @return User\Profile
229
-     */
230
-    protected function fetchUserDisplayName(User\Profile $userProfile, Data\Collection $data)
231
-    {
232
-        $userProfile->displayName = $data->get('namePerson');
233
-
234
-        $userProfile->displayName = $userProfile->displayName
235
-            ? $userProfile->displayName
236
-            : $data->get('namePerson/friendly');
237
-
238
-        $userProfile->displayName = $userProfile->displayName
239
-            ? $userProfile->displayName
240
-            : trim($userProfile->firstName . ' ' . $userProfile->lastName);
241
-
242
-        return $userProfile;
243
-    }
244
-
245
-    /**
246
-     * Extract users gender
247
-     *
248
-     * @param User\Profile $userProfile
249
-     * @param string $gender
250
-     *
251
-     * @return User\Profile
252
-     */
253
-    protected function fetchUserGender(User\Profile $userProfile, $gender)
254
-    {
255
-        $gender = strtolower((string)$gender);
256
-
257
-        if ('f' == $gender) {
258
-            $gender = 'female';
259
-        }
260
-
261
-        if ('m' == $gender) {
262
-            $gender = 'male';
263
-        }
264
-
265
-        $userProfile->gender = $gender;
266
-
267
-        return $userProfile;
268
-    }
269
-
270
-    /**
271
-     * OpenID only provide the user profile one. This method will attempt to retrieve the profile from storage.
272
-     */
273
-    public function getUserProfile()
274
-    {
275
-        $userProfile = $this->storage->get($this->providerId . '.user');
276
-
277
-        if (!is_object($userProfile)) {
278
-            throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
279
-        }
280
-
281
-        return $userProfile;
282
-    }
26
+	/**
27
+	 * LightOpenID instance
28
+	 *
29
+	 * @var object
30
+	 */
31
+	protected $openIdClient = null;
32
+
33
+	/**
34
+	 * Openid provider identifier
35
+	 *
36
+	 * @var string
37
+	 */
38
+	protected $openidIdentifier = '';
39
+
40
+	/**
41
+	 * IPD API Documentation
42
+	 *
43
+	 * OPTIONAL.
44
+	 *
45
+	 * @var string
46
+	 */
47
+	protected $apiDocumentation = '';
48
+
49
+	/**
50
+	 * {@inheritdoc}
51
+	 */
52
+	protected function configure()
53
+	{
54
+		if ($this->config->exists('openid_identifier')) {
55
+			$this->openidIdentifier = $this->config->get('openid_identifier');
56
+		}
57
+
58
+		if (empty($this->openidIdentifier)) {
59
+			throw new InvalidOpenidIdentifierException('OpenID adapter requires an openid_identifier.', 4);
60
+		}
61
+
62
+		$this->setCallback($this->config->get('callback'));
63
+		$this->setApiEndpoints($this->config->get('endpoints'));
64
+	}
65
+
66
+	/**
67
+	 * {@inheritdoc}
68
+	 */
69
+	protected function initialize()
70
+	{
71
+		$hostPort = parse_url($this->callback, PHP_URL_PORT);
72
+		$hostUrl = parse_url($this->callback, PHP_URL_HOST);
73
+
74
+		if ($hostPort) {
75
+			$hostUrl .= ':' . $hostPort;
76
+		}
77
+
78
+		// @fixme: add proxy
79
+		$this->openIdClient = new LightOpenID($hostUrl, null);
80
+	}
81
+
82
+	/**
83
+	 * {@inheritdoc}
84
+	 */
85
+	public function authenticate()
86
+	{
87
+		$this->logger->info(sprintf('%s::authenticate()', get_class($this)));
88
+
89
+		if ($this->isConnected()) {
90
+			return true;
91
+		}
92
+
93
+		if (empty($_REQUEST['openid_mode'])) {
94
+			$this->authenticateBegin();
95
+		} else {
96
+			return $this->authenticateFinish();
97
+		}
98
+
99
+		return null;
100
+	}
101
+
102
+	/**
103
+	 * {@inheritdoc}
104
+	 */
105
+	public function isConnected()
106
+	{
107
+		return (bool)$this->storage->get($this->providerId . '.user');
108
+	}
109
+
110
+	/**
111
+	 * {@inheritdoc}
112
+	 */
113
+	public function disconnect()
114
+	{
115
+		$this->storage->delete($this->providerId . '.user');
116
+
117
+		return true;
118
+	}
119
+
120
+	/**
121
+	 * Initiate the authorization protocol
122
+	 *
123
+	 * Include and instantiate LightOpenID
124
+	 */
125
+	protected function authenticateBegin()
126
+	{
127
+		$this->openIdClient->identity = $this->openidIdentifier;
128
+		$this->openIdClient->returnUrl = $this->callback;
129
+		$this->openIdClient->required = [
130
+			'namePerson/first',
131
+			'namePerson/last',
132
+			'namePerson/friendly',
133
+			'namePerson',
134
+			'contact/email',
135
+			'birthDate',
136
+			'birthDate/birthDay',
137
+			'birthDate/birthMonth',
138
+			'birthDate/birthYear',
139
+			'person/gender',
140
+			'pref/language',
141
+			'contact/postalCode/home',
142
+			'contact/city/home',
143
+			'contact/country/home',
144
+
145
+			'media/image/default',
146
+		];
147
+
148
+		$authUrl = $this->openIdClient->authUrl();
149
+
150
+		$this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]);
151
+
152
+		HttpClient\Util::redirect($authUrl);
153
+	}
154
+
155
+	/**
156
+	 * Finalize the authorization process.
157
+	 *
158
+	 * @throws AuthorizationDeniedException
159
+	 * @throws UnexpectedApiResponseException
160
+	 */
161
+	protected function authenticateFinish()
162
+	{
163
+		$this->logger->debug(
164
+			sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
165
+			[HttpClient\Util::getCurrentUrl(true)]
166
+		);
167
+
168
+		if ($this->openIdClient->mode == 'cancel') {
169
+			throw new AuthorizationDeniedException('User has cancelled the authentication.');
170
+		}
171
+
172
+		if (!$this->openIdClient->validate()) {
173
+			throw new UnexpectedApiResponseException('Invalid response received.');
174
+		}
175
+
176
+		$openidAttributes = $this->openIdClient->getAttributes();
177
+
178
+		if (!$this->openIdClient->identity) {
179
+			throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
180
+		}
181
+
182
+		$userProfile = $this->fetchUserProfile($openidAttributes);
183
+
184
+		/* with openid providers we only get user profiles once, so we store it */
185
+		$this->storage->set($this->providerId . '.user', $userProfile);
186
+	}
187
+
188
+	/**
189
+	 * Fetch user profile from received openid attributes
190
+	 *
191
+	 * @param array $openidAttributes
192
+	 *
193
+	 * @return User\Profile
194
+	 */
195
+	protected function fetchUserProfile($openidAttributes)
196
+	{
197
+		$data = new Data\Collection($openidAttributes);
198
+
199
+		$userProfile = new User\Profile();
200
+
201
+		$userProfile->identifier = $this->openIdClient->identity;
202
+
203
+		$userProfile->firstName = $data->get('namePerson/first');
204
+		$userProfile->lastName = $data->get('namePerson/last');
205
+		$userProfile->email = $data->get('contact/email');
206
+		$userProfile->language = $data->get('pref/language');
207
+		$userProfile->country = $data->get('contact/country/home');
208
+		$userProfile->zip = $data->get('contact/postalCode/home');
209
+		$userProfile->gender = $data->get('person/gender');
210
+		$userProfile->photoURL = $data->get('media/image/default');
211
+		$userProfile->birthDay = $data->get('birthDate/birthDay');
212
+		$userProfile->birthMonth = $data->get('birthDate/birthMonth');
213
+		$userProfile->birthYear = $data->get('birthDate/birthDate');
214
+
215
+		$userProfile = $this->fetchUserGender($userProfile, $data->get('person/gender'));
216
+
217
+		$userProfile = $this->fetchUserDisplayName($userProfile, $data);
218
+
219
+		return $userProfile;
220
+	}
221
+
222
+	/**
223
+	 * Extract users display names
224
+	 *
225
+	 * @param User\Profile $userProfile
226
+	 * @param Data\Collection $data
227
+	 *
228
+	 * @return User\Profile
229
+	 */
230
+	protected function fetchUserDisplayName(User\Profile $userProfile, Data\Collection $data)
231
+	{
232
+		$userProfile->displayName = $data->get('namePerson');
233
+
234
+		$userProfile->displayName = $userProfile->displayName
235
+			? $userProfile->displayName
236
+			: $data->get('namePerson/friendly');
237
+
238
+		$userProfile->displayName = $userProfile->displayName
239
+			? $userProfile->displayName
240
+			: trim($userProfile->firstName . ' ' . $userProfile->lastName);
241
+
242
+		return $userProfile;
243
+	}
244
+
245
+	/**
246
+	 * Extract users gender
247
+	 *
248
+	 * @param User\Profile $userProfile
249
+	 * @param string $gender
250
+	 *
251
+	 * @return User\Profile
252
+	 */
253
+	protected function fetchUserGender(User\Profile $userProfile, $gender)
254
+	{
255
+		$gender = strtolower((string)$gender);
256
+
257
+		if ('f' == $gender) {
258
+			$gender = 'female';
259
+		}
260
+
261
+		if ('m' == $gender) {
262
+			$gender = 'male';
263
+		}
264
+
265
+		$userProfile->gender = $gender;
266
+
267
+		return $userProfile;
268
+	}
269
+
270
+	/**
271
+	 * OpenID only provide the user profile one. This method will attempt to retrieve the profile from storage.
272
+	 */
273
+	public function getUserProfile()
274
+	{
275
+		$userProfile = $this->storage->get($this->providerId . '.user');
276
+
277
+		if (!is_object($userProfile)) {
278
+			throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
279
+		}
280
+
281
+		return $userProfile;
282
+	}
283 283
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -72,7 +72,7 @@  discard block
 block discarded – undo
72 72
         $hostUrl = parse_url($this->callback, PHP_URL_HOST);
73 73
 
74 74
         if ($hostPort) {
75
-            $hostUrl .= ':' . $hostPort;
75
+            $hostUrl .= ':'.$hostPort;
76 76
         }
77 77
 
78 78
         // @fixme: add proxy
@@ -104,7 +104,7 @@  discard block
 block discarded – undo
104 104
      */
105 105
     public function isConnected()
106 106
     {
107
-        return (bool)$this->storage->get($this->providerId . '.user');
107
+        return (bool) $this->storage->get($this->providerId.'.user');
108 108
     }
109 109
 
110 110
     /**
@@ -112,7 +112,7 @@  discard block
 block discarded – undo
112 112
      */
113 113
     public function disconnect()
114 114
     {
115
-        $this->storage->delete($this->providerId . '.user');
115
+        $this->storage->delete($this->providerId.'.user');
116 116
 
117 117
         return true;
118 118
     }
@@ -169,20 +169,20 @@  discard block
 block discarded – undo
169 169
             throw new AuthorizationDeniedException('User has cancelled the authentication.');
170 170
         }
171 171
 
172
-        if (!$this->openIdClient->validate()) {
172
+        if ( ! $this->openIdClient->validate()) {
173 173
             throw new UnexpectedApiResponseException('Invalid response received.');
174 174
         }
175 175
 
176 176
         $openidAttributes = $this->openIdClient->getAttributes();
177 177
 
178
-        if (!$this->openIdClient->identity) {
178
+        if ( ! $this->openIdClient->identity) {
179 179
             throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
180 180
         }
181 181
 
182 182
         $userProfile = $this->fetchUserProfile($openidAttributes);
183 183
 
184 184
         /* with openid providers we only get user profiles once, so we store it */
185
-        $this->storage->set($this->providerId . '.user', $userProfile);
185
+        $this->storage->set($this->providerId.'.user', $userProfile);
186 186
     }
187 187
 
188 188
     /**
@@ -237,7 +237,7 @@  discard block
 block discarded – undo
237 237
 
238 238
         $userProfile->displayName = $userProfile->displayName
239 239
             ? $userProfile->displayName
240
-            : trim($userProfile->firstName . ' ' . $userProfile->lastName);
240
+            : trim($userProfile->firstName.' '.$userProfile->lastName);
241 241
 
242 242
         return $userProfile;
243 243
     }
@@ -252,7 +252,7 @@  discard block
 block discarded – undo
252 252
      */
253 253
     protected function fetchUserGender(User\Profile $userProfile, $gender)
254 254
     {
255
-        $gender = strtolower((string)$gender);
255
+        $gender = strtolower((string) $gender);
256 256
 
257 257
         if ('f' == $gender) {
258 258
             $gender = 'female';
@@ -272,9 +272,9 @@  discard block
 block discarded – undo
272 272
      */
273 273
     public function getUserProfile()
274 274
     {
275
-        $userProfile = $this->storage->get($this->providerId . '.user');
275
+        $userProfile = $this->storage->get($this->providerId.'.user');
276 276
 
277
-        if (!is_object($userProfile)) {
277
+        if ( ! is_object($userProfile)) {
278 278
             throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
279 279
         }
280 280
 
Please login to merge, or discard this patch.
src/Provider/Mastodon.php 2 patches
Indentation   +110 added lines, -110 removed lines patch added patch discarded remove patch
@@ -10,114 +10,114 @@
 block discarded – undo
10 10
 
11 11
 class Mastodon extends OAuth2
12 12
 {
13
-    /**
14
-     * {@inheritdoc}
15
-     */
16
-    public $scope = 'read';
17
-
18
-    /**
19
-     * {@inheritdoc}
20
-     */
21
-    protected $apiDocumentation = 'https://docs.joinmastodon.org/spec/oauth/';
22
-
23
-    /**
24
-     * {@inheritdoc}
25
-     */
26
-    protected function configure()
27
-    {
28
-        parent::configure();
29
-
30
-        if (!$this->config->exists('url')) {
31
-            throw new InvalidApplicationCredentialsException(
32
-                'You must define a Mastodon instance url'
33
-            );
34
-        }
35
-        $url = $this->config->get('url');
36
-
37
-        $this->apiBaseUrl = $url . '/api/v1';
38
-
39
-        $this->authorizeUrl = $url . '/oauth/authorize';
40
-        $this->accessTokenUrl = $url . '/oauth/token';
41
-    }
42
-
43
-    /**
44
-     * {@inheritdoc}
45
-     */
46
-    public function getUserProfile()
47
-    {
48
-        $response = $this->apiRequest('accounts/verify_credentials', 'GET', []);
49
-
50
-        $data = new Data\Collection($response);
51
-
52
-        if (!$data->exists('id') || !$data->get('id')) {
53
-            throw new UnexpectedApiResponseException(
54
-                'Provider API returned an unexpected response.'
55
-            );
56
-        }
57
-
58
-        $userProfile = new Profile();
59
-
60
-        $userProfile->identifier = $data->get('id');
61
-        $userProfile->displayName = $data->get('username');
62
-        $userProfile->photoURL =
63
-            $data->get('avatar') ?: $data->get('avatar_static');
64
-        $userProfile->webSiteURL = $data->get('url');
65
-        $userProfile->description = $data->get('note');
66
-        $userProfile->firstName = $data->get('display_name');
67
-
68
-        return $userProfile;
69
-    }
70
-
71
-    public function setUserStatus($status)
72
-    {
73
-        // Prepare request parameters.
74
-        $params = [];
75
-        if (isset($status['message'])) {
76
-            $params['status'] = $status['message'];
77
-        }
78
-
79
-        if (isset($status['picture'])) {
80
-            $headers = [
81
-                'Content-Type' => 'multipart/form-data',
82
-            ];
83
-
84
-            $pictures = $status['picture'];
85
-
86
-            $ids = [];
87
-
88
-            foreach ($pictures as $picture) {
89
-                $images = $this->apiRequest(
90
-                    $this->config->get('url') . '/api/v2/media',
91
-                    'POST',
92
-                    [
93
-                        'file' => new \CurlFile(
94
-                            $picture,
95
-                            'image/jpg',
96
-                            'filename'
97
-                        ),
98
-                    ],
99
-                    $headers,
100
-                    true
101
-                );
102
-
103
-                $ids[] = $images->id;
104
-            }
105
-
106
-            $params['media_ids'] = $ids;
107
-        }
108
-
109
-        $headers = [
110
-            'Content-Type' => 'application/json',
111
-        ];
112
-
113
-        $response = $this->apiRequest(
114
-            'statuses',
115
-            'POST',
116
-            $params,
117
-            $headers,
118
-            false
119
-        );
120
-
121
-        return $response;
122
-    }
13
+	/**
14
+	 * {@inheritdoc}
15
+	 */
16
+	public $scope = 'read';
17
+
18
+	/**
19
+	 * {@inheritdoc}
20
+	 */
21
+	protected $apiDocumentation = 'https://docs.joinmastodon.org/spec/oauth/';
22
+
23
+	/**
24
+	 * {@inheritdoc}
25
+	 */
26
+	protected function configure()
27
+	{
28
+		parent::configure();
29
+
30
+		if (!$this->config->exists('url')) {
31
+			throw new InvalidApplicationCredentialsException(
32
+				'You must define a Mastodon instance url'
33
+			);
34
+		}
35
+		$url = $this->config->get('url');
36
+
37
+		$this->apiBaseUrl = $url . '/api/v1';
38
+
39
+		$this->authorizeUrl = $url . '/oauth/authorize';
40
+		$this->accessTokenUrl = $url . '/oauth/token';
41
+	}
42
+
43
+	/**
44
+	 * {@inheritdoc}
45
+	 */
46
+	public function getUserProfile()
47
+	{
48
+		$response = $this->apiRequest('accounts/verify_credentials', 'GET', []);
49
+
50
+		$data = new Data\Collection($response);
51
+
52
+		if (!$data->exists('id') || !$data->get('id')) {
53
+			throw new UnexpectedApiResponseException(
54
+				'Provider API returned an unexpected response.'
55
+			);
56
+		}
57
+
58
+		$userProfile = new Profile();
59
+
60
+		$userProfile->identifier = $data->get('id');
61
+		$userProfile->displayName = $data->get('username');
62
+		$userProfile->photoURL =
63
+			$data->get('avatar') ?: $data->get('avatar_static');
64
+		$userProfile->webSiteURL = $data->get('url');
65
+		$userProfile->description = $data->get('note');
66
+		$userProfile->firstName = $data->get('display_name');
67
+
68
+		return $userProfile;
69
+	}
70
+
71
+	public function setUserStatus($status)
72
+	{
73
+		// Prepare request parameters.
74
+		$params = [];
75
+		if (isset($status['message'])) {
76
+			$params['status'] = $status['message'];
77
+		}
78
+
79
+		if (isset($status['picture'])) {
80
+			$headers = [
81
+				'Content-Type' => 'multipart/form-data',
82
+			];
83
+
84
+			$pictures = $status['picture'];
85
+
86
+			$ids = [];
87
+
88
+			foreach ($pictures as $picture) {
89
+				$images = $this->apiRequest(
90
+					$this->config->get('url') . '/api/v2/media',
91
+					'POST',
92
+					[
93
+						'file' => new \CurlFile(
94
+							$picture,
95
+							'image/jpg',
96
+							'filename'
97
+						),
98
+					],
99
+					$headers,
100
+					true
101
+				);
102
+
103
+				$ids[] = $images->id;
104
+			}
105
+
106
+			$params['media_ids'] = $ids;
107
+		}
108
+
109
+		$headers = [
110
+			'Content-Type' => 'application/json',
111
+		];
112
+
113
+		$response = $this->apiRequest(
114
+			'statuses',
115
+			'POST',
116
+			$params,
117
+			$headers,
118
+			false
119
+		);
120
+
121
+		return $response;
122
+	}
123 123
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -27,17 +27,17 @@  discard block
 block discarded – undo
27 27
     {
28 28
         parent::configure();
29 29
 
30
-        if (!$this->config->exists('url')) {
30
+        if ( ! $this->config->exists('url')) {
31 31
             throw new InvalidApplicationCredentialsException(
32 32
                 'You must define a Mastodon instance url'
33 33
             );
34 34
         }
35 35
         $url = $this->config->get('url');
36 36
 
37
-        $this->apiBaseUrl = $url . '/api/v1';
37
+        $this->apiBaseUrl = $url.'/api/v1';
38 38
 
39
-        $this->authorizeUrl = $url . '/oauth/authorize';
40
-        $this->accessTokenUrl = $url . '/oauth/token';
39
+        $this->authorizeUrl = $url.'/oauth/authorize';
40
+        $this->accessTokenUrl = $url.'/oauth/token';
41 41
     }
42 42
 
43 43
     /**
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
 
50 50
         $data = new Data\Collection($response);
51 51
 
52
-        if (!$data->exists('id') || !$data->get('id')) {
52
+        if ( ! $data->exists('id') || ! $data->get('id')) {
53 53
             throw new UnexpectedApiResponseException(
54 54
                 'Provider API returned an unexpected response.'
55 55
             );
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
 
88 88
             foreach ($pictures as $picture) {
89 89
                 $images = $this->apiRequest(
90
-                    $this->config->get('url') . '/api/v2/media',
90
+                    $this->config->get('url').'/api/v2/media',
91 91
                     'POST',
92 92
                     [
93 93
                         'file' => new \CurlFile(
Please login to merge, or discard this patch.
src/Provider/Apple.php 2 patches
Indentation   +274 added lines, -274 removed lines patch added patch discarded remove patch
@@ -64,278 +64,278 @@
 block discarded – undo
64 64
  */
65 65
 class Apple extends OAuth2
66 66
 {
67
-    /**
68
-     * {@inheritdoc}
69
-     */
70
-    protected $scope = 'name email';
71
-
72
-    /**
73
-     * {@inheritdoc}
74
-     */
75
-    protected $apiBaseUrl = 'https://appleid.apple.com/auth/';
76
-
77
-    /**
78
-     * {@inheritdoc}
79
-     */
80
-    protected $authorizeUrl = 'https://appleid.apple.com/auth/authorize';
81
-
82
-    /**
83
-     * {@inheritdoc}
84
-     */
85
-    protected $accessTokenUrl = 'https://appleid.apple.com/auth/token';
86
-
87
-    /**
88
-     * {@inheritdoc}
89
-     */
90
-    protected $apiDocumentation = 'https://developer.apple.com/documentation/sign_in_with_apple';
91
-
92
-    /**
93
-     * {@inheritdoc}
94
-     * The Sign in with Apple servers require percent encoding (or URL encoding)
95
-     * for its query parameters. If you are using the Sign in with Apple REST API,
96
-     * you must provide values with encoded spaces (`%20`) instead of plus (`+`) signs.
97
-     */
98
-    protected $AuthorizeUrlParametersEncType = PHP_QUERY_RFC3986;
99
-
100
-    /**
101
-     * {@inheritdoc}
102
-     */
103
-    protected function initialize()
104
-    {
105
-        parent::initialize();
106
-        $this->AuthorizeUrlParameters['response_mode'] = 'form_post';
107
-
108
-        if ($this->isRefreshTokenAvailable()) {
109
-            $this->tokenRefreshParameters += [
110
-                'client_id' => $this->clientId,
111
-                'client_secret' => $this->clientSecret,
112
-            ];
113
-        }
114
-    }
115
-
116
-    /**
117
-     * {@inheritdoc}
118
-     * @throws InvalidApplicationCredentialsException
119
-     */
120
-    protected function configure()
121
-    {
122
-        $keys = $this->config->get('keys');
123
-        $keys['secret'] = $this->getSecret();
124
-        $this->config->set('keys', $keys);
125
-        parent::configure();
126
-    }
127
-
128
-    /**
129
-     * {@inheritdoc}
130
-     *
131
-     * include id_token $tokenNames
132
-     */
133
-    public function getAccessToken()
134
-    {
135
-        $tokenNames = [
136
-            'access_token',
137
-            'id_token',
138
-            'access_token_secret',
139
-            'token_type',
140
-            'refresh_token',
141
-            'expires_in',
142
-            'expires_at',
143
-        ];
144
-
145
-        $tokens = [];
146
-
147
-        foreach ($tokenNames as $name) {
148
-            if ($this->getStoredData($name)) {
149
-                $tokens[$name] = $this->getStoredData($name);
150
-            }
151
-        }
152
-
153
-        return $tokens;
154
-    }
155
-
156
-    /**
157
-     * {@inheritdoc}
158
-     */
159
-    protected function validateAccessTokenExchange($response)
160
-    {
161
-        $collection = parent::validateAccessTokenExchange($response);
162
-
163
-        $this->storeData('id_token', $collection->get('id_token'));
164
-
165
-        return $collection;
166
-    }
167
-
168
-    /**
169
-     * Get the user profile
170
-     *
171
-     * @throws HttpClientFailureException
172
-     * @throws InvalidAccessTokenException
173
-     * @throws UnexpectedValueException
174
-     * @throws HttpRequestFailedException
175
-     * @throws Exception
176
-     */
177
-    public function getUserProfile()
178
-    {
179
-        $id_token = $this->getStoredData('id_token');
180
-
181
-        $verifyTokenSignature =
182
-            $this->config->exists('verifyTokenSignature') ? $this->config->get('verifyTokenSignature') : true;
183
-
184
-        if (!$verifyTokenSignature) {
185
-            // payload extraction by https://github.com/omidborjian
186
-            // https://github.com/hybridauth/hybridauth/issues/1095#issuecomment-626479263
187
-            // JWT splits the string to 3 components 1) first is header 2) is payload 3) is signature
188
-            $payload = explode('.', $id_token)[1];
189
-            $payload = json_decode(base64_decode($payload));
190
-        } else {
191
-            // validate the token signature and get the payload
192
-            $publicKeys = $this->apiRequest('keys');
193
-
194
-            JWT::$leeway = 120;
195
-
196
-            $error = false;
197
-            $payload = null;
198
-
199
-            foreach ($publicKeys->keys as $publicKey) {
200
-                try {
201
-                    $jwk = (array)$publicKey;
202
-
203
-                    $key = PublicKeyLoader::load(
204
-                        [
205
-                            'e' => new BigInteger(base64_decode($jwk['e']), 256),
206
-                            'n' => new BigInteger(base64_decode(strtr($jwk['n'], '-_', '+/'), true), 256)
207
-                        ]
208
-                    )
209
-                        ->withHash('sha1')
210
-                        ->withMGFHash('sha1');
211
-
212
-                    $pem = (string)$key;
213
-
214
-                    $payload = (version_compare($this->getJwtVersion(), '6.2') < 0) ?
215
-                        JWT::decode($id_token, $pem, ['RS256']) :
216
-                        JWT::decode($id_token, new Key($pem, 'RS256'));
217
-                    break;
218
-                } catch (Exception $e) {
219
-                    $error = $e->getMessage();
220
-                    if ($e instanceof ExpiredException) {
221
-                        break;
222
-                    }
223
-                }
224
-            }
225
-
226
-            if ($error && !$payload) {
227
-                throw new Exception($error);
228
-            }
229
-        }
230
-
231
-        $data = new Data\Collection($payload);
232
-
233
-        if (!$data->exists('sub')) {
234
-            throw new UnexpectedValueException('Missing token payload.');
235
-        }
236
-
237
-        $userProfile = new User\Profile();
238
-        $userProfile->identifier = $data->get('sub');
239
-        $userProfile->email = $data->get('email');
240
-        $this->storeData('expires_at', $data->get('exp'));
241
-
242
-        if (!empty($_REQUEST['user'])) {
243
-            $objUser = json_decode($_REQUEST['user']);
244
-            $user = new Data\Collection($objUser);
245
-            if (!$user->isEmpty()) {
246
-                $name = $user->get('name');
247
-                if (!empty($name->firstName)) {
248
-                    $userProfile->firstName = $name->firstName;
249
-                    $userProfile->lastName = $name->lastName;
250
-                    $userProfile->displayName = join(' ', [$userProfile->firstName, $userProfile->lastName]);
251
-                }
252
-            }
253
-        }
254
-
255
-        return $userProfile;
256
-    }
257
-
258
-    /**
259
-     * Get the Apple secret as a JWT token
260
-     *
261
-     * @return string secret token
262
-     * @throws InvalidApplicationCredentialsException
263
-     */
264
-    private function getSecret()
265
-    {
266
-        // Your 10-character Team ID
267
-        $team_id = $this->config->filter('keys')->get('team_id');
268
-
269
-        if (!$team_id) {
270
-            throw new InvalidApplicationCredentialsException(
271
-                'Missing parameter team_id: your team id is required to generate the JWS token.'
272
-            );
273
-        }
274
-
275
-        // Your Services ID, e.g. com.aaronparecki.services
276
-        $client_id = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
277
-
278
-        if (!$client_id) {
279
-            throw new InvalidApplicationCredentialsException(
280
-                'Missing parameter id: your client id is required to generate the JWS token.'
281
-            );
282
-        }
283
-
284
-        // Find the 10-char Key ID value from the portal
285
-        $key_id = $this->config->filter('keys')->get('key_id');
286
-
287
-        if (!$key_id) {
288
-            throw new InvalidApplicationCredentialsException(
289
-                'Missing parameter key_id: your key id is required to generate the JWS token.'
290
-            );
291
-        }
292
-
293
-        // Find the 10-char Key ID value from the portal
294
-        $key_content = $this->config->filter('keys')->get('key_content');
295
-
296
-        // Save your private key from Apple in a file called `key.txt`
297
-        if (!$key_content) {
298
-            $key_file = $this->config->filter('keys')->get('key_file');
299
-
300
-            if (!$key_file) {
301
-                throw new InvalidApplicationCredentialsException(
302
-                    'Missing parameter key_content or key_file: your key is required to generate the JWS token.'
303
-                );
304
-            }
305
-
306
-            if (!file_exists($key_file)) {
307
-                throw new InvalidApplicationCredentialsException(
308
-                    "Your key file $key_file does not exist."
309
-                );
310
-            }
311
-
312
-            $key_content = file_get_contents($key_file);
313
-        }
314
-
315
-        $data = [
316
-            'iat' => time(),
317
-            'exp' => time() + 86400 * 180,
318
-            'iss' => $team_id,
319
-            'aud' => 'https://appleid.apple.com',
320
-            'sub' => $client_id
321
-        ];
322
-
323
-        return JWT::encode($data, $key_content, 'ES256', $key_id);
324
-    }
325
-
326
-    /**
327
-     * Try to get the installed JWT version
328
-     *
329
-     * If composer 2 is installed use InstalledVersions::getVersion,
330
-     * otherwise return an empty string because no version check is available
331
-     *
332
-     * @return string|null
333
-     */
334
-    private function getJwtVersion()
335
-    {
336
-        // assume old JWT version if no version check is possible because composer 1 is installed
337
-        return class_exists('Composer\InstalledVersions') ?
338
-            InstalledVersions::getVersion('firebase/php-jwt') :
339
-            '';
340
-    }
67
+	/**
68
+	 * {@inheritdoc}
69
+	 */
70
+	protected $scope = 'name email';
71
+
72
+	/**
73
+	 * {@inheritdoc}
74
+	 */
75
+	protected $apiBaseUrl = 'https://appleid.apple.com/auth/';
76
+
77
+	/**
78
+	 * {@inheritdoc}
79
+	 */
80
+	protected $authorizeUrl = 'https://appleid.apple.com/auth/authorize';
81
+
82
+	/**
83
+	 * {@inheritdoc}
84
+	 */
85
+	protected $accessTokenUrl = 'https://appleid.apple.com/auth/token';
86
+
87
+	/**
88
+	 * {@inheritdoc}
89
+	 */
90
+	protected $apiDocumentation = 'https://developer.apple.com/documentation/sign_in_with_apple';
91
+
92
+	/**
93
+	 * {@inheritdoc}
94
+	 * The Sign in with Apple servers require percent encoding (or URL encoding)
95
+	 * for its query parameters. If you are using the Sign in with Apple REST API,
96
+	 * you must provide values with encoded spaces (`%20`) instead of plus (`+`) signs.
97
+	 */
98
+	protected $AuthorizeUrlParametersEncType = PHP_QUERY_RFC3986;
99
+
100
+	/**
101
+	 * {@inheritdoc}
102
+	 */
103
+	protected function initialize()
104
+	{
105
+		parent::initialize();
106
+		$this->AuthorizeUrlParameters['response_mode'] = 'form_post';
107
+
108
+		if ($this->isRefreshTokenAvailable()) {
109
+			$this->tokenRefreshParameters += [
110
+				'client_id' => $this->clientId,
111
+				'client_secret' => $this->clientSecret,
112
+			];
113
+		}
114
+	}
115
+
116
+	/**
117
+	 * {@inheritdoc}
118
+	 * @throws InvalidApplicationCredentialsException
119
+	 */
120
+	protected function configure()
121
+	{
122
+		$keys = $this->config->get('keys');
123
+		$keys['secret'] = $this->getSecret();
124
+		$this->config->set('keys', $keys);
125
+		parent::configure();
126
+	}
127
+
128
+	/**
129
+	 * {@inheritdoc}
130
+	 *
131
+	 * include id_token $tokenNames
132
+	 */
133
+	public function getAccessToken()
134
+	{
135
+		$tokenNames = [
136
+			'access_token',
137
+			'id_token',
138
+			'access_token_secret',
139
+			'token_type',
140
+			'refresh_token',
141
+			'expires_in',
142
+			'expires_at',
143
+		];
144
+
145
+		$tokens = [];
146
+
147
+		foreach ($tokenNames as $name) {
148
+			if ($this->getStoredData($name)) {
149
+				$tokens[$name] = $this->getStoredData($name);
150
+			}
151
+		}
152
+
153
+		return $tokens;
154
+	}
155
+
156
+	/**
157
+	 * {@inheritdoc}
158
+	 */
159
+	protected function validateAccessTokenExchange($response)
160
+	{
161
+		$collection = parent::validateAccessTokenExchange($response);
162
+
163
+		$this->storeData('id_token', $collection->get('id_token'));
164
+
165
+		return $collection;
166
+	}
167
+
168
+	/**
169
+	 * Get the user profile
170
+	 *
171
+	 * @throws HttpClientFailureException
172
+	 * @throws InvalidAccessTokenException
173
+	 * @throws UnexpectedValueException
174
+	 * @throws HttpRequestFailedException
175
+	 * @throws Exception
176
+	 */
177
+	public function getUserProfile()
178
+	{
179
+		$id_token = $this->getStoredData('id_token');
180
+
181
+		$verifyTokenSignature =
182
+			$this->config->exists('verifyTokenSignature') ? $this->config->get('verifyTokenSignature') : true;
183
+
184
+		if (!$verifyTokenSignature) {
185
+			// payload extraction by https://github.com/omidborjian
186
+			// https://github.com/hybridauth/hybridauth/issues/1095#issuecomment-626479263
187
+			// JWT splits the string to 3 components 1) first is header 2) is payload 3) is signature
188
+			$payload = explode('.', $id_token)[1];
189
+			$payload = json_decode(base64_decode($payload));
190
+		} else {
191
+			// validate the token signature and get the payload
192
+			$publicKeys = $this->apiRequest('keys');
193
+
194
+			JWT::$leeway = 120;
195
+
196
+			$error = false;
197
+			$payload = null;
198
+
199
+			foreach ($publicKeys->keys as $publicKey) {
200
+				try {
201
+					$jwk = (array)$publicKey;
202
+
203
+					$key = PublicKeyLoader::load(
204
+						[
205
+							'e' => new BigInteger(base64_decode($jwk['e']), 256),
206
+							'n' => new BigInteger(base64_decode(strtr($jwk['n'], '-_', '+/'), true), 256)
207
+						]
208
+					)
209
+						->withHash('sha1')
210
+						->withMGFHash('sha1');
211
+
212
+					$pem = (string)$key;
213
+
214
+					$payload = (version_compare($this->getJwtVersion(), '6.2') < 0) ?
215
+						JWT::decode($id_token, $pem, ['RS256']) :
216
+						JWT::decode($id_token, new Key($pem, 'RS256'));
217
+					break;
218
+				} catch (Exception $e) {
219
+					$error = $e->getMessage();
220
+					if ($e instanceof ExpiredException) {
221
+						break;
222
+					}
223
+				}
224
+			}
225
+
226
+			if ($error && !$payload) {
227
+				throw new Exception($error);
228
+			}
229
+		}
230
+
231
+		$data = new Data\Collection($payload);
232
+
233
+		if (!$data->exists('sub')) {
234
+			throw new UnexpectedValueException('Missing token payload.');
235
+		}
236
+
237
+		$userProfile = new User\Profile();
238
+		$userProfile->identifier = $data->get('sub');
239
+		$userProfile->email = $data->get('email');
240
+		$this->storeData('expires_at', $data->get('exp'));
241
+
242
+		if (!empty($_REQUEST['user'])) {
243
+			$objUser = json_decode($_REQUEST['user']);
244
+			$user = new Data\Collection($objUser);
245
+			if (!$user->isEmpty()) {
246
+				$name = $user->get('name');
247
+				if (!empty($name->firstName)) {
248
+					$userProfile->firstName = $name->firstName;
249
+					$userProfile->lastName = $name->lastName;
250
+					$userProfile->displayName = join(' ', [$userProfile->firstName, $userProfile->lastName]);
251
+				}
252
+			}
253
+		}
254
+
255
+		return $userProfile;
256
+	}
257
+
258
+	/**
259
+	 * Get the Apple secret as a JWT token
260
+	 *
261
+	 * @return string secret token
262
+	 * @throws InvalidApplicationCredentialsException
263
+	 */
264
+	private function getSecret()
265
+	{
266
+		// Your 10-character Team ID
267
+		$team_id = $this->config->filter('keys')->get('team_id');
268
+
269
+		if (!$team_id) {
270
+			throw new InvalidApplicationCredentialsException(
271
+				'Missing parameter team_id: your team id is required to generate the JWS token.'
272
+			);
273
+		}
274
+
275
+		// Your Services ID, e.g. com.aaronparecki.services
276
+		$client_id = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
277
+
278
+		if (!$client_id) {
279
+			throw new InvalidApplicationCredentialsException(
280
+				'Missing parameter id: your client id is required to generate the JWS token.'
281
+			);
282
+		}
283
+
284
+		// Find the 10-char Key ID value from the portal
285
+		$key_id = $this->config->filter('keys')->get('key_id');
286
+
287
+		if (!$key_id) {
288
+			throw new InvalidApplicationCredentialsException(
289
+				'Missing parameter key_id: your key id is required to generate the JWS token.'
290
+			);
291
+		}
292
+
293
+		// Find the 10-char Key ID value from the portal
294
+		$key_content = $this->config->filter('keys')->get('key_content');
295
+
296
+		// Save your private key from Apple in a file called `key.txt`
297
+		if (!$key_content) {
298
+			$key_file = $this->config->filter('keys')->get('key_file');
299
+
300
+			if (!$key_file) {
301
+				throw new InvalidApplicationCredentialsException(
302
+					'Missing parameter key_content or key_file: your key is required to generate the JWS token.'
303
+				);
304
+			}
305
+
306
+			if (!file_exists($key_file)) {
307
+				throw new InvalidApplicationCredentialsException(
308
+					"Your key file $key_file does not exist."
309
+				);
310
+			}
311
+
312
+			$key_content = file_get_contents($key_file);
313
+		}
314
+
315
+		$data = [
316
+			'iat' => time(),
317
+			'exp' => time() + 86400 * 180,
318
+			'iss' => $team_id,
319
+			'aud' => 'https://appleid.apple.com',
320
+			'sub' => $client_id
321
+		];
322
+
323
+		return JWT::encode($data, $key_content, 'ES256', $key_id);
324
+	}
325
+
326
+	/**
327
+	 * Try to get the installed JWT version
328
+	 *
329
+	 * If composer 2 is installed use InstalledVersions::getVersion,
330
+	 * otherwise return an empty string because no version check is available
331
+	 *
332
+	 * @return string|null
333
+	 */
334
+	private function getJwtVersion()
335
+	{
336
+		// assume old JWT version if no version check is possible because composer 1 is installed
337
+		return class_exists('Composer\InstalledVersions') ?
338
+			InstalledVersions::getVersion('firebase/php-jwt') :
339
+			'';
340
+	}
341 341
 }
Please login to merge, or discard this patch.
Spacing   +16 added lines, -18 removed lines patch added patch discarded remove patch
@@ -181,7 +181,7 @@  discard block
 block discarded – undo
181 181
         $verifyTokenSignature =
182 182
             $this->config->exists('verifyTokenSignature') ? $this->config->get('verifyTokenSignature') : true;
183 183
 
184
-        if (!$verifyTokenSignature) {
184
+        if ( ! $verifyTokenSignature) {
185 185
             // payload extraction by https://github.com/omidborjian
186 186
             // https://github.com/hybridauth/hybridauth/issues/1095#issuecomment-626479263
187 187
             // JWT splits the string to 3 components 1) first is header 2) is payload 3) is signature
@@ -198,7 +198,7 @@  discard block
 block discarded – undo
198 198
 
199 199
             foreach ($publicKeys->keys as $publicKey) {
200 200
                 try {
201
-                    $jwk = (array)$publicKey;
201
+                    $jwk = (array) $publicKey;
202 202
 
203 203
                     $key = PublicKeyLoader::load(
204 204
                         [
@@ -209,11 +209,10 @@  discard block
 block discarded – undo
209 209
                         ->withHash('sha1')
210 210
                         ->withMGFHash('sha1');
211 211
 
212
-                    $pem = (string)$key;
212
+                    $pem = (string) $key;
213 213
 
214 214
                     $payload = (version_compare($this->getJwtVersion(), '6.2') < 0) ?
215
-                        JWT::decode($id_token, $pem, ['RS256']) :
216
-                        JWT::decode($id_token, new Key($pem, 'RS256'));
215
+                        JWT::decode($id_token, $pem, ['RS256']) : JWT::decode($id_token, new Key($pem, 'RS256'));
217 216
                     break;
218 217
                 } catch (Exception $e) {
219 218
                     $error = $e->getMessage();
@@ -223,14 +222,14 @@  discard block
 block discarded – undo
223 222
                 }
224 223
             }
225 224
 
226
-            if ($error && !$payload) {
225
+            if ($error && ! $payload) {
227 226
                 throw new Exception($error);
228 227
             }
229 228
         }
230 229
 
231 230
         $data = new Data\Collection($payload);
232 231
 
233
-        if (!$data->exists('sub')) {
232
+        if ( ! $data->exists('sub')) {
234 233
             throw new UnexpectedValueException('Missing token payload.');
235 234
         }
236 235
 
@@ -239,12 +238,12 @@  discard block
 block discarded – undo
239 238
         $userProfile->email = $data->get('email');
240 239
         $this->storeData('expires_at', $data->get('exp'));
241 240
 
242
-        if (!empty($_REQUEST['user'])) {
241
+        if ( ! empty($_REQUEST['user'])) {
243 242
             $objUser = json_decode($_REQUEST['user']);
244 243
             $user = new Data\Collection($objUser);
245
-            if (!$user->isEmpty()) {
244
+            if ( ! $user->isEmpty()) {
246 245
                 $name = $user->get('name');
247
-                if (!empty($name->firstName)) {
246
+                if ( ! empty($name->firstName)) {
248 247
                     $userProfile->firstName = $name->firstName;
249 248
                     $userProfile->lastName = $name->lastName;
250 249
                     $userProfile->displayName = join(' ', [$userProfile->firstName, $userProfile->lastName]);
@@ -266,7 +265,7 @@  discard block
 block discarded – undo
266 265
         // Your 10-character Team ID
267 266
         $team_id = $this->config->filter('keys')->get('team_id');
268 267
 
269
-        if (!$team_id) {
268
+        if ( ! $team_id) {
270 269
             throw new InvalidApplicationCredentialsException(
271 270
                 'Missing parameter team_id: your team id is required to generate the JWS token.'
272 271
             );
@@ -275,7 +274,7 @@  discard block
 block discarded – undo
275 274
         // Your Services ID, e.g. com.aaronparecki.services
276 275
         $client_id = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
277 276
 
278
-        if (!$client_id) {
277
+        if ( ! $client_id) {
279 278
             throw new InvalidApplicationCredentialsException(
280 279
                 'Missing parameter id: your client id is required to generate the JWS token.'
281 280
             );
@@ -284,7 +283,7 @@  discard block
 block discarded – undo
284 283
         // Find the 10-char Key ID value from the portal
285 284
         $key_id = $this->config->filter('keys')->get('key_id');
286 285
 
287
-        if (!$key_id) {
286
+        if ( ! $key_id) {
288 287
             throw new InvalidApplicationCredentialsException(
289 288
                 'Missing parameter key_id: your key id is required to generate the JWS token.'
290 289
             );
@@ -294,16 +293,16 @@  discard block
 block discarded – undo
294 293
         $key_content = $this->config->filter('keys')->get('key_content');
295 294
 
296 295
         // Save your private key from Apple in a file called `key.txt`
297
-        if (!$key_content) {
296
+        if ( ! $key_content) {
298 297
             $key_file = $this->config->filter('keys')->get('key_file');
299 298
 
300
-            if (!$key_file) {
299
+            if ( ! $key_file) {
301 300
                 throw new InvalidApplicationCredentialsException(
302 301
                     'Missing parameter key_content or key_file: your key is required to generate the JWS token.'
303 302
                 );
304 303
             }
305 304
 
306
-            if (!file_exists($key_file)) {
305
+            if ( ! file_exists($key_file)) {
307 306
                 throw new InvalidApplicationCredentialsException(
308 307
                     "Your key file $key_file does not exist."
309 308
                 );
@@ -335,7 +334,6 @@  discard block
 block discarded – undo
335 334
     {
336 335
         // assume old JWT version if no version check is possible because composer 1 is installed
337 336
         return class_exists('Composer\InstalledVersions') ?
338
-            InstalledVersions::getVersion('firebase/php-jwt') :
339
-            '';
337
+            InstalledVersions::getVersion('firebase/php-jwt') : '';
340 338
     }
341 339
 }
Please login to merge, or discard this patch.
src/Adapter/OAuth2.php 2 patches
Indentation   +716 added lines, -716 removed lines patch added patch discarded remove patch
@@ -24,721 +24,721 @@
 block discarded – undo
24 24
  */
25 25
 abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
26 26
 {
27
-    /**
28
-     * Client Identifier
29
-     *
30
-     * RFC6749: client_id REQUIRED. The client identifier issued to the client during
31
-     * the registration process described by Section 2.2.
32
-     *
33
-     * http://tools.ietf.org/html/rfc6749#section-2.2
34
-     *
35
-     * @var string
36
-     */
37
-    protected $clientId = '';
38
-
39
-    /**
40
-     * Client Secret
41
-     *
42
-     * RFC6749: client_secret REQUIRED. The client secret. The client MAY omit the
43
-     * parameter if the client secret is an empty string.
44
-     *
45
-     * http://tools.ietf.org/html/rfc6749#section-2.2
46
-     *
47
-     * @var string
48
-     */
49
-    protected $clientSecret = '';
50
-
51
-    /**
52
-     * Access Token Scope
53
-     *
54
-     * RFC6749: The authorization and token endpoints allow the client to specify the
55
-     * scope of the access request using the "scope" request parameter.
56
-     *
57
-     * http://tools.ietf.org/html/rfc6749#section-3.3
58
-     *
59
-     * @var string
60
-     */
61
-    protected $scope = '';
62
-
63
-    /**
64
-     * Base URL to provider API
65
-     *
66
-     * This var will be used to build urls when sending signed requests
67
-     *
68
-     * @var string
69
-     */
70
-    protected $apiBaseUrl = '';
71
-
72
-    /**
73
-     * Authorization Endpoint
74
-     *
75
-     * RFC6749: The authorization endpoint is used to interact with the resource
76
-     * owner and obtain an authorization grant.
77
-     *
78
-     * http://tools.ietf.org/html/rfc6749#section-3.1
79
-     *
80
-     * @var string
81
-     */
82
-    protected $authorizeUrl = '';
83
-
84
-    /**
85
-     * Access Token Endpoint
86
-     *
87
-     * RFC6749: The token endpoint is used by the client to obtain an access token by
88
-     * presenting its authorization grant or refresh token.
89
-     *
90
-     * http://tools.ietf.org/html/rfc6749#section-3.2
91
-     *
92
-     * @var string
93
-     */
94
-    protected $accessTokenUrl = '';
95
-
96
-    /**
97
-     * TokenInfo endpoint
98
-     *
99
-     * Access token validation. OPTIONAL.
100
-     *
101
-     * @var string
102
-     */
103
-    protected $accessTokenInfoUrl = '';
104
-
105
-    /**
106
-     * IPD API Documentation
107
-     *
108
-     * OPTIONAL.
109
-     *
110
-     * @var string
111
-     */
112
-    protected $apiDocumentation = '';
113
-
114
-    /**
115
-     * Redirection Endpoint or Callback
116
-     *
117
-     * RFC6749: After completing its interaction with the resource owner, the
118
-     * authorization server directs the resource owner's user-agent back to
119
-     * the client.
120
-     *
121
-     * http://tools.ietf.org/html/rfc6749#section-3.1.2
122
-     *
123
-     * @var string
124
-     */
125
-    protected $callback = '';
126
-
127
-    /**
128
-     * Authorization Url Parameters
129
-     *
130
-     * @var array
131
-     */
132
-    protected $AuthorizeUrlParameters = [];
133
-
134
-
135
-    /**
136
-     * Authorization Url Parameter encoding type
137
-     * @see https://www.php.net/manual/de/function.http-build-query.php
138
-     *
139
-     * @var string
140
-     */
141
-    protected $AuthorizeUrlParametersEncType = PHP_QUERY_RFC1738;
142
-
143
-    /**
144
-     * Authorization Request State
145
-     *
146
-     * @var bool
147
-     */
148
-    protected $supportRequestState = true;
149
-
150
-    /**
151
-     * Access Token name
152
-     *
153
-     * While most providers will use 'access_token' as name for the Access Token attribute, other do not.
154
-     * On the latter case, this should be set by sub classes.
155
-     *
156
-     * @var string
157
-     */
158
-    protected $accessTokenName = 'access_token';
159
-
160
-    /**
161
-     * Authorization Request HTTP method.
162
-     *
163
-     * @see exchangeCodeForAccessToken()
164
-     *
165
-     * @var string
166
-     */
167
-    protected $tokenExchangeMethod = 'POST';
168
-
169
-    /**
170
-     * Authorization Request URL parameters.
171
-     *
172
-     * Sub classes may change add any additional parameter when necessary.
173
-     *
174
-     * @see exchangeCodeForAccessToken()
175
-     *
176
-     * @var array
177
-     */
178
-    protected $tokenExchangeParameters = [];
179
-
180
-    /**
181
-     * Authorization Request HTTP headers.
182
-     *
183
-     * Sub classes may add any additional header when necessary.
184
-     *
185
-     * @see exchangeCodeForAccessToken()
186
-     *
187
-     * @var array
188
-     */
189
-    protected $tokenExchangeHeaders = [];
190
-
191
-    /**
192
-     * Refresh Token Request HTTP method.
193
-     *
194
-     * @see refreshAccessToken()
195
-     *
196
-     * @var string
197
-     */
198
-    protected $tokenRefreshMethod = 'POST';
199
-
200
-    /**
201
-     * Refresh Token Request URL parameters.
202
-     *
203
-     * Sub classes may change add any additional parameter when necessary.
204
-     *
205
-     * @see refreshAccessToken()
206
-     *
207
-     * @var array|null
208
-     */
209
-    protected $tokenRefreshParameters = null;
210
-
211
-    /**
212
-     * Refresh Token Request HTTP headers.
213
-     *
214
-     * Sub classes may add any additional header when necessary.
215
-     *
216
-     * @see refreshAccessToken()
217
-     *
218
-     * @var array
219
-     */
220
-    protected $tokenRefreshHeaders = [];
221
-
222
-    /**
223
-     * Authorization Request URL parameters.
224
-     *
225
-     * Sub classes may change add any additional parameter when necessary.
226
-     *
227
-     * @see apiRequest()
228
-     *
229
-     * @var array
230
-     */
231
-    protected $apiRequestParameters = [];
232
-
233
-    /**
234
-     * Authorization Request HTTP headers.
235
-     *
236
-     * Sub classes may add any additional header when necessary.
237
-     *
238
-     * @see apiRequest()
239
-     *
240
-     * @var array
241
-     */
242
-    protected $apiRequestHeaders = [];
243
-
244
-    /**
245
-     * {@inheritdoc}
246
-     */
247
-    protected function configure()
248
-    {
249
-        $this->clientId = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
250
-        $this->clientSecret = $this->config->filter('keys')->get('secret');
251
-
252
-        if (!$this->clientId || !$this->clientSecret) {
253
-            throw new InvalidApplicationCredentialsException(
254
-                'Your application id is required in order to connect to ' . $this->providerId
255
-            );
256
-        }
257
-
258
-        $this->scope = $this->config->exists('scope') ? $this->config->get('scope') : $this->scope;
259
-
260
-        if ($this->config->exists('tokens')) {
261
-            $this->setAccessToken($this->config->get('tokens'));
262
-        }
27
+	/**
28
+	 * Client Identifier
29
+	 *
30
+	 * RFC6749: client_id REQUIRED. The client identifier issued to the client during
31
+	 * the registration process described by Section 2.2.
32
+	 *
33
+	 * http://tools.ietf.org/html/rfc6749#section-2.2
34
+	 *
35
+	 * @var string
36
+	 */
37
+	protected $clientId = '';
38
+
39
+	/**
40
+	 * Client Secret
41
+	 *
42
+	 * RFC6749: client_secret REQUIRED. The client secret. The client MAY omit the
43
+	 * parameter if the client secret is an empty string.
44
+	 *
45
+	 * http://tools.ietf.org/html/rfc6749#section-2.2
46
+	 *
47
+	 * @var string
48
+	 */
49
+	protected $clientSecret = '';
50
+
51
+	/**
52
+	 * Access Token Scope
53
+	 *
54
+	 * RFC6749: The authorization and token endpoints allow the client to specify the
55
+	 * scope of the access request using the "scope" request parameter.
56
+	 *
57
+	 * http://tools.ietf.org/html/rfc6749#section-3.3
58
+	 *
59
+	 * @var string
60
+	 */
61
+	protected $scope = '';
62
+
63
+	/**
64
+	 * Base URL to provider API
65
+	 *
66
+	 * This var will be used to build urls when sending signed requests
67
+	 *
68
+	 * @var string
69
+	 */
70
+	protected $apiBaseUrl = '';
71
+
72
+	/**
73
+	 * Authorization Endpoint
74
+	 *
75
+	 * RFC6749: The authorization endpoint is used to interact with the resource
76
+	 * owner and obtain an authorization grant.
77
+	 *
78
+	 * http://tools.ietf.org/html/rfc6749#section-3.1
79
+	 *
80
+	 * @var string
81
+	 */
82
+	protected $authorizeUrl = '';
83
+
84
+	/**
85
+	 * Access Token Endpoint
86
+	 *
87
+	 * RFC6749: The token endpoint is used by the client to obtain an access token by
88
+	 * presenting its authorization grant or refresh token.
89
+	 *
90
+	 * http://tools.ietf.org/html/rfc6749#section-3.2
91
+	 *
92
+	 * @var string
93
+	 */
94
+	protected $accessTokenUrl = '';
95
+
96
+	/**
97
+	 * TokenInfo endpoint
98
+	 *
99
+	 * Access token validation. OPTIONAL.
100
+	 *
101
+	 * @var string
102
+	 */
103
+	protected $accessTokenInfoUrl = '';
104
+
105
+	/**
106
+	 * IPD API Documentation
107
+	 *
108
+	 * OPTIONAL.
109
+	 *
110
+	 * @var string
111
+	 */
112
+	protected $apiDocumentation = '';
113
+
114
+	/**
115
+	 * Redirection Endpoint or Callback
116
+	 *
117
+	 * RFC6749: After completing its interaction with the resource owner, the
118
+	 * authorization server directs the resource owner's user-agent back to
119
+	 * the client.
120
+	 *
121
+	 * http://tools.ietf.org/html/rfc6749#section-3.1.2
122
+	 *
123
+	 * @var string
124
+	 */
125
+	protected $callback = '';
126
+
127
+	/**
128
+	 * Authorization Url Parameters
129
+	 *
130
+	 * @var array
131
+	 */
132
+	protected $AuthorizeUrlParameters = [];
133
+
134
+
135
+	/**
136
+	 * Authorization Url Parameter encoding type
137
+	 * @see https://www.php.net/manual/de/function.http-build-query.php
138
+	 *
139
+	 * @var string
140
+	 */
141
+	protected $AuthorizeUrlParametersEncType = PHP_QUERY_RFC1738;
142
+
143
+	/**
144
+	 * Authorization Request State
145
+	 *
146
+	 * @var bool
147
+	 */
148
+	protected $supportRequestState = true;
149
+
150
+	/**
151
+	 * Access Token name
152
+	 *
153
+	 * While most providers will use 'access_token' as name for the Access Token attribute, other do not.
154
+	 * On the latter case, this should be set by sub classes.
155
+	 *
156
+	 * @var string
157
+	 */
158
+	protected $accessTokenName = 'access_token';
159
+
160
+	/**
161
+	 * Authorization Request HTTP method.
162
+	 *
163
+	 * @see exchangeCodeForAccessToken()
164
+	 *
165
+	 * @var string
166
+	 */
167
+	protected $tokenExchangeMethod = 'POST';
168
+
169
+	/**
170
+	 * Authorization Request URL parameters.
171
+	 *
172
+	 * Sub classes may change add any additional parameter when necessary.
173
+	 *
174
+	 * @see exchangeCodeForAccessToken()
175
+	 *
176
+	 * @var array
177
+	 */
178
+	protected $tokenExchangeParameters = [];
179
+
180
+	/**
181
+	 * Authorization Request HTTP headers.
182
+	 *
183
+	 * Sub classes may add any additional header when necessary.
184
+	 *
185
+	 * @see exchangeCodeForAccessToken()
186
+	 *
187
+	 * @var array
188
+	 */
189
+	protected $tokenExchangeHeaders = [];
190
+
191
+	/**
192
+	 * Refresh Token Request HTTP method.
193
+	 *
194
+	 * @see refreshAccessToken()
195
+	 *
196
+	 * @var string
197
+	 */
198
+	protected $tokenRefreshMethod = 'POST';
199
+
200
+	/**
201
+	 * Refresh Token Request URL parameters.
202
+	 *
203
+	 * Sub classes may change add any additional parameter when necessary.
204
+	 *
205
+	 * @see refreshAccessToken()
206
+	 *
207
+	 * @var array|null
208
+	 */
209
+	protected $tokenRefreshParameters = null;
210
+
211
+	/**
212
+	 * Refresh Token Request HTTP headers.
213
+	 *
214
+	 * Sub classes may add any additional header when necessary.
215
+	 *
216
+	 * @see refreshAccessToken()
217
+	 *
218
+	 * @var array
219
+	 */
220
+	protected $tokenRefreshHeaders = [];
221
+
222
+	/**
223
+	 * Authorization Request URL parameters.
224
+	 *
225
+	 * Sub classes may change add any additional parameter when necessary.
226
+	 *
227
+	 * @see apiRequest()
228
+	 *
229
+	 * @var array
230
+	 */
231
+	protected $apiRequestParameters = [];
232
+
233
+	/**
234
+	 * Authorization Request HTTP headers.
235
+	 *
236
+	 * Sub classes may add any additional header when necessary.
237
+	 *
238
+	 * @see apiRequest()
239
+	 *
240
+	 * @var array
241
+	 */
242
+	protected $apiRequestHeaders = [];
243
+
244
+	/**
245
+	 * {@inheritdoc}
246
+	 */
247
+	protected function configure()
248
+	{
249
+		$this->clientId = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
250
+		$this->clientSecret = $this->config->filter('keys')->get('secret');
251
+
252
+		if (!$this->clientId || !$this->clientSecret) {
253
+			throw new InvalidApplicationCredentialsException(
254
+				'Your application id is required in order to connect to ' . $this->providerId
255
+			);
256
+		}
257
+
258
+		$this->scope = $this->config->exists('scope') ? $this->config->get('scope') : $this->scope;
259
+
260
+		if ($this->config->exists('tokens')) {
261
+			$this->setAccessToken($this->config->get('tokens'));
262
+		}
263 263
         
264
-        if ($this->config->exists('supportRequestState')) {
265
-            $this->supportRequestState = $this->config->get('supportRequestState');
266
-        }
267
-
268
-        $this->setCallback($this->config->get('callback'));
269
-        $this->setApiEndpoints($this->config->get('endpoints'));
270
-    }
271
-
272
-    /**
273
-     * {@inheritdoc}
274
-     */
275
-    protected function initialize()
276
-    {
277
-        $this->AuthorizeUrlParameters = [
278
-            'response_type' => 'code',
279
-            'client_id' => $this->clientId,
280
-            'redirect_uri' => $this->callback,
281
-            'scope' => $this->scope,
282
-        ];
283
-
284
-        $this->tokenExchangeParameters = [
285
-            'client_id' => $this->clientId,
286
-            'client_secret' => $this->clientSecret,
287
-            'grant_type' => 'authorization_code',
288
-            'redirect_uri' => $this->callback
289
-        ];
290
-
291
-        $refreshToken = $this->getStoredData('refresh_token');
292
-        if (!empty($refreshToken)) {
293
-            $this->tokenRefreshParameters = [
294
-                'grant_type' => 'refresh_token',
295
-                'refresh_token' => $refreshToken,
296
-            ];
297
-        }
298
-
299
-        $this->apiRequestHeaders = [
300
-            'Authorization' => 'Bearer ' . $this->getStoredData('access_token')
301
-        ];
302
-    }
303
-
304
-    /**
305
-     * {@inheritdoc}
306
-     */
307
-    public function authenticate()
308
-    {
309
-        $this->logger->info(sprintf('%s::authenticate()', get_class($this)));
310
-
311
-        if ($this->isConnected()) {
312
-            return true;
313
-        }
314
-
315
-        try {
316
-            $this->authenticateCheckError();
317
-
318
-            $code = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'code');
319
-
320
-            if (empty($code)) {
321
-                $this->authenticateBegin();
322
-            } else {
323
-                $this->authenticateFinish();
324
-            }
325
-        } catch (Exception $e) {
326
-            $this->clearStoredData();
327
-
328
-            throw $e;
329
-        }
330
-
331
-        return null;
332
-    }
333
-
334
-    /**
335
-     * {@inheritdoc}
336
-     */
337
-    public function isConnected()
338
-    {
339
-        if ((bool)$this->getStoredData('access_token')) {
340
-            return (!$this->hasAccessTokenExpired() || $this->isRefreshTokenAvailable());
341
-        }
342
-        return false;
343
-    }
344
-
345
-    /**
346
-     * If we can use a refresh token, then an expired token does not stop us being connected.
347
-     *
348
-     * @return bool
349
-     */
350
-    public function isRefreshTokenAvailable()
351
-    {
352
-        return is_array($this->tokenRefreshParameters);
353
-    }
354
-
355
-    /**
356
-     * Authorization Request Error Response
357
-     *
358
-     * RFC6749: If the request fails due to a missing, invalid, or mismatching
359
-     * redirection URI, or if the client identifier is missing or invalid,
360
-     * the authorization server SHOULD inform the resource owner of the error.
361
-     *
362
-     * http://tools.ietf.org/html/rfc6749#section-4.1.2.1
363
-     *
364
-     * @throws \Hybridauth\Exception\InvalidAuthorizationCodeException
365
-     * @throws \Hybridauth\Exception\AuthorizationDeniedException
366
-     */
367
-    protected function authenticateCheckError()
368
-    {
369
-        $error = filter_input(INPUT_GET, 'error', FILTER_SANITIZE_SPECIAL_CHARS);
370
-
371
-        if (!empty($error)) {
372
-            $error_description = filter_input(INPUT_GET, 'error_description', FILTER_SANITIZE_SPECIAL_CHARS);
373
-            $error_uri = filter_input(INPUT_GET, 'error_uri', FILTER_SANITIZE_SPECIAL_CHARS);
374
-
375
-            $collated_error = sprintf('Provider returned an error: %s %s %s', $error, $error_description, $error_uri);
376
-
377
-            if ($error == 'access_denied') {
378
-                throw new AuthorizationDeniedException($collated_error);
379
-            }
380
-
381
-            throw new InvalidAuthorizationCodeException($collated_error);
382
-        }
383
-    }
384
-
385
-    /**
386
-     * Initiate the authorization protocol
387
-     *
388
-     * Build Authorization URL for Authorization Request and redirect the user-agent to the
389
-     * Authorization Server.
390
-     */
391
-    protected function authenticateBegin()
392
-    {
393
-        $authUrl = $this->getAuthorizeUrl();
394
-
395
-        $this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]);
396
-
397
-        HttpClient\Util::redirect($authUrl);
398
-    }
399
-
400
-    /**
401
-     * Finalize the authorization process
402
-     *
403
-     * @throws \Hybridauth\Exception\HttpClientFailureException
404
-     * @throws \Hybridauth\Exception\HttpRequestFailedException
405
-     * @throws InvalidAccessTokenException
406
-     * @throws InvalidAuthorizationStateException
407
-     */
408
-    protected function authenticateFinish()
409
-    {
410
-        $this->logger->debug(
411
-            sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
412
-            [HttpClient\Util::getCurrentUrl(true)]
413
-        );
414
-
415
-        $state = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'state');
416
-        $code = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'code');
417
-
418
-        /**
419
-         * Authorization Request State
420
-         *
421
-         * RFC6749: state : RECOMMENDED. An opaque value used by the client to maintain
422
-         * state between the request and callback. The authorization server includes
423
-         * this value when redirecting the user-agent back to the client.
424
-         *
425
-         * http://tools.ietf.org/html/rfc6749#section-4.1.1
426
-         */
427
-        if ($this->supportRequestState
428
-            && (!$state || $this->getStoredData('authorization_state') != $state)
429
-        ) {
430
-            $this->deleteStoredData('authorization_state');
431
-            throw new InvalidAuthorizationStateException(
432
-                'The authorization state [state=' . substr(htmlentities($state), 0, 100) . '] '
433
-                . 'of this page is either invalid or has already been consumed.'
434
-            );
435
-        }
436
-
437
-        /**
438
-         * Authorization Request Code
439
-         *
440
-         * RFC6749: If the resource owner grants the access request, the authorization
441
-         * server issues an authorization code and delivers it to the client:
442
-         *
443
-         * http://tools.ietf.org/html/rfc6749#section-4.1.2
444
-         */
445
-        $response = $this->exchangeCodeForAccessToken($code);
446
-
447
-        $this->validateAccessTokenExchange($response);
448
-
449
-        $this->initialize();
450
-    }
451
-
452
-    /**
453
-     * Build Authorization URL for Authorization Request
454
-     *
455
-     * RFC6749: The client constructs the request URI by adding the following
456
-     * $parameters to the query component of the authorization endpoint URI:
457
-     *
458
-     *    - response_type  REQUIRED. Value MUST be set to "code".
459
-     *    - client_id      REQUIRED.
460
-     *    - redirect_uri   OPTIONAL.
461
-     *    - scope          OPTIONAL.
462
-     *    - state          RECOMMENDED.
463
-     *
464
-     * http://tools.ietf.org/html/rfc6749#section-4.1.1
465
-     *
466
-     * Sub classes may redefine this method when necessary.
467
-     *
468
-     * @param array $parameters
469
-     *
470
-     * @return string Authorization URL
471
-     */
472
-    protected function getAuthorizeUrl($parameters = [])
473
-    {
474
-        $this->AuthorizeUrlParameters = !empty($parameters)
475
-            ? $parameters
476
-            : array_replace(
477
-                (array)$this->AuthorizeUrlParameters,
478
-                (array)$this->config->get('authorize_url_parameters')
479
-            );
480
-
481
-        if ($this->supportRequestState) {
482
-            if (!isset($this->AuthorizeUrlParameters['state'])) {
483
-                $this->AuthorizeUrlParameters['state'] = 'HA-' . str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890');
484
-            }
485
-
486
-            $this->storeData('authorization_state', $this->AuthorizeUrlParameters['state']);
487
-        }
488
-
489
-        $queryParams = http_build_query($this->AuthorizeUrlParameters, '', '&', $this->AuthorizeUrlParametersEncType);
490
-        return $this->authorizeUrl . '?' . $queryParams;
491
-    }
492
-
493
-    /**
494
-     * Access Token Request
495
-     *
496
-     * This method will exchange the received $code in loginFinish() with an Access Token.
497
-     *
498
-     * RFC6749: The client makes a request to the token endpoint by sending the
499
-     * following parameters using the "application/x-www-form-urlencoded"
500
-     * with a character encoding of UTF-8 in the HTTP request entity-body:
501
-     *
502
-     *    - grant_type    REQUIRED. Value MUST be set to "authorization_code".
503
-     *    - code          REQUIRED. The authorization code received from the authorization server.
504
-     *    - redirect_uri  REQUIRED.
505
-     *    - client_id     REQUIRED.
506
-     *
507
-     * http://tools.ietf.org/html/rfc6749#section-4.1.3
508
-     *
509
-     * @param string $code
510
-     *
511
-     * @return string Raw Provider API response
512
-     * @throws \Hybridauth\Exception\HttpClientFailureException
513
-     * @throws \Hybridauth\Exception\HttpRequestFailedException
514
-     */
515
-    protected function exchangeCodeForAccessToken($code)
516
-    {
517
-        $this->tokenExchangeParameters['code'] = $code;
518
-
519
-        $response = $this->httpClient->request(
520
-            $this->accessTokenUrl,
521
-            $this->tokenExchangeMethod,
522
-            $this->tokenExchangeParameters,
523
-            $this->tokenExchangeHeaders
524
-        );
525
-
526
-        $this->validateApiResponse('Unable to exchange code for API access token');
527
-
528
-        return $response;
529
-    }
530
-
531
-    /**
532
-     * Validate Access Token Response
533
-     *
534
-     * RFC6749: If the access token request is valid and authorized, the
535
-     * authorization server issues an access token and optional refresh token.
536
-     * If the request client authentication failed or is invalid, the authorization
537
-     * server returns an error response as described in Section 5.2.
538
-     *
539
-     * Example of a successful response:
540
-     *
541
-     *  HTTP/1.1 200 OK
542
-     *  Content-Type: application/json;charset=UTF-8
543
-     *  Cache-Control: no-store
544
-     *  Pragma: no-cache
545
-     *
546
-     *  {
547
-     *      "access_token":"2YotnFZFEjr1zCsicMWpAA",
548
-     *      "token_type":"example",
549
-     *      "expires_in":3600,
550
-     *      "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
551
-     *      "example_parameter":"example_value"
552
-     *  }
553
-     *
554
-     * http://tools.ietf.org/html/rfc6749#section-4.1.4
555
-     *
556
-     * This method uses Data_Parser to attempt to decodes the raw $response (usually JSON)
557
-     * into a data collection.
558
-     *
559
-     * @param string $response
560
-     *
561
-     * @return \Hybridauth\Data\Collection
562
-     * @throws InvalidAccessTokenException
563
-     */
564
-    protected function validateAccessTokenExchange($response)
565
-    {
566
-        $data = (new Data\Parser())->parse($response);
567
-
568
-        $collection = new Data\Collection($data);
569
-
570
-        if (!$collection->exists('access_token')) {
571
-            throw new InvalidAccessTokenException(
572
-                'Provider returned no access_token: ' . htmlentities($response)
573
-            );
574
-        }
575
-
576
-        $this->storeData('access_token', $collection->get('access_token'));
577
-        $this->storeData('token_type', $collection->get('token_type'));
578
-
579
-        if ($collection->get('refresh_token')) {
580
-            $this->storeData('refresh_token', $collection->get('refresh_token'));
581
-        }
582
-
583
-        // calculate when the access token expire
584
-        if ($collection->exists('expires_in')) {
585
-            $expires_at = time() + (int)$collection->get('expires_in');
586
-
587
-            $this->storeData('expires_in', $collection->get('expires_in'));
588
-            $this->storeData('expires_at', $expires_at);
589
-        }
590
-
591
-        $this->deleteStoredData('authorization_state');
592
-
593
-        $this->initialize();
594
-
595
-        return $collection;
596
-    }
597
-
598
-    /**
599
-     * Refreshing an Access Token
600
-     *
601
-     * RFC6749: If the authorization server issued a refresh token to the
602
-     * client, the client makes a refresh request to the token endpoint by
603
-     * adding the following parameters ... in the HTTP request entity-body:
604
-     *
605
-     *    - grant_type     REQUIRED. Value MUST be set to "refresh_token".
606
-     *    - refresh_token  REQUIRED. The refresh token issued to the client.
607
-     *    - scope          OPTIONAL.
608
-     *
609
-     * http://tools.ietf.org/html/rfc6749#section-6
610
-     *
611
-     * This method is similar to exchangeCodeForAccessToken(). The only
612
-     * difference is here we exchange refresh_token for a new access_token.
613
-     *
614
-     * @param array $parameters
615
-     *
616
-     * @return string|null Raw Provider API response, or null if we cannot refresh
617
-     * @throws \Hybridauth\Exception\HttpClientFailureException
618
-     * @throws \Hybridauth\Exception\HttpRequestFailedException
619
-     * @throws InvalidAccessTokenException
620
-     */
621
-    public function refreshAccessToken($parameters = [])
622
-    {
623
-        $this->tokenRefreshParameters = !empty($parameters)
624
-            ? $parameters
625
-            : $this->tokenRefreshParameters;
626
-
627
-        if (!$this->isRefreshTokenAvailable()) {
628
-            return null;
629
-        }
630
-
631
-        $response = $this->httpClient->request(
632
-            $this->accessTokenUrl,
633
-            $this->tokenRefreshMethod,
634
-            $this->tokenRefreshParameters,
635
-            $this->tokenRefreshHeaders
636
-        );
637
-
638
-        $this->validateApiResponse('Unable to refresh the access token');
639
-
640
-        $this->validateRefreshAccessToken($response);
641
-
642
-        return $response;
643
-    }
644
-
645
-    /**
646
-     * Check whether access token has expired
647
-     *
648
-     * @param int|null $time
649
-     * @return bool|null
650
-     */
651
-    public function hasAccessTokenExpired($time = null)
652
-    {
653
-        if ($time === null) {
654
-            $time = time();
655
-        }
656
-
657
-        $expires_at = $this->getStoredData('expires_at');
658
-        if (!$expires_at) {
659
-            return null;
660
-        }
661
-
662
-        return $expires_at <= $time;
663
-    }
664
-
665
-    /**
666
-     * Validate Refresh Access Token Request
667
-     *
668
-     * RFC6749: If valid and authorized, the authorization server issues an
669
-     * access token as described in Section 5.1.  If the request failed
670
-     * verification or is invalid, the authorization server returns an error
671
-     * response as described in Section 5.2.
672
-     *
673
-     * http://tools.ietf.org/html/rfc6749#section-6
674
-     * http://tools.ietf.org/html/rfc6749#section-5.1
675
-     * http://tools.ietf.org/html/rfc6749#section-5.2
676
-     *
677
-     * This method simply use validateAccessTokenExchange(), however sub
678
-     * classes may redefine it when necessary.
679
-     *
680
-     * @param $response
681
-     *
682
-     * @return \Hybridauth\Data\Collection
683
-     * @throws InvalidAccessTokenException
684
-     */
685
-    protected function validateRefreshAccessToken($response)
686
-    {
687
-        return $this->validateAccessTokenExchange($response);
688
-    }
689
-
690
-    /**
691
-     * Send a signed request to provider API
692
-     *
693
-     * RFC6749: Accessing Protected Resources: The client accesses protected
694
-     * resources by presenting the access token to the resource server. The
695
-     * resource server MUST validate the access token and ensure that it has
696
-     * not expired and that its scope covers the requested resource.
697
-     *
698
-     * Note: Since the specifics of error responses is beyond the scope of
699
-     * RFC6749 and OAuth specifications, Hybridauth will consider any HTTP
700
-     * status code that is different than '200 OK' as an ERROR.
701
-     *
702
-     * http://tools.ietf.org/html/rfc6749#section-7
703
-     *
704
-     * @param string $url
705
-     * @param string $method
706
-     * @param array $parameters
707
-     * @param array $headers
708
-     * @param bool $multipart
709
-     *
710
-     * @return mixed
711
-     * @throws \Hybridauth\Exception\HttpClientFailureException
712
-     * @throws \Hybridauth\Exception\HttpRequestFailedException
713
-     * @throws InvalidAccessTokenException
714
-     */
715
-    public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
716
-    {
717
-        // refresh tokens if needed
718
-        $this->maintainToken();
719
-        if ($this->hasAccessTokenExpired() === true) {
720
-            $this->refreshAccessToken();
721
-        }
722
-
723
-        if (strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0) {
724
-            $url = rtrim($this->apiBaseUrl, '/') . '/' . ltrim($url, '/');
725
-        }
726
-
727
-        $parameters = array_replace($this->apiRequestParameters, (array)$parameters);
728
-        $headers = array_replace($this->apiRequestHeaders, (array)$headers);
729
-
730
-        $response = $this->httpClient->request(
731
-            $url,
732
-            $method,     // HTTP Request Method. Defaults to GET.
733
-            $parameters, // Request Parameters
734
-            $headers,    // Request Headers
735
-            $multipart   // Is request multipart
736
-        );
737
-
738
-        $this->validateApiResponse('Signed API request to ' . $url . ' has returned an error');
739
-
740
-        $response = (new Data\Parser())->parse($response);
741
-
742
-        return $response;
743
-    }
264
+		if ($this->config->exists('supportRequestState')) {
265
+			$this->supportRequestState = $this->config->get('supportRequestState');
266
+		}
267
+
268
+		$this->setCallback($this->config->get('callback'));
269
+		$this->setApiEndpoints($this->config->get('endpoints'));
270
+	}
271
+
272
+	/**
273
+	 * {@inheritdoc}
274
+	 */
275
+	protected function initialize()
276
+	{
277
+		$this->AuthorizeUrlParameters = [
278
+			'response_type' => 'code',
279
+			'client_id' => $this->clientId,
280
+			'redirect_uri' => $this->callback,
281
+			'scope' => $this->scope,
282
+		];
283
+
284
+		$this->tokenExchangeParameters = [
285
+			'client_id' => $this->clientId,
286
+			'client_secret' => $this->clientSecret,
287
+			'grant_type' => 'authorization_code',
288
+			'redirect_uri' => $this->callback
289
+		];
290
+
291
+		$refreshToken = $this->getStoredData('refresh_token');
292
+		if (!empty($refreshToken)) {
293
+			$this->tokenRefreshParameters = [
294
+				'grant_type' => 'refresh_token',
295
+				'refresh_token' => $refreshToken,
296
+			];
297
+		}
298
+
299
+		$this->apiRequestHeaders = [
300
+			'Authorization' => 'Bearer ' . $this->getStoredData('access_token')
301
+		];
302
+	}
303
+
304
+	/**
305
+	 * {@inheritdoc}
306
+	 */
307
+	public function authenticate()
308
+	{
309
+		$this->logger->info(sprintf('%s::authenticate()', get_class($this)));
310
+
311
+		if ($this->isConnected()) {
312
+			return true;
313
+		}
314
+
315
+		try {
316
+			$this->authenticateCheckError();
317
+
318
+			$code = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'code');
319
+
320
+			if (empty($code)) {
321
+				$this->authenticateBegin();
322
+			} else {
323
+				$this->authenticateFinish();
324
+			}
325
+		} catch (Exception $e) {
326
+			$this->clearStoredData();
327
+
328
+			throw $e;
329
+		}
330
+
331
+		return null;
332
+	}
333
+
334
+	/**
335
+	 * {@inheritdoc}
336
+	 */
337
+	public function isConnected()
338
+	{
339
+		if ((bool)$this->getStoredData('access_token')) {
340
+			return (!$this->hasAccessTokenExpired() || $this->isRefreshTokenAvailable());
341
+		}
342
+		return false;
343
+	}
344
+
345
+	/**
346
+	 * If we can use a refresh token, then an expired token does not stop us being connected.
347
+	 *
348
+	 * @return bool
349
+	 */
350
+	public function isRefreshTokenAvailable()
351
+	{
352
+		return is_array($this->tokenRefreshParameters);
353
+	}
354
+
355
+	/**
356
+	 * Authorization Request Error Response
357
+	 *
358
+	 * RFC6749: If the request fails due to a missing, invalid, or mismatching
359
+	 * redirection URI, or if the client identifier is missing or invalid,
360
+	 * the authorization server SHOULD inform the resource owner of the error.
361
+	 *
362
+	 * http://tools.ietf.org/html/rfc6749#section-4.1.2.1
363
+	 *
364
+	 * @throws \Hybridauth\Exception\InvalidAuthorizationCodeException
365
+	 * @throws \Hybridauth\Exception\AuthorizationDeniedException
366
+	 */
367
+	protected function authenticateCheckError()
368
+	{
369
+		$error = filter_input(INPUT_GET, 'error', FILTER_SANITIZE_SPECIAL_CHARS);
370
+
371
+		if (!empty($error)) {
372
+			$error_description = filter_input(INPUT_GET, 'error_description', FILTER_SANITIZE_SPECIAL_CHARS);
373
+			$error_uri = filter_input(INPUT_GET, 'error_uri', FILTER_SANITIZE_SPECIAL_CHARS);
374
+
375
+			$collated_error = sprintf('Provider returned an error: %s %s %s', $error, $error_description, $error_uri);
376
+
377
+			if ($error == 'access_denied') {
378
+				throw new AuthorizationDeniedException($collated_error);
379
+			}
380
+
381
+			throw new InvalidAuthorizationCodeException($collated_error);
382
+		}
383
+	}
384
+
385
+	/**
386
+	 * Initiate the authorization protocol
387
+	 *
388
+	 * Build Authorization URL for Authorization Request and redirect the user-agent to the
389
+	 * Authorization Server.
390
+	 */
391
+	protected function authenticateBegin()
392
+	{
393
+		$authUrl = $this->getAuthorizeUrl();
394
+
395
+		$this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]);
396
+
397
+		HttpClient\Util::redirect($authUrl);
398
+	}
399
+
400
+	/**
401
+	 * Finalize the authorization process
402
+	 *
403
+	 * @throws \Hybridauth\Exception\HttpClientFailureException
404
+	 * @throws \Hybridauth\Exception\HttpRequestFailedException
405
+	 * @throws InvalidAccessTokenException
406
+	 * @throws InvalidAuthorizationStateException
407
+	 */
408
+	protected function authenticateFinish()
409
+	{
410
+		$this->logger->debug(
411
+			sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
412
+			[HttpClient\Util::getCurrentUrl(true)]
413
+		);
414
+
415
+		$state = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'state');
416
+		$code = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'code');
417
+
418
+		/**
419
+		 * Authorization Request State
420
+		 *
421
+		 * RFC6749: state : RECOMMENDED. An opaque value used by the client to maintain
422
+		 * state between the request and callback. The authorization server includes
423
+		 * this value when redirecting the user-agent back to the client.
424
+		 *
425
+		 * http://tools.ietf.org/html/rfc6749#section-4.1.1
426
+		 */
427
+		if ($this->supportRequestState
428
+			&& (!$state || $this->getStoredData('authorization_state') != $state)
429
+		) {
430
+			$this->deleteStoredData('authorization_state');
431
+			throw new InvalidAuthorizationStateException(
432
+				'The authorization state [state=' . substr(htmlentities($state), 0, 100) . '] '
433
+				. 'of this page is either invalid or has already been consumed.'
434
+			);
435
+		}
436
+
437
+		/**
438
+		 * Authorization Request Code
439
+		 *
440
+		 * RFC6749: If the resource owner grants the access request, the authorization
441
+		 * server issues an authorization code and delivers it to the client:
442
+		 *
443
+		 * http://tools.ietf.org/html/rfc6749#section-4.1.2
444
+		 */
445
+		$response = $this->exchangeCodeForAccessToken($code);
446
+
447
+		$this->validateAccessTokenExchange($response);
448
+
449
+		$this->initialize();
450
+	}
451
+
452
+	/**
453
+	 * Build Authorization URL for Authorization Request
454
+	 *
455
+	 * RFC6749: The client constructs the request URI by adding the following
456
+	 * $parameters to the query component of the authorization endpoint URI:
457
+	 *
458
+	 *    - response_type  REQUIRED. Value MUST be set to "code".
459
+	 *    - client_id      REQUIRED.
460
+	 *    - redirect_uri   OPTIONAL.
461
+	 *    - scope          OPTIONAL.
462
+	 *    - state          RECOMMENDED.
463
+	 *
464
+	 * http://tools.ietf.org/html/rfc6749#section-4.1.1
465
+	 *
466
+	 * Sub classes may redefine this method when necessary.
467
+	 *
468
+	 * @param array $parameters
469
+	 *
470
+	 * @return string Authorization URL
471
+	 */
472
+	protected function getAuthorizeUrl($parameters = [])
473
+	{
474
+		$this->AuthorizeUrlParameters = !empty($parameters)
475
+			? $parameters
476
+			: array_replace(
477
+				(array)$this->AuthorizeUrlParameters,
478
+				(array)$this->config->get('authorize_url_parameters')
479
+			);
480
+
481
+		if ($this->supportRequestState) {
482
+			if (!isset($this->AuthorizeUrlParameters['state'])) {
483
+				$this->AuthorizeUrlParameters['state'] = 'HA-' . str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890');
484
+			}
485
+
486
+			$this->storeData('authorization_state', $this->AuthorizeUrlParameters['state']);
487
+		}
488
+
489
+		$queryParams = http_build_query($this->AuthorizeUrlParameters, '', '&', $this->AuthorizeUrlParametersEncType);
490
+		return $this->authorizeUrl . '?' . $queryParams;
491
+	}
492
+
493
+	/**
494
+	 * Access Token Request
495
+	 *
496
+	 * This method will exchange the received $code in loginFinish() with an Access Token.
497
+	 *
498
+	 * RFC6749: The client makes a request to the token endpoint by sending the
499
+	 * following parameters using the "application/x-www-form-urlencoded"
500
+	 * with a character encoding of UTF-8 in the HTTP request entity-body:
501
+	 *
502
+	 *    - grant_type    REQUIRED. Value MUST be set to "authorization_code".
503
+	 *    - code          REQUIRED. The authorization code received from the authorization server.
504
+	 *    - redirect_uri  REQUIRED.
505
+	 *    - client_id     REQUIRED.
506
+	 *
507
+	 * http://tools.ietf.org/html/rfc6749#section-4.1.3
508
+	 *
509
+	 * @param string $code
510
+	 *
511
+	 * @return string Raw Provider API response
512
+	 * @throws \Hybridauth\Exception\HttpClientFailureException
513
+	 * @throws \Hybridauth\Exception\HttpRequestFailedException
514
+	 */
515
+	protected function exchangeCodeForAccessToken($code)
516
+	{
517
+		$this->tokenExchangeParameters['code'] = $code;
518
+
519
+		$response = $this->httpClient->request(
520
+			$this->accessTokenUrl,
521
+			$this->tokenExchangeMethod,
522
+			$this->tokenExchangeParameters,
523
+			$this->tokenExchangeHeaders
524
+		);
525
+
526
+		$this->validateApiResponse('Unable to exchange code for API access token');
527
+
528
+		return $response;
529
+	}
530
+
531
+	/**
532
+	 * Validate Access Token Response
533
+	 *
534
+	 * RFC6749: If the access token request is valid and authorized, the
535
+	 * authorization server issues an access token and optional refresh token.
536
+	 * If the request client authentication failed or is invalid, the authorization
537
+	 * server returns an error response as described in Section 5.2.
538
+	 *
539
+	 * Example of a successful response:
540
+	 *
541
+	 *  HTTP/1.1 200 OK
542
+	 *  Content-Type: application/json;charset=UTF-8
543
+	 *  Cache-Control: no-store
544
+	 *  Pragma: no-cache
545
+	 *
546
+	 *  {
547
+	 *      "access_token":"2YotnFZFEjr1zCsicMWpAA",
548
+	 *      "token_type":"example",
549
+	 *      "expires_in":3600,
550
+	 *      "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
551
+	 *      "example_parameter":"example_value"
552
+	 *  }
553
+	 *
554
+	 * http://tools.ietf.org/html/rfc6749#section-4.1.4
555
+	 *
556
+	 * This method uses Data_Parser to attempt to decodes the raw $response (usually JSON)
557
+	 * into a data collection.
558
+	 *
559
+	 * @param string $response
560
+	 *
561
+	 * @return \Hybridauth\Data\Collection
562
+	 * @throws InvalidAccessTokenException
563
+	 */
564
+	protected function validateAccessTokenExchange($response)
565
+	{
566
+		$data = (new Data\Parser())->parse($response);
567
+
568
+		$collection = new Data\Collection($data);
569
+
570
+		if (!$collection->exists('access_token')) {
571
+			throw new InvalidAccessTokenException(
572
+				'Provider returned no access_token: ' . htmlentities($response)
573
+			);
574
+		}
575
+
576
+		$this->storeData('access_token', $collection->get('access_token'));
577
+		$this->storeData('token_type', $collection->get('token_type'));
578
+
579
+		if ($collection->get('refresh_token')) {
580
+			$this->storeData('refresh_token', $collection->get('refresh_token'));
581
+		}
582
+
583
+		// calculate when the access token expire
584
+		if ($collection->exists('expires_in')) {
585
+			$expires_at = time() + (int)$collection->get('expires_in');
586
+
587
+			$this->storeData('expires_in', $collection->get('expires_in'));
588
+			$this->storeData('expires_at', $expires_at);
589
+		}
590
+
591
+		$this->deleteStoredData('authorization_state');
592
+
593
+		$this->initialize();
594
+
595
+		return $collection;
596
+	}
597
+
598
+	/**
599
+	 * Refreshing an Access Token
600
+	 *
601
+	 * RFC6749: If the authorization server issued a refresh token to the
602
+	 * client, the client makes a refresh request to the token endpoint by
603
+	 * adding the following parameters ... in the HTTP request entity-body:
604
+	 *
605
+	 *    - grant_type     REQUIRED. Value MUST be set to "refresh_token".
606
+	 *    - refresh_token  REQUIRED. The refresh token issued to the client.
607
+	 *    - scope          OPTIONAL.
608
+	 *
609
+	 * http://tools.ietf.org/html/rfc6749#section-6
610
+	 *
611
+	 * This method is similar to exchangeCodeForAccessToken(). The only
612
+	 * difference is here we exchange refresh_token for a new access_token.
613
+	 *
614
+	 * @param array $parameters
615
+	 *
616
+	 * @return string|null Raw Provider API response, or null if we cannot refresh
617
+	 * @throws \Hybridauth\Exception\HttpClientFailureException
618
+	 * @throws \Hybridauth\Exception\HttpRequestFailedException
619
+	 * @throws InvalidAccessTokenException
620
+	 */
621
+	public function refreshAccessToken($parameters = [])
622
+	{
623
+		$this->tokenRefreshParameters = !empty($parameters)
624
+			? $parameters
625
+			: $this->tokenRefreshParameters;
626
+
627
+		if (!$this->isRefreshTokenAvailable()) {
628
+			return null;
629
+		}
630
+
631
+		$response = $this->httpClient->request(
632
+			$this->accessTokenUrl,
633
+			$this->tokenRefreshMethod,
634
+			$this->tokenRefreshParameters,
635
+			$this->tokenRefreshHeaders
636
+		);
637
+
638
+		$this->validateApiResponse('Unable to refresh the access token');
639
+
640
+		$this->validateRefreshAccessToken($response);
641
+
642
+		return $response;
643
+	}
644
+
645
+	/**
646
+	 * Check whether access token has expired
647
+	 *
648
+	 * @param int|null $time
649
+	 * @return bool|null
650
+	 */
651
+	public function hasAccessTokenExpired($time = null)
652
+	{
653
+		if ($time === null) {
654
+			$time = time();
655
+		}
656
+
657
+		$expires_at = $this->getStoredData('expires_at');
658
+		if (!$expires_at) {
659
+			return null;
660
+		}
661
+
662
+		return $expires_at <= $time;
663
+	}
664
+
665
+	/**
666
+	 * Validate Refresh Access Token Request
667
+	 *
668
+	 * RFC6749: If valid and authorized, the authorization server issues an
669
+	 * access token as described in Section 5.1.  If the request failed
670
+	 * verification or is invalid, the authorization server returns an error
671
+	 * response as described in Section 5.2.
672
+	 *
673
+	 * http://tools.ietf.org/html/rfc6749#section-6
674
+	 * http://tools.ietf.org/html/rfc6749#section-5.1
675
+	 * http://tools.ietf.org/html/rfc6749#section-5.2
676
+	 *
677
+	 * This method simply use validateAccessTokenExchange(), however sub
678
+	 * classes may redefine it when necessary.
679
+	 *
680
+	 * @param $response
681
+	 *
682
+	 * @return \Hybridauth\Data\Collection
683
+	 * @throws InvalidAccessTokenException
684
+	 */
685
+	protected function validateRefreshAccessToken($response)
686
+	{
687
+		return $this->validateAccessTokenExchange($response);
688
+	}
689
+
690
+	/**
691
+	 * Send a signed request to provider API
692
+	 *
693
+	 * RFC6749: Accessing Protected Resources: The client accesses protected
694
+	 * resources by presenting the access token to the resource server. The
695
+	 * resource server MUST validate the access token and ensure that it has
696
+	 * not expired and that its scope covers the requested resource.
697
+	 *
698
+	 * Note: Since the specifics of error responses is beyond the scope of
699
+	 * RFC6749 and OAuth specifications, Hybridauth will consider any HTTP
700
+	 * status code that is different than '200 OK' as an ERROR.
701
+	 *
702
+	 * http://tools.ietf.org/html/rfc6749#section-7
703
+	 *
704
+	 * @param string $url
705
+	 * @param string $method
706
+	 * @param array $parameters
707
+	 * @param array $headers
708
+	 * @param bool $multipart
709
+	 *
710
+	 * @return mixed
711
+	 * @throws \Hybridauth\Exception\HttpClientFailureException
712
+	 * @throws \Hybridauth\Exception\HttpRequestFailedException
713
+	 * @throws InvalidAccessTokenException
714
+	 */
715
+	public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
716
+	{
717
+		// refresh tokens if needed
718
+		$this->maintainToken();
719
+		if ($this->hasAccessTokenExpired() === true) {
720
+			$this->refreshAccessToken();
721
+		}
722
+
723
+		if (strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0) {
724
+			$url = rtrim($this->apiBaseUrl, '/') . '/' . ltrim($url, '/');
725
+		}
726
+
727
+		$parameters = array_replace($this->apiRequestParameters, (array)$parameters);
728
+		$headers = array_replace($this->apiRequestHeaders, (array)$headers);
729
+
730
+		$response = $this->httpClient->request(
731
+			$url,
732
+			$method,     // HTTP Request Method. Defaults to GET.
733
+			$parameters, // Request Parameters
734
+			$headers,    // Request Headers
735
+			$multipart   // Is request multipart
736
+		);
737
+
738
+		$this->validateApiResponse('Signed API request to ' . $url . ' has returned an error');
739
+
740
+		$response = (new Data\Parser())->parse($response);
741
+
742
+		return $response;
743
+	}
744 744
 }
Please login to merge, or discard this patch.
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -249,9 +249,9 @@  discard block
 block discarded – undo
249 249
         $this->clientId = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
250 250
         $this->clientSecret = $this->config->filter('keys')->get('secret');
251 251
 
252
-        if (!$this->clientId || !$this->clientSecret) {
252
+        if ( ! $this->clientId || ! $this->clientSecret) {
253 253
             throw new InvalidApplicationCredentialsException(
254
-                'Your application id is required in order to connect to ' . $this->providerId
254
+                'Your application id is required in order to connect to '.$this->providerId
255 255
             );
256 256
         }
257 257
 
@@ -289,7 +289,7 @@  discard block
 block discarded – undo
289 289
         ];
290 290
 
291 291
         $refreshToken = $this->getStoredData('refresh_token');
292
-        if (!empty($refreshToken)) {
292
+        if ( ! empty($refreshToken)) {
293 293
             $this->tokenRefreshParameters = [
294 294
                 'grant_type' => 'refresh_token',
295 295
                 'refresh_token' => $refreshToken,
@@ -297,7 +297,7 @@  discard block
 block discarded – undo
297 297
         }
298 298
 
299 299
         $this->apiRequestHeaders = [
300
-            'Authorization' => 'Bearer ' . $this->getStoredData('access_token')
300
+            'Authorization' => 'Bearer '.$this->getStoredData('access_token')
301 301
         ];
302 302
     }
303 303
 
@@ -336,8 +336,8 @@  discard block
 block discarded – undo
336 336
      */
337 337
     public function isConnected()
338 338
     {
339
-        if ((bool)$this->getStoredData('access_token')) {
340
-            return (!$this->hasAccessTokenExpired() || $this->isRefreshTokenAvailable());
339
+        if ((bool) $this->getStoredData('access_token')) {
340
+            return ( ! $this->hasAccessTokenExpired() || $this->isRefreshTokenAvailable());
341 341
         }
342 342
         return false;
343 343
     }
@@ -368,7 +368,7 @@  discard block
 block discarded – undo
368 368
     {
369 369
         $error = filter_input(INPUT_GET, 'error', FILTER_SANITIZE_SPECIAL_CHARS);
370 370
 
371
-        if (!empty($error)) {
371
+        if ( ! empty($error)) {
372 372
             $error_description = filter_input(INPUT_GET, 'error_description', FILTER_SANITIZE_SPECIAL_CHARS);
373 373
             $error_uri = filter_input(INPUT_GET, 'error_uri', FILTER_SANITIZE_SPECIAL_CHARS);
374 374
 
@@ -425,11 +425,11 @@  discard block
 block discarded – undo
425 425
          * http://tools.ietf.org/html/rfc6749#section-4.1.1
426 426
          */
427 427
         if ($this->supportRequestState
428
-            && (!$state || $this->getStoredData('authorization_state') != $state)
428
+            && ( ! $state || $this->getStoredData('authorization_state') != $state)
429 429
         ) {
430 430
             $this->deleteStoredData('authorization_state');
431 431
             throw new InvalidAuthorizationStateException(
432
-                'The authorization state [state=' . substr(htmlentities($state), 0, 100) . '] '
432
+                'The authorization state [state='.substr(htmlentities($state), 0, 100).'] '
433 433
                 . 'of this page is either invalid or has already been consumed.'
434 434
             );
435 435
         }
@@ -471,23 +471,23 @@  discard block
 block discarded – undo
471 471
      */
472 472
     protected function getAuthorizeUrl($parameters = [])
473 473
     {
474
-        $this->AuthorizeUrlParameters = !empty($parameters)
474
+        $this->AuthorizeUrlParameters = ! empty($parameters)
475 475
             ? $parameters
476 476
             : array_replace(
477
-                (array)$this->AuthorizeUrlParameters,
478
-                (array)$this->config->get('authorize_url_parameters')
477
+                (array) $this->AuthorizeUrlParameters,
478
+                (array) $this->config->get('authorize_url_parameters')
479 479
             );
480 480
 
481 481
         if ($this->supportRequestState) {
482
-            if (!isset($this->AuthorizeUrlParameters['state'])) {
483
-                $this->AuthorizeUrlParameters['state'] = 'HA-' . str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890');
482
+            if ( ! isset($this->AuthorizeUrlParameters['state'])) {
483
+                $this->AuthorizeUrlParameters['state'] = 'HA-'.str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890');
484 484
             }
485 485
 
486 486
             $this->storeData('authorization_state', $this->AuthorizeUrlParameters['state']);
487 487
         }
488 488
 
489 489
         $queryParams = http_build_query($this->AuthorizeUrlParameters, '', '&', $this->AuthorizeUrlParametersEncType);
490
-        return $this->authorizeUrl . '?' . $queryParams;
490
+        return $this->authorizeUrl.'?'.$queryParams;
491 491
     }
492 492
 
493 493
     /**
@@ -567,9 +567,9 @@  discard block
 block discarded – undo
567 567
 
568 568
         $collection = new Data\Collection($data);
569 569
 
570
-        if (!$collection->exists('access_token')) {
570
+        if ( ! $collection->exists('access_token')) {
571 571
             throw new InvalidAccessTokenException(
572
-                'Provider returned no access_token: ' . htmlentities($response)
572
+                'Provider returned no access_token: '.htmlentities($response)
573 573
             );
574 574
         }
575 575
 
@@ -582,7 +582,7 @@  discard block
 block discarded – undo
582 582
 
583 583
         // calculate when the access token expire
584 584
         if ($collection->exists('expires_in')) {
585
-            $expires_at = time() + (int)$collection->get('expires_in');
585
+            $expires_at = time() + (int) $collection->get('expires_in');
586 586
 
587 587
             $this->storeData('expires_in', $collection->get('expires_in'));
588 588
             $this->storeData('expires_at', $expires_at);
@@ -620,11 +620,11 @@  discard block
 block discarded – undo
620 620
      */
621 621
     public function refreshAccessToken($parameters = [])
622 622
     {
623
-        $this->tokenRefreshParameters = !empty($parameters)
623
+        $this->tokenRefreshParameters = ! empty($parameters)
624 624
             ? $parameters
625 625
             : $this->tokenRefreshParameters;
626 626
 
627
-        if (!$this->isRefreshTokenAvailable()) {
627
+        if ( ! $this->isRefreshTokenAvailable()) {
628 628
             return null;
629 629
         }
630 630
 
@@ -655,7 +655,7 @@  discard block
 block discarded – undo
655 655
         }
656 656
 
657 657
         $expires_at = $this->getStoredData('expires_at');
658
-        if (!$expires_at) {
658
+        if ( ! $expires_at) {
659 659
             return null;
660 660
         }
661 661
 
@@ -721,21 +721,21 @@  discard block
 block discarded – undo
721 721
         }
722 722
 
723 723
         if (strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0) {
724
-            $url = rtrim($this->apiBaseUrl, '/') . '/' . ltrim($url, '/');
724
+            $url = rtrim($this->apiBaseUrl, '/').'/'.ltrim($url, '/');
725 725
         }
726 726
 
727
-        $parameters = array_replace($this->apiRequestParameters, (array)$parameters);
728
-        $headers = array_replace($this->apiRequestHeaders, (array)$headers);
727
+        $parameters = array_replace($this->apiRequestParameters, (array) $parameters);
728
+        $headers = array_replace($this->apiRequestHeaders, (array) $headers);
729 729
 
730 730
         $response = $this->httpClient->request(
731 731
             $url,
732
-            $method,     // HTTP Request Method. Defaults to GET.
732
+            $method, // HTTP Request Method. Defaults to GET.
733 733
             $parameters, // Request Parameters
734
-            $headers,    // Request Headers
734
+            $headers, // Request Headers
735 735
             $multipart   // Is request multipart
736 736
         );
737 737
 
738
-        $this->validateApiResponse('Signed API request to ' . $url . ' has returned an error');
738
+        $this->validateApiResponse('Signed API request to '.$url.' has returned an error');
739 739
 
740 740
         $response = (new Data\Parser())->parse($response);
741 741
 
Please login to merge, or discard this patch.