1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2025-03-14 01:42:37 +00:00
comunicapiv3/src/controllers/admin/admin_keys_controller.rs

180 lines
5.4 KiB
Rust
Raw Normal View History

2021-05-14 18:38:46 +02:00
//! # Admin keys controller
//!
//! @author Pierre Hubert
2021-07-11 17:54:15 +02:00
use bcrypt::verify;
2022-08-24 20:08:29 +02:00
use webauthn_rs::prelude::Uuid;
2021-07-11 17:54:15 +02:00
2021-05-14 18:38:46 +02:00
use crate::api_data::admin::admin_auth_success::AdminAuthSuccess;
2021-07-10 19:09:54 +02:00
use crate::api_data::admin::admin_keys_api::AdminKeyAPI;
use crate::constants::admin::AdminRole;
2021-05-14 18:38:46 +02:00
use crate::data::admin::AdminKey;
2021-07-10 19:09:54 +02:00
use crate::data::admin_action_log::AdminAction;
2021-05-14 18:38:46 +02:00
use crate::data::base_request_handler::BaseRequestHandler;
use crate::data::error::Res;
use crate::data::http_request_handler::HttpRequestHandler;
use crate::data::webauthn_config::get_wan;
2021-07-10 19:09:54 +02:00
use crate::helpers::admin_log_helper::log_admin_action;
2023-05-31 19:10:05 +02:00
use crate::helpers::{
admin_access_token_helper, admin_account_helper, admin_account_key_helper,
admin_key_authentication_challenges_helper, admin_key_registration_challenges_helper,
};
2021-05-14 18:38:46 +02:00
use crate::routes::RequestResult;
impl HttpRequestHandler {
pub fn post_admin_auth_key(&mut self, name_mail: &str, name_key_id: &str) -> Res<AdminKey> {
let mail = self.post_string(name_mail)?;
let key_id = self.post_u64(name_key_id)?;
let admin = admin_account_helper::find_admin_by_email(&mail)?;
let keys = admin_account_key_helper::get_admin_keys(admin.id)?;
2023-05-31 19:10:05 +02:00
let key = keys.into_iter().find(|k| k.id == key_id);
2021-05-14 18:38:46 +02:00
match key {
Some(key) => Ok(key),
2023-05-31 19:10:05 +02:00
None => Err(self
.bad_request("The key is not associated with this account!".to_string())
.unwrap_err()),
2021-05-14 18:38:46 +02:00
}
}
}
2021-05-14 18:45:48 +02:00
/// Get an admin keys
2022-03-11 21:56:08 +01:00
pub async fn get_keys_list(r: &mut HttpRequestHandler) -> RequestResult {
2021-05-14 18:45:48 +02:00
let admin_id = r.post_admin_id("id")?;
if admin_id != r.admin_id()? {
2021-05-15 10:07:11 +02:00
r.check_admin_has_role(AdminRole::MANAGE_ADMINS)?;
2021-05-14 18:45:48 +02:00
}
let keys = admin_account_key_helper::get_admin_keys(admin_id)?;
2023-05-31 19:10:05 +02:00
r.set_response(
keys.iter()
.map(AdminKeyAPI::new)
.collect::<Vec<AdminKeyAPI>>(),
)
2021-05-14 18:45:48 +02:00
}
2021-05-14 18:38:46 +02:00
/// Generate a challenge to register a new key
2022-03-11 21:56:08 +01:00
pub async fn challenge_register_key(r: &mut HttpRequestHandler) -> RequestResult {
2022-03-09 18:45:34 +01:00
let wan = get_wan();
2021-05-14 18:38:46 +02:00
2022-08-24 20:08:29 +02:00
let user_info = admin_account_helper::find_admin_by_id(r.admin_id()?)?;
2023-05-31 19:10:05 +02:00
let (res, state) =
wan.start_passkey_registration(Uuid::new_v4(), &user_info.name, &user_info.name, None)?;
2021-05-14 18:38:46 +02:00
admin_key_registration_challenges_helper::set(r.admin_id()?, state)?;
r.set_response(res)
}
/// Register key
2022-03-11 21:56:08 +01:00
pub async fn register_key(r: &mut HttpRequestHandler) -> RequestResult {
2021-07-11 13:49:59 +02:00
let key_name = r.post_string("name")?;
2021-07-11 17:54:15 +02:00
let key_password = r.post_string("password")?;
2021-05-14 18:38:46 +02:00
let creds = r.post_register_public_key_credential("key")?;
let state = r.some_or_internal_error(
admin_key_registration_challenges_helper::get(r.admin_id()?)?,
"No challenge found!",
)?;
let wan = get_wan();
2022-08-24 20:08:29 +02:00
let key = wan.finish_passkey_registration(&creds, &state)?;
2021-05-14 18:38:46 +02:00
2022-08-24 20:08:29 +02:00
let key_id = admin_account_key_helper::add_key(r.admin_id()?, &key_name, key, key_password)?;
2021-05-14 18:38:46 +02:00
2023-05-31 19:10:05 +02:00
log_admin_action(
r.admin_id()?,
&r.remote_ip(),
AdminAction::RegisteredAdminKey {
key_id,
key_name,
target: r.admin_id()?,
},
)?;
2021-07-10 19:09:54 +02:00
2021-05-14 18:38:46 +02:00
r.ok()
}
/// Delete an admin auth key
2022-03-11 21:56:08 +01:00
pub async fn delete_auth_key(r: &mut HttpRequestHandler) -> RequestResult {
2021-05-14 18:38:46 +02:00
let admin_id = r.post_admin_id("adminID")?;
let key_id = r.post_u64("keyID")?;
if admin_id != r.admin_id()? {
2022-03-12 08:55:58 +01:00
r.check_admin_has_role(AdminRole::MANAGE_ADMINS)?;
2021-05-14 18:38:46 +02:00
}
for key in admin_account_key_helper::get_admin_keys(admin_id)? {
if key.id == key_id {
2023-05-31 19:10:05 +02:00
log_admin_action(
r.admin_id()?,
&r.remote_ip(),
AdminAction::DeletedAdminKey {
key_id,
key_name: key.name.to_string(),
target: admin_id,
},
)?;
2021-07-10 19:09:54 +02:00
2021-05-14 18:38:46 +02:00
admin_account_key_helper::delete_key(key)?;
return r.ok();
}
}
r.not_found("Requested key was not found!".to_string())
}
/// Generate a challenge to authenticate with a security key
2022-03-11 21:56:08 +01:00
pub async fn challenge_auth_with_key(r: &mut HttpRequestHandler) -> RequestResult {
2021-05-14 18:38:46 +02:00
let key = r.post_admin_auth_key("mail", "key_id")?;
2023-05-31 19:10:05 +02:00
let (challenge_response, auth_state) = get_wan().start_passkey_authentication(&[key.key])?;
2021-05-14 18:38:46 +02:00
admin_key_authentication_challenges_helper::set(key.id, auth_state)?;
r.set_response(challenge_response)
}
/// Authenticate a user with a security key
2022-03-11 21:56:08 +01:00
pub async fn auth_with_key(r: &mut HttpRequestHandler) -> RequestResult {
2021-05-14 18:38:46 +02:00
let key = r.post_admin_auth_key("mail", "key_id")?;
let credentials = r.post_auth_public_key_credential("credential")?;
let state = r.some_or_internal_error(
admin_key_authentication_challenges_helper::get(key.id)?,
"Associated authentication state not found!",
)?;
// Perform authentication
2022-08-24 20:11:16 +02:00
get_wan().finish_passkey_authentication(&credentials, &state)?;
2021-05-14 18:38:46 +02:00
2021-07-11 17:54:15 +02:00
// Check key password (if any)
if let Some(pass_hash) = key.password {
let password = r.post_string("password")?;
if !verify(password, &pass_hash)? {
r.forbidden("Bad key password!".to_string())?;
}
}
2021-05-14 18:38:46 +02:00
// Generate access token
let token = admin_access_token_helper::create(key.admin_id)?;
2023-05-31 19:10:05 +02:00
log_admin_action(
key.admin_id,
&r.remote_ip(),
AdminAction::AuthWithAccessKey {
key: key.name,
key_id: key.id,
},
)?;
2021-07-10 19:09:54 +02:00
2021-05-14 18:38:46 +02:00
r.set_response(AdminAuthSuccess::new(token))
2023-05-31 19:10:05 +02:00
}