1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-28 17:02:04 +03:00

Linked new API token system into middleware

Base logic in place but needs review and refactor to see if can better
fit into Laravel using 'Guard' system. Currently has issues due to
cookies in use from active session on API.
This commit is contained in:
Dan Brown
2019-12-30 02:16:07 +00:00
parent 2cfa37399c
commit 3de55ee645
7 changed files with 183 additions and 37 deletions

View File

@ -0,0 +1,78 @@
<?php
namespace BookStack\Http\Middleware;
use BookStack\Api\ApiToken;
use BookStack\Http\Request;
use Closure;
use Hash;
class ApiAuthenticate
{
/**
* Handle an incoming request.
*/
public function handle(Request $request, Closure $next)
{
// TODO - Look to extract a lot of the logic here into a 'Guard'
// Ideally would like to be able to request API via browser without having to boot
// the session middleware (in Kernel).
// $sessionCookieName = config('session.cookie');
// if ($request->cookies->has($sessionCookieName)) {
// $sessionCookie = $request->cookies->get($sessionCookieName);
// $sessionCookie = decrypt($sessionCookie, false);
// dd($sessionCookie);
// }
// Return if the user is already found to be signed in via session-based auth.
// This is to make it easy to browser the API via browser after just logging into the system.
if (signedInUser()) {
return $next($request);
}
$authToken = trim($request->header('Authorization', ''));
if (empty($authToken)) {
return $this->unauthorisedResponse(trans('errors.api_no_authorization_found'));
}
if (strpos($authToken, ':') === false || strpos($authToken, 'Token ') !== 0) {
return $this->unauthorisedResponse(trans('errors.api_bad_authorization_format'));
}
[$id, $secret] = explode(':', str_replace('Token ', '', $authToken));
$token = ApiToken::query()
->where('token_id', '=', $id)
->with(['user'])->first();
if ($token === null) {
return $this->unauthorisedResponse(trans('errors.api_user_token_not_found'));
}
if (!Hash::check($secret, $token->secret)) {
return $this->unauthorisedResponse(trans('errors.api_incorrect_token_secret'));
}
if (!$token->user->can('access-api')) {
return $this->unauthorisedResponse(trans('errors.api_user_no_api_permission'), 403);
}
auth()->login($token->user);
return $next($request);
}
/**
* Provide a standard API unauthorised response.
*/
protected function unauthorisedResponse(string $message, int $code = 401)
{
return response()->json([
'error' => [
'code' => $code,
'message' => $message,
]
], 401);
}
}