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 +4 -4
- data/README.md +10 -20
- data/aws-google.gemspec +0 -1
- data/exe/aws-google +1 -55
- data/lib/aws/google.rb +7 -44
- data/lib/aws/google/cached_credentials.rb +47 -0
- data/lib/aws/google/credential_provider.rb +22 -4
- data/lib/aws/google/version.rb +1 -1
- metadata +3 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ea7ae0f33a7dafe59e62cb045d143ed0fdc0a0a017d3e2a17d380cf1f46a49e
|
4
|
+
data.tar.gz: b5bc47171255473122de1cf179828f869a32cd7d6fb5cf5343d85204e7e96c26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
69
|
-
|
70
|
-
```
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
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
|
|
data/aws-google.gemspec
CHANGED
@@ -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'
|
data/exe/aws-google
CHANGED
@@ -6,61 +6,8 @@
|
|
6
6
|
require 'aws/google'
|
7
7
|
require 'time'
|
8
8
|
require 'json'
|
9
|
-
require 'optparse'
|
10
9
|
|
11
|
-
|
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
|
data/lib/aws/google.rb
CHANGED
@@ -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::
|
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 [
|
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[:
|
54
|
-
options[:
|
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
|
7
|
-
# (in front of
|
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(-
|
9
|
+
super.insert(-3, [:google_credentials, {}])
|
10
10
|
end
|
11
11
|
|
12
12
|
def google_credentials(options)
|
13
|
-
|
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
|
data/lib/aws/google/version.rb
CHANGED
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.
|
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-
|
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
|