-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Configurable keyring backends #278
Configurable keyring backends #278
Conversation
This refactors `warg_client::keyring` to make everything a method of a `Keyring` struct which can support multiple `CredentialBuilder`s. Currently, all CLI commands still just use the system default everywhere, but next, a config option can be added to customize it.
8a7570a
to
01e3d40
Compare
Create a `KeyringError` type providing structured information about what went wrong. In the case of a platform error when using the secret-service backend, provide a tip on how to remedy it.
I'm marking this ready for review. The |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code lgtm; cc @calvinrp who has worked on keyring more recently
pub type Result<T, E = KeyringError> = std::result::Result<T, E>; | ||
|
||
impl Keyring { | ||
#[cfg(target_os = "linux")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't think it worth pulling in the dependency just to use it in this one place where it barely provides any simplification. But if it gets pulled in later for wider use then, yes, this should be refactored.
if let Some(ref backend) = config.keyring_backend { | ||
Self::new(backend.as_str()) | ||
} else { | ||
Self::new(Self::SUPPORTED_BACKENDS[0]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Self::new(Self::SUPPORTED_BACKENDS[0]) | |
Self::new(Self::DEFAULT_BACKEND) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calvin already merged, so I'll fix this in my next PR.
pub const DEFAULT_BACKEND: &'static str = Self::SUPPORTED_BACKENDS[0]; | ||
|
||
/// Returns a human-readable description of a keyring backend. | ||
pub fn describe_backend(backend: &str) -> &'static str { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be difficult to make backend
an enum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered this but decided it would create more problems than it would solve. The set of supported backends is platform-dependent, so there would be a distinction between the enumeration of all understood backend identifiers, and the subset of those which are supported on the user's platform. So there would be a design trade-off between:
- Defining two separate enums, one which covers all backends and one which covers those which are supported on the platform.
- Defining only the supported enum, and needing a bunch of conditional attributes every time you want to match on it.
- Defining only the all-backends enum, and putting an
is_supported(&self) -> bool
method on it.
Then we have to decide how exactly we want our Serialize
and Deserialize
implementations to work and which type they should use, and probably put custom error reporting into this traits to not be too cryptic if the user copies a configuration file from one system to another where the backend isn't supported. Altogether it didn't seem worth it, so I just kept this stringly typed.
Thank you! This looks great. |
This adds support for storing warg credentials as flat files in the warg config directory, following up on #278.
Makes keyring backends user-selectable, as discussed in #271 (comment).
client::keyring
functions into aKeyring
struct which can be instantiated with a backend selection.secret-service
backend isn't working.flat-file
backend that stores keys in plaintext alongside the config file.