1
1
Fork 0
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:
J. King 2019-09-24 13:59:52 -04:00
parent 73a27728a1
commit cbd382d768

View file

@ -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];
}
}