Skip to content

Commit c511746

Browse files
committed
Make debug formatting useful on credentials.
As reported in hwchen#201, the existing debug print of credentials gives no information about the underlying platform credential. This fixes that.
1 parent 8f95997 commit c511746

7 files changed

+59
-7
lines changed

src/credential.rs

+19-5
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ if matches!(persistence, credential::CredentialPersistence::UntilDelete) {
2727
}
2828
```
2929
*/
30-
use super::Result;
3130
use std::any::Any;
3231

32+
use super::Result;
33+
3334
/// The API that [credentials](Credential) implement.
3435
pub trait CredentialApi {
3536
/// Set the credential's password (a string).
@@ -66,17 +67,30 @@ pub trait CredentialApi {
6667
/// can do platform-specific things with it (e.g.,
6768
/// query its attributes in the underlying store).
6869
fn as_any(&self) -> &dyn Any;
69-
}
7070

71-
impl std::fmt::Debug for Credential {
72-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73-
self.as_any().fmt(f)
71+
/// The Debug trait call for the object.
72+
///
73+
/// This is used to implement the Debug trait on this type; it
74+
/// allows generic code to provide debug printing as provided by
75+
/// the underlying concrete object.
76+
///
77+
/// We provide a (useless) default implementation for backward
78+
/// compatibility with existing implementors who may have not
79+
/// implemented the Debug trait for their credential objects
80+
fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81+
std::fmt::Debug::fmt(self.as_any(), f)
7482
}
7583
}
7684

7785
/// A thread-safe implementation of the [Credential API](CredentialApi).
7886
pub type Credential = dyn CredentialApi + Send + Sync;
7987

88+
impl std::fmt::Debug for Credential {
89+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90+
self.debug_fmt(f)
91+
}
92+
}
93+
8094
/// A descriptor for the lifetime of stored credentials, returned from
8195
/// a credential store's [persistence](CredentialBuilderApi::persistence) call.
8296
#[non_exhaustive]

src/ios.rs

+7
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ wildcards when looking up credentials by attribute value.)
1616
On iOS, the target parameter is ignored, because there is only one keychain
1717
that can be targeted to store a generic credential.
1818
*/
19+
1920
use security_framework::base::Error;
2021
use security_framework::passwords::{
2122
delete_generic_password, get_generic_password, set_generic_password,
2223
};
24+
use std::fmt::Debug;
2325

2426
use super::credential::{Credential, CredentialApi, CredentialBuilder, CredentialBuilderApi};
2527
use super::error::{decode_password, Error as ErrorCode, Result};
@@ -87,6 +89,11 @@ impl CredentialApi for IosCredential {
8789
fn as_any(&self) -> &dyn std::any::Any {
8890
self
8991
}
92+
93+
/// Expose the concrete debug formatter for use via the [Credential] trait
94+
fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95+
std::fmt::Debug::fmt(self, f)
96+
}
9097
}
9198

9299
impl IosCredential {

src/keyutils.rs

+7
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,13 @@ Alternatively, you can drop the secret-service credential store altogether
9797
with `--no-default-features` and `--features linux-no-secret-service`.
9898
9999
*/
100+
100101
use super::credential::{
101102
Credential, CredentialApi, CredentialBuilder, CredentialBuilderApi, CredentialPersistence,
102103
};
103104
use super::error::{decode_password, Error as ErrorCode, Result};
104105
use linux_keyutils::{KeyError, KeyRing, KeyRingIdentifier};
106+
use std::fmt::Debug;
105107

106108
/// Representation of a keyutils credential.
107109
///
@@ -223,6 +225,11 @@ impl CredentialApi for KeyutilsCredential {
223225
fn as_any(&self) -> &dyn std::any::Any {
224226
self
225227
}
228+
229+
/// Expose the concrete debug formatter for use via the [Credential] trait
230+
fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
231+
std::fmt::Debug::fmt(self, f)
232+
}
226233
}
227234

228235
impl KeyutilsCredential {

src/macos.rs

+6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ name as the target parameter to `Entry::new_with_target`.
2727
Any name other than one of the OS-supplied keychains (User, Common, System, and Dynamic)
2828
will be mapped to `User`.
2929
*/
30+
3031
use security_framework::base::Error;
3132
use security_framework::os::macos::keychain::{SecKeychain, SecPreferencesDomain};
3233
use security_framework::os::macos::passwords::find_generic_password;
@@ -110,6 +111,11 @@ impl CredentialApi for MacCredential {
110111
fn as_any(&self) -> &dyn std::any::Any {
111112
self
112113
}
114+
115+
/// Expose the concrete debug formatter for use via the [Credential] trait
116+
fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117+
std::fmt::Debug::fmt(self, f)
118+
}
113119
}
114120

115121
impl MacCredential {

src/mock.rs

+6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ entry.set_password("test").expect("error has been cleared");
3434
```
3535
*/
3636
use std::cell::RefCell;
37+
use std::fmt::Debug;
3738
use std::sync::Mutex;
3839

3940
use super::credential::{
@@ -174,6 +175,11 @@ impl CredentialApi for MockCredential {
174175
fn as_any(&self) -> &dyn std::any::Any {
175176
self
176177
}
178+
179+
/// Expose the concrete debug formatter for use via the [Credential] trait
180+
fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
181+
std::fmt::Debug::fmt(self, f)
182+
}
177183
}
178184

179185
impl MockCredential {

src/secret_service.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ there is no "default" collection defined under WSL. So
7676
this keystore doesn't work "out of the box" on WSL. See the
7777
issue for more details and possible workarounds.
7878
*/
79-
use std::collections::HashMap;
80-
8179
#[cfg(not(feature = "async-secret-service"))]
8280
use dbus_secret_service::{Collection, EncryptionType, Error, Item, SecretService};
8381
#[cfg(feature = "async-secret-service")]
8482
use secret_service::{
8583
blocking::{Collection, Item, SecretService},
8684
EncryptionType, Error,
8785
};
86+
use std::collections::HashMap;
87+
use std::fmt::Debug;
8888

8989
use super::credential::{Credential, CredentialApi, CredentialBuilder, CredentialBuilderApi};
9090
use super::error::{decode_password, Error as ErrorCode, Result};
@@ -361,6 +361,11 @@ impl CredentialBuilderApi for SsCredentialBuilder {
361361
fn as_any(&self) -> &dyn std::any::Any {
362362
self
363363
}
364+
365+
/// Expose the concrete debug formatter for use via the [Credential] trait
366+
fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
367+
std::fmt::Debug::fmt(self, f)
368+
}
364369
}
365370

366371
//

src/windows.rs

+7
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ the order in which they were made. Careful testing has
2929
shown that modifying the same entry in the same (almost simultaneous) order from
3030
different threads produces different results on different runs.
3131
*/
32+
3233
use byteorder::{ByteOrder, LittleEndian};
34+
use std::fmt::Debug;
3335
use std::iter::once;
3436
use std::mem::MaybeUninit;
3537
use std::str;
@@ -166,6 +168,11 @@ impl CredentialApi for WinCredential {
166168
fn as_any(&self) -> &dyn std::any::Any {
167169
self
168170
}
171+
172+
/// Expose the concrete debug formatter for use via the [Credential] trait
173+
fn debug_fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174+
std::fmt::Debug::fmt(self, f)
175+
}
169176
}
170177

171178
impl WinCredential {

0 commit comments

Comments
 (0)