use super::super::{
errors::{invalid_params, mapped_errors_to_jsonrpc_error, params_required},
method_names,
params::{
CreateSystemAccountParams, CreateTenantParams, DeleteTenantParams,
ExcludeTenantOwnerParams, IncludeTenantOwnerParams, ListTenantParams,
},
response_kind::{
create_response_kind_to_result, delete_response_kind_to_result,
fetch_many_response_kind_to_result,
get_or_create_response_kind_to_result,
},
types::{self, JsonRpcError},
};
use crate::dtos::MyceliumProfileData;
use actix_web::web;
use myc_core::domain::dtos::tenant::TenantMetaKey;
use myc_core::use_cases::super_users::managers::{
create_system_account, create_system_roles, create_tenant, delete_tenant,
exclude_tenant_owner, include_tenant_owner, list_tenant,
};
use myc_diesel::repositories::SqlAppModule;
use myc_http_tools::SystemActor;
use shaku::HasComponent;
use std::str::FromStr;
fn parse_system_actor(s: &str) -> Option<SystemActor> {
match s {
"gatewayManager" => Some(SystemActor::GatewayManager),
"guestsManager" => Some(SystemActor::GuestsManager),
"systemManager" => Some(SystemActor::SystemManager),
_ => None,
}
}
pub async fn dispatch_managers(
profile: &MyceliumProfileData,
app_module: &web::Data<SqlAppModule>,
method: &str,
params: Option<serde_json::Value>,
) -> Result<serde_json::Value, JsonRpcError> {
match method {
method_names::MANAGERS_ACCOUNTS_CREATE_SYSTEM_ACCOUNT => {
let p: CreateSystemAccountParams =
serde_json::from_value(params.ok_or_else(params_required)?)
.map_err(|e| invalid_params(e.to_string()))?;
let actor = parse_system_actor(&p.actor).ok_or_else(|| {
invalid_params(
"actor must be gatewayManager, guestsManager, or systemManager",
)
})?;
let result = create_system_account(
profile.to_profile(),
p.name,
actor,
Box::new(&*app_module.resolve_ref()),
)
.await
.map_err(mapped_errors_to_jsonrpc_error)?;
get_or_create_response_kind_to_result(result)
}
method_names::MANAGERS_GUEST_ROLES_CREATE_SYSTEM_ROLES => {
let result = create_system_roles(
profile.to_profile(),
Box::new(&*app_module.resolve_ref()),
)
.await
.map_err(mapped_errors_to_jsonrpc_error)?;
serde_json::to_value(result).map_err(|e| JsonRpcError {
code: types::codes::INTERNAL_ERROR,
message: e.to_string(),
data: None,
})
}
method_names::MANAGERS_TENANTS_CREATE => {
let p: CreateTenantParams =
serde_json::from_value(params.ok_or_else(params_required)?)
.map_err(|e| invalid_params(e.to_string()))?;
let result = create_tenant(
profile.to_profile(),
p.name,
p.description,
p.owner_id,
Box::new(&*app_module.resolve_ref()),
Box::new(&*app_module.resolve_ref()),
)
.await
.map_err(mapped_errors_to_jsonrpc_error)?;
create_response_kind_to_result(result)
}
method_names::MANAGERS_TENANTS_LIST => {
let p: ListTenantParams = params
.map(serde_json::from_value)
.transpose()
.map_err(|e| invalid_params(e.to_string()))?
.unwrap_or_default();
let tag = match p.tag.as_ref() {
Some(t) => match t.split_once('=') {
Some((k, v)) => Some((k.to_string(), v.to_string())),
None => return Err(invalid_params("Invalid tag format")),
},
None => None,
};
let metadata = match p.metadata.as_ref() {
Some(m) => match m.split_once('=') {
Some((k, v)) => {
let key = TenantMetaKey::from_str(k).map_err(|_| {
invalid_params("Invalid metadata key")
})?;
Some((key, v.to_string()))
}
None => {
return Err(invalid_params("Invalid metadata format"))
}
},
None => None,
};
let result = list_tenant(
profile.to_profile(),
p.name,
p.owner,
metadata,
tag,
p.page_size,
p.skip,
Box::new(&*app_module.resolve_ref()),
)
.await
.map_err(mapped_errors_to_jsonrpc_error)?;
fetch_many_response_kind_to_result(result)
}
method_names::MANAGERS_TENANTS_DELETE => {
let p: DeleteTenantParams =
serde_json::from_value(params.ok_or_else(params_required)?)
.map_err(|e| invalid_params(e.to_string()))?;
let result = delete_tenant(
profile.to_profile(),
p.id,
Box::new(&*app_module.resolve_ref()),
)
.await
.map_err(mapped_errors_to_jsonrpc_error)?;
delete_response_kind_to_result(result)
}
method_names::MANAGERS_TENANTS_INCLUDE_TENANT_OWNER => {
let p: IncludeTenantOwnerParams =
serde_json::from_value(params.ok_or_else(params_required)?)
.map_err(|e| invalid_params(e.to_string()))?;
let result = include_tenant_owner(
profile.to_profile(),
p.id,
p.owner_id,
Box::new(&*app_module.resolve_ref()),
)
.await
.map_err(mapped_errors_to_jsonrpc_error)?;
create_response_kind_to_result(result)
}
method_names::MANAGERS_TENANTS_EXCLUDE_TENANT_OWNER => {
let p: ExcludeTenantOwnerParams =
serde_json::from_value(params.ok_or_else(params_required)?)
.map_err(|e| invalid_params(e.to_string()))?;
let result = exclude_tenant_owner(
profile.to_profile(),
p.id,
p.owner_id,
Box::new(&*app_module.resolve_ref()),
)
.await
.map_err(mapped_errors_to_jsonrpc_error)?;
delete_response_kind_to_result(result)
}
_ => Err(JsonRpcError {
code: types::codes::METHOD_NOT_FOUND,
message: format!("Method not found: {}", method),
data: None,
}),
}
}