1
0
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:
2022-08-24 20:08:29 +02:00
parent 364bca03a6
commit bea1c56e44
11 changed files with 245 additions and 63 deletions

View File

@ -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(),

View File

@ -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)

View File

@ -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)
}
}

View File

@ -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)?)

View File

@ -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")
}

View File

@ -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

View File

@ -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)

View File

@ -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()
};

View File

@ -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()
};