aws-google 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29e2bac01a2d62b1b156badf3fda404596d56fef92f5b8de438095362abea600
4
- data.tar.gz: d25ac4ca974f4991120814679678a923375ede8bbfd0b189917344596f0d79ec
3
+ metadata.gz: 0ea7ae0f33a7dafe59e62cb045d143ed0fdc0a0a017d3e2a17d380cf1f46a49e
4
+ data.tar.gz: b5bc47171255473122de1cf179828f869a32cd7d6fb5cf5343d85204e7e96c26
5
5
  SHA512:
6
- metadata.gz: e2e26e77654e356c81c424dd76d679c09304f44a846bff66d6d204c845d9a918e0bac3dd99d6922c9e4cfb363d773dbcfd679c29f736e46eb52acccb5f4ba0f6
7
- data.tar.gz: 9226a37c273473589a4f56ea3e49a7a9bb652d42b436e39f62f41124ccbd36bf101e4edbd6ee7d5a44e4138e91c135f72d5a6292f8149cc4e3f2272b809add19
6
+ metadata.gz: 7801674b5be60e16e4e32608162b5c79baa06b794ddc4c494f6c04a46b2ad630b6a0ef7d6a552ff9f56091a6f4079cd95942a28a8b35d1a337f7cf335d4a4ba3
7
+ data.tar.gz: 405d08b37bb3167508fc705d458a9472067ddb53c4dcd02fc831a8c33155623c11c414d7bd2181d93a68a5cad0443cd325ea27451f416eeefd2d6e395e47a740
data/README.md CHANGED
@@ -65,28 +65,18 @@ role_credentials = Aws::Google.new(
65
65
  puts Aws::STS::Client.new(credentials: role_credentials).get_caller_identity
66
66
  ```
67
67
 
68
- - Or, set `Aws::Google.config` hash to add Google auth to the default credential provider chain:
69
-
70
- ```ruby
71
- Aws::Google.config = {
72
- role_arn: aws_role,
73
- google_client_id: client_id,
74
- google_client_secret: client_secret,
75
- }
76
-
77
- puts Aws::STS::Client.new.get_caller_identity
68
+ - Or, add the properties to your AWS config profile ([`~/.aws/config`](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-where)) to use Google as the AWS credential provider without any changes to your application code:
69
+
70
+ ```ini
71
+ [my_profile]
72
+ google =
73
+ role_arn = arn:aws:iam::[AccountID]:role/[Role]
74
+ client_id = 123456789012-abcdefghijklmnopqrstuvwzyz0123456.apps.googleusercontent.com
75
+ client_secret = 01234567890abcdefghijklmn
76
+ credential_process = aws-google
78
77
  ```
79
78
 
80
- - Or, set `credential_process` in your AWS config profile ([`~/.aws/config`](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-where)) to `aws-google` to [Source Credentials with an External Process](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html) without any change to your application code:
81
-
82
- ```
83
- [profile my_google]
84
- credential_process = aws-google --profile my_google
85
- aws_role = arn:aws:iam::[AccountID]:role/[Role]
86
- google_client_id = 123456789012-abcdefghijklmnopqrstuvwzyz0123456.apps.googleusercontent.com
87
- google_client_secret = 01234567890abcdefghijklmn
88
-
89
- ```
79
+ The extra `credential_process` config line tells AWS to [Source Credentials with an External Process](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html), in this case the `aws-google` script, which allows you to seamlessly use the same Google login configuration from non-Ruby SDKs (like the CLI).
90
80
 
91
81
  ## Development
92
82
 
@@ -26,7 +26,6 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency 'launchy', '~> 2'
27
27
 
28
28
  spec.add_development_dependency 'activesupport', '~> 5'
29
- spec.add_development_dependency 'bundler'
30
29
  spec.add_development_dependency 'minitest', '~> 5.14.2'
31
30
  spec.add_development_dependency 'mocha', '~> 1.5'
32
31
  spec.add_development_dependency 'rake', '~> 12'
@@ -6,61 +6,8 @@
6
6
  require 'aws/google'
7
7
  require 'time'
8
8
  require 'json'
9
- require 'optparse'
10
9
 
11
- def error(msg)
12
- puts msg
13
- exit 1
14
- end
15
-
16
- options = {}
17
- OptionParser.new do |opts|
18
- opts.on('-p PROFILE', '--profile PROFILE', 'Profile') do |p|
19
- options[:profile] = p
20
- end
21
- opts.on('-v', '--version', 'Version') do
22
- require 'aws/google/version'
23
- puts Aws::Google::VERSION
24
- exit 0
25
- end
26
- opts.on('-r ROLE', '--role ROLE', 'AWS Role arn') do |r|
27
- options[:role_arn] = r
28
- end
29
- opts.on('-i ID', '--client-id ID', 'Google Client ID') do |id|
30
- options[:google_client_id] = id
31
- end
32
- opts.on('-s SECRET', '--client-secret SECRET', 'Google Client Secret') do |secret|
33
- options[:google_client_secret] = secret
34
- end
35
- opts.on('-h DOMAIN', '--domain DOMAIN', 'Google Domain') do |hd|
36
- options[:domain] = hd
37
- end
38
- opts.on('-d DURATION', '--duration DURATION', 'Duration in seconds') do |d|
39
- options[:duration_seconds] = d.to_i
40
- end
41
- opts.on('--port PORT', 'Port number for local server') do |p|
42
- options[:port] = p.to_i
43
- end
44
- opts.on('--online', 'Online authentication, no refresh token') do |o|
45
- options[:online] = true
46
- end
47
- end.parse!
48
-
49
- config = Aws.shared_config
50
- profile = options[:profile] || ENV['AWS_PROFILE'] || 'default'
51
-
52
- options[:role_arn] ||= config.get('aws_role', profile: profile) ||
53
- error('Missing config: aws_role')
54
- options[:google_client_id] ||= config.get('google_client_id', profile: profile) ||
55
- error('Missing config: google_client_id')
56
- options[:google_client_secret] ||= config.get('google_client_secret', profile: profile) ||
57
- error('Missing config: google_client_secret')
58
-
59
- # Cache temporary-session credentials in a separately-named profile.
60
- # Stored credentials take priority over credential_process,
61
- # so they would never be refreshed if stored in the same profile.
62
- options[:profile] += '_session'
63
- google = Aws::Google.new(options)
10
+ google = ::Aws::STS::Client.new.config.credentials
64
11
  credentials = google.credentials
65
12
  output = {
66
13
  Version: 1,
@@ -69,5 +16,4 @@ output = {
69
16
  SessionToken: credentials.session_token,
70
17
  Expiration: Time.at(google.expiration.to_i).iso8601
71
18
  }
72
- require 'json'
73
19
  puts output.to_json
@@ -1,6 +1,7 @@
1
1
  require_relative 'google/version'
2
2
  require 'aws-sdk-core'
3
3
  require_relative 'google/credential_provider'
4
+ require_relative 'google/cached_credentials'
4
5
 
5
6
  require 'googleauth'
6
7
  require 'google/api_client/auth/storage'
@@ -23,7 +24,7 @@ module Aws
23
24
  # constructed.
24
25
  class Google
25
26
  include ::Aws::CredentialProvider
26
- include ::Aws::RefreshingCredentials
27
+ include ::Aws::Google::CachedCredentials
27
28
 
28
29
  class << self
29
30
  attr_accessor :config
@@ -34,13 +35,13 @@ module Aws
34
35
  # @option options [Integer] :duration_seconds
35
36
  # @option options [String] :external_id
36
37
  # @option options [STS::Client] :client STS::Client to use (default: create new client)
37
- # @option options [String] :profile AWS Profile to store temporary credentials (default `default`)
38
38
  # @option options [String] :domain G Suite domain for account-selection hint
39
39
  # @option options [String] :online if `true` only a temporary access token will be provided,
40
40
  # a long-lived refresh token will not be created and stored on the filesystem.
41
41
  # @option options [String] :port port for local server to listen on to capture oauth browser redirect.
42
42
  # Defaults to 1234. Set to nil or 0 to use an out-of-band authentication process.
43
- # @option options [::Google::Auth::ClientId] :google_id
43
+ # @option options [String] :client_id Google client ID
44
+ # @option options [String] :client_secret Google client secret
44
45
  def initialize(options = {})
45
46
  @oauth_attempted = false
46
47
  @assume_role_params = options.slice(
@@ -48,26 +49,15 @@ module Aws
48
49
  input.shape.member_names
49
50
  )
50
51
 
51
- @profile = options[:profile] || ENV['AWS_DEFAULT_PROFILE'] || 'default'
52
52
  @google_id = ::Google::Auth::ClientId.new(
53
- options[:google_client_id],
54
- options[:google_client_secret]
53
+ options[:client_id],
54
+ options[:client_secret]
55
55
  )
56
56
  @client = options[:client] || Aws::STS::Client.new(credentials: nil)
57
57
  @domain = options[:domain]
58
58
  @online = options[:online]
59
59
  @port = options[:port] || 1234
60
-
61
- # Use existing AWS credentials stored in the shared config if available.
62
- # If this is `nil` or expired, #refresh will be called on the first AWS API service call
63
- # to generate AWS credentials derived from Google authentication.
64
- @expiration = Aws.shared_config.get('expiration', profile: @profile) rescue nil
65
- @mutex = Mutex.new
66
- if near_expiration?
67
- refresh!
68
- else
69
- @credentials = Aws.shared_config.credentials(profile: @profile) rescue nil
70
- end
60
+ super
71
61
  end
72
62
 
73
63
  private
@@ -199,35 +189,8 @@ Google ID: #{token_params['sub']}", []
199
189
  c.session_token
200
190
  )
201
191
  @expiration = c.expiration.to_i
202
- write_credentials
203
- end
204
-
205
- # Write credentials and expiration to AWS credentials file.
206
- def write_credentials
207
- # AWS CLI is needed because writing AWS credentials is not supported by the AWS Ruby SDK.
208
- return unless system('which aws >/dev/null 2>&1')
209
- %w[
210
- access_key_id
211
- secret_access_key
212
- session_token
213
- ].map {|x| ["aws_#{x}", @credentials.send(x)]}.
214
- to_h.
215
- merge(expiration: @expiration).each do |key, value|
216
- system("aws configure set #{key} #{value} --profile #{@profile}")
217
- end
218
- end
219
- end
220
-
221
- # Patch Aws::SharedConfig to allow fetching arbitrary keys from the shared config.
222
- module SharedConfigGetKey
223
- def get(key, opts = {})
224
- profile = opts.delete(:profile) || @profile_name
225
- if @parsed_config && (prof_config = @parsed_config[profile])
226
- prof_config[key]
227
- end
228
192
  end
229
193
  end
230
- Aws::SharedConfig.prepend SharedConfigGetKey
231
194
 
232
195
  # Extend ::Google::APIClient::Storage to write {type: 'authorized_user'} to credentials,
233
196
  # as required by Google's default credentials loader.
@@ -0,0 +1,47 @@
1
+ module Aws
2
+ class Google
3
+ Aws::SharedConfig.config_reader :expiration
4
+
5
+ # Mixin module extending `RefreshingCredentials` that caches temporary credentials
6
+ # in the credentials file, so a single session can be reused across multiple processes.
7
+ # The temporary credentials are saved to a separate profile with a '_session' suffix.
8
+ module CachedCredentials
9
+ include RefreshingCredentials
10
+
11
+ # @option options [String] :profile AWS Profile to store temporary credentials (default `default`)
12
+ def initialize(options = {})
13
+ # Use existing AWS credentials stored in the shared session config if available.
14
+ # If this is `nil` or expired, #refresh will be called on the first AWS API service call
15
+ # to generate AWS credentials derived from Google authentication.
16
+ @mutex = Mutex.new
17
+
18
+ @profile = options[:profile] || ENV['AWS_PROFILE'] || ENV['AWS_DEFAULT_PROFILE'] || 'default'
19
+ @session_profile = @profile + '_session'
20
+ @expiration = Aws.shared_config.expiration(profile: @session_profile) rescue nil
21
+ @credentials = Aws.shared_config.credentials(profile: @session_profile) rescue nil
22
+ refresh_if_near_expiration
23
+ end
24
+
25
+ def refresh_if_near_expiration
26
+ if near_expiration?
27
+ @mutex.synchronize do
28
+ if near_expiration?
29
+ refresh
30
+ write_credentials
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ # Write credentials and expiration to AWS credentials file.
37
+ def write_credentials
38
+ # AWS CLI is needed because writing AWS credentials is not supported by the AWS Ruby SDK.
39
+ return unless system('which aws >/dev/null 2>&1')
40
+ Aws::SharedCredentials::KEY_MAP.transform_values(&@credentials.method(:send)).
41
+ merge(expiration: @expiration).each do |key, value|
42
+ system("aws configure set #{key} #{value} --profile #{@session_profile}")
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -3,16 +3,34 @@ module Aws
3
3
  # Inserts GoogleCredentials into the default AWS credential provider chain.
4
4
  # Google credentials will only be used if Aws::Google.config is set before initialization.
5
5
  module CredentialProvider
6
- # Insert google_credentials as the second-to-last credentials provider
7
- # (in front of instance profile, which makes an http request).
6
+ # Insert google_credentials as the third-to-last credentials provider
7
+ # (in front of process credentials and instance_profile credentials).
8
8
  def providers
9
- super.insert(-2, [:google_credentials, {}])
9
+ super.insert(-3, [:google_credentials, {}])
10
10
  end
11
11
 
12
12
  def google_credentials(options)
13
- (config = Google.config) && Google.new(options.merge(config))
13
+ profile_name = determine_profile_name(options)
14
+ if Aws.shared_config.config_enabled?
15
+ Aws.shared_config.google_credentials_from_config(profile: profile_name)
16
+ end
17
+ rescue Errors::NoSuchProfileError
18
+ nil
14
19
  end
15
20
  end
16
21
  ::Aws::CredentialProviderChain.prepend CredentialProvider
22
+
23
+ module GoogleSharedCredentials
24
+ def google_credentials_from_config(opts = {})
25
+ p = opts[:profile] || @profile_name
26
+ if @config_enabled && @parsed_config
27
+ entry = @parsed_config.fetch(p, {})
28
+ if (google_opts = entry['google'])
29
+ Google.new(google_opts.transform_keys(&:to_sym))
30
+ end
31
+ end
32
+ end
33
+ end
34
+ ::Aws::SharedConfig.prepend GoogleSharedCredentials
17
35
  end
18
36
  end
@@ -1,5 +1,5 @@
1
1
  module Aws
2
2
  class Google
3
- VERSION = '0.1.3'.freeze
3
+ VERSION = '0.1.5'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-google
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Will Jordan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-02 00:00:00.000000000 Z
11
+ date: 2020-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-core
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '5'
69
- - !ruby/object:Gem::Dependency
70
- name: bundler
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: minitest
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -169,6 +155,7 @@ files:
169
155
  - bin/setup
170
156
  - exe/aws-google
171
157
  - lib/aws/google.rb
158
+ - lib/aws/google/cached_credentials.rb
172
159
  - lib/aws/google/credential_provider.rb
173
160
  - lib/aws/google/version.rb
174
161
  homepage: https://github.com/code-dot-org/aws-google