First commit
This commit is contained in:
commit
ba104bd674
|
@ -0,0 +1,2 @@
|
||||||
|
.idea/
|
||||||
|
/vendor/
|
|
@ -0,0 +1,42 @@
|
||||||
|
# laravel-bconnect
|
||||||
|
|
||||||
|
The Bluesquare Connect package allows you to use its OAuth server and sync its resources.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
First in your composer.json, add:
|
||||||
|
|
||||||
|
```
|
||||||
|
"require": {
|
||||||
|
"bluesquare/laravel-connect": "dev-master"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://git.bluesquare.io/bluesquare/laravel-connect"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, update your package:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer update bluesquare/laravel-connect
|
||||||
|
```
|
||||||
|
|
||||||
|
Eventually, if you want to customize the config system:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php artisan vendor:publish
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, add in your `.env`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
BCONNECT_CLIENT_ID=your_client_id
|
||||||
|
BCONNECT_CLIENT_SECRET=your_client_secret
|
||||||
|
```
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"name": "bluesquare/laravel-connect",
|
||||||
|
"description": "Consume Bluesquare Connect resources and use its OAuth server.",
|
||||||
|
"keywords": [
|
||||||
|
"package",
|
||||||
|
"bluesquare",
|
||||||
|
"api",
|
||||||
|
"connect",
|
||||||
|
"oauth"
|
||||||
|
],
|
||||||
|
"homepage": "https://git.bluesquare.io/bluesquare/laravel-connect",
|
||||||
|
"license": "proprietary",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Bluesquare",
|
||||||
|
"email": "contact@bluesquare.io",
|
||||||
|
"homepage": "https://bluesquare.io/",
|
||||||
|
"role": "Developers"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Bluesquare\\Connect\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Bluesquare\\Connect\\ConnectServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"guzzlehttp/guzzle": "^6.5",
|
||||||
|
"php": "^7.2"
|
||||||
|
},
|
||||||
|
"prefer-stable": true
|
||||||
|
}
|
|
@ -0,0 +1,297 @@
|
||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "98b09ff09c6392aadb0f56bb9dc51a96",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "guzzlehttp/guzzle",
|
||||||
|
"version": "6.5.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/guzzle/guzzle.git",
|
||||||
|
"reference": "43ece0e75098b7ecd8d13918293029e555a50f82"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82",
|
||||||
|
"reference": "43ece0e75098b7ecd8d13918293029e555a50f82",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-json": "*",
|
||||||
|
"guzzlehttp/promises": "^1.0",
|
||||||
|
"guzzlehttp/psr7": "^1.6.1",
|
||||||
|
"php": ">=5.5"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-curl": "*",
|
||||||
|
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
|
||||||
|
"psr/log": "^1.1"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-intl": "Required for Internationalized Domain Name (IDN) support",
|
||||||
|
"psr/log": "Required for using the Log middleware"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "6.5-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"GuzzleHttp\\": "src/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/functions_include.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Michael Dowling",
|
||||||
|
"email": "mtdowling@gmail.com",
|
||||||
|
"homepage": "https://github.com/mtdowling"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Guzzle is a PHP HTTP client library",
|
||||||
|
"homepage": "http://guzzlephp.org/",
|
||||||
|
"keywords": [
|
||||||
|
"client",
|
||||||
|
"curl",
|
||||||
|
"framework",
|
||||||
|
"http",
|
||||||
|
"http client",
|
||||||
|
"rest",
|
||||||
|
"web service"
|
||||||
|
],
|
||||||
|
"time": "2019-12-23T11:57:10+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "guzzlehttp/promises",
|
||||||
|
"version": "v1.3.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/guzzle/promises.git",
|
||||||
|
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
|
||||||
|
"reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.5.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.4-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"GuzzleHttp\\Promise\\": "src/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/functions_include.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Michael Dowling",
|
||||||
|
"email": "mtdowling@gmail.com",
|
||||||
|
"homepage": "https://github.com/mtdowling"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Guzzle promises library",
|
||||||
|
"keywords": [
|
||||||
|
"promise"
|
||||||
|
],
|
||||||
|
"time": "2016-12-20T10:07:11+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "guzzlehttp/psr7",
|
||||||
|
"version": "1.6.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/guzzle/psr7.git",
|
||||||
|
"reference": "239400de7a173fe9901b9ac7c06497751f00727a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
|
||||||
|
"reference": "239400de7a173fe9901b9ac7c06497751f00727a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.4.0",
|
||||||
|
"psr/http-message": "~1.0",
|
||||||
|
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"psr/http-message-implementation": "1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-zlib": "*",
|
||||||
|
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.6-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"GuzzleHttp\\Psr7\\": "src/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/functions_include.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Michael Dowling",
|
||||||
|
"email": "mtdowling@gmail.com",
|
||||||
|
"homepage": "https://github.com/mtdowling"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tobias Schultze",
|
||||||
|
"homepage": "https://github.com/Tobion"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PSR-7 message implementation that also provides common utility methods",
|
||||||
|
"keywords": [
|
||||||
|
"http",
|
||||||
|
"message",
|
||||||
|
"psr-7",
|
||||||
|
"request",
|
||||||
|
"response",
|
||||||
|
"stream",
|
||||||
|
"uri",
|
||||||
|
"url"
|
||||||
|
],
|
||||||
|
"time": "2019-07-01T23:21:34+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/http-message",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/http-message.git",
|
||||||
|
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||||
|
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Http\\Message\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "http://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interface for HTTP messages",
|
||||||
|
"homepage": "https://github.com/php-fig/http-message",
|
||||||
|
"keywords": [
|
||||||
|
"http",
|
||||||
|
"http-message",
|
||||||
|
"psr",
|
||||||
|
"psr-7",
|
||||||
|
"request",
|
||||||
|
"response"
|
||||||
|
],
|
||||||
|
"time": "2016-08-06T14:39:51+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ralouphie/getallheaders",
|
||||||
|
"version": "3.0.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/ralouphie/getallheaders.git",
|
||||||
|
"reference": "120b605dfeb996808c31b6477290a714d356e822"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
|
||||||
|
"reference": "120b605dfeb996808c31b6477290a714d356e822",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.6"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"php-coveralls/php-coveralls": "^2.1",
|
||||||
|
"phpunit/phpunit": "^5 || ^6.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/getallheaders.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Ralph Khattar",
|
||||||
|
"email": "ralph.khattar@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A polyfill for getallheaders.",
|
||||||
|
"time": "2019-03-08T08:55:37+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": [],
|
||||||
|
"platform-dev": []
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
/**
|
||||||
|
* OAuth model
|
||||||
|
*/
|
||||||
|
'model' => \App\User::class,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuth redirect URI
|
||||||
|
*/
|
||||||
|
'redirect' => env('BCONNECT_REDIRECT', url('/oauth/callback')),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuth client id
|
||||||
|
*/
|
||||||
|
'client_id' => env('BCONNECT_CLIENT_ID', null),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuth client secret
|
||||||
|
*/
|
||||||
|
'client_secret' => env('BCONNECT_CLIENT_SECRET', null),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuth scopes (separated with commas)
|
||||||
|
*/
|
||||||
|
'user_scopes' => '*',
|
||||||
|
'client_scopes' => '*',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bluesquare Connect URL
|
||||||
|
*/
|
||||||
|
'url' => env('BCONNECT_URL', null),
|
||||||
|
];
|
|
@ -0,0 +1,264 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bluesquare\Connect;
|
||||||
|
|
||||||
|
use Bluesquare\Connect\Traits\HasConnectSync;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
|
||||||
|
class Connect
|
||||||
|
{
|
||||||
|
protected $app;
|
||||||
|
protected $synchronized = [];
|
||||||
|
|
||||||
|
public function __construct(array $app)
|
||||||
|
{
|
||||||
|
$this->app = $app;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User config
|
||||||
|
|
||||||
|
public function setSynchronized($models)
|
||||||
|
{
|
||||||
|
$this->synchronized = [];
|
||||||
|
|
||||||
|
foreach ($models as $model)
|
||||||
|
{
|
||||||
|
if (!in_array(HasConnectSync::class, class_uses($model)))
|
||||||
|
throw new ConnectException("$model does not implement HasConnectSync trait.");
|
||||||
|
|
||||||
|
$class = explode('\\', $model);
|
||||||
|
$resource = $model::$connectResource ?? end($class);
|
||||||
|
|
||||||
|
$this->synchronized[$resource] = $model;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $method
|
||||||
|
* @param $uri
|
||||||
|
* @param null $data
|
||||||
|
* @return \Psr\Http\Message\StreamInterface
|
||||||
|
* @throws ConnectException
|
||||||
|
*/
|
||||||
|
public function request($method, $uri, $data = null, $auth = true): StreamInterface
|
||||||
|
{
|
||||||
|
$url = config('bconnect.url') ?? 'https://connect.bluesquare.io';
|
||||||
|
$url = $url . '/' . trim($uri, '/');
|
||||||
|
|
||||||
|
$client = new Client();
|
||||||
|
|
||||||
|
$config = [
|
||||||
|
'headers' => [
|
||||||
|
'Accept' => 'application/json'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($auth === true) {
|
||||||
|
$config['Authorization'] = 'Bearer ' . $this->getAccessToken();
|
||||||
|
}
|
||||||
|
elseif ($auth !== false) {
|
||||||
|
$config['Authorization'] = 'Bearer ' . $auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_null($data)) {
|
||||||
|
$config['form_params'] = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return json_decode(
|
||||||
|
$client->request($method, $url, $config)->getBody(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
$this->deleteAccessToken();
|
||||||
|
throw new ConnectException($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OAuth (user)
|
||||||
|
|
||||||
|
public function redirect($state = null)
|
||||||
|
{
|
||||||
|
if (is_null($state))
|
||||||
|
$state = Str::random();
|
||||||
|
|
||||||
|
$states = session()->get('connect_states');
|
||||||
|
if (!is_array($states))
|
||||||
|
$states = [];
|
||||||
|
$states[] = $state;
|
||||||
|
session()->put('connect_states', $states);
|
||||||
|
|
||||||
|
$query = http_build_query([
|
||||||
|
'client_id' => config('bconnect.client_id'),
|
||||||
|
'scope' => config('bconnect.scopes'),
|
||||||
|
'redirect_uri' => config('bconnect.redirect'),
|
||||||
|
'response_type' => 'code',
|
||||||
|
'state' => $state
|
||||||
|
]);
|
||||||
|
|
||||||
|
$url = config('bconnect.url') . '/oauth/authorize?' . $query;
|
||||||
|
return redirect()->to($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loginFromCallback(Request $request)
|
||||||
|
{
|
||||||
|
// State check
|
||||||
|
|
||||||
|
if (!session()->has('connect_states'))
|
||||||
|
abort(403, "Session expired");
|
||||||
|
|
||||||
|
$states = session()->get('connect_states');
|
||||||
|
|
||||||
|
if (!is_array($states))
|
||||||
|
abort(403, "Session expired");
|
||||||
|
|
||||||
|
if (!$request->has('state') || !in_array($request->state, $states))
|
||||||
|
abort(403, "Invalid state");
|
||||||
|
|
||||||
|
unset($states[array_search($request->state, $states)]);
|
||||||
|
|
||||||
|
session()->put('connect_states', $states);
|
||||||
|
|
||||||
|
// Code check
|
||||||
|
|
||||||
|
if (!$request->has('code'))
|
||||||
|
abort(403, "Missing authorization code");
|
||||||
|
|
||||||
|
$code = $request->code;
|
||||||
|
|
||||||
|
// Access token
|
||||||
|
|
||||||
|
$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'),
|
||||||
|
'authorization_code' => $code
|
||||||
|
], false);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OAuth (client)
|
||||||
|
|
||||||
|
public function getAccessToken()
|
||||||
|
{
|
||||||
|
$access_token = cache()->get('bconnect.access_token');
|
||||||
|
$access_token_expiration = cache()->get('bconnect.access_token_expiration');
|
||||||
|
|
||||||
|
if ($access_token && $access_token_expiration > time() + 60) {
|
||||||
|
return $access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->request('post', '/oauth/token', [
|
||||||
|
'grant_type' => 'client_credentials',
|
||||||
|
'client_id' => config('bconnect.client_id'),
|
||||||
|
'client_secret' => config('bconnect.client_secret'),
|
||||||
|
'scope' => config('bconnect.client_scopes')
|
||||||
|
], false);
|
||||||
|
|
||||||
|
cache()->set('bconnect.access_token', $data['access_token']);
|
||||||
|
cache()->set('bconnect.access_token_expiration', time() + $data['expires_in']);
|
||||||
|
|
||||||
|
return $data['access_token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteAccessToken()
|
||||||
|
{
|
||||||
|
cache()->delete('bconnect.access_token');
|
||||||
|
cache()->delete('bconnect.access_token_expiration');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Webhooks handler
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Request $request
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function handleWebhook(Request $request)
|
||||||
|
{
|
||||||
|
$data = $request->validate([
|
||||||
|
'connectEventType' => 'required|in:created,updated,deleted',
|
||||||
|
'connectResourceType' => 'required',
|
||||||
|
'connectResourceTable' => 'required',
|
||||||
|
'connectResourceData' => 'required|array',
|
||||||
|
'connectResourceData.id' => 'required'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!array_key_exists($data['connectResourceType'], $this->synchronized))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
$model = $this->synchronized[$data['connectResourceType']];
|
||||||
|
$method = $this->getEventMethod($data['connectEventType']);
|
||||||
|
$data = $data['connectResourceData'];
|
||||||
|
$model::$method($data['id'], $data);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resources endpoints
|
||||||
|
|
||||||
|
public function getAll($resourceType)
|
||||||
|
{
|
||||||
|
return $this->request('get', "api/resources/$resourceType");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get($resourceType, $resourceId)
|
||||||
|
{
|
||||||
|
return $this->request('get', "api/resources/$resourceType/$resourceId");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resources sync
|
||||||
|
|
||||||
|
public function syncAll($resourceTypes = null)
|
||||||
|
{
|
||||||
|
$resourceTypes = $resourceTypes ?? $this->synchronized;
|
||||||
|
|
||||||
|
foreach ($resourceTypes as $resourceType)
|
||||||
|
{
|
||||||
|
if (!array_key_exists($resourceType, $this->synchronized))
|
||||||
|
throw new ConnectException("Resource $resourceType not declared as synchronized.");
|
||||||
|
|
||||||
|
$resources = $this->getAll($resourceType);
|
||||||
|
$model = $this->synchronized[$resourceType];
|
||||||
|
$identifiers = [];
|
||||||
|
|
||||||
|
foreach ($resources as $data)
|
||||||
|
{
|
||||||
|
$identifiers[] = intval($data['id']);
|
||||||
|
$this->sync($resourceType, $data['id'], $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($model::all() as $item)
|
||||||
|
{
|
||||||
|
if (!in_array(intval($item->id), $identifiers))
|
||||||
|
$item->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sync($resourceType, $resourceId, $resourceData = null)
|
||||||
|
{
|
||||||
|
if (is_null($resourceData)) {
|
||||||
|
$resourceData = $this->get($resourceType, $resourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
$model = $this->synchronized[$resourceType];
|
||||||
|
$item = $model::find($resourceId);
|
||||||
|
$method = $this->getEventMethod($item ? 'updated' : 'created');
|
||||||
|
$model::$method($resourceId, $resourceData);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
protected function getEventMethod($event)
|
||||||
|
{
|
||||||
|
return 'onConnectResource' . ucfirst($event);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bluesquare\Connect;
|
||||||
|
|
||||||
|
class ConnectException extends \Exception {}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bluesquare\Connect;
|
||||||
|
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class ConnectServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register any application services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
$this->mergeConfigFrom(
|
||||||
|
__DIR__ . '/../config/bconnect.php',
|
||||||
|
'bmail'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->app->singleton(Connect::class, function ($app) {
|
||||||
|
return new Connect($app);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap any application services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
$this->publishes([
|
||||||
|
__DIR__ . '/../config/bconnect.php' => config_path('bconnect.php')
|
||||||
|
], 'config');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bluesquare\Connect\Traits;
|
||||||
|
|
||||||
|
trait HasConnectSync
|
||||||
|
{
|
||||||
|
abstract function fill($data);
|
||||||
|
abstract function save();
|
||||||
|
abstract function delete();
|
||||||
|
|
||||||
|
public static $connectResource;
|
||||||
|
|
||||||
|
public static function onConnectResourceCreated($id, $data)
|
||||||
|
{
|
||||||
|
$record = new self;
|
||||||
|
$record->fill($data);
|
||||||
|
$record->save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function onConnectResourceUpdated($id, $data)
|
||||||
|
{
|
||||||
|
$record = self::find($id) ?? new self;
|
||||||
|
$record->fill($data);
|
||||||
|
$record->save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function onConnectResourceDeleted($id, $data)
|
||||||
|
{
|
||||||
|
$record = self::find($id);
|
||||||
|
return $record ? $record->delete() : false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue