diff options
Diffstat (limited to 'src/api')
-rw-r--r-- | src/api/auth/oauth.rs | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/src/api/auth/oauth.rs b/src/api/auth/oauth.rs index b0ed8ee..39fe6ae 100644 --- a/src/api/auth/oauth.rs +++ b/src/api/auth/oauth.rs @@ -7,6 +7,7 @@ use serde_json::Value; use sha2::Digest; use subtle::ConstantTimeEq; +use crate::api::{EMPTY, Empty}; use crate::api::auth::WithVerifiedFxaLogin; use crate::db::DbConn; use crate::types::oauth::{Scope, ScopeSet}; @@ -187,25 +188,21 @@ pub(crate) async fn scoped_key_data( #[derive(Debug, Deserialize)] #[serde(deny_unknown_fields)] pub(crate) struct OauthDestroy { + #[allow(dead_code)] client_id: String, token: OauthToken, } #[post("/oauth/destroy", data = "<data>")] -pub(crate) async fn destroy(db: &DbConn, data: Json<OauthDestroy>) -> auth::Result<()> { +pub(crate) async fn destroy(db: &DbConn, data: Json<OauthDestroy>) -> auth::Result<Empty> { // MISSING api spec allows an optional basic auth header, but what for? // TODO fxa also checks the authorization header if present, but firefox doesn't send it - let client_id = if let Ok(t) = db.get_refresh_token(&data.token.hash()).await { - t.client_id - } else if let Ok(t) = db.get_access_token(&data.token.hash()).await { - t.client_id - } else { - return Err(auth::Error::InvalidParameter); - }; - // fxa does constant-time checks for client_id, do that here too. - if client_id.as_bytes().ct_eq(data.client_id.as_bytes()).into() { - db.delete_oauth_token(&data.token.hash()).await?; - Ok(Json(())) + // NOTE fxa does a constant-time check for whether the provided client_id matches that + // of the token being destroyed. since we only support a public list we can skip that, + // which also lets us more easily deal with firefox's habit of destroying tokens that are + // already expired + if db.delete_oauth_token(&data.token.hash()).await? { + Ok(EMPTY) } else { Err(auth::Error::InvalidParameter) } |