Skip to content

Commit

Permalink
feat(backend): Add profile data removal functionality in config adapter
Browse files Browse the repository at this point in the history
Refs: #15
  • Loading branch information
maikbasel committed Feb 27, 2024
1 parent b1d815b commit 09f6cfd
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 64 deletions.
2 changes: 2 additions & 0 deletions src-tauri/src/profile/core/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ pub trait ProfileDataSPI: Send + Sync {
profile_name: &str,
settings: &Settings,
) -> Result<(), ProfileError>;

fn remove_profile_data(&self, profile_name: &str) -> Result<(), ProfileError>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ impl ProfileDataSPI for SdkConfigAdapter {

for profile_name in profile_names {
if let Some(profile) = profile_set.get_profile(profile_name) {
let config = extract_config(profile);
let credentials = extract_credentials(profile);
let config = Self::extract_config(profile);
let credentials = Self::extract_credentials(profile);

let settings = Settings::new(credentials, config);

Expand All @@ -59,85 +59,138 @@ impl ProfileDataSPI for SdkConfigAdapter {
profile_name: &str,
settings: &Settings,
) -> error_stack::Result<(), ProfileError> {
update_config_file(profile_name, settings)?;
Self::update_config_file(profile_name, settings)?;

update_credentials_file(profile_name, settings)?;
Self::update_credentials_file(profile_name, settings)?;

Ok(())
}
}

fn update_config_file(profile_name: &str, settings: &Settings) -> Result<(), Report<ProfileError>> {
let user_dir = UserDirs::new().expect("user dir should exist");

let default_aws_config_file_location = user_dir.home_dir().join(".aws").join("config");
let config_file_location = env::var("AWS_CONFIG_FILE").ok().unwrap_or(
default_aws_config_file_location
.to_string_lossy()
.into_owned(),
);
let mut config_file = Ini::load_from_file(&config_file_location)
.change_context(ProfileError::ConfigFileLoadError)?;

let mut profile_section = config_file.with_section(Some(format!("profile {}", profile_name)));
if let (Some(region), Some(output_format)) =
(&settings.config.region, &settings.config.output_format)
{
profile_section
.set("region", region)
.set("output", output_format);
fn remove_profile_data(&self, profile_name: &str) -> error_stack::Result<(), ProfileError> {
Self::delete_from_config(profile_name)?;

config_file
.write_to_file(config_file_location.as_str())
.change_context(ProfileError::ConfigFileWriteError)?;
Self::delete_from_credentials_file(profile_name)?;

Ok(())
}
Ok(())
}

fn update_credentials_file(
profile_name: &str,
settings: &Settings,
) -> Result<(), Report<ProfileError>> {
let user_dir = UserDirs::new().expect("user dir should exist");
let default_aws_credentials_file_location =
user_dir.home_dir().join(".aws").join("credentials");
let credentials_file_location = env::var("AWS_SHARED_CREDENTIALS_FILE").ok().unwrap_or(
default_aws_credentials_file_location
.to_string_lossy()
.into_owned(),
);
let mut credentials_file = Ini::load_from_file(&credentials_file_location)
.change_context(ProfileError::ConfigFileLoadError)?;

let mut profile_section = credentials_file.with_section(Some(profile_name));
if let (Some(access_key_id), Some(secret_access_key)) = (
&settings.credentials.access_key_id,
&settings.credentials.secret_access_key,
) {
profile_section.set("aws_access_key_id", access_key_id).set(
"aws_secret_access_key",
std::str::from_utf8(secret_access_key.unsecure())
.expect("secret access key should be serializable to be UTF-8 string"),
impl SdkConfigAdapter {
fn get_config_file_location() -> Result<String, Report<ProfileError>> {
let user_dir = UserDirs::new().expect("user dir should exist");
let default_aws_config_file_location = user_dir.home_dir().join(".aws").join("config");

let config_file_location = env::var("AWS_CONFIG_FILE").ok().unwrap_or(
default_aws_config_file_location
.to_string_lossy()
.into_owned(),
);

Ok(config_file_location)
}

fn get_credentials_file_location() -> Result<String, Report<ProfileError>> {
let user_dir = UserDirs::new().expect("user dir should exist");

let default_aws_credentials_file_location = user_dir.home_dir().join(".aws").join("config");

let credentials_file_location = env::var("AWS_SHARED_CREDENTIALS_FILE").ok().unwrap_or(
default_aws_credentials_file_location
.to_string_lossy()
.into_owned(),
);

credentials_file
Ok(credentials_file_location)
}

fn delete_from_credentials_file(profile_name: &str) -> Result<(), Report<ProfileError>> {
let credentials_file_location = Self::get_credentials_file_location()?;
let mut config_file = Ini::load_from_file(&credentials_file_location)
.change_context(ProfileError::CredentialsFileLoadError)?;

config_file.delete(Some(profile_name));

config_file
.write_to_file(credentials_file_location.as_str())
.change_context(ProfileError::CredentialsFileWriteError)?;
Ok(())
}

Ok(())
}
fn delete_from_config(profile_name: &str) -> Result<(), Report<ProfileError>> {
let config_file_location = Self::get_config_file_location()?;
let mut config_file = Ini::load_from_file(&config_file_location)
.change_context(ProfileError::ConfigFileLoadError)?;

fn extract_config(profile: &Profile) -> Config {
let output_format = profile.get("output");
let region = profile.get("region");
config_file.delete(Some(format!("profile {}", profile_name)));

Config::new(region, output_format)
}
config_file
.write_to_file(config_file_location.as_str())
.change_context(ProfileError::ConfigFileWriteError)?;
Ok(())
}

fn extract_credentials(profile: &Profile) -> Credentials {
let access_key_id = profile.get("aws_access_key_id");
let secret_access_key = profile.get("aws_secret_access_key").map(SecStr::from);
fn update_config_file(
profile_name: &str,
settings: &Settings,
) -> Result<(), Report<ProfileError>> {
let config_file_location = Self::get_config_file_location()?;
let mut config_file = Ini::load_from_file(&config_file_location)
.change_context(ProfileError::ConfigFileLoadError)?;

let mut profile_section =
config_file.with_section(Some(format!("profile {}", profile_name)));
if let (Some(region), Some(output_format)) =
(&settings.config.region, &settings.config.output_format)
{
profile_section
.set("region", region)
.set("output", output_format);

config_file
.write_to_file(config_file_location.as_str())
.change_context(ProfileError::ConfigFileWriteError)?;
}
Ok(())
}

Credentials::new(access_key_id, secret_access_key)
fn update_credentials_file(
profile_name: &str,
settings: &Settings,
) -> Result<(), Report<ProfileError>> {
let credentials_file_location = Self::get_credentials_file_location()?;
let mut credentials_file = Ini::load_from_file(&credentials_file_location)
.change_context(ProfileError::ConfigFileLoadError)?;

let mut profile_section = credentials_file.with_section(Some(profile_name));
if let (Some(access_key_id), Some(secret_access_key)) = (
&settings.credentials.access_key_id,
&settings.credentials.secret_access_key,
) {
profile_section.set("aws_access_key_id", access_key_id).set(
"aws_secret_access_key",
std::str::from_utf8(secret_access_key.unsecure())
.expect("secret access key should be serializable to be UTF-8 string"),
);

credentials_file
.write_to_file(credentials_file_location.as_str())
.change_context(ProfileError::CredentialsFileWriteError)?;
}

Ok(())
}

fn extract_config(profile: &Profile) -> Config {
let output_format = profile.get("output");
let region = profile.get("region");

Config::new(region, output_format)
}

fn extract_credentials(profile: &Profile) -> Credentials {
let access_key_id = profile.get("aws_access_key_id");
let secret_access_key = profile.get("aws_secret_access_key").map(SecStr::from);

Credentials::new(access_key_id, secret_access_key)
}
}
28 changes: 28 additions & 0 deletions src-tauri/tests/sdk_config_adapter_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,4 +250,32 @@ mod tests {
.is_some()
.is_equal_to("newSecretAccessKey");
}

#[test_context(ValidContext)]
#[test]
#[serial]
fn should_remove_config_for_given_profile(_: &mut ValidContext) {
let config_file_location = env::var("AWS_CONFIG_FILE").ok().unwrap();
let cut: Box<dyn ProfileDataSPI> = Box::new(SdkConfigAdapter);

let result = cut.remove_profile_data("dev");

assert_that(&result).is_ok();
let actual_config = Ini::load_from_file(config_file_location).unwrap();
assert_that(&actual_config.section(Some("profile dev"))).is_none();
}

#[test_context(ValidContext)]
#[test]
#[serial]
fn should_remove_credentials_for_given_profile(_: &mut ValidContext) {
let credentials_file_location = env::var("AWS_SHARED_CREDENTIALS_FILE").ok().unwrap();
let cut: Box<dyn ProfileDataSPI> = Box::new(SdkConfigAdapter);

let result = cut.remove_profile_data("dev");

assert_that(&result).is_ok();
let actual_credentials = Ini::load_from_file(credentials_file_location).unwrap();
assert_that(&actual_credentials.section(Some("dev"))).is_none();
}
}

0 comments on commit 09f6cfd

Please sign in to comment.