Merge pull request #445 from jonnybarnes/develop
MTM Reworked indieauth checking in token endpoint
This commit is contained in:
commit
46133be181
4 changed files with 19 additions and 64 deletions
|
@ -53,24 +53,9 @@ class TokenEndpointController extends Controller
|
||||||
*/
|
*/
|
||||||
public function create(Request $request): JsonResponse
|
public function create(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
if (empty($request->input('me'))) {
|
|
||||||
return response()->json([
|
|
||||||
'error' => 'Missing {me} param from input',
|
|
||||||
], 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
$authorizationEndpoint = $this->client::discoverAuthorizationEndpoint(normalize_url($request->input('me')));
|
|
||||||
|
|
||||||
if (empty($authorizationEndpoint)) {
|
|
||||||
return response()->json([
|
|
||||||
'error' => sprintf('Could not discover the authorization endpoint for %s', $request->input('me')),
|
|
||||||
], 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
$auth = $this->verifyIndieAuthCode(
|
$auth = $this->verifyIndieAuthCode(
|
||||||
$authorizationEndpoint,
|
config('app.authorization_endpoint'),
|
||||||
$request->input('code'),
|
$request->input('code'),
|
||||||
$request->input('me'),
|
|
||||||
$request->input('redirect_uri'),
|
$request->input('redirect_uri'),
|
||||||
$request->input('client_id'),
|
$request->input('client_id'),
|
||||||
);
|
);
|
||||||
|
@ -100,7 +85,6 @@ class TokenEndpointController extends Controller
|
||||||
protected function verifyIndieAuthCode(
|
protected function verifyIndieAuthCode(
|
||||||
string $authorizationEndpoint,
|
string $authorizationEndpoint,
|
||||||
string $code,
|
string $code,
|
||||||
string $me,
|
|
||||||
string $redirectUri,
|
string $redirectUri,
|
||||||
string $clientId
|
string $clientId
|
||||||
): ?array {
|
): ?array {
|
||||||
|
@ -111,7 +95,7 @@ class TokenEndpointController extends Controller
|
||||||
],
|
],
|
||||||
'form_params' => [
|
'form_params' => [
|
||||||
'code' => $code,
|
'code' => $code,
|
||||||
'me' => $me,
|
'me' => config('app.url'),
|
||||||
'redirect_uri' => $redirectUri,
|
'redirect_uri' => $redirectUri,
|
||||||
'client_id' => $clientId,
|
'client_id' => $clientId,
|
||||||
],
|
],
|
||||||
|
|
|
@ -78,6 +78,17 @@ return [
|
||||||
|
|
||||||
'shorturl' => env('APP_SHORTURL', 'shorturl.local'),
|
'shorturl' => env('APP_SHORTURL', 'shorturl.local'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Authorization endpoint
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The authorization endpoint for the application, used primarily for Micropub
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'authorization_endpoint' => env('AUTHORIZATION_ENDPOINT', 'https://indieauth.com/auth'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Application Display Name
|
| Application Display Name
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<link rel="alternate" type="application/jf2feed+json" title="Notes JF2 Feed" href="/blog/feed.jf2">
|
<link rel="alternate" type="application/jf2feed+json" title="Notes JF2 Feed" href="/blog/feed.jf2">
|
||||||
<link rel="openid.server" href="https://indieauth.com/openid">
|
<link rel="openid.server" href="https://indieauth.com/openid">
|
||||||
<link rel="openid.delegate" href="{{ config('app.url') }}">
|
<link rel="openid.delegate" href="{{ config('app.url') }}">
|
||||||
<link rel="authorization_endpoint" href="https://indieauth.com/auth">
|
<link rel="authorization_endpoint" href="{{ config('app.authorization_endpoint') }}">
|
||||||
<link rel="token_endpoint" href="{{ config('app.url') }}/api/token">
|
<link rel="token_endpoint" href="{{ config('app.url') }}/api/token">
|
||||||
<link rel="micropub" href="{{ config('app.url') }}/api/post">
|
<link rel="micropub" href="{{ config('app.url') }}/api/post">
|
||||||
<link rel="webmention" href="{{ config('app.url') }}/webmention">
|
<link rel="webmention" href="{{ config('app.url') }}/webmention">
|
||||||
|
|
|
@ -5,12 +5,10 @@ declare(strict_types=1);
|
||||||
namespace Tests\Feature;
|
namespace Tests\Feature;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use GuzzleHttp\Client as GuzzleClient;
|
use GuzzleHttp\Client;
|
||||||
use GuzzleHttp\Handler\MockHandler;
|
use GuzzleHttp\Handler\MockHandler;
|
||||||
use GuzzleHttp\HandlerStack;
|
use GuzzleHttp\HandlerStack;
|
||||||
use IndieAuth\Client as IndieAuthClient;
|
|
||||||
use JsonException;
|
use JsonException;
|
||||||
use Mockery;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
class TokenEndpointTest extends TestCase
|
class TokenEndpointTest extends TestCase
|
||||||
|
@ -23,11 +21,6 @@ class TokenEndpointTest extends TestCase
|
||||||
*/
|
*/
|
||||||
public function tokenEndpointIssuesToken(): void
|
public function tokenEndpointIssuesToken(): void
|
||||||
{
|
{
|
||||||
$mockIndieAuthClient = Mockery::mock(IndieAuthClient::class);
|
|
||||||
$mockIndieAuthClient->shouldReceive('discoverAuthorizationEndpoint')
|
|
||||||
->with(normalize_url(config('app.url')))
|
|
||||||
->once()
|
|
||||||
->andReturn('https://indieauth.com/auth');
|
|
||||||
$mockHandler = new MockHandler([
|
$mockHandler = new MockHandler([
|
||||||
new \GuzzleHttp\Psr7\Response(200, [], json_encode([
|
new \GuzzleHttp\Psr7\Response(200, [], json_encode([
|
||||||
'me' => config('app.url'),
|
'me' => config('app.url'),
|
||||||
|
@ -35,9 +28,8 @@ class TokenEndpointTest extends TestCase
|
||||||
], JSON_THROW_ON_ERROR)),
|
], JSON_THROW_ON_ERROR)),
|
||||||
]);
|
]);
|
||||||
$handlerStack = HandlerStack::create($mockHandler);
|
$handlerStack = HandlerStack::create($mockHandler);
|
||||||
$mockGuzzleClient = new GuzzleClient(['handler' => $handlerStack]);
|
$mockGuzzleClient = new Client(['handler' => $handlerStack]);
|
||||||
$this->app->instance(IndieAuthClient::class, $mockIndieAuthClient);
|
$this->app->instance(Client::class, $mockGuzzleClient);
|
||||||
$this->app->instance(GuzzleClient::class, $mockGuzzleClient);
|
|
||||||
$response = $this->post('/api/token', [
|
$response = $this->post('/api/token', [
|
||||||
'me' => config('app.url'),
|
'me' => config('app.url'),
|
||||||
'code' => 'abc123',
|
'code' => 'abc123',
|
||||||
|
@ -59,20 +51,14 @@ class TokenEndpointTest extends TestCase
|
||||||
*/
|
*/
|
||||||
public function tokenEndpointReturnsErrorWhenAuthEndpointLacksMeData(): void
|
public function tokenEndpointReturnsErrorWhenAuthEndpointLacksMeData(): void
|
||||||
{
|
{
|
||||||
$mockIndieAuthClient = Mockery::mock(IndieAuthClient::class);
|
|
||||||
$mockIndieAuthClient->shouldReceive('discoverAuthorizationEndpoint')
|
|
||||||
->with(normalize_url(config('app.url')))
|
|
||||||
->once()
|
|
||||||
->andReturn('https://indieauth.com/auth');
|
|
||||||
$mockHandler = new MockHandler([
|
$mockHandler = new MockHandler([
|
||||||
new \GuzzleHttp\Psr7\Response(400, [], json_encode([
|
new \GuzzleHttp\Psr7\Response(400, [], json_encode([
|
||||||
'error' => 'error_message',
|
'error' => 'error_message',
|
||||||
], JSON_THROW_ON_ERROR)),
|
], JSON_THROW_ON_ERROR)),
|
||||||
]);
|
]);
|
||||||
$handlerStack = HandlerStack::create($mockHandler);
|
$handlerStack = HandlerStack::create($mockHandler);
|
||||||
$mockGuzzleClient = new GuzzleClient(['handler' => $handlerStack]);
|
$mockGuzzleClient = new Client(['handler' => $handlerStack]);
|
||||||
$this->app->instance(IndieAuthClient::class, $mockIndieAuthClient);
|
$this->app->instance(Client::class, $mockGuzzleClient);
|
||||||
$this->app->instance(GuzzleClient::class, $mockGuzzleClient);
|
|
||||||
$response = $this->post('/api/token', [
|
$response = $this->post('/api/token', [
|
||||||
'me' => config('app.url'),
|
'me' => config('app.url'),
|
||||||
'code' => 'abc123',
|
'code' => 'abc123',
|
||||||
|
@ -85,30 +71,4 @@ class TokenEndpointTest extends TestCase
|
||||||
'error' => 'There was an error verifying the IndieAuth code',
|
'error' => 'There was an error verifying the IndieAuth code',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @test
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function tokenEndpointReturnsErrorWhenNoAuthEndpointFound(): void
|
|
||||||
{
|
|
||||||
$mockIndieAuthClient = Mockery::mock(IndieAuthClient::class);
|
|
||||||
$mockIndieAuthClient->shouldReceive('discoverAuthorizationEndpoint')
|
|
||||||
->with(normalize_url(config('app.url')))
|
|
||||||
->once()
|
|
||||||
->andReturn(null);
|
|
||||||
$this->app->instance(IndieAuthClient::class, $mockIndieAuthClient);
|
|
||||||
$response = $this->post('/api/token', [
|
|
||||||
'me' => config('app.url'),
|
|
||||||
'code' => 'abc123',
|
|
||||||
'redirect_uri' => config('app.url') . '/indieauth-callback',
|
|
||||||
'client_id' => config('app.url') . '/micropub-client',
|
|
||||||
'state' => random_int(1000, 10000),
|
|
||||||
]);
|
|
||||||
$response->assertStatus(400);
|
|
||||||
$response->assertJson([
|
|
||||||
'error' => 'Could not discover the authorization endpoint for ' . config('app.url'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue