mirror of https://github.com/pixelfed/pixelfed
Fix oauth oob (urn:ietf:wg:oauth:2.0:oob) support. Fixes #2522
parent
8c39ef449a
commit
8afbdb03a8
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\OAuth;
|
||||
|
||||
use Laravel\Passport\Http\Controllers\ApproveAuthorizationController;
|
||||
use Illuminate\Http\Request;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use Nyholm\Psr7\Response as Psr7Response;
|
||||
|
||||
class OobAuthorizationController extends ApproveAuthorizationController
|
||||
{
|
||||
/**
|
||||
* Approve the authorization request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function approve(Request $request)
|
||||
{
|
||||
$this->assertValidAuthToken($request);
|
||||
|
||||
$authRequest = $this->getAuthRequestFromSession($request);
|
||||
$authRequest->setAuthorizationApproved(true);
|
||||
|
||||
return $this->withErrorHandling(function () use ($authRequest) {
|
||||
$response = $this->server->completeAuthorizationRequest($authRequest, new Psr7Response);
|
||||
|
||||
if ($this->isOutOfBandRequest($authRequest)) {
|
||||
$code = $this->extractAuthorizationCode($response);
|
||||
return response()->json([
|
||||
'code' => $code,
|
||||
'state' => $authRequest->getState()
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->convertResponse($response);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the request is an out-of-band OAuth request.
|
||||
*
|
||||
* @param \League\OAuth2\Server\RequestTypes\AuthorizationRequest $authRequest
|
||||
* @return bool
|
||||
*/
|
||||
protected function isOutOfBandRequest($authRequest)
|
||||
{
|
||||
return $authRequest->getRedirectUri() === 'urn:ietf:wg:oauth:2.0:oob';
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the authorization code from the PSR-7 response.
|
||||
*
|
||||
* @param \Psr\Http\Message\ResponseInterface $response
|
||||
* @return string
|
||||
* @throws \League\OAuth2\Server\Exception\OAuthServerException
|
||||
*/
|
||||
protected function extractAuthorizationCode($response)
|
||||
{
|
||||
$location = $response->getHeader('Location')[0] ?? '';
|
||||
|
||||
if (empty($location)) {
|
||||
throw OAuthServerException::serverError('Missing authorization code in response');
|
||||
}
|
||||
|
||||
parse_str(parse_url($location, PHP_URL_QUERY), $params);
|
||||
|
||||
if (!isset($params['code'])) {
|
||||
throw OAuthServerException::serverError('Invalid authorization code format');
|
||||
}
|
||||
|
||||
return $params['code'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle OAuth errors for both redirect and OOB flows.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
protected function withErrorHandling($callback)
|
||||
{
|
||||
try {
|
||||
return $callback();
|
||||
} catch (OAuthServerException $e) {
|
||||
if ($this->isOutOfBandRequest($this->getAuthRequestFromSession(request()))) {
|
||||
return response()->json([
|
||||
'error' => $e->getErrorType(),
|
||||
'message' => $e->getMessage(),
|
||||
'hint' => $e->getHint()
|
||||
], $e->getHttpStatusCode());
|
||||
}
|
||||
|
||||
return $this->convertResponse(
|
||||
$e->generateHttpResponse(new Psr7Response)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue