feat: initial auth extractor

This commit is contained in:
əlemi 2024-03-25 01:58:30 +01:00
parent 41899556bf
commit 384d5147ed
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 53 additions and 0 deletions

52
src/auth.rs Normal file
View file

@ -0,0 +1,52 @@
use axum::{extract::{FromRef, FromRequestParts}, http::{header::{self, HeaderValue, USER_AGENT}, request::Parts, StatusCode}};
use sea_orm::{ColumnTrait, Condition, EntityTrait, QueryFilter};
use crate::{model, server::Context};
#[derive(Debug, Clone)]
pub enum Identity {
Anonymous,
User(String),
Server(String),
}
pub struct AuthIdentity(pub Identity);
#[axum::async_trait]
impl<S> FromRequestParts<S> for AuthIdentity
where
Context: FromRef<S>,
S: Send + Sync,
{
type Rejection = StatusCode;
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
let ctx = Context::from_ref(state);
let mut identity = Identity::Anonymous;
let auth_header = parts
.headers
.get(header::AUTHORIZATION)
.map(|v| v.to_str().unwrap_or(""))
.unwrap_or("");
if auth_header.starts_with("Bearer ") {
match model::session::Entity::find_by_id(auth_header.replace("Bearer ", ""))
.filter(Condition::all().add(model::session::Column::Expires.gt(chrono::Utc::now())))
.one(ctx.db())
.await
{
Ok(Some(x)) => identity = Identity::User(x.actor),
Ok(None) => return Err(StatusCode::UNAUTHORIZED),
Err(e) => {
tracing::error!("failed querying user session: {e}");
return Err(StatusCode::INTERNAL_SERVER_ERROR)
},
}
}
// TODO check and validate HTTP signature
Ok(AuthIdentity(identity))
}
}

View file

@ -5,6 +5,7 @@ pub mod activitypub;
pub mod server;
pub mod router;
pub mod errors;
pub mod auth;
use clap::{Parser, Subcommand};
use sea_orm::{ConnectOptions, Database, EntityTrait, IntoActiveModel};