Skip to content
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

Fix/auth fallback #347

Merged
merged 6 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ impl FallbackStorage {
/// does not exist
fn read_json(&self) -> Result<std::collections::HashMap<String, String>, FallbackStorageError> {
if !self.path.exists() {
tracing::warn!(
"Can't find path for fallback storage on {}",
self.path.to_string_lossy()
);
return Ok(std::collections::HashMap::new());
}
let file = std::fs::File::open(&self.path)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ pub struct AuthenticationStorage {
/// in a global dictionary in the operating system
pub store_key: String,

/// Fallback Storage
fallback_storage: fallback_storage::FallbackStorage,
/// Fallback Storage that will be used if the is no key store application available.
pub fallback_storage: fallback_storage::FallbackStorage,

/// A cache so that we don't have to access the keyring all the time
cache: Arc<Mutex<HashMap<String, Option<Authentication>>>>,
Expand Down
42 changes: 24 additions & 18 deletions crates/rattler_networking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@

//! Networking utilities for Rattler, specifically authenticating requests

use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::sync::OnceLock;

pub use authentication_storage::{authentication::Authentication, storage::AuthenticationStorage};
use reqwest::{Client, IntoUrl, Method, Url};

pub mod authentication_storage;
pub mod retry_policies;

/// A client that can be used to make authenticated requests, based on the [`reqwest::Client`]
#[derive(Clone)]
/// A client that can be used to make authenticated requests, based on the [`reqwest::Client`].
/// By default it uses the fallback storage in the default [`default_auth_store_fallback_directory`].
#[derive(Clone, Default)]
pub struct AuthenticatedClient {
/// The underlying client
client: Client,
Expand All @@ -20,12 +22,24 @@ pub struct AuthenticatedClient {
auth_storage: AuthenticationStorage,
}

impl Default for AuthenticatedClient {
/// Returns the default auth storage directory used by rattler.
/// Would be placed in $HOME/.rattler, except when there is no home then it will be put in '/rattler/'
pub fn default_auth_store_fallback_directory() -> &'static Path {
static FALLBACK_AUTH_DIR: OnceLock<PathBuf> = OnceLock::new();
FALLBACK_AUTH_DIR.get_or_init(|| {
dirs::home_dir()
.map(|home| home.join(".rattler/"))
.unwrap_or_else(|| {
tracing::warn!("using '/rattler' to store fallback authentication credentials because the home directory could not be found");
// This can only happen if the dirs lib can't find a home directory this is very unlikely.
PathBuf::from("/rattler/")
})
})
}

impl Default for AuthenticationStorage {
fn default() -> Self {
AuthenticatedClient {
client: Client::default(),
auth_storage: AuthenticationStorage::new("rattler", &PathBuf::from("~/.rattler")),
}
AuthenticationStorage::new("rattler", default_auth_store_fallback_directory())
}
}

Expand Down Expand Up @@ -113,6 +127,8 @@ impl AuthenticatedClient {

#[cfg(feature = "blocking")]
/// A blocking client that can be used to make authenticated requests, based on the [`reqwest::blocking::Client`]
/// By default it uses the fallback storage in the default [`default_auth_store_fallback_directory`].
#[derive(Default)]
pub struct AuthenticatedClientBlocking {
/// The underlying client
client: reqwest::blocking::Client,
Expand All @@ -135,16 +151,6 @@ impl AuthenticatedClientBlocking {
}
}

#[cfg(feature = "blocking")]
impl Default for AuthenticatedClientBlocking {
fn default() -> Self {
AuthenticatedClientBlocking {
client: Default::default(),
auth_storage: AuthenticationStorage::new("rattler", &PathBuf::from("~/.rattler")),
}
}
}

#[cfg(feature = "blocking")]
impl AuthenticatedClientBlocking {
/// Create a GET request builder for the given URL (see also [`reqwest::blocking::Client::get`])
Expand Down