1use std::fmt;
4
5use nextcloud_auth::BasicAuth;
6use nextcloud_sdk_core::ServerUrl;
7
8#[derive(Clone)]
13pub struct GoaAccount {
14 id: String,
15 username: String,
16 server_url: ServerUrl,
17 auth: BasicAuth,
18 presentation_identity: String,
19}
20
21impl GoaAccount {
22 pub fn new(
24 id: impl Into<String>,
25 username: impl Into<String>,
26 server_url: ServerUrl,
27 auth: BasicAuth,
28 presentation_identity: impl Into<String>,
29 ) -> Self {
30 Self {
31 id: id.into(),
32 username: username.into(),
33 server_url,
34 auth,
35 presentation_identity: presentation_identity.into(),
36 }
37 }
38
39 pub fn id(&self) -> &str {
41 &self.id
42 }
43
44 pub fn username(&self) -> &str {
46 &self.username
47 }
48
49 pub fn server_url(&self) -> &ServerUrl {
51 &self.server_url
52 }
53
54 pub fn auth(&self) -> &BasicAuth {
56 &self.auth
57 }
58
59 pub fn presentation_identity(&self) -> &str {
61 &self.presentation_identity
62 }
63}
64
65impl fmt::Debug for GoaAccount {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 f.debug_struct("GoaAccount")
68 .field("id", &self.id)
69 .field("username", &self.username)
70 .field("server_url", &self.server_url)
71 .field("auth", &"[REDACTED]")
72 .field("presentation_identity", &self.presentation_identity)
73 .finish()
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use nextcloud_auth::{AppPassword, BasicAuth, SecretString};
80 use nextcloud_sdk_core::ServerUrl;
81
82 use super::GoaAccount;
83
84 fn sample_account() -> GoaAccount {
85 let secret = SecretString::new("super-secret-password".to_owned());
86 let creds = AppPassword::new("alice", secret);
87 let auth = BasicAuth::from_app_password(creds);
88 let url = ServerUrl::parse("https://cloud.example.com").unwrap();
89
90 GoaAccount::new(
91 "account_1234",
92 "alice",
93 url,
94 auth,
95 "alice@cloud.example.com",
96 )
97 }
98
99 #[test]
100 fn getters_return_expected_values() {
101 let account = sample_account();
102
103 assert_eq!(account.id(), "account_1234");
104 assert_eq!(account.username(), "alice");
105 assert_eq!(account.server_url().as_str(), "https://cloud.example.com");
106 assert_eq!(account.presentation_identity(), "alice@cloud.example.com");
107 assert_eq!(account.auth().credentials().user(), "alice");
108 }
109
110 #[test]
111 fn debug_redacts_auth_and_secrets() {
112 let account = sample_account();
113 let debug_repr = format!("{account:?}");
114
115 assert!(debug_repr.contains("account_1234"));
116 assert!(debug_repr.contains("alice"));
117 assert!(debug_repr.contains("https://cloud.example.com"));
118 assert!(debug_repr.contains("alice@cloud.example.com"));
119 assert!(debug_repr.contains("[REDACTED]"));
120
121 assert!(!debug_repr.contains("super-secret-password"));
123 assert!(!debug_repr.contains("Basic "));
124 }
125}