googleauth 0.17.1 → 1.8.1
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/CHANGELOG.md +127 -62
- data/README.md +50 -15
- data/lib/googleauth/application_default.rb +15 -30
- data/lib/googleauth/base_client.rb +80 -0
- data/lib/googleauth/client_id.rb +35 -33
- data/lib/googleauth/compute_engine.rb +33 -40
- data/lib/googleauth/credentials.rb +12 -28
- data/lib/googleauth/credentials_loader.rb +21 -50
- data/lib/googleauth/default_credentials.rb +15 -27
- data/lib/googleauth/external_account/aws_credentials.rb +378 -0
- data/lib/googleauth/external_account/base_credentials.rb +158 -0
- data/lib/googleauth/external_account/external_account_utils.rb +103 -0
- data/lib/googleauth/external_account/identity_pool_credentials.rb +118 -0
- data/lib/googleauth/external_account/pluggable_credentials.rb +156 -0
- data/lib/googleauth/external_account.rb +93 -0
- data/lib/googleauth/helpers/connection.rb +35 -0
- data/lib/googleauth/iam.rb +10 -25
- data/lib/googleauth/id_tokens/errors.rb +9 -23
- data/lib/googleauth/id_tokens/key_sources.rb +19 -33
- data/lib/googleauth/id_tokens/verifier.rb +9 -23
- data/lib/googleauth/id_tokens.rb +11 -25
- data/lib/googleauth/json_key_reader.rb +10 -25
- data/lib/googleauth/oauth2/sts_client.rb +109 -0
- data/lib/googleauth/scope_util.rb +45 -27
- data/lib/googleauth/service_account.rb +11 -28
- data/lib/googleauth/signet.rb +16 -58
- data/lib/googleauth/stores/file_token_store.rb +10 -25
- data/lib/googleauth/stores/redis_token_store.rb +10 -25
- data/lib/googleauth/token_store.rb +10 -25
- data/lib/googleauth/user_authorizer.rb +22 -30
- data/lib/googleauth/user_refresh.rb +15 -27
- data/lib/googleauth/version.rb +11 -26
- data/lib/googleauth/web_user_authorizer.rb +14 -29
- data/lib/googleauth.rb +10 -25
- metadata +26 -25
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Copyright 2023 Google, Inc.
|
|
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.
|
|
14
|
+
|
|
15
|
+
require "time"
|
|
16
|
+
require "googleauth/external_account/base_credentials"
|
|
17
|
+
require "googleauth/external_account/external_account_utils"
|
|
18
|
+
|
|
19
|
+
module Google
|
|
20
|
+
# Module Auth provides classes that provide Google-specific authorization used to access Google APIs.
|
|
21
|
+
module Auth
|
|
22
|
+
module ExternalAccount
|
|
23
|
+
# This module handles the retrieval of credentials from Google Cloud by utilizing the any 3PI
|
|
24
|
+
# provider then exchanging the credentials for a short-lived Google Cloud access token.
|
|
25
|
+
class IdentityPoolCredentials
|
|
26
|
+
include Google::Auth::ExternalAccount::BaseCredentials
|
|
27
|
+
include Google::Auth::ExternalAccount::ExternalAccountUtils
|
|
28
|
+
extend CredentialsLoader
|
|
29
|
+
|
|
30
|
+
# Will always be nil, but method still gets used.
|
|
31
|
+
attr_reader :client_id
|
|
32
|
+
|
|
33
|
+
# Initialize from options map.
|
|
34
|
+
#
|
|
35
|
+
# @param [string] audience
|
|
36
|
+
# @param [hash{symbol => value}] credential_source
|
|
37
|
+
# credential_source is a hash that contains either source file or url.
|
|
38
|
+
# credential_source_format is either text or json. To define how we parse the credential response.
|
|
39
|
+
#
|
|
40
|
+
def initialize options = {}
|
|
41
|
+
base_setup options
|
|
42
|
+
|
|
43
|
+
@audience = options[:audience]
|
|
44
|
+
@credential_source = options[:credential_source] || {}
|
|
45
|
+
@credential_source_file = @credential_source[:file]
|
|
46
|
+
@credential_source_url = @credential_source[:url]
|
|
47
|
+
@credential_source_headers = @credential_source[:headers] || {}
|
|
48
|
+
@credential_source_format = @credential_source[:format] || {}
|
|
49
|
+
@credential_source_format_type = @credential_source_format[:type] || "text"
|
|
50
|
+
validate_credential_source
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Implementation of BaseCredentials retrieve_subject_token!
|
|
54
|
+
def retrieve_subject_token!
|
|
55
|
+
content, resource_name = token_data
|
|
56
|
+
if @credential_source_format_type == "text"
|
|
57
|
+
token = content
|
|
58
|
+
else
|
|
59
|
+
begin
|
|
60
|
+
response_data = MultiJson.load content, symbolize_keys: true
|
|
61
|
+
token = response_data[@credential_source_field_name.to_sym]
|
|
62
|
+
rescue StandardError
|
|
63
|
+
raise "Unable to parse subject_token from JSON resource #{resource_name} " \
|
|
64
|
+
"using key #{@credential_source_field_name}"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
raise "Missing subject_token in the credential_source file/response." unless token
|
|
68
|
+
token
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
def validate_credential_source
|
|
74
|
+
# `environment_id` is only supported in AWS or dedicated future external account credentials.
|
|
75
|
+
unless @credential_source[:environment_id].nil?
|
|
76
|
+
raise "Invalid Identity Pool credential_source field 'environment_id'"
|
|
77
|
+
end
|
|
78
|
+
unless ["json", "text"].include? @credential_source_format_type
|
|
79
|
+
raise "Invalid credential_source format #{@credential_source_format_type}"
|
|
80
|
+
end
|
|
81
|
+
# for JSON types, get the required subject_token field name.
|
|
82
|
+
@credential_source_field_name = @credential_source_format[:subject_token_field_name]
|
|
83
|
+
if @credential_source_format_type == "json" && @credential_source_field_name.nil?
|
|
84
|
+
raise "Missing subject_token_field_name for JSON credential_source format"
|
|
85
|
+
end
|
|
86
|
+
# check file or url must be fulfilled and mutually exclusiveness.
|
|
87
|
+
if @credential_source_file && @credential_source_url
|
|
88
|
+
raise "Ambiguous credential_source. 'file' is mutually exclusive with 'url'."
|
|
89
|
+
end
|
|
90
|
+
return unless (@credential_source_file || @credential_source_url).nil?
|
|
91
|
+
raise "Missing credential_source. A 'file' or 'url' must be provided."
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def token_data
|
|
95
|
+
@credential_source_file.nil? ? url_data : file_data
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def file_data
|
|
99
|
+
raise "File #{@credential_source_file} was not found." unless File.exist? @credential_source_file
|
|
100
|
+
content = File.read @credential_source_file, encoding: "utf-8"
|
|
101
|
+
[content, @credential_source_file]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def url_data
|
|
105
|
+
begin
|
|
106
|
+
response = connection.get @credential_source_url do |req|
|
|
107
|
+
req.headers.merge! @credential_source_headers
|
|
108
|
+
end
|
|
109
|
+
rescue Faraday::Error => e
|
|
110
|
+
raise "Error retrieving from credential url: #{e}"
|
|
111
|
+
end
|
|
112
|
+
raise "Unable to retrieve Identity Pool subject token #{response.body}" unless response.success?
|
|
113
|
+
[response.body, @credential_source_url]
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Copyright 2023 Google, Inc.
|
|
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.
|
|
14
|
+
|
|
15
|
+
require "open3"
|
|
16
|
+
require "time"
|
|
17
|
+
require "googleauth/external_account/base_credentials"
|
|
18
|
+
require "googleauth/external_account/external_account_utils"
|
|
19
|
+
|
|
20
|
+
module Google
|
|
21
|
+
# Module Auth provides classes that provide Google-specific authorization used to access Google APIs.
|
|
22
|
+
module Auth
|
|
23
|
+
module ExternalAccount
|
|
24
|
+
# This module handles the retrieval of credentials from Google Cloud by utilizing the any 3PI
|
|
25
|
+
# provider then exchanging the credentials for a short-lived Google Cloud access token.
|
|
26
|
+
class PluggableAuthCredentials
|
|
27
|
+
# constant for pluggable auth enablement in environment variable.
|
|
28
|
+
ENABLE_PLUGGABLE_ENV = "GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES".freeze
|
|
29
|
+
EXECUTABLE_SUPPORTED_MAX_VERSION = 1
|
|
30
|
+
EXECUTABLE_TIMEOUT_MILLIS_DEFAULT = 30 * 1000
|
|
31
|
+
EXECUTABLE_TIMEOUT_MILLIS_LOWER_BOUND = 5 * 1000
|
|
32
|
+
EXECUTABLE_TIMEOUT_MILLIS_UPPER_BOUND = 120 * 1000
|
|
33
|
+
ID_TOKEN_TYPE = ["urn:ietf:params:oauth:token-type:jwt", "urn:ietf:params:oauth:token-type:id_token"].freeze
|
|
34
|
+
|
|
35
|
+
include Google::Auth::ExternalAccount::BaseCredentials
|
|
36
|
+
include Google::Auth::ExternalAccount::ExternalAccountUtils
|
|
37
|
+
extend CredentialsLoader
|
|
38
|
+
|
|
39
|
+
# Will always be nil, but method still gets used.
|
|
40
|
+
attr_reader :client_id
|
|
41
|
+
|
|
42
|
+
# Initialize from options map.
|
|
43
|
+
#
|
|
44
|
+
# @param [string] audience
|
|
45
|
+
# @param [hash{symbol => value}] credential_source
|
|
46
|
+
# credential_source is a hash that contains either source file or url.
|
|
47
|
+
# credential_source_format is either text or json. To define how we parse the credential response.
|
|
48
|
+
#
|
|
49
|
+
def initialize options = {}
|
|
50
|
+
base_setup options
|
|
51
|
+
|
|
52
|
+
@audience = options[:audience]
|
|
53
|
+
@credential_source = options[:credential_source] || {}
|
|
54
|
+
@credential_source_executable = @credential_source[:executable]
|
|
55
|
+
raise "Missing excutable source. An 'executable' must be provided" if @credential_source_executable.nil?
|
|
56
|
+
@credential_source_executable_command = @credential_source_executable[:command]
|
|
57
|
+
if @credential_source_executable_command.nil?
|
|
58
|
+
raise "Missing command field. Executable command must be provided."
|
|
59
|
+
end
|
|
60
|
+
@credential_source_executable_timeout_millis = @credential_source_executable[:timeout_millis] ||
|
|
61
|
+
EXECUTABLE_TIMEOUT_MILLIS_DEFAULT
|
|
62
|
+
if @credential_source_executable_timeout_millis < EXECUTABLE_TIMEOUT_MILLIS_LOWER_BOUND ||
|
|
63
|
+
@credential_source_executable_timeout_millis > EXECUTABLE_TIMEOUT_MILLIS_UPPER_BOUND
|
|
64
|
+
raise "Timeout must be between 5 and 120 seconds."
|
|
65
|
+
end
|
|
66
|
+
@credential_source_executable_output_file = @credential_source_executable[:output_file]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def retrieve_subject_token!
|
|
70
|
+
unless ENV[ENABLE_PLUGGABLE_ENV] == "1"
|
|
71
|
+
raise "Executables need to be explicitly allowed (set GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES to '1') " \
|
|
72
|
+
"to run."
|
|
73
|
+
end
|
|
74
|
+
# check output file first
|
|
75
|
+
subject_token = load_subject_token_from_output_file
|
|
76
|
+
return subject_token unless subject_token.nil?
|
|
77
|
+
# environment variable injection
|
|
78
|
+
env = inject_environment_variables
|
|
79
|
+
output = subprocess_with_timeout env, @credential_source_executable_command,
|
|
80
|
+
@credential_source_executable_timeout_millis
|
|
81
|
+
response = MultiJson.load output, symbolize_keys: true
|
|
82
|
+
parse_subject_token response
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def load_subject_token_from_output_file
|
|
88
|
+
return nil if @credential_source_executable_output_file.nil?
|
|
89
|
+
return nil unless File.exist? @credential_source_executable_output_file
|
|
90
|
+
begin
|
|
91
|
+
content = File.read @credential_source_executable_output_file, encoding: "utf-8"
|
|
92
|
+
response = MultiJson.load content, symbolize_keys: true
|
|
93
|
+
rescue StandardError
|
|
94
|
+
return nil
|
|
95
|
+
end
|
|
96
|
+
begin
|
|
97
|
+
subject_token = parse_subject_token response
|
|
98
|
+
rescue StandardError => e
|
|
99
|
+
return nil if e.message.match(/The token returned by the executable is expired/)
|
|
100
|
+
raise e
|
|
101
|
+
end
|
|
102
|
+
subject_token
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def parse_subject_token response
|
|
106
|
+
validate_response_schema response
|
|
107
|
+
unless response[:success]
|
|
108
|
+
if response[:code].nil? || response[:message].nil?
|
|
109
|
+
raise "Error code and message fields are required in the response."
|
|
110
|
+
end
|
|
111
|
+
raise "Executable returned unsuccessful response: code: #{response[:code]}, message: #{response[:message]}."
|
|
112
|
+
end
|
|
113
|
+
if response[:expiration_time] && response[:expiration_time] < Time.now.to_i
|
|
114
|
+
raise "The token returned by the executable is expired."
|
|
115
|
+
end
|
|
116
|
+
raise "The executable response is missing the token_type field." if response[:token_type].nil?
|
|
117
|
+
return response[:id_token] if ID_TOKEN_TYPE.include? response[:token_type]
|
|
118
|
+
return response[:saml_response] if response[:token_type] == "urn:ietf:params:oauth:token-type:saml2"
|
|
119
|
+
raise "Executable returned unsupported token type."
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def validate_response_schema response
|
|
123
|
+
raise "The executable response is missing the version field." if response[:version].nil?
|
|
124
|
+
if response[:version] > EXECUTABLE_SUPPORTED_MAX_VERSION
|
|
125
|
+
raise "Executable returned unsupported version #{response[:version]}."
|
|
126
|
+
end
|
|
127
|
+
raise "The executable response is missing the success field." if response[:success].nil?
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def inject_environment_variables
|
|
131
|
+
env = ENV.to_h
|
|
132
|
+
env["GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE"] = @audience
|
|
133
|
+
env["GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE"] = @subject_token_type
|
|
134
|
+
env["GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE"] = "0" # only non-interactive mode we support.
|
|
135
|
+
unless @service_account_impersonation_url.nil?
|
|
136
|
+
env["GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL"] = service_account_email
|
|
137
|
+
end
|
|
138
|
+
unless @credential_source_executable_output_file.nil?
|
|
139
|
+
env["GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE"] = @credential_source_executable_output_file
|
|
140
|
+
end
|
|
141
|
+
env
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def subprocess_with_timeout environment_vars, command, timeout_seconds
|
|
145
|
+
Timeout.timeout timeout_seconds do
|
|
146
|
+
output, error, status = Open3.capture3 environment_vars, command
|
|
147
|
+
unless status.success?
|
|
148
|
+
raise "Executable exited with non-zero return code #{status.exitstatus}. Error: #{output}, #{error}"
|
|
149
|
+
end
|
|
150
|
+
output
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Copyright 2022 Google, Inc.
|
|
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.
|
|
14
|
+
|
|
15
|
+
require "time"
|
|
16
|
+
require "uri"
|
|
17
|
+
require "googleauth/credentials_loader"
|
|
18
|
+
require "googleauth/external_account/aws_credentials"
|
|
19
|
+
require "googleauth/external_account/identity_pool_credentials"
|
|
20
|
+
require "googleauth/external_account/pluggable_credentials"
|
|
21
|
+
|
|
22
|
+
module Google
|
|
23
|
+
# Module Auth provides classes that provide Google-specific authorization
|
|
24
|
+
# used to access Google APIs.
|
|
25
|
+
module Auth
|
|
26
|
+
# Authenticates requests using External Account credentials, such
|
|
27
|
+
# as those provided by the AWS provider.
|
|
28
|
+
module ExternalAccount
|
|
29
|
+
# Provides an entrypoint for all Exernal Account credential classes.
|
|
30
|
+
class Credentials
|
|
31
|
+
# The subject token type used for AWS external_account credentials.
|
|
32
|
+
AWS_SUBJECT_TOKEN_TYPE = "urn:ietf:params:aws:token-type:aws4_request".freeze
|
|
33
|
+
MISSING_CREDENTIAL_SOURCE = "missing credential source for external account".freeze
|
|
34
|
+
INVALID_EXTERNAL_ACCOUNT_TYPE = "credential source is not supported external account type".freeze
|
|
35
|
+
|
|
36
|
+
# Create a ExternalAccount::Credentials
|
|
37
|
+
#
|
|
38
|
+
# @param json_key_io [IO] an IO from which the JSON key can be read
|
|
39
|
+
# @param scope [String,Array,nil] the scope(s) to access
|
|
40
|
+
def self.make_creds options = {}
|
|
41
|
+
json_key_io, scope = options.values_at :json_key_io, :scope
|
|
42
|
+
|
|
43
|
+
raise "A json file is required for external account credentials." unless json_key_io
|
|
44
|
+
user_creds = read_json_key json_key_io
|
|
45
|
+
|
|
46
|
+
# AWS credentials is determined by aws subject token type
|
|
47
|
+
return make_aws_credentials user_creds, scope if user_creds[:subject_token_type] == AWS_SUBJECT_TOKEN_TYPE
|
|
48
|
+
|
|
49
|
+
raise MISSING_CREDENTIAL_SOURCE if user_creds[:credential_source].nil?
|
|
50
|
+
user_creds[:scope] = scope
|
|
51
|
+
make_external_account_credentials user_creds
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Reads the required fields from the JSON.
|
|
55
|
+
def self.read_json_key json_key_io
|
|
56
|
+
json_key = MultiJson.load json_key_io.read, symbolize_keys: true
|
|
57
|
+
wanted = [
|
|
58
|
+
:audience, :subject_token_type, :token_url, :credential_source
|
|
59
|
+
]
|
|
60
|
+
wanted.each do |key|
|
|
61
|
+
raise "the json is missing the #{key} field" unless json_key.key? key
|
|
62
|
+
end
|
|
63
|
+
json_key
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
class << self
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def make_aws_credentials user_creds, scope
|
|
70
|
+
Google::Auth::ExternalAccount::AwsCredentials.new(
|
|
71
|
+
audience: user_creds[:audience],
|
|
72
|
+
scope: scope,
|
|
73
|
+
subject_token_type: user_creds[:subject_token_type],
|
|
74
|
+
token_url: user_creds[:token_url],
|
|
75
|
+
credential_source: user_creds[:credential_source],
|
|
76
|
+
service_account_impersonation_url: user_creds[:service_account_impersonation_url]
|
|
77
|
+
)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def make_external_account_credentials user_creds
|
|
81
|
+
unless user_creds[:credential_source][:file].nil? && user_creds[:credential_source][:url].nil?
|
|
82
|
+
return Google::Auth::ExternalAccount::IdentityPoolCredentials.new user_creds
|
|
83
|
+
end
|
|
84
|
+
unless user_creds[:credential_source][:executable].nil?
|
|
85
|
+
return Google::Auth::ExternalAccount::PluggableAuthCredentials.new user_creds
|
|
86
|
+
end
|
|
87
|
+
raise INVALID_EXTERNAL_ACCOUNT_TYPE
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Copyright 2023 Google, Inc.
|
|
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.
|
|
14
|
+
|
|
15
|
+
require "faraday"
|
|
16
|
+
|
|
17
|
+
module Google
|
|
18
|
+
# Module Auth provides classes that provide Google-specific authorization
|
|
19
|
+
# used to access Google APIs.
|
|
20
|
+
module Auth
|
|
21
|
+
# Helpers provides utility methods for Google::Auth.
|
|
22
|
+
module Helpers
|
|
23
|
+
# Connection provides a Faraday connection for use with Google::Auth.
|
|
24
|
+
module Connection
|
|
25
|
+
module_function
|
|
26
|
+
|
|
27
|
+
attr_accessor :default_connection
|
|
28
|
+
|
|
29
|
+
def connection
|
|
30
|
+
@default_connection || Faraday.default_connection
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/googleauth/iam.rb
CHANGED
|
@@ -1,31 +1,16 @@
|
|
|
1
|
-
# Copyright 2015
|
|
2
|
-
# All rights reserved.
|
|
1
|
+
# Copyright 2015 Google, Inc.
|
|
3
2
|
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
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
|
|
7
6
|
#
|
|
8
|
-
#
|
|
9
|
-
# notice, this list of conditions and the following disclaimer.
|
|
10
|
-
# * Redistributions in binary form must reproduce the above
|
|
11
|
-
# copyright notice, this list of conditions and the following disclaimer
|
|
12
|
-
# in the documentation and/or other materials provided with the
|
|
13
|
-
# distribution.
|
|
14
|
-
# * Neither the name of Google Inc. nor the names of its
|
|
15
|
-
# contributors may be used to endorse or promote products derived from
|
|
16
|
-
# this software without specific prior written permission.
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
17
8
|
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
24
|
-
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
25
|
-
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
26
|
-
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
27
|
-
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
-
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
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.
|
|
29
14
|
|
|
30
15
|
require "googleauth/signet"
|
|
31
16
|
require "googleauth/credentials_loader"
|
|
@@ -2,31 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
# Copyright 2020 Google LLC
|
|
4
4
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
8
|
#
|
|
9
|
-
#
|
|
10
|
-
# notice, this list of conditions and the following disclaimer.
|
|
11
|
-
# * Redistributions in binary form must reproduce the above
|
|
12
|
-
# copyright notice, this list of conditions and the following disclaimer
|
|
13
|
-
# in the documentation and/or other materials provided with the
|
|
14
|
-
# distribution.
|
|
15
|
-
# * Neither the name of Google Inc. nor the names of its
|
|
16
|
-
# contributors may be used to endorse or promote products derived from
|
|
17
|
-
# this software without specific prior written permission.
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
18
10
|
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
25
|
-
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
26
|
-
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
27
|
-
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
28
|
-
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
-
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
30
16
|
|
|
31
17
|
|
|
32
18
|
module Google
|
|
@@ -2,31 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
# Copyright 2020 Google LLC
|
|
4
4
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
8
|
#
|
|
9
|
-
#
|
|
10
|
-
# notice, this list of conditions and the following disclaimer.
|
|
11
|
-
# * Redistributions in binary form must reproduce the above
|
|
12
|
-
# copyright notice, this list of conditions and the following disclaimer
|
|
13
|
-
# in the documentation and/or other materials provided with the
|
|
14
|
-
# distribution.
|
|
15
|
-
# * Neither the name of Google Inc. nor the names of its
|
|
16
|
-
# contributors may be used to endorse or promote products derived from
|
|
17
|
-
# this software without specific prior written permission.
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
18
10
|
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
26
|
-
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
27
|
-
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
28
|
-
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
-
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
30
17
|
|
|
31
18
|
require "base64"
|
|
32
19
|
require "json"
|
|
@@ -143,13 +130,8 @@ module Google
|
|
|
143
130
|
end
|
|
144
131
|
n_bn = OpenSSL::BN.new n_data, 2
|
|
145
132
|
e_bn = OpenSSL::BN.new e_data, 2
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
rsa_key.set_key n_bn, e_bn, nil
|
|
149
|
-
else
|
|
150
|
-
rsa_key.n = n_bn
|
|
151
|
-
rsa_key.e = e_bn
|
|
152
|
-
end
|
|
133
|
+
sequence = [OpenSSL::ASN1::Integer.new(n_bn), OpenSSL::ASN1::Integer.new(e_bn)]
|
|
134
|
+
rsa_key = OpenSSL::PKey::RSA.new OpenSSL::ASN1::Sequence(sequence).to_der
|
|
153
135
|
rsa_key.public_key
|
|
154
136
|
end
|
|
155
137
|
|
|
@@ -174,9 +156,13 @@ module Google
|
|
|
174
156
|
x_hex = x_data.unpack1 "H*"
|
|
175
157
|
y_hex = y_data.unpack1 "H*"
|
|
176
158
|
bn = OpenSSL::BN.new ["04#{x_hex}#{y_hex}"].pack("H*"), 2
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
159
|
+
point = OpenSSL::PKey::EC::Point.new group, bn
|
|
160
|
+
sequence = OpenSSL::ASN1::Sequence([
|
|
161
|
+
OpenSSL::ASN1::Sequence([OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
|
|
162
|
+
OpenSSL::ASN1::ObjectId(curve_name)]),
|
|
163
|
+
OpenSSL::ASN1::BitString(point.to_octet_string(:uncompressed))
|
|
164
|
+
])
|
|
165
|
+
OpenSSL::PKey::EC.new sequence.to_der
|
|
180
166
|
end
|
|
181
167
|
end
|
|
182
168
|
end
|
|
@@ -2,31 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
# Copyright 2020 Google LLC
|
|
4
4
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
8
|
#
|
|
9
|
-
#
|
|
10
|
-
# notice, this list of conditions and the following disclaimer.
|
|
11
|
-
# * Redistributions in binary form must reproduce the above
|
|
12
|
-
# copyright notice, this list of conditions and the following disclaimer
|
|
13
|
-
# in the documentation and/or other materials provided with the
|
|
14
|
-
# distribution.
|
|
15
|
-
# * Neither the name of Google Inc. nor the names of its
|
|
16
|
-
# contributors may be used to endorse or promote products derived from
|
|
17
|
-
# this software without specific prior written permission.
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
18
10
|
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
25
|
-
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
26
|
-
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
27
|
-
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
28
|
-
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
-
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
30
16
|
|
|
31
17
|
require "jwt"
|
|
32
18
|
|