Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions rust/agama-software/src/model/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
//! definition, the user configuration, etc.

use std::collections::HashMap;
use std::fmt;

use agama_utils::{
api::software::{
Expand Down Expand Up @@ -576,7 +577,7 @@ pub struct SoftwareOptions {
pub only_required: bool,
}

#[derive(Clone, Debug)]
#[derive(Clone)]
pub struct RegistrationState {
pub product: String,
pub version: String,
Expand All @@ -587,6 +588,19 @@ pub struct RegistrationState {
pub addons: Vec<Addon>,
}

impl fmt::Debug for RegistrationState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RegistrationState")
.field("product", &self.product)
.field("version", &self.version)
.field("code", &self.code.as_ref().map(|_| "[FILTERED]"))
.field("email", &self.email)
.field("url", &self.url)
.field("addons", &self.addons)
.finish()
}
}

#[derive(Clone, Debug)]
pub struct Addon {
pub id: String,
Expand Down Expand Up @@ -620,7 +634,7 @@ mod tests {

use crate::model::{
packages::ResolvableType,
state::{ResolvableSelection, SoftwareStateBuilder},
state::{RegistrationState, ResolvableSelection, SoftwareStateBuilder},
};

fn build_user_config(patterns: Option<PatternsConfig>) -> Config {
Expand Down Expand Up @@ -1052,4 +1066,31 @@ mod tests {

assert_eq!(state.repositories.len(), 3);
}

#[test]
fn test_registration_state_debug() {
let state = RegistrationState {
product: "SLES".to_string(),
version: "16.1".to_string(),
code: Some("secret_code".to_string()),
email: None,
url: None,
addons: vec![],
};

let debug_output = format!("{:?}", state);
assert!(debug_output.contains("code: Some(\"[FILTERED]\")"));
assert!(!debug_output.contains("secret_code"));

let state_no_code = RegistrationState {
product: "SLES".to_string(),
version: "16.1".to_string(),
code: None,
email: None,
url: None,
addons: vec![],
};
let debug_output_no_code = format!("{:?}", state_no_code);
assert!(debug_output_no_code.contains("code: None"));
}
}
2 changes: 2 additions & 0 deletions rust/agama-software/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ impl Service {
SoftwareState::build_from(&product, &state.config, &state.system, &self.selection)
};

tracing::info!("Wanted software state: {new_state:?}");

self.update_selinux(&new_state);

let model = self.model.clone();
Expand Down
43 changes: 42 additions & 1 deletion rust/agama-utils/src/api/software/system_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
// To contact SUSE LLC about this file by physical or electronic mail, you may
// find current contact information at www.suse.com.

use std::fmt;

use serde::Serialize;
use serde_with::skip_serializing_none;

Expand Down Expand Up @@ -69,7 +71,7 @@ pub struct Pattern {
}

#[skip_serializing_none]
#[derive(Clone, Default, Debug, Serialize, utoipa::ToSchema)]
#[derive(Clone, Default, Serialize, utoipa::ToSchema)]
pub struct RegistrationInfo {
/// Registration code.
pub code: Option<String>,
Expand All @@ -81,6 +83,17 @@ pub struct RegistrationInfo {
pub addons: Vec<AddonInfo>,
}

impl fmt::Debug for RegistrationInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RegistrationInfo")
.field("code", &self.code.as_ref().map(|_| "[FILTERED]"))
.field("email", &self.email)
.field("url", &self.url)
.field("addons", &self.addons)
.finish()
}
}

/// Addon registration
#[derive(Clone, Debug, Serialize, utoipa::ToSchema)]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -112,3 +125,31 @@ pub enum AddonRegistration {
Registered { code: Option<String> },
NotRegistered,
}

#[cfg(test)]
mod tests {
use super::RegistrationInfo;

#[test]
fn test_registration_info_debug() {
let state = RegistrationInfo {
code: Some("secret_code".to_string()),
email: Some("me@example.org".to_string()),
url: None,
addons: vec![],
};

let debug_output = format!("{:?}", state);
assert!(debug_output.contains("code: Some(\"[FILTERED]\")"));
assert!(!debug_output.contains("secret_code"));

let state_no_code = RegistrationInfo {
code: None,
email: None,
url: None,
addons: vec![],
};
let debug_output_no_code = format!("{:?}", state_no_code);
assert!(debug_output_no_code.contains("code: None"));
}
}
4 changes: 2 additions & 2 deletions rust/package/agama.changes
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
-------------------------------------------------------------------
Fri Feb 13 12:49:15 UTC 2026 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>
Wed Feb 18 11:33:59 UTC 2026 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

- Do not leak the registration codes (gh#agama-project/agama#3167).
- Do not leak the registration codes (bsc#1258221).

-------------------------------------------------------------------
Fri Feb 13 09:21:12 UTC 2026 - José Iván López González <jlopez@suse.com>
Expand Down
Loading