aws-google 0.1.0
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 +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +5 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +13 -0
- data/README.md +92 -0
- data/Rakefile +10 -0
- data/aws-google.gemspec +35 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/aws/google.rb +193 -0
- data/lib/aws/google/credential_provider.rb +18 -0
- data/lib/aws/google/version.rb +5 -0
- metadata +197 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 76723a29a160f6d7326a3329e08e6316da4e8e224013ef400321cd7780e46340
|
|
4
|
+
data.tar.gz: 2cac963af78ade133bccdafa257bb8bc691a794afa0f1f0172f920ecd5c335a9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 4a2aa252e1108cd54bc562ab4cf2f5c54732f9a66ce86b57fbfd96c43a799c9792d9adb38661488cf00667959a47b091def2a47fc72af55fa2e5d66bd2b9ebf3
|
|
7
|
+
data.tar.gz: 457f3dadbf5bb0b00059576ebc19daeb93a4ddd55867f49d6dab121a17a7041dc87c86fb46b8cc65d77115dbe27cb1a387340344204be7c804c01a82008f9459
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2019 Code.org
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Aws::Google [](https://travis-ci.com/code-dot-org/aws-google)
|
|
2
|
+
|
|
3
|
+
Use Google OAuth as an AWS Credential Provider.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's `Gemfile`:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'aws-google'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
And then execute:
|
|
14
|
+
|
|
15
|
+
$ bundle
|
|
16
|
+
|
|
17
|
+
Or install it yourself as:
|
|
18
|
+
|
|
19
|
+
$ gem install aws-google
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
- Visit the [Google API Console](https://console.developers.google.com/) to create/obtain OAuth 2.0 Client ID credentials (client ID and client secret) for an application in your Google account.
|
|
24
|
+
- Create an AWS IAM Role with the desired IAM policies attached, and a 'trust relationship' (`AssumeRolePolicyDocument`) allowing the `sts:AssumeRoleWithWebIdentity` action to be permitted
|
|
25
|
+
by your Google Client ID and a specific set of Google Account IDs:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"Version": "2012-10-17",
|
|
30
|
+
"Statement": [
|
|
31
|
+
{
|
|
32
|
+
"Effect": "Allow",
|
|
33
|
+
"Principal": {
|
|
34
|
+
"Federated": "accounts.google.com"
|
|
35
|
+
},
|
|
36
|
+
"Action": "sts:AssumeRoleWithWebIdentity",
|
|
37
|
+
"Condition": {
|
|
38
|
+
"StringEquals": {
|
|
39
|
+
"accounts.google.com:aud": "123456789012-abcdefghijklmnopqrstuvwzyz0123456.apps.googleusercontent.com"
|
|
40
|
+
},
|
|
41
|
+
"ForAnyValue:StringEquals": {
|
|
42
|
+
"accounts.google.com:sub": [
|
|
43
|
+
"000000000000000000000",
|
|
44
|
+
"111111111111111111111"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- In your Ruby code, construct an `Aws::Google` object by passing in the AWS role, client id and client secret:
|
|
54
|
+
```ruby
|
|
55
|
+
aws_role = 'arn:aws:iam::[AccountID]:role/[Role]'
|
|
56
|
+
client_id = '123456789012-abcdefghijklmnopqrstuvwzyz0123456.apps.googleusercontent.com'
|
|
57
|
+
client_secret = '01234567890abcdefghijklmn'
|
|
58
|
+
|
|
59
|
+
role_credentials = Aws::Google.new(
|
|
60
|
+
role_arn: aws_role,
|
|
61
|
+
google_client_id: client_id,
|
|
62
|
+
google_client_secret: client_secret
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
puts Aws::STS::Client.new(credentials: role_credentials).get_caller_identity
|
|
66
|
+
```
|
|
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
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Development
|
|
81
|
+
|
|
82
|
+
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.
|
|
83
|
+
|
|
84
|
+
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).
|
|
85
|
+
|
|
86
|
+
## Contributing
|
|
87
|
+
|
|
88
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/code-dot-org/aws-google.
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
The gem is available as open source under the terms of the [Apache 2.0 License](http://opensource.org/licenses/apache-2.0).
|
data/Rakefile
ADDED
data/aws-google.gemspec
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
|
+
require 'aws/google/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'aws-google'
|
|
7
|
+
spec.version = Aws::Google::VERSION
|
|
8
|
+
spec.authors = ['Will Jordan']
|
|
9
|
+
spec.email = ['will@code.org']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'Use Google OAuth as an AWS credential provider'
|
|
12
|
+
spec.description = 'Use Google OAuth as an AWS credential provider.'
|
|
13
|
+
spec.homepage = 'https://github.com/code-dot-org/aws-google'
|
|
14
|
+
spec.license = 'Apache-2.0'
|
|
15
|
+
|
|
16
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
|
19
|
+
end
|
|
20
|
+
spec.bindir = 'exe'
|
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
22
|
+
spec.require_paths = ['lib']
|
|
23
|
+
|
|
24
|
+
spec.add_dependency 'aws-sdk-core', '~> 3'
|
|
25
|
+
spec.add_dependency 'google-api-client', '~> 0.23'
|
|
26
|
+
spec.add_dependency 'launchy', '~> 2' # Peer dependency of Google::APIClient::InstalledAppFlow
|
|
27
|
+
|
|
28
|
+
spec.add_development_dependency 'activesupport', '~> 5'
|
|
29
|
+
spec.add_development_dependency 'bundler', '~> 1'
|
|
30
|
+
spec.add_development_dependency 'minitest', '~> 5.10'
|
|
31
|
+
spec.add_development_dependency 'mocha', '~> 1.5'
|
|
32
|
+
spec.add_development_dependency 'rake', '~> 12'
|
|
33
|
+
spec.add_development_dependency 'timecop', '~> 0.8'
|
|
34
|
+
spec.add_development_dependency 'webmock', '~> 3.3'
|
|
35
|
+
end
|
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
require 'aws/google'
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require 'irb'
|
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/aws/google.rb
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
require_relative 'google/version'
|
|
2
|
+
require 'aws-sdk-core'
|
|
3
|
+
require_relative 'google/credential_provider'
|
|
4
|
+
|
|
5
|
+
require 'googleauth'
|
|
6
|
+
require 'google/api_client/auth/storage'
|
|
7
|
+
require 'google/api_client/auth/storages/file_store'
|
|
8
|
+
|
|
9
|
+
module Aws
|
|
10
|
+
# An auto-refreshing credential provider that works by assuming
|
|
11
|
+
# a role via {Aws::STS::Client#assume_role_with_web_identity},
|
|
12
|
+
# using an ID token derived from a Google refresh token.
|
|
13
|
+
#
|
|
14
|
+
# role_credentials = Aws::Google.new(
|
|
15
|
+
# role_arn: aws_role,
|
|
16
|
+
# google_client_id: client_id,
|
|
17
|
+
# google_client_secret: client_secret
|
|
18
|
+
# )
|
|
19
|
+
#
|
|
20
|
+
# ec2 = Aws::EC2::Client.new(credentials: role_credentials)
|
|
21
|
+
#
|
|
22
|
+
# If you omit `:client` option, a new {Aws::STS::Client} object will be
|
|
23
|
+
# constructed.
|
|
24
|
+
class Google
|
|
25
|
+
include ::Aws::CredentialProvider
|
|
26
|
+
include ::Aws::RefreshingCredentials
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
attr_accessor :config
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @option options [required, String] :role_arn
|
|
33
|
+
# @option options [String] :policy
|
|
34
|
+
# @option options [Integer] :duration_seconds
|
|
35
|
+
# @option options [String] :external_id
|
|
36
|
+
# @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
|
+
# @option options [String] :domain G Suite domain for account-selection hint
|
|
39
|
+
# @option options [String] :online if `true` only a temporary access token will be provided,
|
|
40
|
+
# a long-lived refresh token will not be created and stored on the filesystem.
|
|
41
|
+
# @option options [::Google::Auth::ClientId] :google_id
|
|
42
|
+
def initialize(options = {})
|
|
43
|
+
@oauth_attempted = false
|
|
44
|
+
@assume_role_params = options.slice(
|
|
45
|
+
*Aws::STS::Client.api.operation(:assume_role_with_web_identity).
|
|
46
|
+
input.shape.member_names
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
@profile = options[:profile] || ENV['AWS_DEFAULT_PROFILE'] || 'default'
|
|
50
|
+
@google_id = ::Google::Auth::ClientId.new(
|
|
51
|
+
options[:google_client_id],
|
|
52
|
+
options[:google_client_secret]
|
|
53
|
+
)
|
|
54
|
+
@client = options[:client] || Aws::STS::Client.new(credentials: nil)
|
|
55
|
+
@domain = options[:domain]
|
|
56
|
+
@online = options[:online]
|
|
57
|
+
|
|
58
|
+
# Use existing AWS credentials stored in the shared config if available.
|
|
59
|
+
# If this is `nil` or expired, #refresh will be called on the first AWS API service call
|
|
60
|
+
# to generate AWS credentials derived from Google authentication.
|
|
61
|
+
@expiration = Aws.shared_config.get('expiration', profile: @profile) rescue nil
|
|
62
|
+
@mutex = Mutex.new
|
|
63
|
+
if near_expiration?
|
|
64
|
+
refresh!
|
|
65
|
+
else
|
|
66
|
+
@credentials = Aws.shared_config.credentials(profile: @profile) rescue nil
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# Use cached Application Default Credentials if available,
|
|
73
|
+
# otherwise fallback to creating new Google credentials through browser login.
|
|
74
|
+
def google_client
|
|
75
|
+
@google_client ||= (::Google::Auth.get_application_default rescue nil) || google_oauth
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Create an OAuth2 Client using Google's default browser-based OAuth InstalledAppFlow.
|
|
79
|
+
# Store cached credentials to the standard Google Application Default Credentials location.
|
|
80
|
+
# Ref: http://goo.gl/IUuyuX
|
|
81
|
+
# @return [Signet::OAuth2::Client]
|
|
82
|
+
def google_oauth
|
|
83
|
+
return nil if @oauth_attempted
|
|
84
|
+
@oauth_attempted = true
|
|
85
|
+
|
|
86
|
+
path = "#{ENV['HOME']}/.config/#{::Google::Auth::CredentialsLoader::WELL_KNOWN_PATH}"
|
|
87
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
88
|
+
storage = GoogleStorage.new(::Google::APIClient::FileStore.new(path))
|
|
89
|
+
|
|
90
|
+
options = {
|
|
91
|
+
client_id: @google_id.id,
|
|
92
|
+
client_secret: @google_id.secret,
|
|
93
|
+
scope: %w[openid email]
|
|
94
|
+
}
|
|
95
|
+
uri_options = {include_granted_scopes: true}
|
|
96
|
+
uri_options[:hd] = @domain if @domain
|
|
97
|
+
uri_options[:access_type] = 'online' if @online
|
|
98
|
+
|
|
99
|
+
require 'google/api_client/auth/installed_app'
|
|
100
|
+
if defined?(Launchy) && Launchy::Application::Browser.new.app_list.any?
|
|
101
|
+
::Google::APIClient::InstalledAppFlow.new(options).authorize(storage, uri_options)
|
|
102
|
+
else
|
|
103
|
+
credentials = ::Google::Auth::UserRefreshCredentials.new(
|
|
104
|
+
options.merge(redirect_uri: 'urn:ietf:wg:oauth:2.0:oob')
|
|
105
|
+
)
|
|
106
|
+
url = credentials.authorization_uri(uri_options)
|
|
107
|
+
print 'Open the following URL in the browser and enter the ' \
|
|
108
|
+
"resulting code after authorization:\n#{url}\n> "
|
|
109
|
+
credentials.code = gets
|
|
110
|
+
credentials.fetch_access_token!
|
|
111
|
+
credentials.tap(&storage.method(:write_credentials))
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def refresh
|
|
116
|
+
assume_role = begin
|
|
117
|
+
client = google_client
|
|
118
|
+
return unless client
|
|
119
|
+
|
|
120
|
+
begin
|
|
121
|
+
tries ||= 2
|
|
122
|
+
id_token = client.id_token
|
|
123
|
+
# Decode the JWT id_token to use the Google email as the AWS role session name.
|
|
124
|
+
token_params = JWT.decode(id_token, nil, false).first
|
|
125
|
+
rescue JWT::DecodeError, JWT::ExpiredSignature
|
|
126
|
+
# Refresh and retry once if token is expired or invalid.
|
|
127
|
+
client.refresh!
|
|
128
|
+
raise if (tries -= 1).zero?
|
|
129
|
+
retry
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
@client.assume_role_with_web_identity(
|
|
133
|
+
@assume_role_params.merge(
|
|
134
|
+
web_identity_token: id_token,
|
|
135
|
+
role_session_name: token_params['email']
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
rescue Signet::AuthorizationError => e
|
|
139
|
+
retry if (@google_client = google_oauth)
|
|
140
|
+
raise
|
|
141
|
+
rescue Aws::STS::Errors::AccessDenied => e
|
|
142
|
+
retry if (@google_client = google_oauth)
|
|
143
|
+
raise e, "\nYour Google ID does not have access to the requested AWS Role. Ask your administrator to provide access.
|
|
144
|
+
Role: #{@assume_role_params[:role_arn]}
|
|
145
|
+
Email: #{token_params['email']}
|
|
146
|
+
Google ID: #{token_params['sub']}", e.backtrace
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
c = assume_role.credentials
|
|
150
|
+
@credentials = Aws::Credentials.new(
|
|
151
|
+
c.access_key_id,
|
|
152
|
+
c.secret_access_key,
|
|
153
|
+
c.session_token
|
|
154
|
+
)
|
|
155
|
+
@expiration = c.expiration.to_i
|
|
156
|
+
write_credentials
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Write credentials and expiration to AWS credentials file.
|
|
160
|
+
def write_credentials
|
|
161
|
+
# AWS CLI is needed because writing AWS credentials is not supported by the AWS Ruby SDK.
|
|
162
|
+
return unless system('which aws >/dev/null 2>&1')
|
|
163
|
+
%w[
|
|
164
|
+
access_key_id
|
|
165
|
+
secret_access_key
|
|
166
|
+
session_token
|
|
167
|
+
].map {|x| ["aws_#{x}", @credentials.send(x)]}.
|
|
168
|
+
to_h.
|
|
169
|
+
merge(expiration: @expiration).each do |key, value|
|
|
170
|
+
system("aws configure set #{key} #{value} --profile #{@profile}")
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Patch Aws::SharedConfig to allow fetching arbitrary keys from the shared config.
|
|
176
|
+
module SharedConfigGetKey
|
|
177
|
+
def get(key, opts = {})
|
|
178
|
+
profile = opts.delete(:profile) || @profile_name
|
|
179
|
+
if @parsed_config && (prof_config = @parsed_config[profile])
|
|
180
|
+
prof_config[key]
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
Aws::SharedConfig.prepend SharedConfigGetKey
|
|
185
|
+
|
|
186
|
+
# Extend ::Google::APIClient::Storage to write {type: 'authorized_user'} to credentials,
|
|
187
|
+
# as required by Google's default credentials loader.
|
|
188
|
+
class GoogleStorage < ::Google::APIClient::Storage
|
|
189
|
+
def credentials_hash
|
|
190
|
+
super.merge(type: 'authorized_user')
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Aws
|
|
2
|
+
class Google
|
|
3
|
+
# Inserts GoogleCredentials into the default AWS credential provider chain.
|
|
4
|
+
# Google credentials will only be used if Aws::Google.config is set before initialization.
|
|
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).
|
|
8
|
+
def providers
|
|
9
|
+
super.insert(-2, [:google_credentials, {}])
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def google_credentials(options)
|
|
13
|
+
(config = Google.config) && Google.new(options.merge(config))
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
::Aws::CredentialProviderChain.prepend CredentialProvider
|
|
17
|
+
end
|
|
18
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: aws-google
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Will Jordan
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2019-02-07 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: aws-sdk-core
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '3'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '3'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: google-api-client
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.23'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.23'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: launchy
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '2'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '2'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: activesupport
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '5'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
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: '1'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '1'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: minitest
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '5.10'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '5.10'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: mocha
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '1.5'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '1.5'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rake
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '12'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '12'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: timecop
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0.8'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0.8'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: webmock
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '3.3'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '3.3'
|
|
153
|
+
description: Use Google OAuth as an AWS credential provider.
|
|
154
|
+
email:
|
|
155
|
+
- will@code.org
|
|
156
|
+
executables: []
|
|
157
|
+
extensions: []
|
|
158
|
+
extra_rdoc_files: []
|
|
159
|
+
files:
|
|
160
|
+
- ".gitignore"
|
|
161
|
+
- ".travis.yml"
|
|
162
|
+
- Gemfile
|
|
163
|
+
- LICENSE.txt
|
|
164
|
+
- README.md
|
|
165
|
+
- Rakefile
|
|
166
|
+
- aws-google.gemspec
|
|
167
|
+
- bin/console
|
|
168
|
+
- bin/setup
|
|
169
|
+
- lib/aws/google.rb
|
|
170
|
+
- lib/aws/google/credential_provider.rb
|
|
171
|
+
- lib/aws/google/version.rb
|
|
172
|
+
homepage: https://github.com/code-dot-org/aws-google
|
|
173
|
+
licenses:
|
|
174
|
+
- Apache-2.0
|
|
175
|
+
metadata:
|
|
176
|
+
allowed_push_host: https://rubygems.org
|
|
177
|
+
post_install_message:
|
|
178
|
+
rdoc_options: []
|
|
179
|
+
require_paths:
|
|
180
|
+
- lib
|
|
181
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
182
|
+
requirements:
|
|
183
|
+
- - ">="
|
|
184
|
+
- !ruby/object:Gem::Version
|
|
185
|
+
version: '0'
|
|
186
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
|
+
requirements:
|
|
188
|
+
- - ">="
|
|
189
|
+
- !ruby/object:Gem::Version
|
|
190
|
+
version: '0'
|
|
191
|
+
requirements: []
|
|
192
|
+
rubyforge_project:
|
|
193
|
+
rubygems_version: 2.7.4
|
|
194
|
+
signing_key:
|
|
195
|
+
specification_version: 4
|
|
196
|
+
summary: Use Google OAuth as an AWS credential provider
|
|
197
|
+
test_files: []
|