All checks were successful
continuous-integration/drone/push Build is passing
59 lines
1.9 KiB
Rust
59 lines
1.9 KiB
Rust
use crate::actors::users_actor;
|
|
use crate::actors::users_actor::UsersActor;
|
|
use crate::data::action_logger::{Action, ActionLogger};
|
|
use actix::Addr;
|
|
use actix_identity::Identity;
|
|
use actix_remote_ip::RemoteIP;
|
|
use actix_web::{web, HttpRequest, HttpResponse, Responder};
|
|
use webauthn_rs::prelude::PublicKeyCredential;
|
|
|
|
use crate::data::session_identity::{SessionIdentity, SessionStatus};
|
|
use crate::data::webauthn_manager::WebAuthManagerReq;
|
|
|
|
#[derive(serde::Deserialize)]
|
|
pub struct AuthWebauthnRequest {
|
|
opaque_state: String,
|
|
credential: PublicKeyCredential,
|
|
}
|
|
|
|
pub async fn auth_webauthn(
|
|
id: Identity,
|
|
req: web::Json<AuthWebauthnRequest>,
|
|
manager: WebAuthManagerReq,
|
|
http_req: HttpRequest,
|
|
remote_ip: RemoteIP,
|
|
users: web::Data<Addr<UsersActor>>,
|
|
logger: ActionLogger,
|
|
) -> impl Responder {
|
|
let user_id = SessionIdentity(Some(&id)).user_id();
|
|
|
|
match manager.finish_authentication(&user_id, &req.opaque_state, &req.credential) {
|
|
Ok(_) => {
|
|
users
|
|
.send(users_actor::AddSuccessful2FALogin(
|
|
user_id.clone(),
|
|
remote_ip.0,
|
|
))
|
|
.await
|
|
.unwrap();
|
|
|
|
let session = SessionIdentity(Some(&id));
|
|
session.record_2fa_auth(&http_req);
|
|
session.set_status(&http_req, SessionStatus::SignedIn);
|
|
logger.log(Action::LoginWebauthnAttempt {
|
|
success: true,
|
|
user_id,
|
|
});
|
|
HttpResponse::Ok().body("You are authenticated!")
|
|
}
|
|
Err(e) => {
|
|
log::error!("Failed to authenticate user using webauthn! {:?}", e);
|
|
logger.log(Action::LoginWebauthnAttempt {
|
|
success: false,
|
|
user_id,
|
|
});
|
|
HttpResponse::InternalServerError().body("Failed to validate security key!")
|
|
}
|
|
}
|
|
}
|