From 6dbc2ee43ea22311a7dfe68295e8048df645d28c Mon Sep 17 00:00:00 2001 From: Maxime Renou Date: Mon, 11 May 2020 17:54:18 +0200 Subject: [PATCH] Fix --- src/Connect.php | 135 ++++++++++++++++++++++++++++++++++-------- src/Traits/HasConnectSync.php | 2 +- 2 files changed, 112 insertions(+), 25 deletions(-) diff --git a/src/Connect.php b/src/Connect.php index ae26003..59ebc39 100644 --- a/src/Connect.php +++ b/src/Connect.php @@ -5,6 +5,7 @@ namespace Bluesquare\Connect; use Bluesquare\Connect\Traits\HasConnectSync; use GuzzleHttp\Client; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; use Psr\Http\Message\StreamInterface; @@ -42,10 +43,10 @@ class Connect * @param $method * @param $uri * @param null $data - * @return \Psr\Http\Message\StreamInterface + * @return array * @throws ConnectException */ - public function request($method, $uri, $data = null, $auth = true): StreamInterface + public function request($method, $uri, $data = null, $auth = true): array { $url = $this->getUrl(); $url = $url . '/' . trim($uri, '/'); @@ -70,10 +71,10 @@ class Connect } try { - return json_decode( - $client->request($method, $url, $config)->getBody(), - true - ); + return json_decode( + $client->request($method, $url, $config)->getBody(), + true + ); } catch(\Exception $e) { $this->deleteAccessToken(); @@ -106,20 +107,82 @@ class Connect 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) { // State check - if (!session()->has('connect_states')) - abort(403, "Session expired"); + if (!session()->has('connect_states')) { + Log::debug("Missing session states"); + return redirect('/'); + } $states = session()->get('connect_states'); - if (!is_array($states)) - abort(403, "Session expired"); + if (!is_array($states)) { + Log::debug("Invalid session state"); + return redirect('/'); + } - if (!$request->has('state') || !in_array($request->state, $states)) - abort(403, "Invalid state"); + if (!$request->has('state') || !in_array($request->state, $states)) { + Log::debug("Missing valid state in request"); + return redirect('/'); + } unset($states[array_search($request->state, $states)]); @@ -127,22 +190,26 @@ class Connect // Code check - if (!$request->has('code')) - abort(403, "Missing authorization code"); - - $code = $request->code; + if (!$request->has('code')) { + Log::debug("Missing authorization code"); + return redirect('/'); + } // Access token + $expires_at = now(); + $connect_data = $this->getAccessTokenFromAuhtorizationCode($request->code); + $connect_data['expires_at'] = $expires_at->addSeconds($connect_data['expires_in']); - $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'), - 'code' => $code - ], false); + $model_data = $this->getUserData($connect_data['access_token']); - return $data; + $this->sync('User', $model_data['id']); + + $model = $this->synchronized['User']; + $user = $model::findOrFail($model_data['id']); + + $this->updateUserConnectData($user, $connect_data); + + return $user; } // OAuth (client) @@ -222,6 +289,8 @@ class Connect foreach ($resourceTypes as $resourceType) { + $resourceType = $this->resolveResourceType($resourceType); + if (!array_key_exists($resourceType, $this->synchronized)) throw new ConnectException("Resource $resourceType not declared as synchronized."); @@ -245,6 +314,8 @@ class Connect public function sync($resourceType, $resourceId, $resourceData = null) { + $resourceType = $this->resolveResourceType($resourceType); + if (is_null($resourceData)) { $resourceData = $this->get($resourceType, $resourceId); } @@ -257,6 +328,22 @@ class Connect // + protected function resolveResourceType($class) + { + if (in_array($class, $this->synchronized)) + return array_flip($this->synchronized)[$class]; + + return $class; + } + + protected function resolveResourceModel($class) + { + if (array_key_exists($class, $this->synchronized)) + return $this->synchronized[$class]; + + return $class; + } + protected function getEventMethod($event) { return 'onConnectResource' . ucfirst($event); diff --git a/src/Traits/HasConnectSync.php b/src/Traits/HasConnectSync.php index 61d9463..879a812 100644 --- a/src/Traits/HasConnectSync.php +++ b/src/Traits/HasConnectSync.php @@ -4,7 +4,7 @@ namespace Bluesquare\Connect\Traits; trait HasConnectSync { - abstract function fill($data); + abstract function fill(array $attributes); abstract function save(); abstract function delete();