Command and tokens trait

This commit is contained in:
Maxime Renou 2020-05-12 15:57:23 +02:00
parent f057dd513c
commit 807d12a2b5
4 changed files with 167 additions and 90 deletions

43
src/Commands/Sync.php Normal file
View File

@ -0,0 +1,43 @@
<?php
namespace Bluesquare\Connect\Commands;
use Bluesquare\Connect\Connect;
use Illuminate\Console\Command;
class Sync extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'connect:sync';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Synchronize Bluesquare Connect resources';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle(Connect $connect)
{
$connect->syncAll();
}
}

View File

@ -3,6 +3,7 @@
namespace Bluesquare\Connect; namespace Bluesquare\Connect;
use Bluesquare\Connect\Traits\HasConnectSync; use Bluesquare\Connect\Traits\HasConnectSync;
use Bluesquare\Connect\Traits\HasConnectTokens;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Routing\Router; use Illuminate\Routing\Router;
@ -112,62 +113,6 @@ class Connect
return redirect()->to($url); return redirect()->to($url);
} }
public function getAccessTokenFromAuhtorizationCode($code)
{
$data = $this->request('post', 'oauth/token', [
'grant_type' => 'authorization_code',
'client_id' => config('bconnect.client_id'),
'client_secret' => config('bconnect.client_secret'),
'scope' => config('bconnect.user_scopes'),
'redirect_uri' => config('bconnect.redirect_url'),
'code' => $code
], false);
return $data;
}
public function getAccessTokenFromRefreshToken($refresh_token)
{
$data = $this->request('post', 'oauth/token', [
'grant_type' => 'refresh_token',
'client_id' => config('bconnect.client_id'),
'client_secret' => config('bconnect.client_secret'),
'scope' => config('bconnect.user_scopes'),
'redirect_uri' => config('bconnect.redirect_url'),
'refresh_token' => $refresh_token
], false);
return $data;
}
public function getUserData($access_token)
{
return $this->request('get', 'api/user', null, $access_token);
}
public function updateUserConnectData($model, $data)
{
$model->connect_access_token = $data['access_token'];
$model->connect_refresh_token = $data['refresh_token'];
$model->connect_expires_at = $data['expires_at'];
$model->save();
}
public function getUserAccessToken($model)
{
if (empty($model->connect_access_token) || empty($model->connect_refresh_token) || empty($model->connect_expires_at)) {
throw new ConnectException("Missing Bluesquare Connect attributes on model: connect_access_token, connect_refresh_token, connect_expires_at");
}
if ($model->connect_expires_at <= now()) {
$connect_data = $this->getAccessTokenFromRefreshToken($model->connect_refresh_token);
$this->updateUserConnectData($model, $connect_data);
return $connect_data['access_token'];
}
return $model->connect_access_token;
}
public function loginFromCallback(Request $request) public function loginFromCallback(Request $request)
{ {
// State check // State check
@ -202,7 +147,7 @@ class Connect
// Access token // Access token
$expires_at = now(); $expires_at = now();
$connect_data = $this->getAccessTokenFromAuhtorizationCode($request->code); $connect_data = $this->getAccessTokenFromAuthorizationCode($request->code);
$connect_data['expires_at'] = $expires_at->addSeconds($connect_data['expires_in']); $connect_data['expires_at'] = $expires_at->addSeconds($connect_data['expires_in']);
$model_data = $this->getUserData($connect_data['access_token']); $model_data = $this->getUserData($connect_data['access_token']);
@ -223,6 +168,68 @@ class Connect
return redirect('/'); return redirect('/');
} }
public function getAccessTokenFromAuthorizationCode($code)
{
$data = $this->request('post', 'oauth/token', [
'grant_type' => 'authorization_code',
'client_id' => config('bconnect.client_id'),
'client_secret' => config('bconnect.client_secret'),
'scope' => config('bconnect.user_scopes'),
'redirect_uri' => config('bconnect.redirect_url'),
'code' => $code
], false);
return $data;
}
public function getAccessTokenFromRefreshToken($refresh_token)
{
$data = $this->request('post', 'oauth/token', [
'grant_type' => 'refresh_token',
'client_id' => config('bconnect.client_id'),
'client_secret' => config('bconnect.client_secret'),
'scope' => config('bconnect.user_scopes'),
'redirect_uri' => config('bconnect.redirect_url'),
'refresh_token' => $refresh_token
], false);
return $data;
}
public function getUserData($access_token)
{
return $this->request('get', 'api/user', null, $access_token);
}
public function updateUserConnectData($user, $data)
{
if (!in_array(HasConnectTokens::class, class_uses(get_class($user))))
return false;
$user->connect_access_token = $data['access_token'];
$user->connect_refresh_token = $data['refresh_token'];
$user->connect_expires_at = $data['expires_at'];
return $user->save();
}
public function getUserAccessToken($user)
{
$has_fields = in_array(HasConnectTokens::class, class_uses(get_class($user)));
if (!$has_fields) {
throw new ConnectException("User class does not implement HasConnectTokens");
}
if ($user->connect_expires_at <= now()) {
$connect_data = $this->getAccessTokenFromRefreshToken($user->connect_refresh_token);
$this->updateUserConnectData($user, $connect_data);
return $connect_data['access_token'];
}
return $user->connect_access_token;
}
// OAuth (client) // OAuth (client)
public function getAccessToken() public function getAccessToken()
@ -253,7 +260,7 @@ class Connect
cache()->delete('bconnect.access_token_expiration'); cache()->delete('bconnect.access_token_expiration');
} }
// Webhooks handler // Webhook handler
/** /**
* @param Request $request * @param Request $request
@ -291,7 +298,7 @@ class Connect
return true; return true;
} }
// Resources endpoints // Resources getters
public function getAll($resourceType) public function getAll($resourceType)
{ {
@ -303,7 +310,7 @@ class Connect
return $this->request('get', "api/resources/$resourceType/$resourceId"); return $this->request('get', "api/resources/$resourceType/$resourceId");
} }
// Resources sync // Resources syncing
public function syncAll($resourceTypes = null) public function syncAll($resourceTypes = null)
{ {
@ -348,7 +355,26 @@ class Connect
$model::$method($resourceId, $resourceData); $model::$method($resourceId, $resourceData);
} }
// // Routing
public function routes()
{
Route::namespace('\Bluesquare\Connect\Controllers')
->group(function () {
Route::get('connect/authorize', 'ConnectController@authorize');
Route::get('connect/callback', 'ConnectController@callback');
});
}
public function apiRoutes()
{
Route::namespace('\Bluesquare\Connect\Controllers')
->group(function () {
Route::post('connect/webhook', 'ConnectController@webhook');
});
}
// Misc
protected function resolveResourceType($class) protected function resolveResourceType($class)
{ {
@ -375,21 +401,4 @@ class Connect
{ {
return config('bconnect.url') ?? 'https://connect.bluesquare.io'; return config('bconnect.url') ?? 'https://connect.bluesquare.io';
} }
public function routes()
{
Route::namespace('\Bluesquare\Connect\Controllers')
->group(function () {
Route::get('connect/authorize', 'ConnectController@authorize');
Route::get('connect/callback', 'ConnectController@callback');
});
}
public function apiRoutes()
{
Route::namespace('\Bluesquare\Connect\Controllers')
->group(function () {
Route::post('connect/webhook', 'ConnectController@webhook');
});
}
} }

View File

@ -2,6 +2,7 @@
namespace Bluesquare\Connect; namespace Bluesquare\Connect;
use Bluesquare\Connect\Commands\Sync;
use Bluesquare\Connect\View\Components\Button; use Bluesquare\Connect\View\Components\Button;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
@ -14,14 +15,34 @@ class ConnectServiceProvider extends ServiceProvider
*/ */
public function register() public function register()
{ {
// Config
$this->mergeConfigFrom( $this->mergeConfigFrom(
__DIR__ . '/../config/bconnect.php', __DIR__ . '/../config/bconnect.php',
'bmail' 'bconnect'
); );
// Singletons
$this->app->singleton(Connect::class, function ($app) { $this->app->singleton(Connect::class, function ($app) {
return new Connect($app); return new Connect($app);
}); });
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
// Config
$this->publishes([
__DIR__ . '/../config/bconnect.php' => config_path('bconnect.php')
]);
// Views
$this->loadViewsFrom(__DIR__.'/../resources/views/connect', 'connect'); $this->loadViewsFrom(__DIR__.'/../resources/views/connect', 'connect');
@ -32,17 +53,13 @@ class ConnectServiceProvider extends ServiceProvider
$this->loadViewComponentsAs('connect', [ $this->loadViewComponentsAs('connect', [
Button::class Button::class
]); ]);
}
/** // Commands
* Bootstrap any application services.
* if ($this->app->runningInConsole()) {
* @return void $this->commands([
*/ Sync::class
public function boot() ]);
{ }
$this->publishes([
__DIR__ . '/../config/bconnect.php' => config_path('bconnect.php')
], 'config');
} }
} }

View File

@ -0,0 +1,8 @@
<?php
namespace Bluesquare\Connect\Traits;
trait HasConnectTokens
{
//
}