mirror of
				https://gitlab.com/comunic/comunicapiv3
				synced 2025-11-04 01:24:04 +00:00 
			
		
		
		
	Can get admin roles through API
This commit is contained in:
		@@ -12,6 +12,7 @@ pub struct AdminInfoAPI {
 | 
			
		||||
    name: String,
 | 
			
		||||
    email: String,
 | 
			
		||||
    time_create: u64,
 | 
			
		||||
    roles: Vec<&'static str>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl AdminInfoAPI {
 | 
			
		||||
@@ -21,6 +22,7 @@ impl AdminInfoAPI {
 | 
			
		||||
            name: a.name.clone(),
 | 
			
		||||
            email: a.email.clone(),
 | 
			
		||||
            time_create: a.time_create,
 | 
			
		||||
            roles: a.roles.iter().map(|r| r.to_id()).collect(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/api_data/admin/admin_role_api.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/api_data/admin/admin_role_api.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
//! # Administrator role details api
 | 
			
		||||
//!
 | 
			
		||||
//! @author Pierre Hubert
 | 
			
		||||
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
 | 
			
		||||
use crate::constants::admin::AdminRoleMetadata;
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize)]
 | 
			
		||||
pub struct AdminRoleDetailsAPI {
 | 
			
		||||
    id: &'static str,
 | 
			
		||||
    name: &'static str,
 | 
			
		||||
    description: &'static str,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl AdminRoleDetailsAPI {
 | 
			
		||||
    pub fn new(r: &AdminRoleMetadata) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            id: r.id,
 | 
			
		||||
            name: r.name,
 | 
			
		||||
            description: r.description,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -7,4 +7,5 @@ pub mod admin_auth_success;
 | 
			
		||||
pub mod admin_id_api;
 | 
			
		||||
pub mod admin_info_api;
 | 
			
		||||
pub mod admin_keys_api;
 | 
			
		||||
pub mod admin_res_create_reset_token;
 | 
			
		||||
pub mod admin_res_create_reset_token;
 | 
			
		||||
pub mod admin_role_api;
 | 
			
		||||
@@ -3,41 +3,19 @@
 | 
			
		||||
//! @author Pierre Hubert
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
use crate::api_data::admin::admin_auth_options::AdminAuthOptions;
 | 
			
		||||
use crate::api_data::admin::admin_auth_success::AdminAuthSuccess;
 | 
			
		||||
use crate::api_data::admin::admin_id_api::AdminIDAPI;
 | 
			
		||||
use crate::api_data::admin::admin_info_api::AdminInfoAPI;
 | 
			
		||||
use crate::api_data::admin::admin_keys_api::AdminKeyAPI;
 | 
			
		||||
use crate::api_data::admin::admin_res_create_reset_token::AdminResCreateResetToken;
 | 
			
		||||
use crate::data::admin::{AdminKey, NewAdminGeneralSettings};
 | 
			
		||||
use crate::data::admin::NewAdminGeneralSettings;
 | 
			
		||||
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;
 | 
			
		||||
use crate::helpers::{admin_access_token_helper, admin_account_helper, admin_account_key_helper, admin_key_authentication_challenges_helper, admin_key_registration_challenges_helper};
 | 
			
		||||
use crate::helpers::{admin_access_token_helper, admin_account_helper, admin_account_key_helper};
 | 
			
		||||
use crate::routes::RequestResult;
 | 
			
		||||
use crate::utils::date_utils::time;
 | 
			
		||||
 | 
			
		||||
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)?;
 | 
			
		||||
 | 
			
		||||
        let key = keys.into_iter()
 | 
			
		||||
            .filter(|k| k.id == key_id)
 | 
			
		||||
            .next();
 | 
			
		||||
 | 
			
		||||
        match key {
 | 
			
		||||
            Some(key) => Ok(key),
 | 
			
		||||
            None => Err(self.bad_request("The key is not associated with this account!".to_string()).unwrap_err())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get admin auth options
 | 
			
		||||
pub fn get_auth_options(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    let mail = r.post_email("mail")?;
 | 
			
		||||
@@ -137,85 +115,4 @@ pub fn generate_reset_token(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    let token = admin_account_helper::create_new_reset_token(admin_id)?;
 | 
			
		||||
 | 
			
		||||
    r.set_response(AdminResCreateResetToken::new(token))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Register key
 | 
			
		||||
pub fn register_key(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    let name = r.post_string("name")?;
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
    let key = wan.register_credential(creds, state, |_| Ok(false))?;
 | 
			
		||||
 | 
			
		||||
    admin_account_key_helper::add_key(r.admin_id()?, &name, key)?;
 | 
			
		||||
 | 
			
		||||
    r.ok()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Delete an admin auth key
 | 
			
		||||
pub fn delete_auth_key(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    let admin_id = r.post_admin_id("adminID")?;
 | 
			
		||||
    let key_id = r.post_u64("keyID")?;
 | 
			
		||||
 | 
			
		||||
    if admin_id != r.admin_id()? {
 | 
			
		||||
        unimplemented!(); // TODO
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for key in admin_account_key_helper::get_admin_keys(admin_id)? {
 | 
			
		||||
        if key.id == key_id {
 | 
			
		||||
            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
 | 
			
		||||
pub fn challenge_auth_with_key(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    let key = r.post_admin_auth_key("mail", "key_id")?;
 | 
			
		||||
 | 
			
		||||
    let (challenge_response, auth_state) =
 | 
			
		||||
        get_wan().generate_challenge_authenticate(vec![key.key], None)?;
 | 
			
		||||
 | 
			
		||||
    admin_key_authentication_challenges_helper::set(key.id, auth_state)?;
 | 
			
		||||
 | 
			
		||||
    r.set_response(challenge_response)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Authenticate a user with a security key
 | 
			
		||||
pub fn auth_with_key(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    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
 | 
			
		||||
    let state = get_wan().authenticate_credential(credentials, state)?;
 | 
			
		||||
    r.some_or_bad_request(state, "Invalid key!")?;
 | 
			
		||||
 | 
			
		||||
    // Generate access token
 | 
			
		||||
    let token = admin_access_token_helper::create(key.admin_id)?;
 | 
			
		||||
 | 
			
		||||
    r.set_response(AdminAuthSuccess::new(token))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										113
									
								
								src/controllers/admin/admin_keys_controller.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								src/controllers/admin/admin_keys_controller.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
//! # Admin keys controller
 | 
			
		||||
//!
 | 
			
		||||
//! @author Pierre Hubert
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
use crate::api_data::admin::admin_auth_success::AdminAuthSuccess;
 | 
			
		||||
use crate::data::admin::AdminKey;
 | 
			
		||||
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;
 | 
			
		||||
use crate::helpers::{admin_access_token_helper, admin_account_helper, admin_account_key_helper, admin_key_authentication_challenges_helper, admin_key_registration_challenges_helper};
 | 
			
		||||
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)?;
 | 
			
		||||
 | 
			
		||||
        let key = keys.into_iter()
 | 
			
		||||
            .filter(|k| k.id == key_id)
 | 
			
		||||
            .next();
 | 
			
		||||
 | 
			
		||||
        match key {
 | 
			
		||||
            Some(key) => Ok(key),
 | 
			
		||||
            None => Err(self.bad_request("The key is not associated with this account!".to_string()).unwrap_err())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Register key
 | 
			
		||||
pub fn register_key(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    let name = r.post_string("name")?;
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
    let key = wan.register_credential(creds, state, |_| Ok(false))?;
 | 
			
		||||
 | 
			
		||||
    admin_account_key_helper::add_key(r.admin_id()?, &name, key)?;
 | 
			
		||||
 | 
			
		||||
    r.ok()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Delete an admin auth key
 | 
			
		||||
pub fn delete_auth_key(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    let admin_id = r.post_admin_id("adminID")?;
 | 
			
		||||
    let key_id = r.post_u64("keyID")?;
 | 
			
		||||
 | 
			
		||||
    if admin_id != r.admin_id()? {
 | 
			
		||||
        unimplemented!(); // TODO
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for key in admin_account_key_helper::get_admin_keys(admin_id)? {
 | 
			
		||||
        if key.id == key_id {
 | 
			
		||||
            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
 | 
			
		||||
pub fn challenge_auth_with_key(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    let key = r.post_admin_auth_key("mail", "key_id")?;
 | 
			
		||||
 | 
			
		||||
    let (challenge_response, auth_state) =
 | 
			
		||||
        get_wan().generate_challenge_authenticate(vec![key.key], None)?;
 | 
			
		||||
 | 
			
		||||
    admin_key_authentication_challenges_helper::set(key.id, auth_state)?;
 | 
			
		||||
 | 
			
		||||
    r.set_response(challenge_response)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Authenticate a user with a security key
 | 
			
		||||
pub fn auth_with_key(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    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
 | 
			
		||||
    let state = get_wan().authenticate_credential(credentials, state)?;
 | 
			
		||||
    r.some_or_bad_request(state, "Invalid key!")?;
 | 
			
		||||
 | 
			
		||||
    // Generate access token
 | 
			
		||||
    let token = admin_access_token_helper::create(key.admin_id)?;
 | 
			
		||||
 | 
			
		||||
    r.set_response(AdminAuthSuccess::new(token))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								src/controllers/admin/admin_roles_controller.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/controllers/admin/admin_roles_controller.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
//! # Admin roles controller
 | 
			
		||||
//!
 | 
			
		||||
//! @author Pierre Hubert
 | 
			
		||||
 | 
			
		||||
use crate::api_data::admin::admin_role_api::AdminRoleDetailsAPI;
 | 
			
		||||
use crate::constants::admin::ADMIN_ROLES_LIST;
 | 
			
		||||
use crate::data::base_request_handler::BaseRequestHandler;
 | 
			
		||||
use crate::data::http_request_handler::HttpRequestHandler;
 | 
			
		||||
use crate::routes::RequestResult;
 | 
			
		||||
 | 
			
		||||
pub fn get_list(r: &mut HttpRequestHandler) -> RequestResult {
 | 
			
		||||
    let res = ADMIN_ROLES_LIST.iter()
 | 
			
		||||
        .map(AdminRoleDetailsAPI::new)
 | 
			
		||||
        .collect::<Vec<AdminRoleDetailsAPI>>();
 | 
			
		||||
 | 
			
		||||
    r.set_response(res)
 | 
			
		||||
}
 | 
			
		||||
@@ -2,4 +2,6 @@
 | 
			
		||||
//!
 | 
			
		||||
//! @author Pierre Hubert
 | 
			
		||||
 | 
			
		||||
pub mod admin_account_controller;
 | 
			
		||||
pub mod admin_account_controller;
 | 
			
		||||
pub mod admin_keys_controller;
 | 
			
		||||
pub mod admin_roles_controller;
 | 
			
		||||
@@ -355,10 +355,15 @@ pub fn get_routes() -> Vec<Route> {
 | 
			
		||||
        Route::admin_post("/admin/accounts/keys", Box::new(admin_account_controller::get_keys_list)),
 | 
			
		||||
        Route::admin_post("/admin/accounts/update_general_settings", Box::new(admin_account_controller::update_general_settings)),
 | 
			
		||||
        Route::admin_post("/admin/accounts/generate_reset_token", Box::new(admin_account_controller::generate_reset_token)),
 | 
			
		||||
        Route::admin_post("/admin/accounts/challenge_register_key", Box::new(admin_account_controller::challenge_register_key)),
 | 
			
		||||
        Route::admin_post("/admin/accounts/register_key", Box::new(admin_account_controller::register_key)),
 | 
			
		||||
        Route::admin_post("/admin/accounts/delete_auth_key", Box::new(admin_account_controller::delete_auth_key)),
 | 
			
		||||
        Route::limited_admin_post_without_login("/admin/accounts/challenge_auth_with_key", Box::new(admin_account_controller::challenge_auth_with_key), LimitPolicy::ANY(10)),
 | 
			
		||||
        Route::limited_admin_post_without_login("/admin/accounts/auth_with_key", Box::new(admin_account_controller::auth_with_key), LimitPolicy::ANY(10)),
 | 
			
		||||
 | 
			
		||||
        // Admin security keys controller
 | 
			
		||||
        Route::admin_post("/admin/keys/challenge_register_key", Box::new(admin_keys_controller::challenge_register_key)),
 | 
			
		||||
        Route::admin_post("/admin/keys/register_key", Box::new(admin_keys_controller::register_key)),
 | 
			
		||||
        Route::admin_post("/admin/keys/delete_auth_key", Box::new(admin_keys_controller::delete_auth_key)),
 | 
			
		||||
        Route::limited_admin_post_without_login("/admin/keys/challenge_auth_with_key", Box::new(admin_keys_controller::challenge_auth_with_key), LimitPolicy::ANY(10)),
 | 
			
		||||
        Route::limited_admin_post_without_login("/admin/keys/auth_with_key", Box::new(admin_keys_controller::auth_with_key), LimitPolicy::ANY(10)),
 | 
			
		||||
 | 
			
		||||
        // Admin roles controller
 | 
			
		||||
        Route::admin_post("/admin/roles/list", Box::new(admin_roles_controller::get_list))
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user