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
|
@ -235,6 +235,10 @@ class Auth extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
*/
|
*/
|
||||||
protected function opIssueAccessToken(ServerRequestInterface $req): ResponseInterface {
|
protected function opIssueAccessToken(ServerRequestInterface $req): ResponseInterface {
|
||||||
$post = $req->getParsedBody();
|
$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") {
|
if (($post['grant_type'] ?? "") !== "authorization_code") {
|
||||||
throw new ExceptionAuth("unsupported_grant_type");
|
throw new ExceptionAuth("unsupported_grant_type");
|
||||||
}
|
}
|
||||||
|
@ -244,7 +248,11 @@ class Auth extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
throw new ExceptionAuth("invalid_grant");
|
throw new ExceptionAuth("invalid_grant");
|
||||||
}
|
}
|
||||||
// issue an access token
|
// 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']);
|
Arsse::$db->tokenRevoke($user, "microsub.auth", $post['code']);
|
||||||
$tr->commit();
|
$tr->commit();
|
||||||
// return the Bearer token and associated data
|
// return the Bearer token and associated data
|
||||||
|
@ -285,13 +293,54 @@ class Auth extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
return [$token['user'], $data['type'] ?? "id"];
|
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
|
* @throws \JKingWeb\Arsse\REST\Microsub\ExceptionAuth
|
||||||
*/
|
*/
|
||||||
|
@ -305,10 +354,12 @@ class Auth extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||||
} catch (\JKingWeb\Arsse\Db\ExceptionInput $e) {
|
} catch (\JKingWeb\Arsse\Db\ExceptionInput $e) {
|
||||||
throw new ExceptionAuth("invalid_token");
|
throw new ExceptionAuth("invalid_token");
|
||||||
}
|
}
|
||||||
|
$data = @json_decode($token['data'], true) ?? [];
|
||||||
|
$data['scope'] = $data['scope'] ?? self::SCOPES;
|
||||||
// scope is hard-coded for now
|
// scope is hard-coded for now
|
||||||
if (array_diff($scopes, self::SCOPES)) {
|
if (array_diff($scopes, $data['scope'])) {
|
||||||
throw new ExceptionAuth("insufficient_scope");
|
throw new ExceptionAuth("insufficient_scope");
|
||||||
}
|
}
|
||||||
return [$token['user'], self::SCOPES];
|
return [$token['user'], $data];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue