From a2e63d82bdcc8597ca8d6decfaf905a6a1e2e977 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Sun, 20 Jun 2021 00:16:41 +0200 Subject: [PATCH] invalidate cached client tokens --- app/controllers/OAuth.scala | 9 ++++-- app/views/account/security.scala | 2 +- modules/oauth/src/main/AccessTokenApi.scala | 31 +++++++++++++++------ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/app/controllers/OAuth.scala b/app/controllers/OAuth.scala index 9fe368156b..e93d50b0d9 100644 --- a/app/controllers/OAuth.scala +++ b/app/controllers/OAuth.scala @@ -105,8 +105,13 @@ final class OAuth(env: Env) extends LilaController(env) { revokeClientForm .bindFromRequest() .fold( - _ => funit, - origin => env.oAuth.tokenApi.revokeByClientOrigin(origin, me) // TODO: also remove from token cache + _ => BadRequest.fuccess, + origin => + env.oAuth.tokenApi.revokeByClientOrigin(origin, me) map { + _ foreach { token => + env.oAuth.server.deleteCached(token) + } + } inject NoContent ) } diff --git a/app/views/account/security.scala b/app/views/account/security.scala index 283b25eda8..d365675dc2 100644 --- a/app/views/account/security.scala +++ b/app/views/account/security.scala @@ -22,7 +22,7 @@ object security { account.layout(title = s"${u.username} - ${trans.security.txt()}", active = "security") { div(cls := "account security")( div(cls := "box")( - h1(trans.sessions()), + h1(trans.security()), standardFlash(cls := "box__pad"), div(cls := "box__pad")( p( diff --git a/modules/oauth/src/main/AccessTokenApi.scala b/modules/oauth/src/main/AccessTokenApi.scala index 5fd734d329..b3d21d8812 100644 --- a/modules/oauth/src/main/AccessTokenApi.scala +++ b/modules/oauth/src/main/AccessTokenApi.scala @@ -63,8 +63,8 @@ final class AccessTokenApi(colls: OauthColls)(implicit ec: scala.concurrent.Exec ) -> List( UnwindField(F.scopes), GroupField(F.clientOrigin)( - F.usedAt -> MaxField(F.usedAt), - F.scopes -> AddFieldToSet(F.scopes) + F.usedAt -> MaxField(F.usedAt), + F.scopes -> AddFieldToSet(F.scopes) ), Sort(Descending(F.usedAt)) ) @@ -74,21 +74,34 @@ final class AccessTokenApi(colls: OauthColls)(implicit ec: scala.concurrent.Exec for { doc <- docs origin <- doc.getAsOpt[String]("_id") - usedAt = doc.getAsOpt[DateTime](F.usedAt) + usedAt = doc.getAsOpt[DateTime](F.usedAt) scopes <- doc.getAsOpt[List[OAuthScope]](F.scopes) } yield AccessTokenApi.Client(origin, usedAt, scopes) } - def revokeByClientOrigin(clientOrigin: String, user: User): Funit = - colls.token { - _.delete - .one( + def revokeByClientOrigin(clientOrigin: String, user: User): Fu[List[AccessToken.Id]] = + colls.token { coll => + coll + .find( $doc( F.userId -> user.id, F.clientOrigin -> clientOrigin - ) + ), + $doc(F.id -> 1).some ) - .void + .sort($sort desc F.usedAt) + .cursor[Bdoc]() + .list(100) + .flatMap { invalidate => + coll.delete + .one( + $doc( + F.userId -> user.id, + F.clientOrigin -> clientOrigin + ) + ) + .inject(invalidate.flatMap(_.getAsOpt[AccessToken.Id](F.id))) + } } def revokeByPublicId(publicId: String, user: User): Fu[Option[AccessToken]] =