mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-23 09:02:41 +00:00
Token verification and revocation
This commit is contained in:
parent
73a27728a1
commit
cbd382d768
1 changed files with 59 additions and 8 deletions
|
@ -196,7 +196,7 @@ class Auth extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
'client' => $query['client_id'],
|
||||
'redir' => $query['redirect_uri'],
|
||||
'type' => $type,
|
||||
],\JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE);
|
||||
], \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE);
|
||||
// issue an authorization code and build the redirect URL
|
||||
$code = Arsse::$db->tokenCreate($user, "microsub.auth", null, Date::add("PT2M"), $data);
|
||||
$next = URL::queryAppend($redir, "code=$code&state=$state");
|
||||
|
@ -235,6 +235,10 @@ class Auth extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
*/
|
||||
protected function opIssueAccessToken(ServerRequestInterface $req): ResponseInterface {
|
||||
$post = $req->getParsedBody();
|
||||
// revocation is a special case of POSTing to the token URL
|
||||
if ($post['action'] ?? "" === "revoke") {
|
||||
return $this->opRevokeToken($req);
|
||||
}
|
||||
if (($post['grant_type'] ?? "") !== "authorization_code") {
|
||||
throw new ExceptionAuth("unsupported_grant_type");
|
||||
}
|
||||
|
@ -244,7 +248,11 @@ class Auth extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
throw new ExceptionAuth("invalid_grant");
|
||||
}
|
||||
// issue an access token
|
||||
$token = Arsse::$db->tokenCreate($user, "microsub.access");
|
||||
$data = json_encode([
|
||||
'me' => $post['me'],
|
||||
'client_id' => $post['client_id'],
|
||||
], \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE);
|
||||
$token = Arsse::$db->tokenCreate($user, "microsub.access", null, null, $data);
|
||||
Arsse::$db->tokenRevoke($user, "microsub.auth", $post['code']);
|
||||
$tr->commit();
|
||||
// return the Bearer token and associated data
|
||||
|
@ -285,13 +293,54 @@ class Auth extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
return [$token['user'], $data['type'] ?? "id"];
|
||||
}
|
||||
|
||||
protected function opTokenVerification(string $user, ServerRequestInterface $req): ResponseInterface {
|
||||
|
||||
/** Handles token verification as an API call
|
||||
*
|
||||
* The static `validateBearer` method should be used to check the validity of a bearer token in normal use
|
||||
*
|
||||
* @see https://indieauth.spec.indieweb.org/#access-token-verification
|
||||
*/
|
||||
protected function opTokenVerification(ServerRequestInterface $req): ResponseInterface {
|
||||
try {
|
||||
if (!$req->hasHeader("Authorization")) {
|
||||
throw new ExceptionAuth("invalid_token");
|
||||
}
|
||||
$authorization = $req->getHeader("Authorization")[0];
|
||||
list($user, $data) = self::validateBearer($authorization);
|
||||
} catch (ExceptionAuth $e) {
|
||||
$errCode = $e->getMessage();
|
||||
$httpCode = [
|
||||
'invalid_request' => 400,
|
||||
'invalid_token' => 401,
|
||||
][$errCode] ?? 500;
|
||||
return new EmptyResponse($httpCode, ['WWW-Authenticate' => "Bearer error=\"$erroCode\""]);
|
||||
}
|
||||
return new JsonResponse([
|
||||
'me' => $data['me'] ?? "",
|
||||
'client_id' => $data['client_id'] ?? "",
|
||||
'scope' => $data['scope'] ?? self::SCOPES,
|
||||
]);
|
||||
}
|
||||
|
||||
/** Checks that the simplied bearer token is valid
|
||||
/** Handles token revocation
|
||||
*
|
||||
* Returns an indexed array with the user associated with the token, as well as the granted scope
|
||||
* @see https://indieauth.spec.indieweb.org/#token-revocation
|
||||
*/
|
||||
protected function opRevokeToken(ServerRequestInterface $req): ResponseInterface {
|
||||
$token = ($req->getParsedBody() ?? [])['token'] ?? "";
|
||||
if (!strlen($token)) {
|
||||
return new EmptyResponse(422);
|
||||
}
|
||||
try {
|
||||
$info = Arsse::$db->tokenLookup("microsub.access", $token);
|
||||
Arsse::$db->tokenRevoke($info['user'], "mucrosub.access", $token);
|
||||
} catch (\JKingWeb\Arsse\Db\ExceptionInput $e) {
|
||||
}
|
||||
return new EmptyResponse(200);
|
||||
}
|
||||
|
||||
/** Checks that the supplied bearer token is valid i.e. logs a bearer in
|
||||
*
|
||||
* Returns an indexed array with the user associated with the token, as well as other data
|
||||
*
|
||||
* @throws \JKingWeb\Arsse\REST\Microsub\ExceptionAuth
|
||||
*/
|
||||
|
@ -305,10 +354,12 @@ class Auth extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
} catch (\JKingWeb\Arsse\Db\ExceptionInput $e) {
|
||||
throw new ExceptionAuth("invalid_token");
|
||||
}
|
||||
$data = @json_decode($token['data'], true) ?? [];
|
||||
$data['scope'] = $data['scope'] ?? self::SCOPES;
|
||||
// scope is hard-coded for now
|
||||
if (array_diff($scopes, self::SCOPES)) {
|
||||
if (array_diff($scopes, $data['scope'])) {
|
||||
throw new ExceptionAuth("insufficient_scope");
|
||||
}
|
||||
return [$token['user'], self::SCOPES];
|
||||
return [$token['user'], $data];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue