v0.1.4-pre.013
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/src/constants.rs
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
//! Application-owned tracing targets and domains.
|
||||
|
||||
@@ -23,3 +23,5 @@ pub(crate) const TRACING_DOMAIN_DOCUMENTS: &str = "config.documents";
|
||||
pub(crate) const TRACING_DOMAIN_PROFILES: &str = "config.profiles";
|
||||
/// Structured domain for safe Config environment reports.
|
||||
pub(crate) const TRACING_DOMAIN_ENVIRONMENT: &str = "config.environment";
|
||||
/// Structured domain for explicit privileged Secret reveal operations.
|
||||
pub(crate) const TRACING_DOMAIN_SECRETS: &str = "config.secrets";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/src/errors.rs
|
||||
// version: 6
|
||||
// version: 7
|
||||
|
||||
//! Application-local error codes for the configuration desktop shell.
|
||||
|
||||
@@ -32,3 +32,8 @@ pub(crate) const ERROR_CODE_TAURI_WINDOW_OPERATION_FAILED: ksp_core_lib::ErrorCo
|
||||
|
||||
/// A Documents command requested a registered file that is not a Config-kind document.
|
||||
pub(crate) const ERROR_CODE_DOCUMENT_KIND_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "document_kind_invalid");
|
||||
/// Privileged reveal was requested for a non-Secret KSP/KSPB namespace.
|
||||
pub(crate) const ERROR_CODE_SECRET_REVEAL_REQUIRES_SECRET: ksp_core_lib::ErrorCode =
|
||||
ksp_core_lib::ErrorCode::new("config_desk", "secret_reveal_requires_secret");
|
||||
/// Privileged reveal requested an unsupported source selector.
|
||||
pub(crate) const ERROR_CODE_SECRET_REVEAL_SOURCE_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "secret_reveal_source_invalid");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/src/lib.rs
|
||||
// version: 9
|
||||
// version: 10
|
||||
|
||||
//! Tauri desktop application for managing and validating KSP configuration.
|
||||
|
||||
@@ -16,6 +16,7 @@ mod environment;
|
||||
mod errors;
|
||||
mod frontend_logging;
|
||||
mod profiles;
|
||||
mod secrets;
|
||||
mod splash;
|
||||
mod tauri;
|
||||
mod tw_main;
|
||||
@@ -32,6 +33,7 @@ pub(crate) use self::constants::TRACING_DOMAIN_DOCUMENTS;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_ENVIRONMENT;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_FRONTEND;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_PROFILES;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_SECRETS;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_WINDOWS;
|
||||
pub(crate) use self::constants::TRACING_TARGET;
|
||||
pub(crate) use self::constants::TRACING_TARGET_FRONTEND;
|
||||
@@ -53,6 +55,8 @@ pub(crate) use self::errors::ERROR_CODE_FRONTEND_LOG_TARGET_INVALID;
|
||||
pub(crate) use self::errors::ERROR_CODE_LOGGING_BOOTSTRAP_FAILED;
|
||||
pub(crate) use self::errors::ERROR_CODE_PROFILE_CONTRACT_MISSING;
|
||||
pub(crate) use self::errors::ERROR_CODE_PROFILE_PROJECTION_FAILED;
|
||||
pub(crate) use self::errors::ERROR_CODE_SECRET_REVEAL_REQUIRES_SECRET;
|
||||
pub(crate) use self::errors::ERROR_CODE_SECRET_REVEAL_SOURCE_INVALID;
|
||||
pub(crate) use self::errors::ERROR_CODE_SPLASH_ORIGIN_INVALID;
|
||||
pub(crate) use self::errors::ERROR_CODE_SPLASH_SETTING_INVALID;
|
||||
pub(crate) use self::errors::ERROR_CODE_TAURI_RUNTIME_FAILED;
|
||||
@@ -62,6 +66,8 @@ pub(crate) use self::frontend_logging::FrontendLogPayloadDto;
|
||||
pub(crate) use self::frontend_logging::emit_frontend_log_event;
|
||||
pub(crate) use self::profiles::ConfigProfileDetailDto;
|
||||
pub(crate) use self::profiles::ConfigProfileDocumentDto;
|
||||
pub(crate) use self::secrets::SecretRevealRequestDto;
|
||||
pub(crate) use self::secrets::SecretRevealResponseDto;
|
||||
pub(crate) use self::splash::SplashOrderDto;
|
||||
pub(crate) use self::splash::SplashSettings;
|
||||
pub(crate) use self::tw_main::show_and_focus as show_main_window;
|
||||
|
||||
105
crates/ksp-app-config-desk/src/secrets.rs
Normal file
105
crates/ksp-app-config-desk/src/secrets.rs
Normal file
@@ -0,0 +1,105 @@
|
||||
// file: crates/ksp-app-config-desk/src/secrets.rs
|
||||
// version: 1
|
||||
|
||||
//! Privileged, explicitly requested Config Secret reveal boundary for Config Desk.
|
||||
|
||||
use ts_rs::TS; // rust-rules: derive-import
|
||||
|
||||
/// Privileged reveal request kept separate from ordinary environment-report DTOs.
|
||||
#[derive(serde::Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/secrets/SecretRevealRequestDto.ts")]
|
||||
pub(crate) struct SecretRevealRequestDto {
|
||||
/// Secret KSP/KSPB variable to reveal.
|
||||
pub(crate) variable_name: String,
|
||||
/// Requested source: `effective` or `dotenv`.
|
||||
pub(crate) source: String,
|
||||
}
|
||||
|
||||
/// Privileged reveal response. This type deliberately does not derive `Clone` or `Debug`.
|
||||
#[derive(serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/secrets/SecretRevealResponseDto.ts")]
|
||||
pub(crate) struct SecretRevealResponseDto {
|
||||
/// Secret variable that was explicitly requested.
|
||||
pub(crate) variable_name: String,
|
||||
/// Source that was explicitly requested.
|
||||
pub(crate) source: String,
|
||||
/// Real value when the requested source contains one; never include this field in logs or ordinary application state.
|
||||
pub(crate) value: std::option::Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
enum SecretRevealSource {
|
||||
Effective,
|
||||
DotEnv,
|
||||
}
|
||||
|
||||
impl SecretRevealSource {
|
||||
fn parse(value: &str) -> ksp_core_lib::Result<Self> {
|
||||
return match value {
|
||||
"effective" => std::result::Result::Ok(Self::Effective),
|
||||
"dotenv" => std::result::Result::Ok(Self::DotEnv),
|
||||
_ => std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_SECRET_REVEAL_SOURCE_INVALID,
|
||||
"Secret reveal source must be effective or dotenv",
|
||||
)),
|
||||
};
|
||||
}
|
||||
|
||||
const fn label(self) -> &'static str {
|
||||
return match self {
|
||||
Self::Effective => "effective",
|
||||
Self::DotEnv => "dotenv",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Reveals one real Secret value only after the dedicated Tauri command has been explicitly invoked.
|
||||
pub(crate) fn reveal(state: &crate::AppState, request: SecretRevealRequestDto) -> ksp_core_lib::Result<SecretRevealResponseDto> {
|
||||
return reveal_from_management(state.config_management(), request);
|
||||
}
|
||||
|
||||
fn reveal_from_management(management: &ksp_config_lib::ConfigManagement, request: SecretRevealRequestDto) -> ksp_core_lib::Result<SecretRevealResponseDto> {
|
||||
let source = validate_request(request.variable_name.as_str(), request.source.as_str());
|
||||
let source = match source {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let value = match source {
|
||||
SecretRevealSource::Effective => management.reveal_effective_environment_value(request.variable_name.as_str()),
|
||||
SecretRevealSource::DotEnv => management.reveal_dotenv_value(request.variable_name.as_str()),
|
||||
};
|
||||
let value = match value {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET,
|
||||
domain = crate::TRACING_DOMAIN_SECRETS,
|
||||
variable_name = request.variable_name.as_str(),
|
||||
source = source.label(),
|
||||
value_present = value.is_some(),
|
||||
"privileged Config Secret reveal completed"
|
||||
);
|
||||
return std::result::Result::Ok(SecretRevealResponseDto { variable_name: request.variable_name, source: source.label().to_owned(), value });
|
||||
}
|
||||
|
||||
fn validate_request(variable_name: &str, source: &str) -> ksp_core_lib::Result<SecretRevealSource> {
|
||||
let sensitivity = ksp_config_lib::ConfigSensitivity::from_variable_name(variable_name);
|
||||
let sensitivity = match sensitivity {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
if sensitivity != ksp_config_lib::ConfigSensitivity::Secret {
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_SECRET_REVEAL_REQUIRES_SECRET,
|
||||
"Privileged reveal is restricted to KSP/KSPB Secret namespaces",
|
||||
));
|
||||
}
|
||||
return SecretRevealSource::parse(source);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "../unit_tests/secrets.rs"]
|
||||
mod tests;
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/src/tauri.rs
|
||||
// version: 10
|
||||
// version: 11
|
||||
|
||||
//! Tauri runtime assembly for the KSP configuration desktop application.
|
||||
|
||||
@@ -47,6 +47,7 @@ fn configure_commands(builder: tauri::Builder<tauri::Wry>) -> tauri::Builder<tau
|
||||
get_environment_report,
|
||||
set_environment_value,
|
||||
remove_environment_value,
|
||||
reveal_environment_value,
|
||||
emit_frontend_log,
|
||||
splash_frontend_ready
|
||||
]);
|
||||
@@ -157,6 +158,18 @@ fn remove_environment_value(
|
||||
};
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn reveal_environment_value(
|
||||
request: crate::SecretRevealRequestDto,
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
) -> std::result::Result<crate::SecretRevealResponseDto, crate::CommandErrorDto> {
|
||||
let result = crate::secrets::reveal(&state, request);
|
||||
return match result {
|
||||
std::result::Result::Ok(value) => std::result::Result::Ok(value),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(crate::CommandErrorDto::from_error(&error)),
|
||||
};
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn emit_frontend_log(payload: crate::FrontendLogPayloadDto) -> std::result::Result<(), crate::CommandErrorDto> {
|
||||
let result = crate::emit_frontend_log_event(payload);
|
||||
|
||||
Reference in New Issue
Block a user