Skip to content

Commit

Permalink
refactor(config)!: simplify secrets config
Browse files Browse the repository at this point in the history
Internally tag the `Secrets` enum to simplify configurations.
Previously, providing secrets in the main config was quite the hassle:
```toml
[secrets.Plaintext.github]
token = "token"
```
This implicitly uses the `Plaintext` auth option, to provide secrets
from the main config directly. Having a more explicit (and simpler) way
to configure this makes configuration less confusing.

Thus, make auth configuration internally tagged. The config now accepts
a `secrets.type` which can be one of "Plaintext", "SecretsFile", or
"Keyring".

BREAKING CHANGE: Old configurations will break. Users will need to
change the `secrets` section of their configuration:
```toml
[secrets]
type = "Keyring"
```
Replaces the old `secrets = "Keyring" to use the system keyring to store
secrets.
```toml
[secrets]
type = "SecretsFile"
file = "path/to/file.toml"
```
Replaces the old way to store secrets in a separate plaintext secrets
file.
```toml
[secrets]
type = "Plaintext"

[secrets.your_remote]
token = "token"
[secrets.remote]
username = "user"
password = "password"
```
Replaces the old way to store secrets inline. Instead of the old
`[secrets.Plaintext.<provider>`, the config now directly uses
`[secrets.<provider>`, with a section to denote the type to use
(`secrets.type`).
  • Loading branch information
benpueschel committed Aug 2, 2024
1 parent 3be625f commit 018f00f
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 10 deletions.
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,18 +137,25 @@ The configuration file is a TOML file with the following structure:
# On Linux, you will need to have a keyring daemon,
# like gnome-keyring, installed and running.
# On MacOS and Windows, the keyring should work out of the box.
secrets = "Keyring"
[secrets]
type = "Keyring"

# You can also store access tokens in a plaintext file:
# Please note that this is not recommended for security reasons.
#secrets.SecretsFile = "~/.config/gritty/secrets.toml"
#
# [secrets]
# type = "SecretsFile"
# file = "~/.config/gritty/secrets.toml"

# You can also store access tokens directly in the config file:
# Please note that this is by far the least secure option to store your tokens.
#[secrets.Plaintext.github]
#token = "your_access_token"
#[secrets.Plaintext.gitea]
#token = "your_access_token"
#
# [secrets]
# type = "Plaintext"
# [secrets.github]
# token = "your_access_token"
# [secrets.gitea]
# token = "your_access_token"

# You can add as many remotes as you like. The name of the remote is
# specified in square brackets after the `remotes` keyword. If you want the
Expand Down
2 changes: 1 addition & 1 deletion src/commands/create_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,5 +205,5 @@ fn ask_for_secrets_file() -> Result<Secrets> {
if !input.is_empty() {
path = input;
}
Ok(Secrets::SecretsFile(path))
Ok(Secrets::SecretsFile { file: path })
}
9 changes: 6 additions & 3 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ pub struct GitRemoteConfig {

pub type InlineSecrets = HashMap<String, AuthConfig>;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "type")]
pub enum Secrets {
/// Use the system keyring to store secrets.
/// This works on Linux, macOS, Windows, and probably on BSD variants.
#[cfg(feature = "keyring")]
Keyring,
SecretsFile(String),
SecretsFile {
file: String,
},
Plaintext(InlineSecrets),
}

Expand Down Expand Up @@ -131,7 +134,7 @@ impl Config {
self.save()?;
Ok(())
}
Secrets::SecretsFile(file) => {
Secrets::SecretsFile { file } => {
let file = file.replace('~', env::var("HOME").unwrap().as_str());
let path = Path::new(&file);
fs::create_dir_all(path.parent().unwrap())?;
Expand Down Expand Up @@ -181,7 +184,7 @@ impl Config {
)));
}
}
Secrets::SecretsFile(file) => {
Secrets::SecretsFile { file } => {
let file = file.replace('~', env::var("HOME").unwrap().as_str());
if !Path::new(&file).exists() {
return Err(Error::not_found(format!(
Expand Down

0 comments on commit 018f00f

Please sign in to comment.