Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/darin/update-aws-sdk' into cli-o…
Browse files Browse the repository at this point in the history
…nly-auth
  • Loading branch information
snickell committed Nov 11, 2024
2 parents ded320a + 5d43d4e commit a8d93e9
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 27 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/pr-verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Run Tests

on:
pull_request:
branches:
- main

jobs:
# Test on code-dot-org Ruby version
test_3_0_5:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.0.5
bundler-cache: true

- name: Install gems
run: bundle install

- name: Run tests
run: bundle exec rake test

#Test on latest Ruby
test_3_3:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3
bundler-cache: true

- name: Install gems
run: bundle install

- name: Run tests
run: bundle exec rake test
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.0.5
8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM ruby:3.0.5

WORKDIR /app

# Copy bare minimum files to install gems
COPY Gemfile aws-google.gemspec /app/
COPY lib /app/lib
RUN bundle install
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@ Or install it yourself as:
Visit the [Google API Console](https://console.developers.google.com/) to create/obtain [OAuth 2.0 Client ID credentials](https://support.google.com/cloud/answer/6158849) (client ID and client secret) for an application in your Google account.

### Create an AWS IAM Role
Create an AWS IAM Role with the desired IAM policies attached, and a ['trust policy'](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#term_trust-policy) ([`AssumeRolePolicyDocument`](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateRole.html)) allowing the [`sts:AssumeRoleWithWebIdentity`](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html) action with [Web Identity Federation condition keys](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-wif) authorizing
Create an AWS IAM Role with the desired IAM policies attached, and a ['trust policy'][1] ([`AssumeRolePolicyDocument`][2]) allowing the [`sts:AssumeRoleWithWebIdentity`][3] action with [Web Identity Federation condition keys][4] authorizing
your Google Client ID (`accounts.google.com:aud`) and a specific set of Google Account IDs (`accounts.google.com:sub`):

[1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#term_trust-policy "IAM Trust Policy"
[2]: https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateRole.html "Create Role API"
[3]: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html "Assume Role With Identity API"
[4]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-wif "IAM Condition Keys"

```json
{
"Version": "2012-10-17",
Expand All @@ -53,6 +58,7 @@ your Google Client ID (`accounts.google.com:aud`) and a specific set of Google A

### Method 1: `Aws::Google`
In your Ruby code, construct an `Aws::Google` object by passing the AWS `role_arn`, Google `client_id` and `client_secret`, either as constructor arguments or via the `Aws::Google.config` global defaults:

```ruby
require 'aws/google'

Expand Down Expand Up @@ -87,9 +93,22 @@ The extra `credential_process` config line tells AWS to [Source Credentials with

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
Prerequisites:

* Ruby 3.0.5

You can have Ruby installed locally, or use Docker and mount this repository into a Ruby container. By using Docker you can avoid conflicts with differing Ruby versions or other installed gems. To run and 'bash' into a Ruby container, install Docker and run the following. See [docker-compose.yml](docker-compose.yml) for details.

```
docker compose build
docker compose run ruby
```

With either option, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run `bundle exec rake install`.

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).

## Contributing

Expand Down
21 changes: 11 additions & 10 deletions aws-google.gemspec
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
lib = File.expand_path('../lib', __FILE__)
lib = File.expand_path('lib', __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'aws/google/version'

Gem::Specification.new do |spec|
spec.required_ruby_version = '>= 3.0.5'
spec.name = 'aws-google'
spec.version = Aws::Google::VERSION
spec.authors = ['Will Jordan']
Expand All @@ -21,14 +22,14 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ['lib']

spec.add_dependency 'aws-sdk-core', '~> 3.130'
spec.add_dependency 'google-apis-core'
spec.add_dependency 'launchy', '~> 2'
spec.add_dependency 'aws-sdk-core', '~> 3.211.0'
spec.add_dependency 'google-apis-core', '~> 0.15.1'
spec.add_dependency 'launchy', '~> 3.0.1'

spec.add_development_dependency 'activesupport', '~> 5'
spec.add_development_dependency 'minitest', '~> 5.14.2'
spec.add_development_dependency 'mocha', '~> 1.5'
spec.add_development_dependency 'rake', '~> 12'
spec.add_development_dependency 'timecop', '~> 0.8'
spec.add_development_dependency 'webmock', '~> 3.3'
spec.add_development_dependency 'activesupport', '~> 6.1.7.8'
spec.add_development_dependency 'minitest', '~> 5.25.1'
spec.add_development_dependency 'mocha', '~> 2.4.5'
spec.add_development_dependency 'rake', '~> 13.2.1'
spec.add_development_dependency 'timecop', '~> 0.9.10'
spec.add_development_dependency 'webmock', '3.24.0'
end
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: '3'
services:
ruby:
build: .
volumes:
- .:/app
working_dir: /app
command: bash
27 changes: 18 additions & 9 deletions lib/aws/google/cached_credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,31 @@ def initialize(options = {})
end

def refresh_if_near_expiration
if near_expiration?(SYNC_EXPIRATION_LENGTH)
@mutex.synchronize do
if near_expiration?(SYNC_EXPIRATION_LENGTH)
refresh
write_credentials
end
return unless near_expiration?(SYNC_EXPIRATION_LENGTH)

@mutex.synchronize do
if near_expiration?(SYNC_EXPIRATION_LENGTH)
refresh
write_credentials
end
end
end

# Write credentials and expiration to AWS credentials file.
def write_credentials
# AWS CLI is needed because writing AWS credentials is not supported by the AWS Ruby SDK.
# Ensure the AWS CLI is available before attempting to write credentials.
return unless system('which aws >/dev/null 2>&1')
Aws::SharedCredentials::KEY_MAP.transform_values(&@credentials.method(:send)).
merge(expiration: @expiration).each do |key, value|

# Manually map the credentials to the keys used by AWS CLI
credentials_map = {
'aws_access_key_id' => @credentials.access_key_id,
'aws_secret_access_key' => @credentials.secret_access_key,
'aws_session_token' => @credentials.session_token,
'expiration' => @expiration
}

# Use the AWS CLI to set the credentials in the session profile
credentials_map.each do |key, value|
system("aws configure set #{key} #{value} --profile #{@session_profile}")
end
end
Expand Down
11 changes: 6 additions & 5 deletions test/aws/google_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@
it 'refreshes expired Google auth token credentials' do
m = mock
m.stubs(:refresh!)
m.stubs(:id_token).
returns(JWT.encode({ email: 'email', exp: Time.now.to_i - 1 }, '')).
then.returns(JWT.encode({ email: 'email' }, ''))
m.stubs(:id_token)
.returns(JWT.encode({ email: 'email', exp: Time.now.to_i - 1 }, ''))
.then.returns(JWT.encode({ email: 'email' }, ''))
Google::Auth.stubs(:get_application_default).returns(m)

system.times(5)
Expand All @@ -108,6 +108,7 @@
expiration = provider.expiration
_(expiration).must_equal(provider.expiration)
Timecop.travel(1.5.hours.from_now) do
provider.refresh!
_(expiration).wont_equal(provider.expiration)
end
end
Expand All @@ -124,7 +125,7 @@
Aws::Google.any_instance.expects(:refresh).never
Aws::Google.new(config).credentials
end

it 'uses config defaults for new AWS clients' do
Aws::Google.stubs(:config).returns(config)
@oauth_default.once
Expand Down Expand Up @@ -204,7 +205,7 @@
Aws::Google.new(config).credentials
end
end

describe 'no shared config' do
before do
Aws.shared_config.fresh(
Expand Down

0 comments on commit a8d93e9

Please sign in to comment.