summaryrefslogtreecommitdiff
path: root/src/login
diff options
context:
space:
mode:
Diffstat (limited to 'src/login')
-rw-r--r--src/login/app.rs11
-rw-r--r--src/login/routes.rs17
-rw-r--r--src/login/routes/test/logout.rs30
3 files changed, 36 insertions, 22 deletions
diff --git a/src/login/app.rs b/src/login/app.rs
index b8916a8..182c62c 100644
--- a/src/login/app.rs
+++ b/src/login/app.rs
@@ -120,16 +120,13 @@ impl<'a> Logins<'a> {
Ok(())
}
- pub async fn logout(&self, secret: &IdentitySecret) -> Result<(), ValidateError> {
+ pub async fn logout(&self, token: &token::Id) -> Result<(), ValidateError> {
let mut tx = self.db.begin().await?;
- let token = tx
- .tokens()
- .revoke(secret)
- .await
- .not_found(|| ValidateError::InvalidToken)?;
+ tx.tokens().revoke(token).await?;
tx.commit().await?;
- self.logins.broadcast(&types::TokenRevoked::from(token));
+ self.logins
+ .broadcast(&types::TokenRevoked::from(token.clone()));
Ok(())
}
diff --git a/src/login/routes.rs b/src/login/routes.rs
index 4664063..8d9e938 100644
--- a/src/login/routes.rs
+++ b/src/login/routes.rs
@@ -78,27 +78,32 @@ struct LogoutRequest {}
async fn on_logout(
State(app): State<App>,
+ RequestedAt(now): RequestedAt,
identity: IdentityToken,
// This forces the only valid request to be `{}`, and not the infinite
// variation allowed when there's no body extractor.
Json(LogoutRequest {}): Json<LogoutRequest>,
) -> Result<(IdentityToken, StatusCode), LogoutError> {
if let Some(secret) = identity.secret() {
- app.logins().logout(&secret).await.map_err(LogoutError)?;
+ let (token, _) = app.logins().validate(&secret, &now).await?;
+ app.logins().logout(&token).await?;
}
let identity = identity.clear();
Ok((identity, StatusCode::NO_CONTENT))
}
-#[derive(Debug)]
-struct LogoutError(app::ValidateError);
+#[derive(Debug, thiserror::Error)]
+#[error(transparent)]
+enum LogoutError {
+ ValidateError(#[from] app::ValidateError),
+ DatabaseError(#[from] sqlx::Error),
+}
impl IntoResponse for LogoutError {
fn into_response(self) -> Response {
- let Self(error) = self;
- match error {
- error @ app::ValidateError::InvalidToken => {
+ match self {
+ error @ Self::ValidateError(app::ValidateError::InvalidToken) => {
(StatusCode::UNAUTHORIZED, error.to_string()).into_response()
}
other => Internal::from(other).into_response(),
diff --git a/src/login/routes/test/logout.rs b/src/login/routes/test/logout.rs
index 05594be..20b0d55 100644
--- a/src/login/routes/test/logout.rs
+++ b/src/login/routes/test/logout.rs
@@ -22,6 +22,7 @@ async fn successful() {
let (response_identity, response_status) = routes::on_logout(
State(app.clone()),
+ fixtures::now(),
identity.clone(),
Json(routes::LogoutRequest {}),
)
@@ -57,10 +58,14 @@ async fn no_identity() {
// Call the endpoint
let identity = fixtures::identity::not_logged_in();
- let (identity, status) =
- routes::on_logout(State(app), identity, Json(routes::LogoutRequest {}))
- .await
- .expect("logged out with no token");
+ let (identity, status) = routes::on_logout(
+ State(app),
+ fixtures::now(),
+ identity,
+ Json(routes::LogoutRequest {}),
+ )
+ .await
+ .expect("logged out with no token");
// Verify the return value's basic structure
@@ -77,12 +82,19 @@ async fn invalid_token() {
// Call the endpoint
let identity = fixtures::identity::fictitious();
- let routes::LogoutError(error) =
- routes::on_logout(State(app), identity, Json(routes::LogoutRequest {}))
- .await
- .expect_err("logged out with an invalid token");
+ let error = routes::on_logout(
+ State(app),
+ fixtures::now(),
+ identity,
+ Json(routes::LogoutRequest {}),
+ )
+ .await
+ .expect_err("logged out with an invalid token");
// Verify the return value's basic structure
- assert!(matches!(error, app::ValidateError::InvalidToken));
+ assert!(matches!(
+ error,
+ routes::LogoutError::ValidateError(app::ValidateError::InvalidToken)
+ ));
}