mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2024-11-25 23:09:22 +00:00
Can generate admin key enrollment challenge
This commit is contained in:
parent
158d35171d
commit
70860ab184
45
Cargo.lock
generated
45
Cargo.lock
generated
@ -816,6 +816,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"sha1",
|
"sha1",
|
||||||
"tokio 0.2.25",
|
"tokio 0.2.25",
|
||||||
|
"webauthn-rs",
|
||||||
"webpage",
|
"webpage",
|
||||||
"webrtc-sdp",
|
"webrtc-sdp",
|
||||||
"yaml-rust",
|
"yaml-rust",
|
||||||
@ -1401,6 +1402,12 @@ dependencies = [
|
|||||||
"tracing-futures",
|
"tracing-futures",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "half"
|
||||||
|
version = "1.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
@ -2948,6 +2955,25 @@ dependencies = [
|
|||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_bytes"
|
||||||
|
version = "0.11.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_cbor"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
|
||||||
|
dependencies = [
|
||||||
|
"half",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.123"
|
version = "1.0.123"
|
||||||
@ -3798,6 +3824,25 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webauthn-rs"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dca232368e409a186d2cc0a83380398429a5b6c39608143c2a9bcc16e96b08d0"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.12.3",
|
||||||
|
"log",
|
||||||
|
"nom",
|
||||||
|
"openssl",
|
||||||
|
"rand 0.7.3",
|
||||||
|
"serde",
|
||||||
|
"serde_bytes",
|
||||||
|
"serde_cbor",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpage"
|
name = "webpage"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -40,4 +40,5 @@ mp4 = "0.8.1"
|
|||||||
zip = "0.5.10"
|
zip = "0.5.10"
|
||||||
webpage = "1.2.0"
|
webpage = "1.2.0"
|
||||||
gouth = "0.2.0"
|
gouth = "0.2.0"
|
||||||
tokio = { version = "0.2" }
|
tokio = { version = "0.2" }
|
||||||
|
webauthn-rs = "0.2.5"
|
@ -2,6 +2,8 @@
|
|||||||
//!
|
//!
|
||||||
//! @author Pierre Hubert
|
//! @author Pierre Hubert
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use crate::api_data::admin::admin_auth_options::AdminAuthOptions;
|
use crate::api_data::admin::admin_auth_options::AdminAuthOptions;
|
||||||
use crate::api_data::admin::admin_auth_success::AdminAuthSuccess;
|
use crate::api_data::admin::admin_auth_success::AdminAuthSuccess;
|
||||||
use crate::api_data::admin::admin_id_api::AdminIDAPI;
|
use crate::api_data::admin::admin_id_api::AdminIDAPI;
|
||||||
@ -9,7 +11,8 @@ use crate::api_data::admin::admin_info_api::AdminInfoAPI;
|
|||||||
use crate::data::admin::NewAdminGeneralSettings;
|
use crate::data::admin::NewAdminGeneralSettings;
|
||||||
use crate::data::base_request_handler::BaseRequestHandler;
|
use crate::data::base_request_handler::BaseRequestHandler;
|
||||||
use crate::data::http_request_handler::HttpRequestHandler;
|
use crate::data::http_request_handler::HttpRequestHandler;
|
||||||
use crate::helpers::{admin_access_token_helper, admin_account_helper};
|
use crate::data::webauthn_config::get_wan;
|
||||||
|
use crate::helpers::{admin_access_token_helper, admin_account_helper, admin_key_registration_challenges_helper};
|
||||||
use crate::routes::RequestResult;
|
use crate::routes::RequestResult;
|
||||||
use crate::utils::date_utils::time;
|
use crate::utils::date_utils::time;
|
||||||
|
|
||||||
@ -89,4 +92,15 @@ pub fn update_general_settings(r: &mut HttpRequestHandler) -> RequestResult {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
r.ok()
|
r.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate a challenge to register a new key
|
||||||
|
pub fn challenge_register_key(r: &mut HttpRequestHandler) -> RequestResult {
|
||||||
|
let mut wan = get_wan();
|
||||||
|
|
||||||
|
let (res, state) = wan.generate_challenge_register(&r.admin_id()?.id_str(), None)?;
|
||||||
|
|
||||||
|
admin_key_registration_challenges_helper::set(r.admin_id()?, state)?;
|
||||||
|
|
||||||
|
r.set_response(res)
|
||||||
}
|
}
|
@ -13,6 +13,10 @@ impl AdminID {
|
|||||||
pub fn id(&self) -> u64 {
|
pub fn id(&self) -> u64 {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn id_str(&self) -> String {
|
||||||
|
format!("{}", self.0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NewAdmin {
|
pub struct NewAdmin {
|
||||||
@ -47,12 +51,12 @@ pub struct AdminKey {
|
|||||||
pub struct AdminAccessToken {
|
pub struct AdminAccessToken {
|
||||||
pub token: String,
|
pub token: String,
|
||||||
pub id: AdminID,
|
pub id: AdminID,
|
||||||
pub last_refresh: u64
|
pub last_refresh: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// New admin general settings
|
/// New admin general settings
|
||||||
pub struct NewAdminGeneralSettings {
|
pub struct NewAdminGeneralSettings {
|
||||||
pub id: AdminID,
|
pub id: AdminID,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub email: String
|
pub email: String,
|
||||||
}
|
}
|
@ -41,4 +41,5 @@ pub mod call_signal;
|
|||||||
pub mod new_notifications_settings;
|
pub mod new_notifications_settings;
|
||||||
pub mod push_notification;
|
pub mod push_notification;
|
||||||
pub mod presence;
|
pub mod presence;
|
||||||
pub mod admin;
|
pub mod admin;
|
||||||
|
pub mod webauthn_config;
|
36
src/data/webauthn_config.rs
Normal file
36
src/data/webauthn_config.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//! # Webauthn config
|
||||||
|
//!
|
||||||
|
//! @author Pierre Hubert
|
||||||
|
|
||||||
|
use webauthn_rs::{Webauthn, WebauthnConfig};
|
||||||
|
|
||||||
|
use crate::data::config::conf;
|
||||||
|
|
||||||
|
pub struct ComunicAdminWebauthnConfig {}
|
||||||
|
|
||||||
|
impl WebauthnConfig for ComunicAdminWebauthnConfig {
|
||||||
|
fn get_relying_party_name(&self) -> String {
|
||||||
|
"ComunicAdmin".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_origin(&self) -> &String {
|
||||||
|
&conf().admin_url
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_relying_party_id(&self) -> String {
|
||||||
|
self.get_origin()
|
||||||
|
.replace("https://", "")
|
||||||
|
.replace("http://", "")
|
||||||
|
.split(":")
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.split("/")
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_wan() -> Webauthn<ComunicAdminWebauthnConfig> {
|
||||||
|
Webauthn::new(ComunicAdminWebauthnConfig {})
|
||||||
|
}
|
@ -13,7 +13,7 @@ use crate::utils::date_utils::time;
|
|||||||
|
|
||||||
static mut CACHE: Option<Arc<Mutex<HashMap<AdminID, AdminAccessToken>>>> = None;
|
static mut CACHE: Option<Arc<Mutex<HashMap<AdminID, AdminAccessToken>>>> = None;
|
||||||
|
|
||||||
/// Initialize this helper
|
/// Initialize this helper's cache
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let map = HashMap::new();
|
let map = HashMap::new();
|
||||||
|
34
src/helpers/admin_key_registration_challenges_helper.rs
Normal file
34
src/helpers/admin_key_registration_challenges_helper.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
//! # Administrators key registration challenges helper
|
||||||
|
//!
|
||||||
|
//! Allows to temporarily stores keys registration challenges
|
||||||
|
//!
|
||||||
|
//! @author Pierre Hubert
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use webauthn_rs::RegistrationState;
|
||||||
|
|
||||||
|
use crate::data::admin::AdminID;
|
||||||
|
use crate::data::error::Res;
|
||||||
|
|
||||||
|
static mut CACHE: Option<Arc<Mutex<HashMap<AdminID, RegistrationState>>>> = None;
|
||||||
|
|
||||||
|
/// Initialize this helper's cache
|
||||||
|
pub fn init() {
|
||||||
|
unsafe {
|
||||||
|
let map = HashMap::new();
|
||||||
|
CACHE = Some(Arc::new(Mutex::new(map)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Store a new entry in the cache
|
||||||
|
pub fn set(admin: AdminID, key: RegistrationState) -> Res {
|
||||||
|
let cache = unsafe {
|
||||||
|
CACHE.as_ref().unwrap().lock()
|
||||||
|
};
|
||||||
|
|
||||||
|
cache?.insert(admin, key);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -23,4 +23,5 @@ pub mod independent_push_notifications_service_helper;
|
|||||||
pub mod firebase_notifications_helper;
|
pub mod firebase_notifications_helper;
|
||||||
pub mod forez_presence_helper;
|
pub mod forez_presence_helper;
|
||||||
pub mod admin_account_helper;
|
pub mod admin_account_helper;
|
||||||
pub mod admin_access_token_helper;
|
pub mod admin_access_token_helper;
|
||||||
|
pub mod admin_key_registration_challenges_helper;
|
@ -353,5 +353,6 @@ pub fn get_routes() -> Vec<Route> {
|
|||||||
Route::admin_post("/admin/accounts/id", Box::new(admin_account_controller::get_admin_id)),
|
Route::admin_post("/admin/accounts/id", Box::new(admin_account_controller::get_admin_id)),
|
||||||
Route::admin_post("/admin/accounts/info", Box::new(admin_account_controller::get_admin_info)),
|
Route::admin_post("/admin/accounts/info", Box::new(admin_account_controller::get_admin_info)),
|
||||||
Route::admin_post("/admin/accounts/update_general_settings", Box::new(admin_account_controller::update_general_settings)),
|
Route::admin_post("/admin/accounts/update_general_settings", Box::new(admin_account_controller::update_general_settings)),
|
||||||
|
Route::admin_post("/admin/accounts/challenge_register_key", Box::new(admin_account_controller::challenge_register_key))
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -17,7 +17,7 @@ use crate::controllers::{rtc_relay_controller, user_ws_controller};
|
|||||||
use crate::data::base_request_handler::{BaseRequestHandler, PostFile, RequestValue};
|
use crate::data::base_request_handler::{BaseRequestHandler, PostFile, RequestValue};
|
||||||
use crate::data::config::Config;
|
use crate::data::config::Config;
|
||||||
use crate::data::http_request_handler::HttpRequestHandler;
|
use crate::data::http_request_handler::HttpRequestHandler;
|
||||||
use crate::helpers::{api_helper, requests_limit_helper, admin_access_token_helper};
|
use crate::helpers::{admin_access_token_helper, admin_key_registration_challenges_helper, api_helper, requests_limit_helper};
|
||||||
use crate::routes::{get_routes, RequestResult, Route, RouteScope};
|
use crate::routes::{get_routes, RequestResult, Route, RouteScope};
|
||||||
use crate::routes::Method::{GET, POST};
|
use crate::routes::Method::{GET, POST};
|
||||||
use crate::utils::user_data_utils::user_data_path;
|
use crate::utils::user_data_utils::user_data_path;
|
||||||
@ -221,7 +221,7 @@ fn process_simple_route(route: &Route, req: &mut HttpRequestHandler) -> RequestR
|
|||||||
if route.need_login || req.has_post_parameter("token") {
|
if route.need_login || req.has_post_parameter("token") {
|
||||||
req.check_user_token()?;
|
req.check_user_token()?;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
// "Admin" user scope
|
// "Admin" user scope
|
||||||
RouteScope::ADMIN => {
|
RouteScope::ADMIN => {
|
||||||
@ -234,7 +234,6 @@ fn process_simple_route(route: &Route, req: &mut HttpRequestHandler) -> RequestR
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let res: RequestResult = (route.func)(req);
|
let res: RequestResult = (route.func)(req);
|
||||||
|
|
||||||
requests_limit_helper::trigger_after(res.is_ok(), req, route)?;
|
requests_limit_helper::trigger_after(res.is_ok(), req, route)?;
|
||||||
@ -350,8 +349,8 @@ pub async fn start_server(conf: &Config) -> std::io::Result<()> {
|
|||||||
|
|
||||||
// Initialize limit helper
|
// Initialize limit helper
|
||||||
requests_limit_helper::init();
|
requests_limit_helper::init();
|
||||||
|
|
||||||
admin_access_token_helper::init();
|
admin_access_token_helper::init();
|
||||||
|
admin_key_registration_challenges_helper::init();
|
||||||
|
|
||||||
let addr = conf.server_listen_address();
|
let addr = conf.server_listen_address();
|
||||||
println!("Start to listen on http://{}/", addr);
|
println!("Start to listen on http://{}/", addr);
|
||||||
|
Loading…
Reference in New Issue
Block a user