diff --git a/app/Http/Controllers/IndieAuthController.php b/app/Http/Controllers/IndieAuthController.php index 3086ccda..60a32200 100644 --- a/app/Http/Controllers/IndieAuthController.php +++ b/app/Http/Controllers/IndieAuthController.php @@ -2,7 +2,6 @@ namespace App\Http\Controllers; -use IndieAuth\Client; use Illuminate\Http\Request; use App\Services\TokenService; use App\Services\IndieAuthService; @@ -14,11 +13,6 @@ class IndieAuthController extends Controller */ protected $indieAuthService; - /** - * The IndieAuth Client implementation. - */ - protected $client; - /** * The Token handling service. */ @@ -28,16 +22,14 @@ class IndieAuthController extends Controller * Inject the dependencies. * * @param \App\Services\IndieAuthService $indieAuthService - * @param \IndieAuth\Client $client + * @param \App\Services\TokenService $tokenService * @return void */ public function __construct( IndieAuthService $indieAuthService = null, - Client $client = null, TokenService $tokenService = null ) { $this->indieAuthService = $indieAuthService ?? new IndieAuthService(); - $this->client = $client ?? new Client(); $this->tokenService = $tokenService ?? new TokenService(); } @@ -53,21 +45,19 @@ class IndieAuthController extends Controller public function start(Request $request) { $authorizationEndpoint = $this->indieAuthService->getAuthorizationEndpoint( - $request->input('me'), - $this->client + $request->input('me') ); - if ($authorizationEndpoint) { + if ($authorizationEndpoint !== null) { $authorizationURL = $this->indieAuthService->buildAuthorizationURL( $authorizationEndpoint, - $request->input('me'), - $this->client + $request->input('me') ); if ($authorizationURL) { return redirect($authorizationURL); } } - return redirect(route('micropub-client'))->withErrors('Unable to determine authorisation endpoint', 'indieauth'); + return redirect(route('micropub-client'))->with('error', 'Unable to determine authorisation endpoint'); } /** @@ -80,14 +70,17 @@ class IndieAuthController extends Controller public function callback(Request $request) { if ($request->session()->get('state') != $request->input('state')) { - return redirect(route('micropub-client'))->withErrors( - 'Invalid state value returned from indieauth server', - 'indieauth' + return redirect(route('micropub-client'))->with( + 'error', + 'Invalid state value returned from indieauth server' ); } - $tokenEndpoint = $this->indieAuthService->getTokenEndpoint($request->input('me'), $this->client); + $tokenEndpoint = $this->indieAuthService->getTokenEndpoint($request->input('me')); if ($tokenEndpoint === false) { - return redirect(route('micropub-client'))->withErrors('Unable to determine token endpoint', 'indieauth'); + return redirect(route('micropub-client'))->with( + 'error', + 'Unable to determine token endpoint' + ); } $data = [ 'endpoint' => $tokenEndpoint, @@ -97,7 +90,7 @@ class IndieAuthController extends Controller 'client_id' => route('micropub-client'), 'state' => $request->input('state'), ]; - $token = $this->indieAuthService->getAccessToken($data, $this->client); + $token = $this->indieAuthService->getAccessToken($data); if (array_key_exists('access_token', $token)) { $request->session()->put('me', $token['me']); @@ -106,7 +99,10 @@ class IndieAuthController extends Controller return redirect(route('micropub-client')); } - return redirect(route('micropub-client'))->withErrors('Unable to get a token from the endpoint', 'indieauth'); + return redirect(route('micropub-client'))->with( + 'error', + 'Unable to get a token from the endpoint' + ); } /** @@ -136,7 +132,7 @@ class IndieAuthController extends Controller 'client_id' => $request->input('client_id'), 'state' => $request->input('state'), ]; - $auth = $this->indieAuthService->verifyIndieAuthCode($authData, $this->client); + $auth = $this->indieAuthService->verifyIndieAuthCode($authData); if (array_key_exists('me', $auth)) { $scope = $auth['scope'] ?? ''; $tokenData = [ diff --git a/app/Services/IndieAuthService.php b/app/Services/IndieAuthService.php index e44334b3..ec01370f 100644 --- a/app/Services/IndieAuthService.php +++ b/app/Services/IndieAuthService.php @@ -1,20 +1,34 @@ client = new Client(); + } /** * Given a domain, determing the assocaited authorization endpoint, * if one exists. * * @param string The domain - * @param \IndieAuth\Client $client * @return string|null */ - public function getAuthorizationEndpoint($domain, $client) + public function getAuthorizationEndpoint(string $domain): ?string { - return $client->discoverAuthorizationEndpoint($client->normalizeMeURL($domain)); + $endpoint = $this->client->discoverAuthorizationEndpoint($this->client->normalizeMeURL($domain)); + if ($endpoint === false) { + return null; + } + + return $endpoint; } /** @@ -22,20 +36,18 @@ class IndieAuthService * * @param string $authEndpoint * @param string $domain - * @param \IndieAuth\Client $client * @return string */ - public function buildAuthorizationURL($authEndpoint, $domain, $client) + public function buildAuthorizationURL(string $authEndpoint, string $domain): string { - $domain = $client->normalizeMeURL($domain); $state = bin2hex(openssl_random_pseudo_bytes(16)); session(['state' => $state]); $redirectURL = route('indieauth-callback'); $clientId = route('micropub-client'); $scope = 'post'; - $authorizationURL = $client->buildAuthorizationURL( + $authorizationURL = $this->client->buildAuthorizationURL( $authEndpoint, - $domain, + $this->client->normalizeMeURL($domain), $redirectURL, $clientId, $state, @@ -49,24 +61,22 @@ class IndieAuthService * Discover the token endpoint for a given domain. * * @param string The domain - * @param \IndieAuth\Client $client * @return string|null */ - public function getTokenEndpoint($domain, $client) + public function getTokenEndpoint(string $domain): ?string { - return $client->discoverTokenEndpoint($domain); + return $this->client->discoverTokenEndpoint($this->client->normalizeMeURL($domain)); } /** * Retrieve a token from the token endpoint. * * @param array The relavent data - * @param \IndieAuth\Client $client * @return array */ - public function getAccessToken(array $data, $client) + public function getAccessToken(array $data): array { - return $client->getAccessToken( + return $this->client->getAccessToken( $data['endpoint'], $data['code'], $data['me'], @@ -81,14 +91,13 @@ class IndieAuthService * valid. * * @param array The data. - * @param \IndieAuth\Client $client * @return array|null */ - public function verifyIndieAuthCode(array $data, $client) + public function verifyIndieAuthCode(array $data): ?array { - $authEndpoint = $client->discoverAuthorizationEndpoint($data['me']); + $authEndpoint = $this->client->discoverAuthorizationEndpoint($data['me']); if ($authEndpoint) { - return $client->verifyIndieAuthCode( + return $this->client->verifyIndieAuthCode( $authEndpoint, $data['code'], $data['me'], @@ -103,11 +112,10 @@ class IndieAuthService * Determine the micropub endpoint. * * @param string $domain - * @param \IndieAuth\Client $client - * @return string The endpoint + * @return string|null The endpoint */ - public function discoverMicropubEndpoint($domain, $client) + public function discoverMicropubEndpoint(string $domain): ?string { - return $client->discoverMicropubEndpoint($client->normalizeMeURL($domain)); + return $this->client->discoverMicropubEndpoint($this->client->normalizeMeURL($domain)); } } diff --git a/routes/web.php b/routes/web.php index 9d46a2df..8ad4f84f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -109,7 +109,7 @@ Route::group(['domain' => config('url.longurl')], function () { Route::get('notes/tagged/{tag}', 'NotesController@tagged'); //indieauth - Route::any('indieauth/start', 'IndieAuthController@start')->name('indieauth-start'); + Route::post('indieauth/start', 'IndieAuthController@start')->name('indieauth-start'); Route::get('indieauth/callback', 'IndieAuthController@callback')->name('indieauth-callback'); Route::get('logout', 'IndieAuthController@logout')->name('indieauth-logout'); Route::post('api/token', 'IndieAuthController@tokenEndpoint'); //hmmm? diff --git a/tests/Feature/IndieAuthControllerTest.php b/tests/Feature/IndieAuthControllerTest.php index c5ed4de1..402b39dc 100644 --- a/tests/Feature/IndieAuthControllerTest.php +++ b/tests/Feature/IndieAuthControllerTest.php @@ -15,8 +15,8 @@ class IndieAuthControllerTest extends TestCase */ public function test_indieauthcontroller_begin_auth_flow_redirects_back_to_client_on_error() { - $response = $this->call('GET', '/indieauth/start', ['me' => 'http://example.org']); - $this->assertSame(config('app.url') . '/micropub/create', $response->headers->get('Location')); + $response = $this->call('POST', '/indieauth/start', ['me' => 'http://example.org']); + $this->assertSame(route('micropub-client'), $response->headers->get('Location')); } /** @@ -26,7 +26,7 @@ class IndieAuthControllerTest extends TestCase */ public function test_indieauthcontroller_begin_auth_redirects_to_endpoint() { - $response = $this->call('GET', '/indieauth/start', ['me' => config('app.url')]); + $response = $this->call('POST', '/indieauth/start', ['me' => config('app.url')]); $this->assertSame( 'https://indieauth.com/auth?me=', substr($response->headers->get('Location'), 0, 30) @@ -46,6 +46,6 @@ class IndieAuthControllerTest extends TestCase 'indieauth/callback', ['me', config('app.url'), 'state' => 'request-session'] ); - $response->assertSessionHasErrors(); + $response->assertSessionHas(['error' => 'Invalid state value returned from indieauth server']); } } diff --git a/tests/Unit/IndieAuthServiceTest.php b/tests/Unit/IndieAuthServiceTest.php index 3035d8f5..96598ef6 100644 --- a/tests/Unit/IndieAuthServiceTest.php +++ b/tests/Unit/IndieAuthServiceTest.php @@ -16,11 +16,22 @@ class IndieAuthServiceTest extends TestCase public function test_indieauthservice_getauthorizationendpoint_method() { $service = new \App\Services\IndieAuthService(); - $client = new \IndieAuth\Client(); - $result = $service->getAuthorizationEndpoint(config('app.url'), $client); + $result = $service->getAuthorizationEndpoint(config('app.url')); $this->assertEquals('https://indieauth.com/auth', $result); } + /** + * Test the getAuthorizationEndpoint method returns null on failure. + * + * @return void + */ + public function test_indieauthservice_getauthorizationendpoint_method_returns_null_on_failure() + { + $service = new \App\Services\IndieAuthService(); + $result = $service->getAuthorizationEndpoint('http://example.org'); + $this->assertEquals(null, $result); + } + /** * Test that the Service build the correct redirect URL. * @@ -29,11 +40,9 @@ class IndieAuthServiceTest extends TestCase public function test_indieauthservice_builds_correct_redirect_url() { $service = new \App\Services\IndieAuthService(); - $client = new \IndieAuth\Client(); $result = $service->buildAuthorizationURL( 'https://indieauth.com/auth', - config('app.url'), - $client + config('app.url') ); $this->assertEquals( 'https://indieauth.com/auth?me=', @@ -49,8 +58,7 @@ class IndieAuthServiceTest extends TestCase public function test_indieauthservice_gettokenendpoint_method() { $service = new \App\Services\IndieAuthService(); - $client = new \IndieAuth\Client(); - $result = $service->getTokenEndpoint(config('app.url'), $client); + $result = $service->getTokenEndpoint(config('app.url')); $this->assertEquals(config('app.url') . '/api/token', $result); } @@ -62,8 +70,7 @@ class IndieAuthServiceTest extends TestCase public function test_indieauthservice_discovermicropubendpoint_method() { $service = new \App\Services\IndieAuthService(); - $client = new \IndieAuth\Client(); - $result = $service->discoverMicropubEndpoint(config('app.url'), $client); + $result = $service->discoverMicropubEndpoint(config('app.url')); $this->assertEquals(config('app.url') . '/api/post', $result); } }