Skip to content

Commit

Permalink
Merge pull request #51 from icewind1991/token-file
Browse files Browse the repository at this point in the history
client: allow storing the client token in a separate file
  • Loading branch information
zhaofengli authored Jan 1, 2024
2 parents 9a9e2c0 + 4badbff commit 40b869b
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 9 deletions.
2 changes: 1 addition & 1 deletion client/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub struct StructuredApiError {

impl ApiClient {
pub fn from_server_config(config: ServerConfig) -> Result<Self> {
let client = build_http_client(config.token.as_deref());
let client = build_http_client(config.token()?.as_deref());

Ok(Self {
endpoint: Url::parse(&config.endpoint)?,
Expand Down
13 changes: 9 additions & 4 deletions client/src/command/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use clap::Parser;

use crate::cache::ServerName;
use crate::cli::Opts;
use crate::config::{Config, ServerConfig};
use crate::config::{Config, ServerConfig, ServerTokenConfig};

/// Log into an Attic server.
#[derive(Debug, Parser)]
Expand Down Expand Up @@ -32,8 +32,10 @@ pub async fn run(opts: Opts) -> Result<()> {

server.endpoint = sub.endpoint.to_owned();

if sub.token.is_some() {
server.token = sub.token.to_owned();
if let Some(token) = &sub.token {
server.token = Some(ServerTokenConfig::Raw {
token: token.clone(),
});
}
} else {
eprintln!("✍️ Configuring server \"{}\"", sub.name.as_str());
Expand All @@ -42,7 +44,10 @@ pub async fn run(opts: Opts) -> Result<()> {
sub.name.to_owned(),
ServerConfig {
endpoint: sub.endpoint.to_owned(),
token: sub.token.to_owned(),
token: sub
.token
.to_owned()
.map(|token| ServerTokenConfig::Raw { token }),
},
);
}
Expand Down
2 changes: 1 addition & 1 deletion client/src/command/use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub async fn run(opts: Opts) -> Result<()> {
nix_config.add_trusted_public_key(&public_key);

// Modify netrc
if let Some(token) = &server.token {
if let Some(token) = server.token()? {
eprintln!("+ Access Token");

let mut nix_netrc = NixNetrc::load().await?;
Expand Down
37 changes: 34 additions & 3 deletions client/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
//! experience (e.g., `attic login`).
use std::collections::HashMap;
use std::fs::{self, OpenOptions, Permissions};
use std::fs::{self, read_to_string, OpenOptions, Permissions};
use std::io::Write;
use std::ops::{Deref, DerefMut};
use std::os::unix::fs::{OpenOptionsExt, PermissionsExt};
use std::path::PathBuf;

use anyhow::{anyhow, Result};
use anyhow::{anyhow, Context, Result};
use serde::{Deserialize, Serialize};
use xdg::BaseDirectories;

Expand Down Expand Up @@ -52,7 +52,38 @@ pub struct ConfigData {
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ServerConfig {
pub endpoint: String,
pub token: Option<String>,
#[serde(flatten)]
pub token: Option<ServerTokenConfig>,
}

impl ServerConfig {
pub fn token(&self) -> Result<Option<String>> {
self.token.as_ref().map(|token| token.get()).transpose()
}
}

/// Configured server token
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum ServerTokenConfig {
Raw {
token: String,
},
File {
#[serde(rename = "token-file")]
token_file: String,
},
}

impl ServerTokenConfig {
/// Get the token either directly from the config or through the token file
pub fn get(&self) -> Result<String> {
match self {
ServerTokenConfig::Raw { token } => Ok(token.clone()),
ServerTokenConfig::File { token_file } => Ok(read_to_string(token_file)
.with_context(|| format!("Failed to read token from {token_file}"))?),
}
}
}

/// Wrapper that automatically saves the config once dropped.
Expand Down

0 comments on commit 40b869b

Please sign in to comment.