Fixes to make SO login work. GitHub now works also (was a FF plugin bug)

This commit is contained in:
2018-07-10 22:57:50 +02:00
parent d74b76da3e
commit be3164e997
10 changed files with 53 additions and 15 deletions
@@ -1,5 +1,6 @@
<?php namespace SocialNorm\GitHub;
use SocialNorm\Exceptions\AuthNotUsableException;
use SocialNorm\Exceptions\InvalidAuthorizationCodeException;
use SocialNorm\Providers\OAuth2Provider;
@@ -15,7 +16,8 @@ class GitHubProvider extends OAuth2Provider
protected $headers = [
'authorize' => [],
'access_token' => [
'Accept' => 'application/json'
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded'
],
'user_details' => [
'Accept' => 'application/vnd.github.v3'
@@ -72,10 +74,13 @@ class GitHubProvider extends OAuth2Provider
protected function getPrimaryEmail($emails)
{
foreach ($emails as $email) {
if ($email['primary']) {
if ($email['primary'] && $email['verified']) {
return $email['email'];
}
}
if (!$emails[0]['verified']) {
throw new AuthNotUsableException("No verified e-mail.");
}
return $emails[0]['email'];
}
@@ -0,0 +1,7 @@
<?php namespace SocialNorm\Exceptions;
/**
* oauth granted ok but user has no verified e-mail
* or no users were found (in the case of SO)
*/
class AuthNotUsableException extends \RuntimeException {}
@@ -99,6 +99,7 @@ abstract class OAuth2Provider implements Provider
} catch (BadResponseException $e) {
throw new InvalidAuthorizationCodeException((string) $e->getResponse()->getBody());
}
return $this->parseTokenResponse((string) $response->getBody());
}
@@ -128,11 +129,15 @@ abstract class OAuth2Provider implements Provider
protected function parseJsonTokenResponse($response)
{
$response = json_decode($response);
if (! isset($response->access_token)) {
throw new InvalidAuthorizationCodeException;
$parsed = json_decode($response);
if ($parsed === false || json_last_error())
throw new InvalidAuthorizationCodeException('No access token in response: ' . $response . ", error " . json_last_error_msg());
if (! isset($parsed->access_token)) {
throw new InvalidAuthorizationCodeException('No access token in response: ' . $response);
}
return $response->access_token;
return $parsed->access_token;
}
abstract protected function getAuthorizeUrl();
@@ -31,7 +31,7 @@ final class Request
public function authorizationCode()
{
if (! isset($this->queryParams['code'])) {
throw new ApplicationRejectedException;
throw new ApplicationRejectedException("Did not receive auth code. " . json_encode($this->queryParams));
}
return $this->queryParams['code'];
}
@@ -53,8 +53,11 @@ class SocialNorm
protected function verifyState()
{
if ($this->session->get('oauth.state') !== $this->request->state()) {
throw new InvalidAuthorizationCodeException("State failed to verify");
$expected = $this->session->get('oauth.state');
$received = $this->request->state();
if ($expected !== $received) {
throw new InvalidAuthorizationCodeException("State failed to verify - session: $expected, from provider: $received");
}
}
}
@@ -1,5 +1,7 @@
<?php namespace SocialNorm\StackOverflow;
use SocialNorm\Exceptions\AuthNotUsableException;
use SocialNorm\Exceptions\InvalidAuthorizationCodeException;
use SocialNorm\Providers\OAuth2Provider;
use GuzzleHttp\Client as HttpClient;
use SocialNorm\Request;
@@ -21,6 +23,7 @@ class StackOverflowProvider extends OAuth2Provider
protected $headers = [
'authorize' => [],
'access_token' => [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded'
],
'user_details' => [],
@@ -65,12 +68,21 @@ class StackOverflowProvider extends OAuth2Provider
protected function parseTokenResponse($response)
{
return $this->parseJsonTokenResponse($response);
return explode('=', $response, 2)[1];
}
protected function parseUserDataResponse($response)
{
return json_decode($response, true);
$decoded = (array)json_decode($response, true);
if ($decoded === false || json_last_error())
throw new InvalidAuthorizationCodeException('Corrupt response json: ' . $response . ", error " . json_last_error_msg());
if (0 == count(array_get($decoded, 'items'))) {
throw new AuthNotUsableException('No profile on StackOverflow. Resp: '.$response);
}
return $decoded;
}
protected function userId()