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

Update Config File Parsing Logic to Parse Services Section #51

Merged
merged 13 commits into from
Jan 8, 2025
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
1 change: 1 addition & 0 deletions include/aws/sdkutils/aws_profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ enum aws_profile_source_type { AWS_PST_NONE, AWS_PST_CONFIG, AWS_PST_CREDENTIALS
enum aws_profile_section_type {
AWS_PROFILE_SECTION_TYPE_PROFILE,
AWS_PROFILE_SECTION_TYPE_SSO_SESSION,
AWS_PROFILE_SECTION_TYPE_SERVICES,

AWS_PROFILE_SECTION_TYPE_COUNT,
};
Expand Down
76 changes: 47 additions & 29 deletions source/aws_profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@ static void s_aws_profile_collection_destroy_internal(struct aws_profile_collect

AWS_STATIC_STRING_FROM_LITERAL(s_profile_token, "profile");
AWS_STATIC_STRING_FROM_LITERAL(s_sso_session_token, "sso-session");
AWS_STATIC_STRING_FROM_LITERAL(s_services_token, "services");

const struct aws_profile *aws_profile_collection_get_profile(
const struct aws_profile_collection *profile_collection,
Expand All @@ -635,7 +636,7 @@ static int s_profile_collection_add_profile(
struct aws_profile_collection *profile_collection,
const enum aws_profile_section_type section_type,
const struct aws_byte_cursor *profile_name,
bool has_prefix,
bool has_profile_prefix,
const struct profile_file_parse_context *context,
struct aws_profile **current_profile_out) {

Expand All @@ -660,7 +661,7 @@ static int s_profile_collection_add_profile(
/*
* In a config file, "profile default" always supercedes "default"
*/
if (!has_prefix && existing_profile && existing_profile->has_profile_prefix) {
if (!has_profile_prefix && existing_profile && existing_profile->has_profile_prefix) {
/*
* existing one supercedes: ignore this (and its properties) completely by failing the add
* which sets the current profile to NULL
Expand All @@ -673,7 +674,7 @@ static int s_profile_collection_add_profile(
return AWS_OP_SUCCESS;
}

if (has_prefix && existing_profile && !existing_profile->has_profile_prefix) {
if (has_profile_prefix && existing_profile && !existing_profile->has_profile_prefix) {
/*
* stomp over existing: remove it, then proceed with add
* element destroy function will clean up the profile and key
Expand All @@ -692,7 +693,7 @@ static int s_profile_collection_add_profile(
return AWS_OP_SUCCESS;
}

struct aws_profile *new_profile = aws_profile_new(profile_collection->allocator, profile_name, has_prefix);
struct aws_profile *new_profile = aws_profile_new(profile_collection->allocator, profile_name, has_profile_prefix);
if (new_profile == NULL) {
goto on_aws_profile_new_failure;
}
Expand Down Expand Up @@ -862,6 +863,37 @@ static struct aws_byte_cursor s_trim_trailing_whitespace_comment(const struct aw
return trimmed;
}

static int s_parse_section_type_prefix(
struct aws_byte_cursor *profile_cursor,
enum aws_profile_section_type *out_section_type) {
/* check profile prefix */
if (s_parse_by_token(profile_cursor, s_profile_token, NULL)) {
if (s_parse_by_character_predicate(profile_cursor, s_is_whitespace, NULL, 1)) {
*out_section_type = AWS_PROFILE_SECTION_TYPE_PROFILE;
return AWS_OP_SUCCESS;
}
return aws_raise_error(AWS_ERROR_SDKUTILS_PARSE_RECOVERABLE);
}

/* check sso-session prefix */
if (s_parse_by_token(profile_cursor, s_sso_session_token, NULL)) {
if (s_parse_by_character_predicate(profile_cursor, s_is_whitespace, NULL, 1)) {
*out_section_type = AWS_PROFILE_SECTION_TYPE_SSO_SESSION;
return AWS_OP_SUCCESS;
}
return aws_raise_error(AWS_ERROR_SDKUTILS_PARSE_RECOVERABLE);
}
/* check services prefix */
if (s_parse_by_token(profile_cursor, s_services_token, NULL)) {
if (s_parse_by_character_predicate(profile_cursor, s_is_whitespace, NULL, 1)) {
*out_section_type = AWS_PROFILE_SECTION_TYPE_SERVICES;
return AWS_OP_SUCCESS;
}
return aws_raise_error(AWS_ERROR_SDKUTILS_PARSE_RECOVERABLE);
}
return aws_raise_error(AWS_ERROR_SDKUTILS_PARSE_RECOVERABLE);
}

/**
* Attempts to parse profile declaration lines
*
Expand Down Expand Up @@ -895,42 +927,28 @@ static bool s_parse_profile_declaration(
enum aws_profile_section_type section_type = AWS_PROFILE_SECTION_TYPE_PROFILE;

/*
* Check if the profile name starts with the 'profile' keyword. We need to check for
* "profile" and at least one whitespace character. A partial match
* Check if the profile name starts with a valid prefix. We need to check for
* prefix and at least one whitespace character. A partial match like
* ("[profilefoo]" for example) should rewind and use the whole name properly.
*/
struct aws_byte_cursor backtrack_cursor = profile_cursor;
bool has_profile_prefix = s_parse_by_token(&profile_cursor, s_profile_token, NULL) &&
s_parse_by_character_predicate(&profile_cursor, s_is_whitespace, NULL, 1);
bool has_sso_session_prefix = !has_profile_prefix && s_parse_by_token(&profile_cursor, s_sso_session_token, NULL) &&
s_parse_by_character_predicate(&profile_cursor, s_is_whitespace, NULL, 1);

if (has_profile_prefix) {
bool has_valid_section_type_prefix = false;
if (s_parse_section_type_prefix(&profile_cursor, &section_type) != AWS_OP_SUCCESS) {
profile_cursor = backtrack_cursor;
} else {
has_valid_section_type_prefix = true;
if (context->profile_collection->profile_source == AWS_PST_CREDENTIALS) {
AWS_LOGF_WARN(
AWS_LS_SDKUTILS_PROFILE,
"Profile declarations in credentials files are not allowed to begin with the \"profile\" keyword");
"Profile declarations in credentials files are not allowed to begin with the section-type keyword");
s_log_parse_context(AWS_LL_WARN, context);

context->parse_error = AWS_ERROR_SDKUTILS_PARSE_RECOVERABLE;
return true;
}

s_parse_by_character_predicate(&profile_cursor, s_is_whitespace, NULL, 0);
} else if (has_sso_session_prefix) {
if (context->profile_collection->profile_source == AWS_PST_CREDENTIALS) {
AWS_LOGF_WARN(AWS_LS_SDKUTILS_PROFILE, "sso-session declarations in credentials files are not allowed");
s_log_parse_context(AWS_LL_WARN, context);

context->parse_error = AWS_ERROR_SDKUTILS_PARSE_RECOVERABLE;
return true;
}
section_type = AWS_PROFILE_SECTION_TYPE_SSO_SESSION;
s_parse_by_character_predicate(&profile_cursor, s_is_whitespace, NULL, 0);
} else {
profile_cursor = backtrack_cursor;
}

struct aws_byte_cursor profile_name;
if (!s_parse_by_character_predicate(&profile_cursor, s_is_identifier, &profile_name, 0)) {
AWS_LOGF_WARN(AWS_LS_SDKUTILS_PROFILE, "Profile declarations must contain a valid identifier for a name");
Expand All @@ -940,8 +958,8 @@ static bool s_parse_profile_declaration(
return true;
}

if (context->profile_collection->profile_source == AWS_PST_CONFIG && !has_profile_prefix &&
!s_is_default_profile_name(&profile_name) && !has_sso_session_prefix) {
if (context->profile_collection->profile_source == AWS_PST_CONFIG && !has_valid_section_type_prefix &&
!s_is_default_profile_name(&profile_name)) {
AWS_LOGF_WARN(
AWS_LS_SDKUTILS_PROFILE,
"Non-default profile declarations in config files must use the \"profile\" keyword");
Expand Down Expand Up @@ -989,7 +1007,7 @@ static bool s_parse_profile_declaration(
context->profile_collection,
section_type,
&profile_name,
has_profile_prefix,
has_valid_section_type_prefix && section_type == AWS_PROFILE_SECTION_TYPE_PROFILE,
context,
&context->current_profile)) {
AWS_LOGF_ERROR(AWS_LS_SDKUTILS_PROFILE, "Failed to add profile to profile collection");
Expand Down
5 changes: 3 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ add_test_case(aws_profile_trimmable_property_profile_test)
add_test_case(aws_profile_empty_property_profile_test)
add_test_case(aws_profile_multiple_empty_profile_test)
add_test_case(aws_profile_multiple_profile_test)
add_test_case(aws_profile_multiple_profile_with_sso_session_test)
add_test_case(aws_profile_sso_session_in_credentials_test)
add_test_case(aws_profile_multiple_sections)
add_test_case(aws_profile_sections_in_credentials_test)
add_test_case(aws_profile_sso_session_without_name_test)
add_test_case(aws_profile_services_invalid_prefix_test)
add_test_case(aws_profile_blank_lines_ignored_test)
add_test_case(aws_profile_pound_comments_ignored_test)
add_test_case(aws_profile_semicolon_comments_ignored_test)
Expand Down
Loading