Skip to content

Commit

Permalink
Add Account Id to Credentials (#260)
Browse files Browse the repository at this point in the history
  • Loading branch information
waahm7 authored Jan 27, 2025
1 parent 8927de4 commit 274a1d2
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 16 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:

env:
BUILDER_VERSION: v0.9.72
BUILDER_VERSION: v0.9.74
BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net
BUILDER_SOURCE: releases
PACKAGE_NAME: aws-c-auth
Expand All @@ -28,4 +28,4 @@ jobs:
run: |
python3 -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder')"
chmod a+x builder
./builder build -p ${{ env.PACKAGE_NAME }} --compiler=gcc-9 --cmake-extra=-DASSERT_LOCK_HELD=ON --coverage
./builder build -p ${{ env.PACKAGE_NAME }} --compiler=gcc --cmake-extra=-DASSERT_LOCK_HELD=ON --coverage
32 changes: 32 additions & 0 deletions include/aws/auth/credentials.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ struct aws_credentials_provider_static_options {
struct aws_byte_cursor access_key_id;
struct aws_byte_cursor secret_access_key;
struct aws_byte_cursor session_token;
struct aws_byte_cursor account_id;
};

/**
Expand Down Expand Up @@ -743,6 +744,28 @@ struct aws_credentials *aws_credentials_new(
struct aws_byte_cursor session_token_cursor,
uint64_t expiration_timepoint_seconds);

/**
* Creates a new set of aws credentials with account_id
*
* @param allocator memory allocator to use
* @param access_key_id_cursor value for the aws access key id field
* @param secret_access_key_cursor value for the secret access key field
* @param session_token_cursor (optional) security token associated with the credentials
* @param account_id (optional) value for the account_id field
* @param expiration_timepoint_seconds timepoint, in seconds since epoch, that the credentials will no longer
* be valid past. For credentials that do not expire, use UINT64_MAX
*
* @return a valid credentials object, or NULL
*/
AWS_AUTH_API
struct aws_credentials *aws_credentials_new_with_account_id(
struct aws_allocator *allocator,
struct aws_byte_cursor access_key_id_cursor,
struct aws_byte_cursor secret_access_key_cursor,
struct aws_byte_cursor session_token_cursor,
struct aws_byte_cursor account_id_cursor,
uint64_t expiration_timepoint_seconds);

/**
* Creates a new set of aws anonymous credentials.
* Use Anonymous credentials, when you want to skip the signing process.
Expand Down Expand Up @@ -848,6 +871,15 @@ struct aws_byte_cursor aws_credentials_get_secret_access_key(const struct aws_cr
AWS_AUTH_API
struct aws_byte_cursor aws_credentials_get_session_token(const struct aws_credentials *credentials);

/**
* Get the AWS account id from a set of credentials
*
* @param credentials to get the account id from
* @return a byte cursor to the account id or an empty byte cursor if there is no account id
*/
AWS_AUTH_API
struct aws_byte_cursor aws_credentials_get_account_id(const struct aws_credentials *credentials);

/**
* Get the expiration timepoint (in seconds since epoch) associated with a set of credentials
*
Expand Down
44 changes: 44 additions & 0 deletions source/credentials.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct aws_credentials_identity {
struct aws_string *access_key_id;
struct aws_string *secret_access_key;
struct aws_string *session_token;
struct aws_string *account_id;
};

/* aws_token identity contains only a token to represent token only identities like a bearer token. */
Expand Down Expand Up @@ -85,13 +86,34 @@ struct aws_credentials {
/*
* Credentials API implementations
*/

struct aws_credentials *aws_credentials_new(
struct aws_allocator *allocator,
struct aws_byte_cursor access_key_id_cursor,
struct aws_byte_cursor secret_access_key_cursor,
struct aws_byte_cursor session_token_cursor,
uint64_t expiration_timepoint_seconds) {

struct aws_byte_cursor account_id;
AWS_ZERO_STRUCT(account_id);

return aws_credentials_new_with_account_id(
allocator,
access_key_id_cursor,
secret_access_key_cursor,
session_token_cursor,
account_id,
expiration_timepoint_seconds);
}

struct aws_credentials *aws_credentials_new_with_account_id(
struct aws_allocator *allocator,
struct aws_byte_cursor access_key_id_cursor,
struct aws_byte_cursor secret_access_key_cursor,
struct aws_byte_cursor session_token_cursor,
struct aws_byte_cursor account_id_cursor,
uint64_t expiration_timepoint_seconds) {

if (access_key_id_cursor.ptr == NULL || access_key_id_cursor.len == 0) {
aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
return NULL;
Expand Down Expand Up @@ -133,6 +155,14 @@ struct aws_credentials *aws_credentials_new(
}
}

if (account_id_cursor.ptr != NULL && account_id_cursor.len > 0) {
credentials_identity->account_id =
aws_string_new_from_array(allocator, account_id_cursor.ptr, account_id_cursor.len);
if (credentials_identity->account_id == NULL) {
goto error;
}
}

credentials->expiration_timepoint_seconds = expiration_timepoint_seconds;

return credentials;
Expand Down Expand Up @@ -166,6 +196,7 @@ static void s_aws_credentials_destroy(struct aws_credentials *credentials) {
aws_string_destroy(credentials->identity.credentials_identity.access_key_id);
aws_string_destroy_secure(credentials->identity.credentials_identity.secret_access_key);
aws_string_destroy_secure(credentials->identity.credentials_identity.session_token);
aws_string_destroy_secure(credentials->identity.credentials_identity.account_id);
break;
case ECC_IDENTITY:
aws_string_destroy(credentials->identity.ecc_identity.access_key_id);
Expand Down Expand Up @@ -255,6 +286,19 @@ struct aws_byte_cursor aws_credentials_get_session_token(const struct aws_creden
return s_empty_token_cursor;
}

struct aws_byte_cursor aws_credentials_get_account_id(const struct aws_credentials *credentials) {
switch (credentials->identity_type) {
case AWS_CREDENTIALS_IDENTITY:
if (credentials->identity.credentials_identity.account_id != NULL) {
return aws_byte_cursor_from_string(credentials->identity.credentials_identity.account_id);
}
break;
default:
break;
}
return s_empty_token_cursor;
}

struct aws_byte_cursor aws_credentials_get_token(const struct aws_credentials *credentials) {
switch (credentials->identity_type) {
case TOKEN_IDENTITY:
Expand Down
9 changes: 7 additions & 2 deletions source/credentials_provider_static.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,13 @@ struct aws_credentials_provider *aws_credentials_provider_new_static(

AWS_ZERO_STRUCT(*provider);

struct aws_credentials *credentials = aws_credentials_new(
allocator, options->access_key_id, options->secret_access_key, options->session_token, UINT64_MAX);
struct aws_credentials *credentials = aws_credentials_new_with_account_id(
allocator,
options->access_key_id,
options->secret_access_key,
options->session_token,
options->account_id,
UINT64_MAX);
if (credentials == NULL) {
goto on_new_credentials_failure;
}
Expand Down
50 changes: 38 additions & 12 deletions tests/credentials_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
AWS_STATIC_STRING_FROM_LITERAL(s_access_key_id_test_value, "My Access Key");
AWS_STATIC_STRING_FROM_LITERAL(s_secret_access_key_test_value, "SekritKey");
AWS_STATIC_STRING_FROM_LITERAL(s_session_token_test_value, "Some Session Token");
AWS_STATIC_STRING_FROM_LITERAL(s_account_id_test_value, "Some Account Value");

static int s_credentials_create_destroy_test(struct aws_allocator *allocator, void *ctx) {
(void)ctx;
Expand Down Expand Up @@ -115,7 +116,8 @@ static int s_do_basic_provider_test(
int expected_calls,
const struct aws_string *expected_access_key_id,
const struct aws_string *expected_secret_access_key,
const struct aws_string *expected_session_token) {
const struct aws_string *expected_session_token,
const struct aws_string *expected_account_id) {

struct aws_get_credentials_test_callback_result callback_results;
aws_get_credentials_test_callback_result_init(&callback_results, expected_calls);
Expand All @@ -141,6 +143,13 @@ static int s_do_basic_provider_test(
} else {
ASSERT_TRUE(aws_credentials_get_session_token(callback_results.credentials).len == 0);
}

if (expected_account_id != NULL) {
ASSERT_CURSOR_VALUE_STRING_EQUALS(
aws_credentials_get_account_id(callback_results.credentials), expected_account_id);
} else {
ASSERT_TRUE(aws_credentials_get_account_id(callback_results.credentials).len == 0);
}
} else {
ASSERT_TRUE(expected_access_key_id == NULL);
ASSERT_TRUE(expected_secret_access_key == NULL);
Expand All @@ -159,6 +168,7 @@ static int s_static_credentials_provider_basic_test(struct aws_allocator *alloca
.access_key_id = aws_byte_cursor_from_string(s_access_key_id_test_value),
.secret_access_key = aws_byte_cursor_from_string(s_secret_access_key_test_value),
.session_token = aws_byte_cursor_from_string(s_session_token_test_value),
.account_id = aws_byte_cursor_from_string(s_account_id_test_value),
.shutdown_options =
{
.shutdown_callback = s_on_shutdown_complete,
Expand All @@ -172,8 +182,12 @@ static int s_static_credentials_provider_basic_test(struct aws_allocator *alloca

ASSERT_TRUE(
s_do_basic_provider_test(
provider, 1, s_access_key_id_test_value, s_secret_access_key_test_value, s_session_token_test_value) ==
AWS_OP_SUCCESS);
provider,
1,
s_access_key_id_test_value,
s_secret_access_key_test_value,
s_session_token_test_value,
s_account_id_test_value) == AWS_OP_SUCCESS);

aws_credentials_provider_release(provider);

Expand All @@ -198,7 +212,7 @@ static int s_anonymous_credentials_provider_basic_test(struct aws_allocator *all

struct aws_credentials_provider *provider = aws_credentials_provider_new_anonymous(allocator, &shutdown_options);

ASSERT_TRUE(s_do_basic_provider_test(provider, 1, NULL, NULL, NULL) == AWS_OP_SUCCESS);
ASSERT_TRUE(s_do_basic_provider_test(provider, 1, NULL, NULL, NULL, NULL) == AWS_OP_SUCCESS);

aws_credentials_provider_release(provider);

Expand Down Expand Up @@ -236,8 +250,12 @@ static int s_environment_credentials_provider_basic_test(struct aws_allocator *a

ASSERT_TRUE(
s_do_basic_provider_test(
provider, 1, s_access_key_id_test_value, s_secret_access_key_test_value, s_session_token_test_value) ==
AWS_OP_SUCCESS);
provider,
1,
s_access_key_id_test_value,
s_secret_access_key_test_value,
s_session_token_test_value,
NULL) == AWS_OP_SUCCESS);

aws_credentials_provider_release(provider);

Expand Down Expand Up @@ -270,7 +288,7 @@ static int s_environment_credentials_provider_empty_env_test(struct aws_allocato

struct aws_credentials_provider *provider = aws_credentials_provider_new_environment(allocator, &options);
/* Instead of getting an empty credentials, should just fail to fetch credentials */
ASSERT_TRUE(s_do_basic_provider_test(provider, 1, NULL, NULL, NULL) == AWS_OP_SUCCESS);
ASSERT_TRUE(s_do_basic_provider_test(provider, 1, NULL, NULL, NULL, NULL) == AWS_OP_SUCCESS);

aws_credentials_provider_release(provider);

Expand Down Expand Up @@ -300,7 +318,7 @@ static int s_do_environment_credentials_provider_failure(struct aws_allocator *a

struct aws_credentials_provider *provider = aws_credentials_provider_new_environment(allocator, &options);

ASSERT_TRUE(s_do_basic_provider_test(provider, 1, NULL, NULL, NULL) == AWS_OP_SUCCESS);
ASSERT_TRUE(s_do_basic_provider_test(provider, 1, NULL, NULL, NULL, NULL) == AWS_OP_SUCCESS);

aws_credentials_provider_release(provider);

Expand Down Expand Up @@ -1338,8 +1356,12 @@ static int s_credentials_provider_default_test(struct aws_allocator *allocator,

ASSERT_TRUE(
s_do_basic_provider_test(
provider, 1, s_access_key_id_test_value, s_secret_access_key_test_value, s_session_token_test_value) ==
AWS_OP_SUCCESS);
provider,
1,
s_access_key_id_test_value,
s_secret_access_key_test_value,
s_session_token_test_value,
NULL) == AWS_OP_SUCCESS);

/*
* Verify that there's some caching before the environment by modifying the environment and requerying
Expand All @@ -1350,8 +1372,12 @@ static int s_credentials_provider_default_test(struct aws_allocator *allocator,

ASSERT_TRUE(
s_do_basic_provider_test(
provider, 1, s_access_key_id_test_value, s_secret_access_key_test_value, s_session_token_test_value) ==
AWS_OP_SUCCESS);
provider,
1,
s_access_key_id_test_value,
s_secret_access_key_test_value,
s_session_token_test_value,
NULL) == AWS_OP_SUCCESS);

aws_credentials_provider_release(provider);

Expand Down

0 comments on commit 274a1d2

Please sign in to comment.