Skip to content

Commit

Permalink
Merge pull request #9 from curio-team/feature/log-verification-exception
Browse files Browse the repository at this point in the history
Add `AMO_SSL_VERIFYPEER` option + add 1M leeway for token verification
  • Loading branch information
bartjroos authored Dec 15, 2023
2 parents b0ce192 + cf1d17f commit ea8547c
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 28 deletions.
36 changes: 22 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,31 @@ __!!__ Please make sure your app is using _https_, to prevent unwanted exposure
To use amoclient in your project:

1. In your laravel project run: `composer require studiokaa/amoclient`

2. Set these keys in your .env file:
* AMO_CLIENT_ID
* AMO_CLIENT_SECRET
* AMO_API_LOG (optional)
* Default: no
* Set to 'yes' to make Amoclient log all usage of access_tokens and refresh_tokens to the default log-channel.
* AMO_APP_FOR (optional)
* Default: teachers

* `AMO_CLIENT_ID`
* `AMO_CLIENT_SECRET`
* `AMO_API_LOG` *(optional)*
* *Default:* `no`
* Set to `yes` to make Amoclient log all usage of access_tokens and refresh_tokens to the default log-channel.
* `AMO_APP_FOR` *(optional)*
* *Default:* `teachers`
* This key determines if students can login to your application.
* May be one of:
* _all_: everyone can login, you may restrict access using guards or middleware.
* _teachers_: a student will be completely blocked and no user will be created when they try to login.
* AMO_USE_MIGRATION (optional)
* Default: yes
* `all`: everyone can login, you may restrict access using guards or middleware.
* `teachers`: a student will be completely blocked and no user will be created when they try to login.
* `AMO_USE_MIGRATION` *(optional)*
* *Default:* `yes`
* Set to no if you want to use your own migration instead of the users migration this package provides
* `AMO_SSL_VERIFYPEER` *(optional)*
* *Default:* `yes`
* Set to `no` if you want to disable SSL verification. This is only recommended for during development and only on trusted networks.

3. Alter your User model and add the line: `public $incrementing = false;`
4. (Recommended) Remove any default users-migration from your app, because Amoclient will conflict with it. Do _not_ remove the user-model. If you want to keep using your own migration, in your .env file set: `AMO_USE_MIGRATION=no`

4. *(Recommended)* Remove any default users-migration from your app, because Amoclient will conflict with it. Do _not_ remove the user-model. If you want to keep using your own migration, in your .env file set: `AMO_USE_MIGRATION=no`

5. Lastly, run `php artisan migrate`.


Expand Down Expand Up @@ -112,6 +120,6 @@ class MyController extends Controller
],
```
* **Note:** `../amoclient` should point to where you cloned this package
5. Run `composer require "vendorname/packagename @dev"` inside the test project
5. Run `composer require "studiokaa/amoclient @dev"` inside the test project

You can now test and modify this package. Changes will immediately be reflected in the test project.
You can now test and modify this package. Changes will immediately be reflected in the test project.
23 changes: 18 additions & 5 deletions src/AmoAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ class AmoAPI

public function __construct()
{
$this->client = new \GuzzleHttp\Client;
$config = [];

if (config('amoclient.ssl_verify_peer') === 'no') {
$config = ['curl' => [CURLOPT_SSL_VERIFYPEER => false]];
}

$this->client = new \GuzzleHttp\Client($config);
$this->logging = config('amoclient.api_log') == 'yes' ? true : false;
}

Expand All @@ -26,7 +32,7 @@ public function get($endpoint)
private function call($endpoint = 'user', $method = 'GET')
{
$access_token = session('access_token');

if($access_token == null)
{
abort(401, 'No access token: probably not logged-in');
Expand Down Expand Up @@ -83,11 +89,18 @@ private function refresh($refresh_token)

return $access_token;
}
catch(\GuzzleHttp\Exception\ClientException $e)
catch(\GuzzleHttp\Exception\ClientException $e)
{
$this->log('refreshing token failed, redirecting for authorization');
$url = app('StudioKaa\Amoclient\AmoclientController')->redirect()->getTargetUrl();
abort(302, '', ["Location" => $url]);
$controller = app('StudioKaa\Amoclient\AmoclientController');
$redirector = $controller->redirect();

// Workaround for Livewire. TODO: Find a better way to do this.
if (get_class($redirector) === 'Livewire\Features\SupportRedirects\Redirector') {
$redirector = $redirector->response($controller->redirectUrl());
}

abort(302, '', ["Location" => $redirector->getTargetUrl()]);
}
}

Expand Down
24 changes: 18 additions & 6 deletions src/AmoclientController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,35 @@

class AmoclientController extends Controller
{
public function redirect()
public function redirectUrl()
{
$client_id = config('amoclient.client_id');
if($client_id == null)
{
abort(500, 'Please set AMO_CLIENT_ID and AMO_CLIENT_SECRET in .env file.');
}

return redirect('https://login.curio.codes/oauth/authorize?client_id=' . $client_id . '&redirect_id=' . url('amoclient/callback') . '&response_type=code');
return 'https://login.curio.codes/oauth/authorize?client_id=' . $client_id . '&redirect_id=' . url('amoclient/callback') . '&response_type=code';
}

public function redirect()
{
$url = $this->redirectUrl();

return redirect($url);
}

public function callback(Request $request)
{
$config = [];

$http = new \GuzzleHttp\Client;
try {
if (config('amoclient.ssl_verify_peer') === 'no') {
$config = ['curl' => [CURLOPT_SSL_VERIFYPEER => false]];
}

$http = new \GuzzleHttp\Client($config);

try {
//Exchange authcode for tokens
$response = $http->post('https://login.curio.codes/oauth/token', [
'form_params' => [
Expand All @@ -44,14 +56,14 @@ public function callback(Request $request)
try {
$token = $config->parser()->parse($tokens->id_token);
} catch (\Lcobucci\JWT\Exception $exception) {
abort(400, 'Access token could not be parsed!');
abort(400, $exception->getMessage());
}

try {
$constraints = $config->validationConstraints();
$config->validator()->assert($token, ...$constraints);
} catch (RequiredConstraintsViolated $exception) {
abort(400, 'Access token could not be verified!');
abort(400, $exception->getMessage());
}

$claims = $token->claims();
Expand Down
11 changes: 9 additions & 2 deletions src/AmoclientHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,17 @@ public static function getTokenConfig()
);

self::$cachedConfig->setValidationConstraints(
new ValidAt(new SystemClock(new DateTimeZone(\date_default_timezone_get()))),
new ValidAt(
new SystemClock(
new DateTimeZone(\date_default_timezone_get()),
),
// Fixes occasional "The token was issued in the future" when we're slow (e.g: when debugging with dd)
// Gives us a 1 minute leeway
new \DateInterval('PT1M')
),
new SignedWith(new Sha256(), InMemory::plainText($client_id))
);

return self::$cachedConfig;
}
}
3 changes: 2 additions & 1 deletion src/config/amoclient.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
'client_secret' => env('AMO_CLIENT_SECRET', null),
'app_for' => env('AMO_APP_FOR', 'teachers'),
'use_migration' => env('AMO_USE_MIGRATION', 'yes'),
'api_log' => env('AMO_API_LOG', 'no')
'api_log' => env('AMO_API_LOG', 'no'),
'ssl_verify_peer' => env('AMO_SSL_VERIFYPEER', 'yes'),
];

0 comments on commit ea8547c

Please sign in to comment.