auth/src/dto/credential_mapper.rs
2024-03-16 17:34:43 +08:00

76 lines
2.0 KiB
Rust

#![allow(non_snake_case)]
use uuid::Uuid;
use sqlx::Pool;
use sqlx::Sqlite;
use webauthn_rs::prelude::Passkey;
use webauthn_rs::prelude::WebauthnError;
pub async fn get_credential_from_uid(
uid: Uuid,
pool: &Pool<Sqlite>,
) -> Result<Vec<Passkey>, String> {
let uid = uid.to_string();
let result = sqlx::query!(
"SELECT credential FROM credentials WHERE user_id = $1;",
uid
)
.fetch_all(pool)
.await
.map_err(|e| e.to_string())?;
result
.into_iter()
.map(|e| serde_json::from_str::<Passkey>(&e.CREDENTIAL).map_err(|e| e.to_string()))
.collect()
}
pub async fn update_credential_on_success(
new_cred: Passkey,
uid: Uuid,
old_cred: Passkey,
pool: &sqlx::Pool<sqlx::Sqlite>,
) -> Result<String, String> {
let new_cred_str =
serde_json::to_string(&new_cred).map_err(|_| "Cannot Serialize new passkey")?;
let old_cred_str =
serde_json::to_string(&old_cred).map_err(|_| "Cannot Serialize old passkey")?;
let uid = uid.to_string();
if sqlx::query!(
"UPDATE credentials SET credential = $1 WHERE user_id = $2 AND credential = $3;",
new_cred_str,
uid,
old_cred_str
)
.execute(pool)
.await
.is_ok_and(|e| e.rows_affected() != 1)
{
return Err(WebauthnError::AuthenticationFailure.to_string());
}
Ok("Successful Operation update_credential_on_success".to_owned())
}
/// Return Rows Affected
pub async fn add_credential_by_id(
uid: Uuid,
cred: &Passkey,
pool: &sqlx::Pool<sqlx::Sqlite>,
) -> Result<u64, String> {
let uid = uid.to_string();
// Serialise the key
let serialised_key =
serde_json::ser::to_string(&cred).map_err(|_| "Key Serialisation failed")?;
let res = sqlx::query!(
"INSERT INTO credentials(user_id, credential) VALUES($1, $2);",
uid,
serialised_key
)
.execute(pool)
.await
.map_err(|_| WebauthnError::UserNotPresent.to_string())?
.rows_affected();
Ok(res)
}