1
0
Fork 0
forked from alemi/upub

feat: super barebones auth route

This commit is contained in:
əlemi 2024-03-24 23:55:48 +01:00
parent a0d75d0807
commit a3df3e882e
Signed by: alemi
GPG key ID: A4895B84D311642C
3 changed files with 50 additions and 1 deletions

View file

@ -23,3 +23,5 @@ uuid = { version = "1.8.0", features = ["v4"] }
jrd = "0.1" jrd = "0.1"
# nodeinfo = "0.0.2" # the version on crates.io doesn't re-export necessary types to build the struct!!! # nodeinfo = "0.0.2" # the version on crates.io doesn't re-export necessary types to build the struct!!!
nodeinfo = { git = "https://codeberg.org/thefederationinfo/nodeinfo-rs", rev = "e865094804" } nodeinfo = { git = "https://codeberg.org/thefederationinfo/nodeinfo-rs", rev = "e865094804" }
rand = "0.8.5"
sha256 = "1.5.0"

View file

@ -9,8 +9,10 @@ pub mod jsonld;
pub use jsonld::JsonLD; pub use jsonld::JsonLD;
use axum::{extract::State, http::StatusCode, Json}; use axum::{extract::State, http::StatusCode, Json};
use rand::Rng;
use sea_orm::{ColumnTrait, Condition, EntityTrait, QueryFilter};
use crate::{activitystream::{object::{actor::{ActorMut, ActorType}, ObjectMut}, BaseMut}, server::Context, url}; use crate::{activitystream::{object::{actor::{ActorMut, ActorType}, ObjectMut}, BaseMut}, model, server::Context, url};
use self::jsonld::LD; use self::jsonld::LD;
@ -55,3 +57,46 @@ pub async fn view(State(ctx): State<Context>) -> Result<Json<serde_json::Value>,
)) ))
} }
#[derive(Debug, Clone, serde::Deserialize)]
pub struct LoginForm {
email: String,
password: String,
}
pub async fn auth(State(ctx): State<Context>, Json(login): Json<LoginForm>) -> Result<Json<serde_json::Value>, StatusCode> {
// TODO salt the pwd
match model::credential::Entity::find()
.filter(Condition::all()
.add(model::credential::Column::Email.eq(login.email))
.add(model::credential::Column::Password.eq(sha256::digest(login.password)))
)
.one(ctx.db())
.await
{
Ok(Some(x)) => {
// TODO should probably use crypto-safe rng
let token : String = rand::thread_rng()
.sample_iter(&rand::distributions::Alphanumeric)
.take(128)
.map(char::from)
.collect();
model::session::Entity::insert(
model::session::ActiveModel {
id: sea_orm::ActiveValue::NotSet,
actor: sea_orm::ActiveValue::Set(x.id),
session: sea_orm::ActiveValue::Set(token.clone()),
expires: sea_orm::ActiveValue::Set(chrono::Utc::now() + std::time::Duration::from_secs(3600 * 6)),
}
)
.exec(ctx.db())
.await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(Json(serde_json::Value::String(token)))
},
Ok(None) => Err(StatusCode::UNAUTHORIZED),
Err(e) => {
tracing::error!("error querying db for user credentials: {e}");
Err(StatusCode::INTERNAL_SERVER_ERROR)
}
}
}

View file

@ -12,6 +12,8 @@ pub async fn serve(db: DatabaseConnection, domain: String) {
// .route("/inbox", post(ap::inbox::post)) // .route("/inbox", post(ap::inbox::post))
// .route("/outbox", get(ap::outbox::get)) // .route("/outbox", get(ap::outbox::get))
// .route("/outbox", get(ap::outbox::post)) // .route("/outbox", get(ap::outbox::post))
// AUTH routes
.route("/auth", post(ap::auth))
// .well-known and discovery // .well-known and discovery
.route("/.well-known/webfinger", get(ap::well_known::webfinger)) .route("/.well-known/webfinger", get(ap::well_known::webfinger))
.route("/.well-known/host-meta", get(ap::well_known::host_meta)) .route("/.well-known/host-meta", get(ap::well_known::host_meta))