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 +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
|