Skip to content

Commit

Permalink
Change authType default to bearer + testing
Browse files Browse the repository at this point in the history
  • Loading branch information
pelmered committed Sep 17, 2024
1 parent a00e1e8 commit c2dc62f
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 27 deletions.
17 changes: 8 additions & 9 deletions src/Credentials.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,16 @@ public function addAuthToRequest(PendingRequest $httpClient, Options $options):
}
if (is_callable($this->customCallback)) {
return ($this->customCallback)($httpClient);
}

if ($options->authType === self::AUTH_TYPE_BASIC) {
if (! $this->clientId || ! $this->clientSecret) {
throw new InvalidArgumentException('Basic auth requires client id and client secret. Check documentation/readme.');
}

return $httpClient->withBasicAuth($this->clientId, $this->clientSecret);
}

if ($this->token) {
if ($options->authType === self::AUTH_TYPE_QUERY) {
return $httpClient->withQueryParameters([
Expand All @@ -123,16 +131,7 @@ public function addAuthToRequest(PendingRequest $httpClient, Options $options):

return $httpClient->withToken($this->token, $options->authType);
}
if ($options->authType === self::AUTH_TYPE_BASIC) {
if (! $this->clientId || ! $this->clientSecret) {
throw new InvalidArgumentException('Basic auth requires client id and client secret. Check documentation/readme. ');
}

return $httpClient->withBasicAuth($this->clientId, $this->clientSecret);
}
if ($options->authType === self::AUTH_TYPE_CUSTOM && is_callable($this->customCallback)) {
return ($this->customCallback)($httpClient);
}

return $httpClient;
}
Expand Down
7 changes: 4 additions & 3 deletions src/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Pelmered\LaravelHttpOAuthHelper;

use Carbon\Carbon;
use Closure;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Expand All @@ -13,11 +14,11 @@ class Options
*/
final public function __construct(
public array $scopes = [],
public string $authType = Credentials::AUTH_TYPE_BASIC, //TODO: Which auth type should be default?
public string $authType = Credentials::AUTH_TYPE_BEARER,
public string $grantType = Credentials::GRANT_TYPE_CLIENT_CREDENTIALS,
public string $tokenType = AccessToken::TOKEN_TYPE_BEARER,
public string $tokenName = 'token',
public int|string|Closure $expires = 3600,
public int|string|Closure|Carbon $expires = 3600,
public string|Closure $accessToken = 'access_token',
public ?Closure $tokenTypeCustomCallback = null,
public ?string $cacheKey = null,
Expand Down Expand Up @@ -91,7 +92,7 @@ protected static function getDefaults(): array
'scopes' => [],
'grantType' => Credentials::GRANT_TYPE_CLIENT_CREDENTIALS,
'tokenType' => AccessToken::TOKEN_TYPE_BEARER,
'authType' => Credentials::AUTH_TYPE_BASIC,
'authType' => Credentials::AUTH_TYPE_BEARER,
'expires' => 3600,
'accessToken' => 'access_token',
];
Expand Down
4 changes: 4 additions & 0 deletions src/RefreshToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ protected function getExpiresAtFromResponse(Response $response, callable|string|
$expires = $response->json()[$expires];
}

if (is_int($expires)) {
return Carbon::now()->addSeconds($expires - 60);
}

return Carbon::parse($expires)->subMinute();
}

Expand Down
15 changes: 14 additions & 1 deletion tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@
|
*/

use Carbon\Carbon;

expect()->extend('toBeOne', function () {
return $this->toBe(1);
});

expect()->extend('toBeWithin', function ($integer, $acceptableDiff) {
return $this->toBeBetween($integer-$acceptableDiff, $integer+$acceptableDiff);
});

/*
|--------------------------------------------------------------------------
| Functions
Expand All @@ -41,5 +47,12 @@

function something()
{
// ..

}
function isSameAccessToken($accessToken1, $accessToken2)
{
expect($accessToken1->getAccessToken())->toBe($accessToken2->getAccessToken())
->and($accessToken1->getExpiresIn())->toBeWithin($accessToken1->getExpiresIn(), 10)
->and($accessToken1->getExpiresAt())->toBeInstanceOf(Carbon::class)
->and($accessToken1->getCustomCallback())->toBe($accessToken1->getCustomCallback());
}
5 changes: 4 additions & 1 deletion tests/Unit/MacroTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
[
'my_client_id', 'my_client_secret',
],
['scopes' => ['scope1', 'scope2']],
[
'scopes' => ['scope1', 'scope2'],
'authType' => 'basic',
],
)->get('https://example.com/api');

expect($response->json()['data'])->toBe('some data with bearer token');
Expand Down
105 changes: 104 additions & 1 deletion tests/Unit/RefreshTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
new Options(
scopes: ['scope1', 'scope2'],
grantType: 'client_credentials',
authType: 'basic'
),
);

Expand All @@ -38,6 +39,23 @@
});
});

test('refresh token basic with invalid credentials', function () {
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Basic auth requires client id and client secret. Check documentation/readme.');

$accessToken = app(RefreshToken::class)(
'https://example.com/oauth/token',
new Credentials([
'token',
]),
new Options(
scopes: ['scope1', 'scope2'],
authType: Credentials::AUTH_TYPE_BASIC,
grantType: 'client_credentials',
),
);
});

test('refresh token body', function () {
Cache::clear();
$accessToken = app(RefreshToken::class)(
Expand Down Expand Up @@ -186,6 +204,7 @@
accessToken: static function ($response) {
return $response->json()['custom_access_token'];
},
authType: Credentials::AUTH_TYPE_BASIC,
),
);

Expand Down Expand Up @@ -302,6 +321,7 @@
&& $request->url() === 'https://example.com/oauth/token';
});
});

test('auth type query', function () {

app(RefreshToken::class)(
Expand All @@ -322,9 +342,92 @@

expect($token)->toBe('my_query_token');


return $request->url() === 'https://example.com/oauth/token?custom_token_name=my_query_token';
});
});

test('set token expiry with string key with date', function () {

$this->clearExistingFakes();

/** @var Carbon $nowDate */
$nowDate = Carbon::create(2024, 11, 11, 11);

Carbon::setTestNow($nowDate);

Http::fake([
'https://example.com/oauth/token' => Http::response([
'token_type' => 'Bearer',
'access_token' => 'my_custom_access_token',
'scope' => 'scope1 scope2',
'expires_date' => $nowDate->addHour(),
], 200),
]);

$accessToken = app(RefreshToken::class)(
'https://example.com/oauth/token',
new Credentials('my_query_token'),
new Options(
scopes: ['scope1', 'scope2'],
expires: 'expires_date',
),
);

expect($accessToken->getExpiresAt()->timestamp)->toBe($nowDate->subMinute()->timestamp);
});

