aws-google 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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