feat(tokens): implemented token duplication protection

This commit is contained in:
antifallobst 2023-08-17 03:17:20 +02:00
parent 5f5534f597
commit 9f0280c204
Signed by: antifallobst
GPG Key ID: 2B4F402172791BAF
2 changed files with 35 additions and 16 deletions

View File

@ -92,7 +92,7 @@ pub async fn verify(
return Ok(data::VerifyResponse::Blocked); return Ok(data::VerifyResponse::Blocked);
} }
let token = match VerificationToken::check(pool, request.token).await? { let token = match VerificationToken::check(pool, &request.token).await? {
Some(t) => t, Some(t) => t,
None => return Ok(data::VerifyResponse::TokenUnknown), None => return Ok(data::VerifyResponse::TokenUnknown),
}; };
@ -135,12 +135,15 @@ pub async fn delete(pool: &MySqlPool, token: String) -> Result<data::DeleteRespo
return Ok(data::DeleteResponse::Blocked); return Ok(data::DeleteResponse::Blocked);
} }
let token = match AuthToken::check(pool, token).await? { let token = match AuthToken::check(pool, &token).await? {
Some(t) => t, Some(t) => t,
None => return Ok(data::DeleteResponse::Unauthorized), None => return Ok(data::DeleteResponse::Unauthorized),
}; };
sqlx::query!(r#"DELETE FROM AuthTokens WHERE account = ?;"#, token.account) sqlx::query!(
r#"DELETE FROM AuthTokens WHERE account = ?;"#,
token.account
)
.execute(pool) .execute(pool)
.await?; .await?;

View File

@ -1,4 +1,3 @@
use crate::accounts::Account;
use anyhow::{Error, Result}; use anyhow::{Error, Result};
use sqlx::{mysql::MySqlPool, types::chrono as sqlx_chrono}; use sqlx::{mysql::MySqlPool, types::chrono as sqlx_chrono};
@ -27,12 +26,16 @@ impl AuthToken {
} }
}; };
let token = Self { let mut token = Self {
token: uuid::Uuid::new_v4().simple().to_string(), token: uuid::Uuid::new_v4().simple().to_string(),
account: account_id as u64, account: account_id as u64,
expire, expire,
}; };
while AuthToken::check(pool, &token.token).await?.is_some() {
token.token = uuid::Uuid::new_v4().simple().to_string();
}
sqlx::query!( sqlx::query!(
r#" r#"
INSERT INTO AuthTokens (token, account, expire) VALUES (?, ?, ?); INSERT INTO AuthTokens (token, account, expire) VALUES (?, ?, ?);
@ -47,7 +50,7 @@ impl AuthToken {
Ok(token) Ok(token)
} }
pub async fn check(pool: &MySqlPool, alphanumeric_token: String) -> Result<Option<Self>> { pub async fn check(pool: &MySqlPool, alphanumeric_token: &String) -> Result<Option<Self>> {
let query_result = sqlx::query!( let query_result = sqlx::query!(
r#"SELECT * FROM AuthTokens WHERE token = ?;"#, r#"SELECT * FROM AuthTokens WHERE token = ?;"#,
alphanumeric_token alphanumeric_token
@ -107,12 +110,19 @@ impl VerificationToken {
} }
}; };
let token = Self { let mut token = Self {
token: uuid::Uuid::new_v4().simple().to_string(), token: uuid::Uuid::new_v4().simple().to_string(),
account: account_id as u64, account: account_id as u64,
expire, expire,
}; };
while VerificationToken::check(pool, &token.token)
.await?
.is_some()
{
token.token = uuid::Uuid::new_v4().simple().to_string();
}
sqlx::query!( sqlx::query!(
r#" r#"
INSERT INTO VerificationTokens (token, account, expire) VALUES (?, ?, ?); INSERT INTO VerificationTokens (token, account, expire) VALUES (?, ?, ?);
@ -127,7 +137,7 @@ impl VerificationToken {
Ok(token) Ok(token)
} }
pub async fn check(pool: &MySqlPool, alphanumeric_token: String) -> Result<Option<Self>> { pub async fn check(pool: &MySqlPool, alphanumeric_token: &String) -> Result<Option<Self>> {
let query_result = sqlx::query!( let query_result = sqlx::query!(
r#"SELECT * FROM VerificationTokens WHERE token = ?;"#, r#"SELECT * FROM VerificationTokens WHERE token = ?;"#,
alphanumeric_token alphanumeric_token
@ -162,11 +172,17 @@ impl VerificationToken {
} }
pub async fn apply(&self, pool: &MySqlPool) -> Result<()> { pub async fn apply(&self, pool: &MySqlPool) -> Result<()> {
sqlx::query!(r#"DELETE FROM VerificationTokens WHERE token = ?;"#, self.token) sqlx::query!(
r#"DELETE FROM VerificationTokens WHERE token = ?;"#,
self.token
)
.execute(pool) .execute(pool)
.await?; .await?;
sqlx::query!(r#"UPDATE Accounts SET verified=true WHERE id = ?;"#, self.account) sqlx::query!(
r#"UPDATE Accounts SET verified=true WHERE id = ?;"#,
self.account
)
.execute(pool) .execute(pool)
.await?; .await?;