nom-nom-nix-gc/src/handlers/mod.rs

56 lines
2.4 KiB
Rust

use webauthn_rs::prelude::{RegisterPublicKeyCredential, Uuid};
use actix_web::{error, HttpResponse, http::header::{ContentType, self}, web, cookie::{Cookie, SameSite}, HttpRequest};
use crate::{models::{AppState, User}, templates};
pub async fn landing_page (app_state: web::Data<AppState<'_>>) -> HttpResponse {
let content: String = templates::landing_page(app_state.hbs.clone()).unwrap();
HttpResponse::Ok()
.content_type(ContentType::html())
.body(content)
}
pub async fn start_webauthn_registration(app_state: web::Data<AppState<'_>>, user: web::Json<User>) -> HttpResponse {
let (creation_challenge_response, passkey_registration) = app_state.webauthn.start_passkey_registration(user.uuid, &user.user_name, &user.display_name, None).unwrap();
let uuid_str = user.uuid.to_string();
{
let mut session = app_state.session.user_registrations.write().await;
session.insert(user.clone(), passkey_registration);
}
{
let mut uuid_db = app_state.db.user_uuid_object.write().await;
uuid_db.insert(user.uuid, user.into_inner());
}
let res = serde_json::to_string(&creation_challenge_response).unwrap();
let cookie = Cookie::build("uuid", &uuid_str)
.secure(true)
.same_site(SameSite::Strict)
.finish();
HttpResponse::Ok()
.content_type(ContentType::json())
.insert_header((header::SET_COOKIE, cookie.encoded().to_string()))
.body(res)
}
pub async fn finish_webauthn_registration(req: HttpRequest, app_state: web::Data<AppState<'_>>, register: web::Json<RegisterPublicKeyCredential>) -> impl actix_web::Responder {
let cook = req.cookie("uuid");
let uuid = Uuid::parse_str(cook.unwrap().value()).unwrap();
let registration_result = {
let users = app_state.db.user_uuid_object.read().await;
let user = users.get(&uuid).unwrap();
let session = app_state.session.user_registrations.read().await;
let passkey_registration = session.get(&user).unwrap();
app_state.webauthn.finish_passkey_registration(&register, passkey_registration)
};
let mut user_keys = app_state.db.user_keys.write().await;
match registration_result {
Ok(passkey) => {
user_keys.insert(uuid, passkey);
HttpResponse::Ok()
.body("ok")
},
Err(_) =>
HttpResponse::from_error(error::ErrorUnauthorized("Webauthn challenge failed"))
}
}