wip: fix auth example

This commit is contained in:
Gabor Körber 2024-06-15 09:10:00 +02:00
parent 6dcbb4c316
commit 84c127edcd
4 changed files with 51 additions and 8 deletions

10
Cargo.lock generated
View File

@ -1849,6 +1849,7 @@ dependencies = [
"serde_json",
"slug",
"sqlformat",
"thiserror",
"tokio",
"tower-http",
"tracing",
@ -2437,6 +2438,7 @@ dependencies = [
"sea-orm",
"serde",
"serde_json",
"thiserror",
"tokio",
]
@ -3379,18 +3381,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.51"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7"
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.51"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df"
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",

View File

@ -55,3 +55,4 @@ async-trait = "0.1.77"
tracing = "0.1.40"
tower-http = { version = "0.5.1", features = ["trace"] }
chrono = "0.4.38"
thiserror = "1.0.61"

View File

@ -25,3 +25,4 @@ sea-orm = { version = "0.12.10", features = [
axum-login = "0.15.3"
async-trait = "0.1.80"
password-auth = "1.0.0"
thiserror = "1.0.61"

View File

@ -3,8 +3,10 @@ use axum_login::{AuthUser, AuthnBackend, UserId};
use password_auth::verify_password;
use sea_orm::{ActiveModelTrait, DatabaseConnection, EntityTrait, ModelTrait, Set};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use tokio::task;
#[derive(Debug, Clone)]
struct UserDatabase {
connection: DatabaseConnection,
}
@ -51,6 +53,16 @@ impl AuthUser for User {
}
}
impl From<entity::user::Model> for User {
fn from(value: entity::user::Model) -> Self {
User {
id: value.id,
username: value.username,
password: "".to_owned(), // TODO: password field.
}
}
}
// This allows us to extract the authentication fields from forms. We use this
// to authenticate requests with the backend.
#[derive(Debug, Clone, Deserialize)]
@ -60,10 +72,32 @@ pub struct Credentials {
pub next: Option<String>,
}
#[derive(Debug, Error)]
pub struct NotFoundError {
pub details: String,
}
impl NotFoundError {
pub fn new(details: &str) -> Self {
NotFoundError {
details: details.to_string(),
}
}
}
impl std::fmt::Display for NotFoundError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Not Found... Error: {}", self.details)
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Sqlx(#[from] sqlx::Error),
DbErr(#[from] sea_orm::DbErr),
#[error("Not Found: {0}")]
NotFound(#[from] NotFoundError),
#[error(transparent)]
TaskJoin(#[from] task::JoinError),
@ -95,14 +129,19 @@ impl AuthnBackend for UserDatabase {
}
async fn get_user(&self, user_id: &UserId<Self>) -> Result<Option<Self::User>, Self::Error> {
let user = entity::User::find_by_id(*user_id)
let user_found = entity::User::find_by_id(*user_id)
.one(&self.connection)
.await?;
Ok(user)
if let Some(user) = user_found {
let rear_user: User = user.into();
Ok(Some(rear_user))
} else {
Ok(None)
}
}
}
// We use a type alias for convenience.
//
// Note that we've supplied our concrete backend here.
pub type AuthSession = axum_login::AuthSession<Backend>;
pub type AuthSession = axum_login::AuthSession<UserDatabase>;