X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/3d11cba223cad16ad13faee010259e97b05dcee9..refs/pull/3138/head:/app/Api/ApiTokenGuard.php diff --git a/app/Api/ApiTokenGuard.php b/app/Api/ApiTokenGuard.php index ba0b4b5dd..1bb672556 100644 --- a/app/Api/ApiTokenGuard.php +++ b/app/Api/ApiTokenGuard.php @@ -2,16 +2,17 @@ namespace BookStack\Api; +use BookStack\Auth\Access\LoginService; use BookStack\Exceptions\ApiAuthException; use Illuminate\Auth\GuardHelpers; use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Guard; +use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Hash; use Symfony\Component\HttpFoundation\Request; class ApiTokenGuard implements Guard { - use GuardHelpers; /** @@ -19,9 +20,14 @@ class ApiTokenGuard implements Guard */ protected $request; + /** + * @var LoginService + */ + protected $loginService; /** * The last auth exception thrown in this request. + * * @var ApiAuthException */ protected $lastAuthException; @@ -29,13 +35,14 @@ class ApiTokenGuard implements Guard /** * ApiTokenGuard constructor. */ - public function __construct(Request $request) + public function __construct(Request $request, LoginService $loginService) { $this->request = $request; + $this->loginService = $loginService; } - + /** - * @inheritDoc + * {@inheritdoc} */ public function user() { @@ -46,6 +53,7 @@ class ApiTokenGuard implements Guard } $user = null; + try { $user = $this->getAuthorisedUserFromRequest(); } catch (ApiAuthException $exception) { @@ -53,19 +61,20 @@ class ApiTokenGuard implements Guard } $this->user = $user; + return $user; } /** * Determine if current user is authenticated. If not, throw an exception. * - * @return \Illuminate\Contracts\Auth\Authenticatable - * * @throws ApiAuthException + * + * @return \Illuminate\Contracts\Auth\Authenticatable */ public function authenticate() { - if (! is_null($user = $this->user())) { + if (!is_null($user = $this->user())) { return $user; } @@ -78,6 +87,7 @@ class ApiTokenGuard implements Guard /** * Check the API token in the request and fetch a valid authorised user. + * * @throws ApiAuthException */ protected function getAuthorisedUserFromRequest(): Authenticatable @@ -92,11 +102,16 @@ class ApiTokenGuard implements Guard $this->validateToken($token, $secret); + if ($this->loginService->awaitingEmailConfirmation($token->user)) { + throw new ApiAuthException(trans('errors.email_confirmation_awaiting')); + } + return $token->user; } /** * Validate the format of the token header value string. + * * @throws ApiAuthException */ protected function validateTokenHeaderValue(string $authToken): void @@ -113,6 +128,7 @@ class ApiTokenGuard implements Guard /** * Validate the given secret against the given token and ensure the token * currently has access to the instance API. + * * @throws ApiAuthException */ protected function validateToken(?ApiToken $token, string $secret): void @@ -125,13 +141,18 @@ class ApiTokenGuard implements Guard throw new ApiAuthException(trans('errors.api_incorrect_token_secret')); } + $now = Carbon::now(); + if ($token->expires_at <= $now) { + throw new ApiAuthException(trans('errors.api_user_token_expired'), 403); + } + if (!$token->user->can('access-api')) { throw new ApiAuthException(trans('errors.api_user_no_api_permission'), 403); } } /** - * @inheritDoc + * {@inheritdoc} */ public function validate(array $credentials = []) { @@ -157,4 +178,4 @@ class ApiTokenGuard implements Guard { $this->user = null; } -} \ No newline at end of file +}