fix(aws): prevent endless loop when AWS config file is a directory (#3335)
When opening a directory as a file the intial open works, while subsequent line-reads will fail with _is a directory_. Since erroring line-reads were just skipped this lead to an endless loop.
This commit is contained in:
parent
5ce8811397
commit
006fbf0dd5
|
@ -1,6 +1,4 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{BufRead, BufReader};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
@ -10,7 +8,7 @@ use super::{Context, Module, RootModuleConfig};
|
||||||
|
|
||||||
use crate::configs::aws::AwsConfig;
|
use crate::configs::aws::AwsConfig;
|
||||||
use crate::formatter::StringFormatter;
|
use crate::formatter::StringFormatter;
|
||||||
use crate::utils::render_time;
|
use crate::utils::{read_file, render_time};
|
||||||
|
|
||||||
type Profile = String;
|
type Profile = String;
|
||||||
type Region = String;
|
type Region = String;
|
||||||
|
@ -40,19 +38,19 @@ fn get_config_file_path(context: &Context) -> Option<PathBuf> {
|
||||||
fn get_aws_region_from_config(context: &Context, aws_profile: Option<&str>) -> Option<Region> {
|
fn get_aws_region_from_config(context: &Context, aws_profile: Option<&str>) -> Option<Region> {
|
||||||
let config_location = get_config_file_path(context)?;
|
let config_location = get_config_file_path(context)?;
|
||||||
|
|
||||||
let file = File::open(&config_location).ok()?;
|
let contents = read_file(&config_location).ok()?;
|
||||||
let reader = BufReader::new(file);
|
|
||||||
let lines = reader.lines().filter_map(Result::ok);
|
|
||||||
|
|
||||||
let region_line = if let Some(aws_profile) = aws_profile {
|
let region_line = if let Some(aws_profile) = aws_profile {
|
||||||
lines
|
contents
|
||||||
|
.lines()
|
||||||
.skip_while(|line| line != &format!("[profile {}]", &aws_profile))
|
.skip_while(|line| line != &format!("[profile {}]", &aws_profile))
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.take_while(|line| !line.starts_with('['))
|
.take_while(|line| !line.starts_with('['))
|
||||||
.find(|line| line.starts_with("region"))
|
.find(|line| line.starts_with("region"))
|
||||||
} else {
|
} else {
|
||||||
lines
|
contents
|
||||||
.skip_while(|line| line != "[default]")
|
.lines()
|
||||||
|
.skip_while(|&line| line != "[default]")
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.take_while(|line| !line.starts_with('['))
|
.take_while(|line| !line.starts_with('['))
|
||||||
.find(|line| line.starts_with("region"))
|
.find(|line| line.starts_with("region"))
|
||||||
|
@ -91,11 +89,7 @@ fn get_credentials_duration(context: &Context, aws_profile: Option<&Profile>) ->
|
||||||
{
|
{
|
||||||
chrono::DateTime::parse_from_rfc3339(&expiration_date).ok()
|
chrono::DateTime::parse_from_rfc3339(&expiration_date).ok()
|
||||||
} else {
|
} else {
|
||||||
let credentials_location = get_credentials_file_path(context)?;
|
let contents = read_file(get_credentials_file_path(context)?).ok()?;
|
||||||
|
|
||||||
let file = File::open(&credentials_location).ok()?;
|
|
||||||
let reader = BufReader::new(file);
|
|
||||||
let lines = reader.lines().filter_map(Result::ok);
|
|
||||||
|
|
||||||
let profile_line = if let Some(aws_profile) = aws_profile {
|
let profile_line = if let Some(aws_profile) = aws_profile {
|
||||||
format!("[{}]", aws_profile)
|
format!("[{}]", aws_profile)
|
||||||
|
@ -103,7 +97,8 @@ fn get_credentials_duration(context: &Context, aws_profile: Option<&Profile>) ->
|
||||||
"[default]".to_string()
|
"[default]".to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
let expiration_date_line = lines
|
let expiration_date_line = contents
|
||||||
|
.lines()
|
||||||
.skip_while(|line| line != &profile_line)
|
.skip_while(|line| line != &profile_line)
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.take_while(|line| !line.starts_with('['))
|
.take_while(|line| !line.starts_with('['))
|
||||||
|
@ -182,7 +177,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::test::ModuleRenderer;
|
use crate::test::ModuleRenderer;
|
||||||
use ansi_term::Color;
|
use ansi_term::Color;
|
||||||
use std::fs::File;
|
use std::fs::{create_dir, File};
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -306,6 +301,37 @@ mod tests {
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn credentials_file_is_ignored_when_is_directory() -> io::Result<()> {
|
||||||
|
let dir = tempfile::tempdir()?;
|
||||||
|
let config_path = dir.path().join("credentials");
|
||||||
|
create_dir(&config_path)?;
|
||||||
|
|
||||||
|
assert!(ModuleRenderer::new("aws")
|
||||||
|
.env(
|
||||||
|
"AWS_CREDENTIALS_FILE",
|
||||||
|
config_path.to_string_lossy().as_ref(),
|
||||||
|
)
|
||||||
|
.collect()
|
||||||
|
.is_none());
|
||||||
|
|
||||||
|
dir.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn config_file_path_is_ignored_when_is_directory() -> io::Result<()> {
|
||||||
|
let dir = tempfile::tempdir()?;
|
||||||
|
let config_path = dir.path().join("config");
|
||||||
|
create_dir(&config_path)?;
|
||||||
|
|
||||||
|
assert!(ModuleRenderer::new("aws")
|
||||||
|
.env("AWS_CONFIG_FILE", config_path.to_string_lossy().as_ref())
|
||||||
|
.collect()
|
||||||
|
.is_none());
|
||||||
|
|
||||||
|
dir.close()
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn default_profile_set() -> io::Result<()> {
|
fn default_profile_set() -> io::Result<()> {
|
||||||
let dir = tempfile::tempdir()?;
|
let dir = tempfile::tempdir()?;
|
||||||
|
|
Loading…
Reference in New Issue