1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-11-23 11:02:35 +03:00

Consume authorization code on use

This commit is contained in:
Quentin Gliech
2021-09-17 18:24:43 +02:00
parent 1813984a1c
commit e08dae27b1
3 changed files with 42 additions and 2 deletions

View File

@@ -661,6 +661,18 @@
]
}
},
"eaddc1e33715ad31b4195fda72dbe870f179dd8da53a88d0543b72a278ed1d3d": {
"query": "\n DELETE FROM oauth2_codes\n WHERE id = $1\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int8"
]
},
"nullable": []
}
},
"f9a09ff53b6f221649f4f050e3d5ade114f852ddf50a78610a6c0ef0689af681": {
"query": "\n INSERT INTO users (username, hashed_password)\n VALUES ($1, $2)\n RETURNING id\n ",
"describe": {

View File

@@ -47,7 +47,7 @@ use crate::{
},
storage::oauth2::{
access_token::{add_access_token, revoke_access_token},
authorization_code::lookup_code,
authorization_code::{consume_code, lookup_code},
refresh_token::{add_refresh_token, lookup_refresh_token, replace_refresh_token},
},
tokens,
@@ -154,13 +154,13 @@ async fn authorization_code_grant(
conn: &mut PoolConnection<Postgres>,
) -> Result<AccessTokenResponse, Rejection> {
let mut txn = conn.begin().await.wrap_error()?;
// TODO: recover from failed code lookup with invalid_grant instead
let code = lookup_code(&mut txn, &grant.code).await.wrap_error()?;
if client.client_id != code.client_id {
return error(UnauthorizedClient);
}
// TODO: verify PKCE
// TODO: make the code invalid
let ttl = Duration::minutes(5);
let (access_token, refresh_token) = {
let mut rng = thread_rng();
@@ -208,6 +208,8 @@ async fn authorization_code_grant(
.with_refresh_token(refresh_token.token)
.with_id_token(id_token);
consume_code(&mut txn, code.id).await.wrap_error()?;
txn.commit().await.wrap_error()?;
Ok(params)

View File

@@ -90,3 +90,29 @@ pub async fn lookup_code(
.await
.context("could not lookup oauth2 code")
}
pub async fn consume_code(
executor: impl Executor<'_, Database = Postgres>,
code_id: i64,
) -> anyhow::Result<()> {
// TODO: mark the code as invalid instead to allow invalidating the whole
// session on code reuse
let res = sqlx::query!(
r#"
DELETE FROM oauth2_codes
WHERE id = $1
"#,
code_id,
)
.execute(executor)
.await
.context("could not consume authorization code")?;
if res.rows_affected() == 1 {
Ok(())
} else {
Err(anyhow::anyhow!(
"no row were affected when consuming authorization code"
))
}
}