We need to manually check the indieauth endpoint ourselves now

This commit is contained in:
Jonny Barnes 2022-09-24 18:28:05 +01:00
parent b93a8587a3
commit e456f688a3
Signed by: jonny
SSH key fingerprint: SHA256:CTuSlns5U7qlD9jqHvtnVmfYV3Zwl2Z7WnJ4/dqOaL8
3 changed files with 135 additions and 60 deletions

View file

@ -5,18 +5,26 @@ declare(strict_types=1);
namespace App\Http\Controllers;
use App\Services\TokenService;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Exception\BadResponseException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use IndieAuth\Client;
class TokenEndpointController extends Controller
{
/**
* The IndieAuth Client.
* @var Client The IndieAuth Client.
*/
protected Client $client;
/**
* The Token handling service.
* @var GuzzleClient The GuzzleHttp client.
*/
protected GuzzleClient $guzzle;
/**
* @var TokenService The Token handling service.
*/
protected TokenService $tokenService;
@ -24,57 +32,100 @@ class TokenEndpointController extends Controller
* Inject the dependencies.
*
* @param Client $client
* @param GuzzleClient $guzzle
* @param TokenService $tokenService
*/
public function __construct(
Client $client,
GuzzleClient $guzzle,
TokenService $tokenService
) {
$this->client = $client;
$this->guzzle = $guzzle;
$this->tokenService = $tokenService;
}
/**
* If the user has authd via the IndieAuth protocol, issue a valid token.
*
* @param Request $request
* @return JsonResponse
*/
public function create(): JsonResponse
public function create(Request $request): JsonResponse
{
$authorizationEndpoint = $this->client->discoverAuthorizationEndpoint(normalize_url(request()->input('me')));
if ($authorizationEndpoint) {
$auth = $this->client->verifyIndieAuthCode(
$authorizationEndpoint,
request()->input('code'),
request()->input('me'),
request()->input('redirect_uri'),
request()->input('client_id'),
null // code_verifier
);
if (array_key_exists('me', $auth)) {
$scope = $auth['scope'] ?? '';
$tokenData = [
'me' => request()->input('me'),
'client_id' => request()->input('client_id'),
'scope' => $scope,
];
$token = $this->tokenService->getNewToken($tokenData);
$content = [
'me' => request()->input('me'),
'scope' => $scope,
'access_token' => $token,
];
return response()->json($content);
}
if (empty($request->input('me'))) {
return response()->json([
'error' => 'There was an error verifying the authorisation code.',
'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(
$authorizationEndpoint,
$request->input('code'),
$request->input('me'),
$request->input('redirect_uri'),
$request->input('client_id'),
);
if ($auth === null || !array_key_exists('me', $auth)) {
return response()->json([
'error' => 'There was an error verifying the IndieAuth code',
], 401);
}
return response()->json([
'error' => 'Cant determine the authorisation endpoint.',
], 400);
$scope = $auth['scope'] ?? '';
$tokenData = [
'me' => $request->input('me'),
'client_id' => $request->input('client_id'),
'scope' => $scope,
];
$token = $this->tokenService->getNewToken($tokenData);
$content = [
'me' => $request->input('me'),
'scope' => $scope,
'access_token' => $token,
];
return response()->json($content);
}
protected function verifyIndieAuthCode(
string $authorizationEndpoint,
string $code,
string $me,
string $redirectUri,
string $clientId
): ?array {
try {
$response = $this->guzzle->request('POST', $authorizationEndpoint, [
'headers' => [
'Accept' => 'application/json',
],
'form_params' => [
'code' => $code,
'me' => $me,
'redirect_uri' => $redirectUri,
'client_id' => $clientId,
],
]);
} catch (BadResponseException) {
return null;
}
try {
$authData = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException) {
return null;
}
return $authData;
}
}