diff --git a/src/account.rs b/src/account.rs index e22283d..3c03a0e 100644 --- a/src/account.rs +++ b/src/account.rs @@ -1,9 +1,15 @@ +pub mod db; + use axum::{ Router, routing::{get, post} }; +use axum_session_auth::AuthSession; +use axum_session_mongo::SessionMongoPool; +use db::User; +use http::method::Method; +use mongodb::{Client, bson::oid::ObjectId}; -mod db; pub fn router() -> Router { Router::new() @@ -35,3 +41,7 @@ pub async fn post_sign_up() {} pub async fn post_backup() {} pub async fn get_restore() {} + +async fn auth(method: Method, auth: AuthSession) { + //TODO: Auth loop (get from crate example) +} diff --git a/src/account/db.rs b/src/account/db.rs index 140bd1d..d9ff4e4 100644 --- a/src/account/db.rs +++ b/src/account/db.rs @@ -1,15 +1,12 @@ +use anyhow::Result; +use axum::async_trait; +use axum_session_auth::Authentication; use serde::{Deserialize, Serialize}; use mongodb::{ - bson::{DateTime, oid::ObjectId}, + bson::{doc, oid::ObjectId, DateTime}, Client, - Database, - error::Error, }; -pub async fn get_database_client() -> Result { - Ok(Client::with_uri_str("mongodb:://localhost:27017").await?.database("dermy")) -} - #[derive(Serialize, Deserialize)] pub struct Mole { #[serde(rename = "_id", skip_serializing_if = "Option::is_none")] @@ -87,26 +84,51 @@ impl LogEntry { } } -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub struct User { #[serde(rename = "_id", skip_serializing_if = "Option::is_none")] pub id: Option, #[serde(rename="_auth")] pub auth: Auth, pub username: String, + #[serde(skip_serializing)] + logged_in: bool, } impl User { pub fn new(username: String) -> Self { let id = None; let auth = Default::default(); + let logged_in = false; Self { id, auth, username, + logged_in, } } } -#[derive(Default, Serialize, Deserialize)] +#[async_trait] +impl Authentication for User { + async fn load_user(user_id: ObjectId, db: Option<&Client>) -> Result { + Ok(db.unwrap() + .database("dermy") + .collection::("users") + .find_one(doc! {"_id": user_id}, None).await?.unwrap()) + } + + fn is_authenticated(&self) -> bool { + self.logged_in + } + + fn is_active(&self) -> bool { + self.logged_in + } + + fn is_anonymous(&self) -> bool { + !self.logged_in + } +} +#[derive(Clone, Default, Serialize, Deserialize)] pub struct Auth { #[serde(rename = "_hash", skip_serializing_if = "Option::is_none")] pub hash: Option, diff --git a/src/lib.rs b/src/lib.rs index 6d69af3..64d0220 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,29 @@ mod account; mod model; -pub async fn run() { - let app = router(); +use account::db::User; +use anyhow::Result; +use axum_session::{SessionConfig, SessionLayer, SessionStore}; +use axum_session_auth::{AuthConfig, AuthSessionLayer}; +use axum_session_mongo::SessionMongoPool; +use mongodb::{bson::oid::ObjectId, Client}; + +pub async fn run() -> Result<()> { + let db = Client::with_uri_str("mongodb://localhost:27017").await?; + let session_store = session(db.clone()).await?; + let auth_config = AuthConfig::::default(); + + + let app = router() + .layer(SessionLayer::new(session_store)) + .layer(AuthSessionLayer:: + ::new(Some(db)).with_config(auth_config) + ); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); - axum::serve(listener, app).await.unwrap(); + axum::serve(listener, app).await?; + + Ok(()) } fn router() -> axum::Router { @@ -13,3 +31,11 @@ fn router() -> axum::Router { .nest("/account", account::router()) .nest("/predict", model::router()) } + +async fn session(db: Client) -> Result> { + let session_config = SessionConfig::default() + .with_table_name("sessions"); + + Ok(SessionStore:: + ::new(Some(db.clone().into()), session_config).await?) +} diff --git a/src/main.rs b/src/main.rs index 272213f..f71cfcc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,7 @@ +use anyhow::Result; + #[tokio::main] -async fn main() { - dermy_server::run().await; +async fn main() -> Result<()> { + dermy_server::run().await?; + Ok(()) }