feat: sync, webhook, tokens refresh, fillable, key config
This commit is contained in:
parent
4156db2cdc
commit
830ebbcdd3
|
@ -3,8 +3,8 @@
|
|||
namespace Bluesquare\Connect;
|
||||
|
||||
use Bluesquare\Connect\Traits\HasConnectData;
|
||||
use Bluesquare\Connect\Traits\HasConnectSync;
|
||||
use Bluesquare\Connect\Traits\HasConnectTokens;
|
||||
use Bluesquare\Connect\Traits\HasConnectWebhook;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Router;
|
||||
|
@ -44,7 +44,7 @@ class Connect
|
|||
]
|
||||
];
|
||||
|
||||
if ($access_token !== null) {
|
||||
if (! is_null($access_token)) {
|
||||
$config['headers']['Authorization'] = 'Bearer ' . $access_token;
|
||||
}
|
||||
|
||||
|
@ -125,16 +125,15 @@ class Connect
|
|||
// Access token
|
||||
|
||||
$expires_at = now();
|
||||
$connect_data = $this->getAccessTokenFromAuthorizationCode($request->code);
|
||||
$connect_data = $this->getAccessTokenFromAuthorizationCode($request->get('code'));
|
||||
$connect_data['expires_at'] = $expires_at->addSeconds($connect_data['expires_in']);
|
||||
|
||||
// User data
|
||||
|
||||
$user_data = $this->getUserData($connect_data['access_token']);
|
||||
$user = $this->resolveUser($user_data);
|
||||
|
||||
$user = $this->sync('create', $user_data);
|
||||
$this->updateUserConnectData($user, $connect_data);
|
||||
$this->updateUserData($user, $user_data);
|
||||
$user->save();
|
||||
|
||||
// Login
|
||||
|
@ -148,7 +147,7 @@ class Connect
|
|||
|
||||
public function getAccessTokenFromAuthorizationCode($code)
|
||||
{
|
||||
$data = $this->request('post', 'oauth/token', [
|
||||
return $this->request('post', 'oauth/token', [
|
||||
'grant_type' => 'authorization_code',
|
||||
'client_id' => config('bconnect.client_id'),
|
||||
'client_secret' => config('bconnect.client_secret'),
|
||||
|
@ -156,13 +155,11 @@ class Connect
|
|||
'redirect_uri' => config('bconnect.redirect_url'),
|
||||
'code' => $code
|
||||
]);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getAccessTokenFromRefreshToken($refresh_token)
|
||||
{
|
||||
$data = $this->request('post', 'oauth/token', [
|
||||
return $this->request('post', 'oauth/token', [
|
||||
'grant_type' => 'refresh_token',
|
||||
'client_id' => config('bconnect.client_id'),
|
||||
'client_secret' => config('bconnect.client_secret'),
|
||||
|
@ -170,8 +167,6 @@ class Connect
|
|||
'redirect_uri' => config('bconnect.redirect_url'),
|
||||
'refresh_token' => $refresh_token
|
||||
]);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getUserData($access_token)
|
||||
|
@ -199,17 +194,38 @@ class Connect
|
|||
|
||||
// Sync
|
||||
|
||||
public function handleWebhook(Request $request)
|
||||
public function sync(string $event, array $data)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'event_type' => 'required|in:created,updated,deleted,restored',
|
||||
'connect_data' => 'required|array',
|
||||
'connect_data.id' => 'required'
|
||||
]);
|
||||
$class = config('bconnect.model');
|
||||
|
||||
//@TODO
|
||||
if (in_array($event, ['update', 'delete'])) {
|
||||
$model = $this->resolveUser($data);
|
||||
|
||||
return ['handled' => false];
|
||||
if (! $model->exists() && $event === 'delete')
|
||||
return $model;
|
||||
}
|
||||
else {
|
||||
$hasSoftDeletes = in_array(\Illuminate\Database\Eloquent\SoftDeletes::class, class_uses($class));
|
||||
$model = $this->resolveUser($data, $hasSoftDeletes);
|
||||
|
||||
if ($model->exists()) {
|
||||
if ($hasSoftDeletes) {
|
||||
$event = 'restore';
|
||||
} else {
|
||||
$event = 'update';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array(HasConnectWebhook::class, class_uses($class))) {
|
||||
$method = 'onConnect' . ucfirst($event);
|
||||
$model->$method($data);
|
||||
} else {
|
||||
$this->updateUserData($model, $data);
|
||||
$model->save();
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
public function updateUserConnectData($user, $data)
|
||||
|
@ -224,20 +240,32 @@ class Connect
|
|||
$user->fillConnectData($data);
|
||||
}
|
||||
|
||||
protected function resolveUser($data)
|
||||
protected function resolveUser($data, $withTrashed = false)
|
||||
{
|
||||
$model = config('bconnect.model');
|
||||
$class = config('bconnect.model');
|
||||
$query = $class::query();
|
||||
|
||||
if (in_array(HasConnectData::class, class_uses($model))) {
|
||||
$origin = is_array($model::$connectIdentifier) ? $model::$connectIdentifier[0] : $model::$connectIdentifier;
|
||||
$target = is_array($model::$connectIdentifier) ? $model::$connectIdentifier[1] : $model::$connectIdentifier;
|
||||
if ($withTrashed)
|
||||
$query->withTrashed();
|
||||
|
||||
$user = $model::where($target, $data[$origin])->first() ?? new $model;
|
||||
$model = new $class;
|
||||
|
||||
if (in_array(HasConnectData::class, class_uses($class))) {
|
||||
$id = $model->getConnectIdentifier();
|
||||
|
||||
$origin = is_array($id) ? $id[0] : $id;
|
||||
$target = is_array($id) ? $id[1] : $id;
|
||||
|
||||
$model = $query->where($target, $data[$origin])->first() ?? $model;
|
||||
$model->$target = $data[$origin];
|
||||
} else {
|
||||
$user = $model::where('email', $data['email'])->first() ?? new $model;
|
||||
$model = $query->where('email', $data['email'])->first() ?? $model;
|
||||
|
||||
if (! $model->exists())
|
||||
$model->email = $data['email'];
|
||||
}
|
||||
|
||||
return $user;
|
||||
return $model;
|
||||
}
|
||||
|
||||
// Routing
|
||||
|
|
|
@ -10,7 +10,7 @@ class ConnectServiceProvider extends ServiceProvider
|
|||
{
|
||||
public function register()
|
||||
{
|
||||
$this->mergeConfigFrom($this->path('src/config/bconnect.php'), 'bconnect');
|
||||
$this->mergeConfigFrom($this->path('config/bconnect.php'), 'bconnect');
|
||||
|
||||
$this->app->singleton(Connect::class, function ($app) {
|
||||
return new Connect($app);
|
||||
|
@ -19,7 +19,7 @@ class ConnectServiceProvider extends ServiceProvider
|
|||
|
||||
public function boot()
|
||||
{
|
||||
$config_path = $this->path('src/config/bconnect.php');
|
||||
$config_path = $this->path('config/bconnect.php');
|
||||
$views_path = $this->path('resources/views/connect');
|
||||
|
||||
$this->publishes([
|
||||
|
@ -50,6 +50,6 @@ class ConnectServiceProvider extends ServiceProvider
|
|||
|
||||
private function path($path = '')
|
||||
{
|
||||
return __DIR__ . "/../../$path";
|
||||
return __DIR__ . "/../$path";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,19 @@ class ConnectController extends Controller
|
|||
|
||||
public function webhook(Request $request, Connect $connect)
|
||||
{
|
||||
return $connect->handleWebhook($request);
|
||||
$hash = sha1(config('bconnect.client_secret') . date('Y-m-d'));
|
||||
|
||||
if ($request->header('x-connect-hash') !== $hash)
|
||||
abort(403);
|
||||
|
||||
$data = $request->validate([
|
||||
'event_type' => 'required|in:create,update,delete',
|
||||
'connect_data' => 'required|array',
|
||||
'connect_data.*' => 'nullable',
|
||||
'connect_data.id' => 'required',
|
||||
'connect_data.email' => 'required_if:event_type,create|required_if:event_type,update',
|
||||
]);
|
||||
|
||||
$connect->sync($data['event_type'], $data['connect_data']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Bluesquare\Connect\Traits;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
trait HasConnectData
|
||||
{
|
||||
public static $connectIdentifier = 'connect_id';
|
||||
|
||||
protected $connectFillable = [];
|
||||
public function getConnectIdentifier()
|
||||
{
|
||||
return $this->connectIdentifier ?? 'connect_id';
|
||||
}
|
||||
|
||||
public function fillConnectData(array $data)
|
||||
{
|
||||
foreach ($this->connectFillable as $origin => $target) {
|
||||
if (is_string($origin)) {
|
||||
$this->$target = $data[$origin] ?? null;
|
||||
} else {
|
||||
$this->$target = $data[$target] ?? null;
|
||||
$touched = [];
|
||||
|
||||
$fillable = $this->connectFillable ?? [];
|
||||
|
||||
foreach ($fillable as $origin => $targets) {
|
||||
$value = is_string($origin) ? $data[$origin] : $data[$targets];
|
||||
$targets = is_string($origin) && is_array($targets) ? $targets : [$targets];
|
||||
|
||||
foreach ($targets as $target) {
|
||||
$parts = explode('|', $target);
|
||||
$target = $parts[0];
|
||||
$currentValue = $value ?? ($parts[1] ?? null);
|
||||
$target_model = $this;
|
||||
$parts = explode('.', $target);
|
||||
|
||||
foreach ($parts as $i => $property) {
|
||||
if ($i < count($parts) - 1) {
|
||||
$target_model = $target_model->$property;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($target_model !== $this)
|
||||
$touched[] = $target_model;
|
||||
|
||||
$target_model->$property = $currentValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function fill(array $attributes);
|
||||
foreach ($touched as $model)
|
||||
$model->save();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Bluesquare\Connect\Traits;
|
||||
|
||||
trait HasConnectWebhook
|
||||
{
|
||||
public function onConnectCreate(array $data)
|
||||
{
|
||||
$this->onConnectUpdate($data);
|
||||
}
|
||||
|
||||
public function onConnectUpdate(array $data)
|
||||
{
|
||||
if (in_array(HasConnectData::class, class_uses(self::class))) {
|
||||
$this->fillConnectData($data);
|
||||
} else {
|
||||
$this->email = $data['email'];
|
||||
}
|
||||
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public function onConnectDelete(array $data)
|
||||
{
|
||||
$this->onConnectUpdate($data);
|
||||
|
||||
if (in_array(\Illuminate\Database\Eloquent\SoftDeletes::class, class_uses(self::class))) {
|
||||
$this->delete();
|
||||
} elseif (array_key_exists('remember_token', $this->attributes)) {
|
||||
$this->remember_token = null;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function onConnectRestore(array $data)
|
||||
{
|
||||
$this->restore();
|
||||
|
||||
$this->onConnectUpdate($data);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue