From 95e195a5dede5e0d22633f27afdc306cda23cd73 Mon Sep 17 00:00:00 2001 From: FoskyM Date: Mon, 2 Oct 2023 05:30:13 +0800 Subject: [PATCH] feat: oauth resource(ResourceScopeMiddleware.php) --- extend.php | 8 +++- src/Controllers/ApiUserController.php | 49 +++++++++++++++++++++ src/Middlewares/ResourceScopeMiddleware.php | 36 +++++++-------- src/OAuth.php | 6 ++- 4 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 src/Controllers/ApiUserController.php diff --git a/extend.php b/extend.php index c3ec7d9..b4680d5 100644 --- a/extend.php +++ b/extend.php @@ -12,6 +12,7 @@ namespace FoskyM\OAuthCenter; use Flarum\Extend; +use Flarum\Http\Middleware\AuthenticateWithHeader; use Flarum\Http\Middleware\CheckCsrfToken; use FoskyM\OAuthCenter\Middlewares\ResourceScopeMiddleware; use FoskyM\OAuthCenter\Middlewares\UnsetCsrfMiddleware; @@ -41,14 +42,17 @@ return [ ->get('/oauth-scopes', 'oauth.scopes.list', Api\Controller\ListScopeController::class) ->post('/oauth-scopes', 'oauth.scopes.create', Api\Controller\CreateScopeController::class) ->patch('/oauth-scopes/{id}', 'oauth.scopes.update', Api\Controller\UpdateScopeController::class) - ->delete('/oauth-scopes/{id}', 'oauth.scopes.delete', Api\Controller\DeleteScopeController::class), + ->delete('/oauth-scopes/{id}', 'oauth.scopes.delete', Api\Controller\DeleteScopeController::class) + + ->get('/user', 'user.show', Controllers\ApiUserController::class), (new Extend\Settings) ->serializeToForum('foskym-oauth-center.allow_implicit', 'foskym-oauth-center.allow_implicit', 'boolval') ->serializeToForum('foskym-oauth-center.enforce_state', 'foskym-oauth-center.enforce_state', 'boolval') ->serializeToForum('foskym-oauth-center.require_exact_redirect_uri', 'foskym-oauth-center.require_exact_redirect_uri', 'boolval'), + (new Extend\Middleware('api')) + ->insertAfter(AuthenticateWithHeader::class, ResourceScopeMiddleware::class), (new Extend\Middleware('forum')) ->insertBefore(CheckCsrfToken::class, UnsetCsrfMiddleware::class), - (new Extend\Middleware('api'))->add(ResourceScopeMiddleware::class), ]; diff --git a/src/Controllers/ApiUserController.php b/src/Controllers/ApiUserController.php new file mode 100644 index 0000000..d20fdd2 --- /dev/null +++ b/src/Controllers/ApiUserController.php @@ -0,0 +1,49 @@ +settings = $settings; + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + $actor = RequestUtil::getActor($request); + $actor = $actor->toArray(); + $data = [ + 'id' => $actor['id'], + 'username' => $actor['username'], + 'nickname' => $actor['nickname'], + 'avatar_url' => $actor['avatar_url'], + 'email' => $actor['email'], + 'is_email_confirmed' => $actor['is_email_confirmed'], + 'joined_at' => $actor['joined_at'], + 'last_seen_at' => $actor['last_seen_at'], + 'discussion_count' => $actor['discussion_count'], + 'comment_count' => $actor['comment_count'], + ]; + return new JsonResponse($data); + } +} diff --git a/src/Middlewares/ResourceScopeMiddleware.php b/src/Middlewares/ResourceScopeMiddleware.php index 620e1a5..22a0216 100644 --- a/src/Middlewares/ResourceScopeMiddleware.php +++ b/src/Middlewares/ResourceScopeMiddleware.php @@ -5,6 +5,7 @@ namespace FoskyM\OAuthCenter\Middlewares; use Flarum\Foundation\ErrorHandling\ExceptionHandler\IlluminateValidationExceptionHandler; use Flarum\Foundation\ErrorHandling\JsonApiFormatter; use Flarum\Settings\SettingsRepositoryInterface; +use Flarum\User\User; use FoskyM\OAuthCenter\OAuth; use FoskyM\OAuthCenter\Storage; use Illuminate\Support\Arr; @@ -15,11 +16,8 @@ use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use Flarum\Http\RequestUtil; -use Flarum\Api\JsonApiResponse; -use Tobscure\JsonApi\Document; -use Tobscure\JsonApi\Exception\Handler\ResponseBag; - use FoskyM\OAuthCenter\Models\Scope; + class ResourceScopeMiddleware implements MiddlewareInterface { protected $settings; @@ -29,31 +27,29 @@ class ResourceScopeMiddleware implements MiddlewareInterface } public function process(Request $request, RequestHandlerInterface $handler): Response { - $path = $request->getUri()->getPath(); + if (!$request->getAttribute('originalUri')) { + return $handler->handle($request); + } + + $path = $request->getAttribute('originalUri')->getPath(); $token = Arr::get($request->getQueryParams(), 'access_token', ''); if ($token !== '' && $scope = Scope::get_path_scope($path)) { if (strtolower($request->getMethod()) === strtolower($scope->method)) { try { $oauth = new OAuth($this->settings); $server = $oauth->server(); - $request = $oauth->request(); - if (!$server->verifyResourceRequest($request::createFromGlobals(), null, $scope->scope)) { + $oauth_request = $oauth->request()::createFromGlobals(); + + if (!$server->verifyResourceRequest($oauth_request, null, $scope->scope)) { return new JsonResponse(json_decode($server->getResponse()->getResponseBody(), true)); } - /*$error = new ResponseBag('422', [ - [ - 'status' => '422', - 'code' => 'validation_error', - 'source' => [ - 'pointer' => $path, - ], - 'detail' => 'Yikes! The access token don\'t has the scope.', - ], - ]); - $document = new Document(); - $document->setErrors($error->getErrors()); - return new JsonApiResponse($document, $error->getStatus());*/ + $token = $server->getAccessTokenData($oauth_request); + $actor = User::find($token['user_id']); + + $request = RequestUtil::withActor($request, $actor); + $request = $request->withAttribute('bypassCsrfToken', true); + $request = $request->withoutAttribute('session'); } catch (ValidationException $exception) { $handler = resolve(IlluminateValidationExceptionHandler::class); diff --git a/src/OAuth.php b/src/OAuth.php index 8718df0..66c67a8 100644 --- a/src/OAuth.php +++ b/src/OAuth.php @@ -36,9 +36,13 @@ class OAuth { return new Request; } + + public function storage(): Storage + { + return new Storage; + } public function server(): Server { - $storage = new Storage; $server = new Server($storage, array( 'allow_implicit' => $this->settings->get('foskym-oauth-center.allow_implicit') == "1",