1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2024-11-26 15:29:21 +00:00

Can get admin roles through API

This commit is contained in:
Pierre HUBERT 2021-05-14 18:38:46 +02:00
parent 73837553c7
commit 4365caf602
8 changed files with 173 additions and 112 deletions

View File

@ -12,6 +12,7 @@ pub struct AdminInfoAPI {
name: String, name: String,
email: String, email: String,
time_create: u64, time_create: u64,
roles: Vec<&'static str>,
} }
impl AdminInfoAPI { impl AdminInfoAPI {
@ -21,6 +22,7 @@ impl AdminInfoAPI {
name: a.name.clone(), name: a.name.clone(),
email: a.email.clone(), email: a.email.clone(),
time_create: a.time_create, time_create: a.time_create,
roles: a.roles.iter().map(|r| r.to_id()).collect(),
} }
} }
} }

View 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,
}
}
}

View File

@ -8,3 +8,4 @@ pub mod admin_id_api;
pub mod admin_info_api; pub mod admin_info_api;
pub mod admin_keys_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;

View File

@ -3,41 +3,19 @@
//! @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;
use crate::api_data::admin::admin_info_api::AdminInfoAPI; use crate::api_data::admin::admin_info_api::AdminInfoAPI;
use crate::api_data::admin::admin_keys_api::AdminKeyAPI; use crate::api_data::admin::admin_keys_api::AdminKeyAPI;
use crate::api_data::admin::admin_res_create_reset_token::AdminResCreateResetToken; 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::base_request_handler::BaseRequestHandler;
use crate::data::error::Res;
use crate::data::http_request_handler::HttpRequestHandler; 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};
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; use crate::routes::RequestResult;
use crate::utils::date_utils::time; 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 /// Get admin auth options
pub fn get_auth_options(r: &mut HttpRequestHandler) -> RequestResult { pub fn get_auth_options(r: &mut HttpRequestHandler) -> RequestResult {
let mail = r.post_email("mail")?; let mail = r.post_email("mail")?;
@ -138,84 +116,3 @@ pub fn generate_reset_token(r: &mut HttpRequestHandler) -> RequestResult {
r.set_response(AdminResCreateResetToken::new(token)) 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))
}

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

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

View File

@ -3,3 +3,5 @@
//! @author Pierre Hubert //! @author Pierre Hubert
pub mod admin_account_controller; pub mod admin_account_controller;
pub mod admin_keys_controller;
pub mod admin_roles_controller;

View File

@ -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/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/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/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)), // Admin security keys controller
Route::admin_post("/admin/accounts/delete_auth_key", Box::new(admin_account_controller::delete_auth_key)), Route::admin_post("/admin/keys/challenge_register_key", Box::new(admin_keys_controller::challenge_register_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::admin_post("/admin/keys/register_key", Box::new(admin_keys_controller::register_key)),
Route::limited_admin_post_without_login("/admin/accounts/auth_with_key", Box::new(admin_account_controller::auth_with_key), LimitPolicy::ANY(10)), 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))
] ]
} }