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

pull/26/head
Ondřej Hruška 6 years ago
parent d74b76da3e
commit be3164e997
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 6
      config/app.php
  2. 4
      config/session.php
  3. 2
      database/migrations/2014_10_12_000000_create_users_table.php
  4. 2
      sideload/adamwathan/eloquent-oauth/src/EloquentIdentityStore.php
  5. 9
      sideload/socialnorm/github/src/GitHubProvider.php
  6. 7
      sideload/socialnorm/socialnorm/src/Exceptions/AuthNotUsableException.php
  7. 13
      sideload/socialnorm/socialnorm/src/Providers/OAuth2Provider.php
  8. 2
      sideload/socialnorm/socialnorm/src/Request.php
  9. 7
      sideload/socialnorm/socialnorm/src/SocialNorm.php
  10. 16
      sideload/socialnorm/stackoverflow/src/StackOverflowProvider.php

@ -220,4 +220,10 @@ return [
// -------------- added keys -------------- // -------------- added keys --------------
'pretty_json' => env('PRETTY_JSON', false), 'pretty_json' => env('PRETTY_JSON', false),
'debug_blacklist' => [
'_COOKIE' => array_keys($_COOKIE),
'_SERVER' => array_keys($_SERVER),
'_ENV' => array_keys($_ENV),
],
]; ];

@ -177,7 +177,7 @@ return [
| |
*/ */
'http_only' => true, 'http_only' => env('SESSION_HTTPONLY', true),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -192,6 +192,6 @@ return [
| |
*/ */
'same_site' => 'lax', // this was changed, leaving it as 'null' caused session to be reset during oAuth2 login 'same_site' => env('SESSION_SAMESITE', null), // this was changed, leaving it as 'null' caused session to be reset during oAuth2 login
]; ];

@ -16,7 +16,7 @@ class CreateUsersTable extends Migration
Schema::create('users', function (Blueprint $table) { Schema::create('users', function (Blueprint $table) {
$table->increments('id'); $table->increments('id');
$table->timestamps(); $table->timestamps();
$table->string('name'); $table->string('name')->unique();
$table->string('email')->unique()->nullable(); $table->string('email')->unique()->nullable();
$table->string('password')->nullable(); $table->string('password')->nullable();
$table->rememberToken(); $table->rememberToken();

@ -25,7 +25,7 @@ class EloquentIdentityStore implements IdentityStore
{ {
$first = User::where('email', $providerUser->email)->first(); $first = User::where('email', $providerUser->email)->first();
if($first->email) return $first; if($first && $first->email) return $first;
return null; return null;
} }

@ -1,5 +1,6 @@
<?php namespace SocialNorm\GitHub; <?php namespace SocialNorm\GitHub;
use SocialNorm\Exceptions\AuthNotUsableException;
use SocialNorm\Exceptions\InvalidAuthorizationCodeException; use SocialNorm\Exceptions\InvalidAuthorizationCodeException;
use SocialNorm\Providers\OAuth2Provider; use SocialNorm\Providers\OAuth2Provider;
@ -15,7 +16,8 @@ class GitHubProvider extends OAuth2Provider
protected $headers = [ protected $headers = [
'authorize' => [], 'authorize' => [],
'access_token' => [ 'access_token' => [
'Accept' => 'application/json' 'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded'
], ],
'user_details' => [ 'user_details' => [
'Accept' => 'application/vnd.github.v3' 'Accept' => 'application/vnd.github.v3'
@ -72,10 +74,13 @@ class GitHubProvider extends OAuth2Provider
protected function getPrimaryEmail($emails) protected function getPrimaryEmail($emails)
{ {
foreach ($emails as $email) { foreach ($emails as $email) {
if ($email['primary']) { if ($email['primary'] && $email['verified']) {
return $email['email']; return $email['email'];
} }
} }
if (!$emails[0]['verified']) {
throw new AuthNotUsableException("No verified e-mail.");
}
return $emails[0]['email']; 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) { } catch (BadResponseException $e) {
throw new InvalidAuthorizationCodeException((string) $e->getResponse()->getBody()); throw new InvalidAuthorizationCodeException((string) $e->getResponse()->getBody());
} }
return $this->parseTokenResponse((string) $response->getBody()); return $this->parseTokenResponse((string) $response->getBody());
} }
@ -128,11 +129,15 @@ abstract class OAuth2Provider implements Provider
protected function parseJsonTokenResponse($response) protected function parseJsonTokenResponse($response)
{ {
$response = json_decode($response); $parsed = json_decode($response);
if (! isset($response->access_token)) {
throw new InvalidAuthorizationCodeException; 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(); abstract protected function getAuthorizeUrl();

@ -31,7 +31,7 @@ final class Request
public function authorizationCode() public function authorizationCode()
{ {
if (! isset($this->queryParams['code'])) { if (! isset($this->queryParams['code'])) {
throw new ApplicationRejectedException; throw new ApplicationRejectedException("Did not receive auth code. " . json_encode($this->queryParams));
} }
return $this->queryParams['code']; return $this->queryParams['code'];
} }

@ -53,8 +53,11 @@ class SocialNorm
protected function verifyState() protected function verifyState()
{ {
if ($this->session->get('oauth.state') !== $this->request->state()) { $expected = $this->session->get('oauth.state');
throw new InvalidAuthorizationCodeException("State failed to verify"); $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; <?php namespace SocialNorm\StackOverflow;
use SocialNorm\Exceptions\AuthNotUsableException;
use SocialNorm\Exceptions\InvalidAuthorizationCodeException;
use SocialNorm\Providers\OAuth2Provider; use SocialNorm\Providers\OAuth2Provider;
use GuzzleHttp\Client as HttpClient; use GuzzleHttp\Client as HttpClient;
use SocialNorm\Request; use SocialNorm\Request;
@ -21,6 +23,7 @@ class StackOverflowProvider extends OAuth2Provider
protected $headers = [ protected $headers = [
'authorize' => [], 'authorize' => [],
'access_token' => [ 'access_token' => [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded' 'Content-Type' => 'application/x-www-form-urlencoded'
], ],
'user_details' => [], 'user_details' => [],
@ -65,12 +68,21 @@ class StackOverflowProvider extends OAuth2Provider
protected function parseTokenResponse($response) protected function parseTokenResponse($response)
{ {
return $this->parseJsonTokenResponse($response); return explode('=', $response, 2)[1];
} }
protected function parseUserDataResponse($response) 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() protected function userId()

Loading…
Cancel
Save