test('set token expiry with string key with integer', function () {

/** @var Carbon $nowDate */
$nowDate = Carbon::create(2024, 11, 11, 11);

Carbon::setTestNow($nowDate);

$accessToken = app(RefreshToken::class)(
'https://example.com/oauth/token',
new Credentials('my_query_token'),
new Options(
scopes: ['scope1', 'scope2'],
expires: 'expires_in',
),
);

expect($accessToken->getExpiresAt()->timestamp)->toBe($nowDate->addSeconds(7200)->subMinute()->timestamp);
});

test('set token expiry with carbon object', function () {

/** @var Carbon $nowDate */
$nowDate = Carbon::create(2024, 11, 11, 11);

Carbon::setTestNow($nowDate);

$accessToken = app(RefreshToken::class)(
'https://example.com/oauth/token',
new Credentials('my_query_token'),
new Options(
scopes: ['scope1', 'scope2'],
expires: Carbon::now()->addHour(),
),
);

expect($accessToken->getExpiresAt()->timestamp)->toBe($nowDate->addHour()->subMinute()->timestamp);
});

test('invalid token expiry', function () {
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid expires option');

app(RefreshToken::class)(
'https://example.com/oauth/token',
new Credentials('my_query_token'),
new Options(
scopes: ['scope1', 'scope2'],
expires: function () {
return new stdClass;
},
),
);
});

})->done(assignee: 'pelmered');
41 changes: 29 additions & 12 deletions tests/Unit/TokenStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

uses(\Pelmered\LaravelHttpOAuthHelper\Tests\TestCase::class);

use Carbon\Carbon;
use Illuminate\Cache\ArrayStore;
use Illuminate\Cache\FileStore;
use Illuminate\Support\Facades\Cache;
use Orchestra\Testbench\Attributes\DefineEnvironment;
use Pelmered\LaravelHttpOAuthHelper\AccessToken;
use Pelmered\LaravelHttpOAuthHelper\Credentials;
use Pelmered\LaravelHttpOAuthHelper\Options;
use Pelmered\LaravelHttpOAuthHelper\TokenStore;
Expand All @@ -14,29 +17,43 @@

});

/*
it('reads and stores a token in cache', function () {
it('reads and stores a token in cache be default', function () {
Cache::clear();
Cache::spy();

Cache::shouldReceive('get')->once()->with('oauth_token_example.comoauthtoken')->andReturn(null);
/** @var Carbon $nowDate */
$nowDate = Carbon::create(2024, 11, 11, 11);

$accessToken = TokenStore::get(
Carbon::setTestNow($nowDate);

$cacheBefore = Cache::get('oauth_token_example.comoauthtoken');

$accessToken1 = TokenStore::get(
'https://example.com/oauth/token',
new Credentials(
clientId: 'this_is_my_client_id',
clientSecret: 'this_is_my_client_secret',
new Credentials('my_token'),
new Options(
scopes: ['scope1', 'scope2'],
),
);

$cacheAfterOne = Cache::get('oauth_token_example.comoauthtoken');

Carbon::setTestNow($nowDate->addHour());

$accessToken2 = TokenStore::get(
'https://example.com/oauth/token',
new Credentials('my_token'),
new Options(
scopes: ['scope1', 'scope2'],
authType: Credentials::AUTH_TYPE_BASIC,
),
);

// Does not work with composer update --prefer-lowest
//Cache::shouldHaveReceived('put')->once()->with('oauth_token_example.comoauthtoken', $accessToken, 3540);
expect($cacheBefore)->toBeNull();

isSameAccessToken($accessToken1, $cacheAfterOne);

isSameAccessToken($accessToken1, $accessToken2);

});
*/

it('reads and stores a token in cache with custom cache driver', function () {

Expand Down

0 comments on commit c2dc62f

Please sign in to comment.