OAuth: Save auth tokens

main
Igor Scheller 4 years ago committed by msquare
parent 304b599cf4
commit d423bb07d3

@ -0,0 +1,41 @@
<?php
namespace Engelsystem\Migrations;
use Engelsystem\Database\Migration\Migration;
use Illuminate\Database\Schema\Blueprint;
class OauthAddTokens extends Migration
{
use Reference;
/**
* Run the migration
*/
public function up()
{
$this->schema->table(
'oauth',
function (Blueprint $table) {
$table->string('access_token')->nullable()->default(null)->after('identifier');
$table->string('refresh_token')->nullable()->default(null)->after('access_token');
$table->dateTime('expires_at')->nullable()->default(null)->after('refresh_token');
}
);
}
/**
* Reverse the migration
*/
public function down()
{
$this->schema->table(
'oauth',
function (Blueprint $table) {
$table->dropColumn('access_token');
$table->dropColumn('refresh_token');
$table->dropColumn('expires_at');
}
);
}
}

@ -227,8 +227,11 @@ function guest_register()
if ($session->has('oauth2_connect_provider') && $session->has('oauth2_user_id')) { if ($session->has('oauth2_connect_provider') && $session->has('oauth2_user_id')) {
$oauth = new OAuth([ $oauth = new OAuth([
'provider' => $session->get('oauth2_connect_provider'), 'provider' => $session->get('oauth2_connect_provider'),
'identifier' => $session->get('oauth2_user_id'), 'identifier' => $session->get('oauth2_user_id'),
'access_token' => $session->get('oauth2_access_token'),
'refresh_token' => $session->get('oauth2_refresh_token'),
'expires_at' => $session->get('oauth2_expires_at'),
]); ]);
$oauth->user() $oauth->user()
->associate($user) ->associate($user)
@ -236,6 +239,9 @@ function guest_register()
$session->remove('oauth2_connect_provider'); $session->remove('oauth2_connect_provider');
$session->remove('oauth2_user_id'); $session->remove('oauth2_user_id');
$session->remove('oauth2_access_token');
$session->remove('oauth2_refresh_token');
$session->remove('oauth2_expires_at');
} }
// Assign user-group and set password // Assign user-group and set password

@ -16,6 +16,7 @@ use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException; use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Provider\GenericProvider; use League\OAuth2\Client\Provider\GenericProvider;
use League\OAuth2\Client\Provider\ResourceOwnerInterface as ResourceOwner; use League\OAuth2\Client\Provider\ResourceOwnerInterface as ResourceOwner;
use League\OAuth2\Client\Token\AccessTokenInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Session\Session as Session; use Symfony\Component\HttpFoundation\Session\Session as Session;
@ -136,6 +137,16 @@ class OAuthController extends BaseController
->where('identifier', $resourceOwner->getId()) ->where('identifier', $resourceOwner->getId())
->first(); ->first();
$expirationTime = $accessToken->getExpires();
$expirationTime = $expirationTime ? Carbon::createFromTimestamp($expirationTime) : null;
if ($oauth) {
$oauth->access_token = $accessToken->getToken();
$oauth->refresh_token = $accessToken->getRefreshToken();
$oauth->expires_at = $expirationTime;
$oauth->save();
}
$user = $this->auth->user(); $user = $this->auth->user();
if ($oauth && $user && $user->id != $oauth->user_id) { if ($oauth && $user && $user->id != $oauth->user_id) {
throw new HttpNotFound('oauth.already-connected'); throw new HttpNotFound('oauth.already-connected');
@ -144,7 +155,13 @@ class OAuthController extends BaseController
$connectProvider = $this->session->get('oauth2_connect_provider'); $connectProvider = $this->session->get('oauth2_connect_provider');
$this->session->remove('oauth2_connect_provider'); $this->session->remove('oauth2_connect_provider');
if (!$oauth && $user && $connectProvider && $connectProvider == $providerName) { if (!$oauth && $user && $connectProvider && $connectProvider == $providerName) {
$oauth = new OAuth(['provider' => $providerName, 'identifier' => $resourceOwner->getId()]); $oauth = new OAuth([
'provider' => $providerName,
'identifier' => $resourceOwner->getId(),
'access_token' => $accessToken->getToken(),
'refresh_token' => $accessToken->getRefreshToken(),
'expires_at' => $expirationTime,
]);
$oauth->user() $oauth->user()
->associate($user) ->associate($user)
->save(); ->save();
@ -156,10 +173,16 @@ class OAuthController extends BaseController
$this->addNotification('oauth.connected'); $this->addNotification('oauth.connected');
} }
$config = ($this->config->get('oauth')[$providerName]); $config = $this->config->get('oauth')[$providerName];
$userdata = new Collection($resourceOwner->toArray()); $userdata = new Collection($resourceOwner->toArray());
if (!$oauth) { if (!$oauth) {
return $this->redirectRegisterOrThrowNotFound($providerName, $resourceOwner->getId(), $config, $userdata); return $this->redirectRegisterOrThrowNotFound(
$providerName,
$resourceOwner->getId(),
$accessToken,
$config,
$userdata
);
} }
if (isset($config['mark_arrived']) && $config['mark_arrived']) { if (isset($config['mark_arrived']) && $config['mark_arrived']) {
@ -282,16 +305,18 @@ class OAuthController extends BaseController
} }
/** /**
* @param string $providerName * @param string $providerName
* @param string $providerUserIdentifier * @param string $providerUserIdentifier
* @param array $config * @param AccessTokenInterface $accessToken
* @param Collection $userdata * @param array $config
* @param Collection $userdata
* *
* @return Response * @return Response
*/ */
protected function redirectRegisterOrThrowNotFound( protected function redirectRegisterOrThrowNotFound(
string $providerName, string $providerName,
string $providerUserIdentifier, string $providerUserIdentifier,
AccessTokenInterface $accessToken,
array $config, array $config,
Collection $userdata Collection $userdata
): Response { ): Response {
@ -315,6 +340,12 @@ class OAuthController extends BaseController
$this->session->set('oauth2_connect_provider', $providerName); $this->session->set('oauth2_connect_provider', $providerName);
$this->session->set('oauth2_user_id', $providerUserIdentifier); $this->session->set('oauth2_user_id', $providerUserIdentifier);
$expirationTime = $accessToken->getExpires();
$expirationTime = $expirationTime ? Carbon::createFromTimestamp($expirationTime) : null;
$this->session->set('oauth2_access_token', $accessToken->getToken());
$this->session->set('oauth2_refresh_token', $accessToken->getRefreshToken());
$this->session->set('oauth2_expires_at', $expirationTime);
return $this->redirector->to('/register'); return $this->redirector->to('/register');
} }
} }

@ -12,12 +12,17 @@ use Illuminate\Database\Query\Builder as QueryBuilder;
* @property int $id * @property int $id
* @property string $provider * @property string $provider
* @property string $identifier * @property string $identifier
* @property string $access_token
* @property string $refresh_token
* @property Carbon|null $expires_at
* @property Carbon|null $created_at * @property Carbon|null $created_at
* @property Carbon|null $updated_at * @property Carbon|null $updated_at
* *
* @method static QueryBuilder|OAuth[] whereId($value) * @method static QueryBuilder|OAuth[] whereId($value)
* @method static QueryBuilder|OAuth[] whereProvider($value) * @method static QueryBuilder|OAuth[] whereProvider($value)
* @method static QueryBuilder|OAuth[] whereIdentifier($value) * @method static QueryBuilder|OAuth[] whereIdentifier($value)
* @method static QueryBuilder|OAuth[] whereAccessToken($value)
* @method static QueryBuilder|OAuth[] whereRefreshToken($value)
*/ */
class OAuth extends BaseModel class OAuth extends BaseModel
{ {
@ -29,9 +34,17 @@ class OAuth extends BaseModel
/** @var bool Enable timestamps */ /** @var bool Enable timestamps */
public $timestamps = true; public $timestamps = true;
/** @var string[] */
protected $dates = [
'expires_at',
];
/** @var array */ /** @var array */
protected $fillable = [ protected $fillable = [
'provider', 'provider',
'identifier', 'identifier',
'access_token',
'refresh_token',
'expires_at',
]; ];
} }

