forked from nix-community/nix-init
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcfg.rs
More file actions
85 lines (74 loc) · 2.51 KB
/
Copy pathcfg.rs
File metadata and controls
85 lines (74 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use std::{fs, path::PathBuf};
use anyhow::{Context, Result};
use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION};
use rustc_hash::FxHashMap;
use secrecy::{ExposeSecret, SecretString};
use serde::Deserialize;
use tokio::process::Command;
use xdg::BaseDirectories;
use crate::utils::{CommandExt, ResultExt};
#[derive(Default, Deserialize)]
#[serde(default, rename_all = "kebab-case")]
pub struct Config {
pub commit: bool,
pub maintainers: Vec<String>,
pub nixpkgs: Option<String>,
pub access_tokens: AccessTokens,
}
#[derive(Default, Deserialize)]
pub struct AccessTokens(FxHashMap<String, AccessToken>);
impl AccessTokens {
pub async fn insert_header(&mut self, headers: &mut HeaderMap, host: &str) {
let value = match self.0.get(host) {
Some(AccessToken::Text(token)) => format!("Bearer {}", token.expose_secret()),
Some(AccessToken::Command { command }) => {
let mut args = command.iter();
let Some(cmd) = args.next() else {
return;
};
let Some(stdout) = Command::new(cmd).args(args).get_stdout().await.ok_warn() else {
return;
};
let Some(token) = String::from_utf8(stdout).ok_warn() else {
return;
};
format!("Bearer {}", token.trim())
}
Some(AccessToken::File { file }) => {
let Some(token) = fs::read_to_string(file).ok_warn() else {
return;
};
format!("Bearer {}", token.trim())
}
None => return,
};
let Some(mut value) = HeaderValue::from_str(&value).ok_warn() else {
return;
};
value.set_sensitive(true);
headers.insert(AUTHORIZATION, value);
}
}
#[derive(Deserialize)]
#[serde(untagged)]
enum AccessToken {
Text(SecretString),
Command { command: Vec<String> },
File { file: PathBuf },
}
pub fn load_config(cfg: Option<PathBuf>) -> Result<Config> {
Ok(cfg
.or_else(|| {
BaseDirectories::with_prefix("nix-init")
.ok()
.and_then(|dirs| dirs.find_config_file("config.toml"))
})
.map(|cfg| {
anyhow::Ok(
toml::from_str(&fs::read_to_string(cfg).context("failed to read config file")?)
.context("failed to parse config file")?,
)
})
.transpose()?
.unwrap_or_default())
}