mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2025-07-12 18:42:48 +00:00
Update webauthn-rs
crate
This commit is contained in:
@ -20,7 +20,7 @@ pub struct AdminAuthOptions {
|
||||
}
|
||||
|
||||
impl AdminAuthOptions {
|
||||
pub fn new(admin: &Admin, keys: &Vec<AdminKey>) -> Self {
|
||||
pub fn new(admin: &Admin, keys: &[AdminKey]) -> Self {
|
||||
Self {
|
||||
reset_token: admin.reset_token.is_some(),
|
||||
keys: keys.iter().map(|k| AuthKey { id: k.id, name: k.name.to_string(), password: k.password.is_some() }).collect(),
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
|
||||
use bcrypt::verify;
|
||||
use webauthn_rs::prelude::Uuid;
|
||||
|
||||
use crate::api_data::admin::admin_auth_success::AdminAuthSuccess;
|
||||
use crate::api_data::admin::admin_keys_api::AdminKeyAPI;
|
||||
@ -27,8 +28,7 @@ impl HttpRequestHandler {
|
||||
let keys = admin_account_key_helper::get_admin_keys(admin.id)?;
|
||||
|
||||
let key = keys.into_iter()
|
||||
.filter(|k| k.id == key_id)
|
||||
.next();
|
||||
.find(|k| k.id == key_id);
|
||||
|
||||
match key {
|
||||
Some(key) => Ok(key),
|
||||
@ -55,7 +55,13 @@ pub async fn get_keys_list(r: &mut HttpRequestHandler) -> RequestResult {
|
||||
pub async fn challenge_register_key(r: &mut HttpRequestHandler) -> RequestResult {
|
||||
let wan = get_wan();
|
||||
|
||||
let (res, state) = wan.generate_challenge_register(&r.admin_id()?.id_str(), false)?;
|
||||
let user_info = admin_account_helper::find_admin_by_id(r.admin_id()?)?;
|
||||
|
||||
let (res, state) = wan.start_passkey_registration(
|
||||
Uuid::new_v4(),
|
||||
&user_info.name,
|
||||
&user_info.name,
|
||||
None)?;
|
||||
|
||||
admin_key_registration_challenges_helper::set(r.admin_id()?, state)?;
|
||||
|
||||
@ -74,9 +80,9 @@ pub async fn register_key(r: &mut HttpRequestHandler) -> RequestResult {
|
||||
)?;
|
||||
|
||||
let wan = get_wan();
|
||||
let key = wan.register_credential(&creds, &state, |_| Ok(false))?;
|
||||
let key = wan.finish_passkey_registration(&creds, &state)?;
|
||||
|
||||
let key_id = admin_account_key_helper::add_key(r.admin_id()?, &key_name, key.0, key_password)?;
|
||||
let key_id = admin_account_key_helper::add_key(r.admin_id()?, &key_name, key, key_password)?;
|
||||
|
||||
log_admin_action(r.admin_id()?, &r.remote_ip(),
|
||||
AdminAction::RegisteredAdminKey {
|
||||
@ -120,7 +126,7 @@ pub async fn challenge_auth_with_key(r: &mut HttpRequestHandler) -> RequestResul
|
||||
let key = r.post_admin_auth_key("mail", "key_id")?;
|
||||
|
||||
let (challenge_response, auth_state) =
|
||||
get_wan().generate_challenge_authenticate(vec![key.key])?;
|
||||
get_wan().start_passkey_authentication(&[key.key])?;
|
||||
|
||||
admin_key_authentication_challenges_helper::set(key.id, auth_state)?;
|
||||
|
||||
@ -138,9 +144,9 @@ pub async fn auth_with_key(r: &mut HttpRequestHandler) -> RequestResult {
|
||||
)?;
|
||||
|
||||
// Perform authentication
|
||||
let state = get_wan().authenticate_credential(&credentials, &state)?;
|
||||
if !state.1.user_present {
|
||||
r.forbidden("Invalid key!".to_string())?;
|
||||
let state = get_wan().finish_passkey_authentication(&credentials, &state)?;
|
||||
if !state.user_verified() {
|
||||
r.forbidden("Invalid key! (user_verified = false)".to_string())?;
|
||||
}
|
||||
|
||||
// Check key password (if any)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use mysql::serde::{Deserializer, Serializer};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use webauthn_rs::proto::Credential;
|
||||
use webauthn_rs::prelude::Passkey;
|
||||
|
||||
use crate::constants::admin::{ADMIN_ROLES_LIST, AdminRole};
|
||||
use crate::data::u64_visitor::U64Visitor;
|
||||
@ -50,7 +50,7 @@ pub struct AdminKey {
|
||||
pub admin_id: AdminID,
|
||||
pub name: String,
|
||||
pub time_add: u64,
|
||||
pub key: Credential,
|
||||
pub key: Passkey,
|
||||
pub password: Option<String>,
|
||||
}
|
||||
|
||||
@ -98,6 +98,6 @@ impl Serialize for AdminID {
|
||||
impl<'de> Deserialize<'de> for AdminID {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error> where
|
||||
D: Deserializer<'de> {
|
||||
deserializer.deserialize_u64(U64Visitor {}).map(|id| AdminID::new(id))
|
||||
deserializer.deserialize_u64(U64Visitor {}).map(AdminID::new)
|
||||
}
|
||||
}
|
@ -565,14 +565,14 @@ pub trait BaseRequestHandler {
|
||||
}
|
||||
|
||||
/// Get the response to a key register credential included in the request
|
||||
fn post_register_public_key_credential(&mut self, name: &str) -> Res<webauthn_rs::proto::RegisterPublicKeyCredential> {
|
||||
fn post_register_public_key_credential(&mut self, name: &str) -> Res<webauthn_rs::prelude::RegisterPublicKeyCredential> {
|
||||
let str = self.post_string(name)?;
|
||||
|
||||
Ok(serde_json::from_str(&str)?)
|
||||
}
|
||||
|
||||
/// Get the response to a key authentication included in the request
|
||||
fn post_auth_public_key_credential(&mut self, name: &str) -> Res<webauthn_rs::proto::PublicKeyCredential> {
|
||||
fn post_auth_public_key_credential(&mut self, name: &str) -> Res<webauthn_rs::prelude::PublicKeyCredential> {
|
||||
let str = self.post_string(name)?;
|
||||
|
||||
Ok(serde_json::from_str(&str)?)
|
||||
|
@ -2,41 +2,25 @@
|
||||
//!
|
||||
//! @author Pierre Hubert
|
||||
|
||||
use webauthn_rs::{Webauthn, WebauthnConfig};
|
||||
use webauthn_rs::{Webauthn, WebauthnBuilder};
|
||||
|
||||
use crate::data::config::conf;
|
||||
|
||||
pub struct ComunicAdminWebauthnConfig {
|
||||
origin: url::Url,
|
||||
relying_party_id: String,
|
||||
}
|
||||
|
||||
impl WebauthnConfig for ComunicAdminWebauthnConfig {
|
||||
fn get_relying_party_name(&self) -> &str {
|
||||
"ComunicAdmin"
|
||||
}
|
||||
|
||||
fn get_origin(&self) -> &url::Url {
|
||||
&self.origin
|
||||
}
|
||||
|
||||
fn get_relying_party_id(&self) -> &str {
|
||||
&self.relying_party_id
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_wan() -> Webauthn<ComunicAdminWebauthnConfig> {
|
||||
Webauthn::new(ComunicAdminWebauthnConfig {
|
||||
origin: url::Url::parse(&conf().admin_url).unwrap(),
|
||||
relying_party_id: conf().admin_url
|
||||
pub fn get_wan() -> Webauthn {
|
||||
WebauthnBuilder::new(
|
||||
conf().admin_url
|
||||
.replace("https://", "")
|
||||
.replace("http://", "")
|
||||
.split(":")
|
||||
.split(':')
|
||||
.next()
|
||||
.unwrap()
|
||||
.split("/")
|
||||
.split('/')
|
||||
.next()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
})
|
||||
.unwrap(),
|
||||
&url::Url::parse(&conf().admin_url).unwrap(),
|
||||
)
|
||||
.expect("Invalid Webauthn configuration!")
|
||||
.rp_name("ComunicAdmin")
|
||||
.build()
|
||||
.expect("Failed to build Webauthn object")
|
||||
}
|
@ -21,7 +21,7 @@ pub fn create(new_admin: &NewAdmin) -> Res<AdminID> {
|
||||
.add_str("name", &new_admin.name)
|
||||
.add_str("email", &new_admin.email)
|
||||
.insert_expect_result()
|
||||
.map(|i| AdminID::new(i))
|
||||
.map(AdminID::new)
|
||||
}
|
||||
|
||||
/// Check out whether an admin exists or not
|
||||
|
@ -3,7 +3,7 @@
|
||||
//! @author Pierre Hubert
|
||||
|
||||
use bcrypt::{DEFAULT_COST, hash_with_result};
|
||||
use webauthn_rs::proto::Credential;
|
||||
use webauthn_rs::prelude::Passkey;
|
||||
|
||||
use crate::constants::database_tables_names::ADMIN_KEYS_TABLE;
|
||||
use crate::data::admin::{AdminID, AdminKey};
|
||||
@ -12,7 +12,7 @@ use crate::helpers::database;
|
||||
use crate::utils::date_utils::time;
|
||||
|
||||
/// Save a new key in the database
|
||||
pub fn add_key(id: AdminID, name: &str, key: Credential, password: String) -> Res<u64> {
|
||||
pub fn add_key(id: AdminID, name: &str, key: Passkey, password: String) -> Res<u64> {
|
||||
database::InsertQuery::new(ADMIN_KEYS_TABLE)
|
||||
.add_admin_id("admin_id", id)
|
||||
.add_str("name", name)
|
||||
|
@ -7,11 +7,11 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use webauthn_rs::AuthenticationState;
|
||||
use webauthn_rs::prelude::PasskeyAuthentication;
|
||||
|
||||
use crate::data::error::Res;
|
||||
|
||||
static mut CACHE: Option<Arc<Mutex<HashMap<u64, AuthenticationState>>>> = None;
|
||||
static mut CACHE: Option<Arc<Mutex<HashMap<u64, PasskeyAuthentication>>>> = None;
|
||||
|
||||
/// Initialize this helper's cache
|
||||
pub fn init() {
|
||||
@ -22,7 +22,7 @@ pub fn init() {
|
||||
}
|
||||
|
||||
/// Store a new entry in the cache
|
||||
pub fn set(key_id: u64, state: AuthenticationState) -> Res {
|
||||
pub fn set(key_id: u64, state: PasskeyAuthentication) -> Res {
|
||||
let cache = unsafe {
|
||||
CACHE.as_ref().unwrap().lock()
|
||||
};
|
||||
@ -32,7 +32,7 @@ pub fn set(key_id: u64, state: AuthenticationState) -> Res {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get(key_id: u64) -> Res<Option<AuthenticationState>> {
|
||||
pub fn get(key_id: u64) -> Res<Option<PasskeyAuthentication>> {
|
||||
let cache = unsafe {
|
||||
CACHE.as_ref().unwrap().lock()
|
||||
};
|
||||
|
@ -7,12 +7,12 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use webauthn_rs::RegistrationState;
|
||||
use webauthn_rs::prelude::PasskeyRegistration;
|
||||
|
||||
use crate::data::admin::AdminID;
|
||||
use crate::data::error::Res;
|
||||
|
||||
static mut CACHE: Option<Arc<Mutex<HashMap<AdminID, RegistrationState>>>> = None;
|
||||
static mut CACHE: Option<Arc<Mutex<HashMap<AdminID, PasskeyRegistration>>>> = None;
|
||||
|
||||
/// Initialize this helper's cache
|
||||
pub fn init() {
|
||||
@ -23,7 +23,7 @@ pub fn init() {
|
||||
}
|
||||
|
||||
/// Store a new entry in the cache
|
||||
pub fn set(admin: AdminID, key: RegistrationState) -> Res {
|
||||
pub fn set(admin: AdminID, key: PasskeyRegistration) -> Res {
|
||||
let cache = unsafe {
|
||||
CACHE.as_ref().unwrap().lock()
|
||||
};
|
||||
@ -33,7 +33,7 @@ pub fn set(admin: AdminID, key: RegistrationState) -> Res {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get(admin: AdminID) -> Res<Option<RegistrationState>> {
|
||||
pub fn get(admin: AdminID) -> Res<Option<PasskeyRegistration>> {
|
||||
let cache = unsafe {
|
||||
CACHE.as_ref().unwrap().lock()
|
||||
};
|
||||
|
Reference in New Issue
Block a user