A fork of attic a self-hostable Nix Binary Cache server
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #51 from icewind1991/token-file

client: allow storing the client token in a separate file

authored by

Zhaofeng Li and committed by
GitHub
40b869ba 9a9e2c0c

+45 -9
+1 -1
client/src/api/mod.rs
··· 62 62 63 63 impl ApiClient { 64 64 pub fn from_server_config(config: ServerConfig) -> Result<Self> { 65 - let client = build_http_client(config.token.as_deref()); 65 + let client = build_http_client(config.token()?.as_deref()); 66 66 67 67 Ok(Self { 68 68 endpoint: Url::parse(&config.endpoint)?,
+9 -4
client/src/command/login.rs
··· 3 3 4 4 use crate::cache::ServerName; 5 5 use crate::cli::Opts; 6 - use crate::config::{Config, ServerConfig}; 6 + use crate::config::{Config, ServerConfig, ServerTokenConfig}; 7 7 8 8 /// Log into an Attic server. 9 9 #[derive(Debug, Parser)] ··· 32 32 33 33 server.endpoint = sub.endpoint.to_owned(); 34 34 35 - if sub.token.is_some() { 36 - server.token = sub.token.to_owned(); 35 + if let Some(token) = &sub.token { 36 + server.token = Some(ServerTokenConfig::Raw { 37 + token: token.clone(), 38 + }); 37 39 } 38 40 } else { 39 41 eprintln!("✍️ Configuring server \"{}\"", sub.name.as_str()); ··· 42 44 sub.name.to_owned(), 43 45 ServerConfig { 44 46 endpoint: sub.endpoint.to_owned(), 45 - token: sub.token.to_owned(), 47 + token: sub 48 + .token 49 + .to_owned() 50 + .map(|token| ServerTokenConfig::Raw { token }), 46 51 }, 47 52 ); 48 53 }
+1 -1
client/src/command/use.rs
··· 49 49 nix_config.add_trusted_public_key(&public_key); 50 50 51 51 // Modify netrc 52 - if let Some(token) = &server.token { 52 + if let Some(token) = server.token()? { 53 53 eprintln!("+ Access Token"); 54 54 55 55 let mut nix_netrc = NixNetrc::load().await?;
+34 -3
client/src/config.rs
··· 5 5 //! experience (e.g., `attic login`). 6 6 7 7 use std::collections::HashMap; 8 - use std::fs::{self, OpenOptions, Permissions}; 8 + use std::fs::{self, read_to_string, OpenOptions, Permissions}; 9 9 use std::io::Write; 10 10 use std::ops::{Deref, DerefMut}; 11 11 use std::os::unix::fs::{OpenOptionsExt, PermissionsExt}; 12 12 use std::path::PathBuf; 13 13 14 - use anyhow::{anyhow, Result}; 14 + use anyhow::{anyhow, Context, Result}; 15 15 use serde::{Deserialize, Serialize}; 16 16 use xdg::BaseDirectories; 17 17 ··· 52 52 #[derive(Debug, Clone, Deserialize, Serialize)] 53 53 pub struct ServerConfig { 54 54 pub endpoint: String, 55 - pub token: Option<String>, 55 + #[serde(flatten)] 56 + pub token: Option<ServerTokenConfig>, 57 + } 58 + 59 + impl ServerConfig { 60 + pub fn token(&self) -> Result<Option<String>> { 61 + self.token.as_ref().map(|token| token.get()).transpose() 62 + } 63 + } 64 + 65 + /// Configured server token 66 + #[derive(Debug, Clone, Deserialize, Serialize)] 67 + #[serde(untagged)] 68 + pub enum ServerTokenConfig { 69 + Raw { 70 + token: String, 71 + }, 72 + File { 73 + #[serde(rename = "token-file")] 74 + token_file: String, 75 + }, 76 + } 77 + 78 + impl ServerTokenConfig { 79 + /// Get the token either directly from the config or through the token file 80 + pub fn get(&self) -> Result<String> { 81 + match self { 82 + ServerTokenConfig::Raw { token } => Ok(token.clone()), 83 + ServerTokenConfig::File { token_file } => Ok(read_to_string(token_file) 84 + .with_context(|| format!("Failed to read token from {token_file}"))?), 85 + } 86 + } 56 87 } 57 88 58 89 /// Wrapper that automatically saves the config once dropped.