From 1abada3a84de3a259b1552df536788609e2d28b6 Mon Sep 17 00:00:00 2001 From: Drazen Urch Date: Sat, 2 May 2020 10:42:29 +0200 Subject: [PATCH] Support anonymous credentials, friendlier interface, closes #85 --- aws-creds/Cargo.toml | 2 +- aws-creds/src/credentials.rs | 87 ++++++++++++++++++++++++------------ 2 files changed, 60 insertions(+), 29 deletions(-) diff --git a/aws-creds/Cargo.toml b/aws-creds/Cargo.toml index 6c3ba15275..6becc04ef8 100644 --- a/aws-creds/Cargo.toml +++ b/aws-creds/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-creds" -version = "0.21.0" +version = "0.22.0" authors = ["Drazen Urch"] description = "Tiny Rust library for working with Amazon IAM credentials, supports `s3` crate" repository = "https://github.com/durch/rust-s3" diff --git a/aws-creds/src/credentials.rs b/aws-creds/src/credentials.rs index 4e1924dfcd..ec037ca54c 100644 --- a/aws-creds/src/credentials.rs +++ b/aws-creds/src/credentials.rs @@ -1,4 +1,4 @@ -use crate::{Result, AwsCredsError}; +use crate::{AwsCredsError, Result}; use ini::Ini; use std::collections::HashMap; use std::env; @@ -24,6 +24,8 @@ use std::env; /// // Load credentials from `[my-profile]` profile /// let credentials = Credentials::new(None, None, None, None, Some("my-profile".into())); /// ``` +/// // Use anonymous credentials for public objects +/// let credentials = Credentials::anonymous(); /// /// Credentials may also be initialized directly or by the following environment variables: /// @@ -38,8 +40,8 @@ use std::env; /// use awscreds::Credentials; /// /// // Load credentials directly -/// let access_key = String::from("AKIAIOSFODNN7EXAMPLE"); -/// let secret_key = String::from("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"); +/// let access_key = "AKIAIOSFODNN7EXAMPLE"; +/// let secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"; /// let credentials = Credentials::new(Some(access_key), Some(secret_key), None, None, None); /// /// // Load credentials from the environment @@ -51,9 +53,9 @@ use std::env; #[derive(Clone, Debug, Eq, PartialEq)] pub struct Credentials { /// AWS public access key. - pub access_key: String, + pub access_key: Option, /// AWS secret key. - pub secret_key: String, + pub secret_key: Option, /// Temporary token issued by AWS service. pub security_token: Option, pub session_token: Option, @@ -62,14 +64,20 @@ pub struct Credentials { impl Credentials { pub fn new_blocking( - access_key: Option, - secret_key: Option, - security_token: Option, - session_token: Option, - profile: Option, + access_key: Option<&str>, + secret_key: Option<&str>, + security_token: Option<&str>, + session_token: Option<&str>, + profile: Option<&str>, ) -> Result { let mut rt = tokio::runtime::Runtime::new().unwrap(); - Ok(rt.block_on(Credentials::new(access_key, secret_key, security_token, session_token, profile))?) + Ok(rt.block_on(Credentials::new( + access_key, + secret_key, + security_token, + session_token, + profile, + ))?) } pub async fn default() -> Result { @@ -79,25 +87,48 @@ impl Credentials { pub fn default_blocking() -> Result { let mut rt = tokio::runtime::Runtime::new().unwrap(); Ok(rt.block_on(Credentials::default())?) - } + } + + pub fn anonymous() -> Result { + Ok(Credentials { + access_key: None, + secret_key: None, + security_token: None, + session_token: None, + _private: () + }) + } /// Initialize Credentials directly with key ID, secret key, and optional /// token. pub async fn new( - access_key: Option, - secret_key: Option, - security_token: Option, - session_token: Option, - profile: Option, + access_key: Option<&str>, + secret_key: Option<&str>, + security_token: Option<&str>, + session_token: Option<&str>, + profile: Option<&str>, ) -> Result { + + let security_token = if let Some(security_token) = security_token{ + Some(security_token.to_string()) + } else { + None + }; + + let session_token = if let Some(session_token) = session_token { + Some(session_token.to_string()) + } else { + None + }; + let credentials = if let Some(access_key) = access_key { if let Some(secret_key) = secret_key { Some(Credentials { - access_key, - secret_key, + access_key: Some(access_key.to_string()), + secret_key: Some(secret_key.to_string()), security_token, session_token, - _private: () + _private: (), }) } else { None @@ -133,8 +164,8 @@ impl Credentials { Err(_) => None, }; Ok(Credentials { - access_key, - secret_key, + access_key: Some(access_key), + secret_key: Some(secret_key), security_token, session_token, _private: (), @@ -184,8 +215,8 @@ impl Credentials { let secret_key = resp.get("SecretAccessKey").unwrap().clone(); let security_token = Some(resp.get("Token").unwrap().clone()); Ok(Credentials { - access_key, - secret_key, + access_key: Some(access_key), + secret_key: Some(secret_key), security_token, session_token: None, _private: (), @@ -206,7 +237,7 @@ impl Credentials { false } - pub fn from_profile(section: Option) -> Result { + pub fn from_profile(section: Option<&str>) -> Result { let home_dir = match dirs::home_dir() { Some(path) => Ok(path), None => Err(AwsCredsError::from("Invalid home dir")), @@ -215,7 +246,7 @@ impl Credentials { let conf = Ini::load_from_file(&profile)?; let section = match section { Some(s) => s, - None => String::from("default"), + None => "default", }; let mut access_key = Err(AwsCredsError::from("Missing aws_access_key_id section")); let mut secret_key = Err(AwsCredsError::from("Missing aws_secret_access_key section")); @@ -241,8 +272,8 @@ impl Credentials { } Ok(Credentials { - access_key: access_key?, - secret_key: secret_key?, + access_key: Some(access_key?), + secret_key: Some(secret_key?), security_token, session_token, _private: (),