@ -94,6 +94,9 @@ class OAuthControllerTest extends TestCase
$this->session->set('oauth2_connect_provider', 'testprovider'); $this->session->set('oauth2_connect_provider', 'testprovider');
$accessToken = $this->createMock(AccessToken::class); $accessToken = $this->createMock(AccessToken::class);
$this->setExpects($accessToken, 'getToken', null, 'test-token', $this->atLeastOnce());
$this->setExpects($accessToken, 'getRefreshToken', null, 'test-refresh-token', $this->atLeastOnce());
$this->setExpects($accessToken, 'getExpires', null, 4242424242, $this->atLeastOnce());
/** @var ResourceOwnerInterface|MockObject $resourceOwner */ /** @var ResourceOwnerInterface|MockObject $resourceOwner */
$resourceOwner = $this->createMock(ResourceOwnerInterface::class); $resourceOwner = $this->createMock(ResourceOwnerInterface::class);
@ -153,7 +156,13 @@ class OAuthControllerTest extends TestCase
// Login using provider // Login using provider
$controller->index($request); $controller->index($request);
$this->assertFalse($this->session->has('oauth2_connect_provider')); $this->assertFalse($this->session->has('oauth2_connect_provider'));
$this->assertFalse((bool)User::find(1)->state->arrived); $this->assertFalse((bool)$this->otherUser->state->arrived);
// Tokens updated
$oauth = $this->otherUser->oauth[0];
$this->assertEquals('test-token', $oauth->access_token);
$this->assertEquals('test-refresh-token', $oauth->refresh_token);
$this->assertEquals(4242424242, $oauth->expires_at->unix());
// Mark as arrived // Mark as arrived
$oauthConfig = $this->config->get('oauth'); $oauthConfig = $this->config->get('oauth');
@ -321,6 +330,9 @@ class OAuthControllerTest extends TestCase
public function testIndexRedirectRegister() public function testIndexRedirectRegister()
{ {
$accessToken = $this->createMock(AccessToken::class); $accessToken = $this->createMock(AccessToken::class);
$this->setExpects($accessToken, 'getToken', null, 'test-token', $this->atLeastOnce());
$this->setExpects($accessToken, 'getRefreshToken', null, 'test-refresh-token', $this->atLeastOnce());
$this->setExpects($accessToken, 'getExpires', null, 4242424242, $this->atLeastOnce());
/** @var ResourceOwnerInterface|MockObject $resourceOwner */ /** @var ResourceOwnerInterface|MockObject $resourceOwner */
$resourceOwner = $this->createMock(ResourceOwnerInterface::class); $resourceOwner = $this->createMock(ResourceOwnerInterface::class);
@ -374,6 +386,9 @@ class OAuthControllerTest extends TestCase
$controller->index($request); $controller->index($request);
$this->assertEquals('testprovider', $this->session->get('oauth2_connect_provider')); $this->assertEquals('testprovider', $this->session->get('oauth2_connect_provider'));
$this->assertEquals('provider-not-connected-identifier', $this->session->get('oauth2_user_id')); $this->assertEquals('provider-not-connected-identifier', $this->session->get('oauth2_user_id'));
$this->assertEquals('test-token', $this->session->get('oauth2_access_token'));
$this->assertEquals('test-refresh-token', $this->session->get('oauth2_refresh_token'));
$this->assertEquals(4242424242, $this->session->get('oauth2_expires_at')->unix());
$this->assertEquals( $this->assertEquals(
[ [
'name' => 'username', 'name' => 'username',

Loading…
Cancel
Save