56 lines
2.4 KiB
Rust
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(®ister, 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"))
|
|
}
|
|
}
|