Skip to content

Commit

Permalink
feat: Drop support for Ruby 2.4 and add support for Ruby 3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
dazuma committed Mar 2, 2021
1 parent 636e560 commit 6644806
Show file tree
Hide file tree
Showing 15 changed files with 42 additions and 39 deletions.
2 changes: 0 additions & 2 deletions .rubocop.yml
Expand Up @@ -15,5 +15,3 @@ Metrics/ModuleLength:
Metrics/BlockLength:
Exclude:
- "googleauth.gemspec"
Style/SafeNavigation:
Enabled: false
9 changes: 2 additions & 7 deletions Gemfile
Expand Up @@ -8,7 +8,7 @@ group :development do
gem "coveralls", "~> 0.7"
gem "fakefs", "~> 0.6"
gem "fakeredis", "~> 0.5"
gem "google-style", "~> 1.24.0"
gem "google-style", "~> 1.25.1"
gem "logging", "~> 2.0"
gem "minitest", "~> 5.14"
gem "minitest-focus", "~> 1.1"
Expand All @@ -21,10 +21,5 @@ group :development do
gem "webmock", "~> 3.8"
end

platforms :jruby do
group :development do
end
end

gem "faraday", "~> 0.17"
gem "faraday", ">= 0.17.3", "< 2.0"
gem "gems", "~> 1.2"
14 changes: 8 additions & 6 deletions README.md
Expand Up @@ -182,12 +182,14 @@ Custom storage implementations can also be used. See

## Supported Ruby Versions

This library requires Ruby 2.4 or later.

In general, this library supports Ruby versions that are considered current and
supported by Ruby Core (that is, Ruby versions that are either in normal
maintenance or in security maintenance).
See https://www.ruby-lang.org/en/downloads/branches/ for further details.
This library is supported on Ruby 2.5+.

Google provides official support for Ruby versions that are actively supported
by Ruby Core—that is, Ruby versions that are either in normal maintenance or in
security maintenance, and not end of life. Currently, this means Ruby 2.5 and
later. Older versions of Ruby _may_ still work, but are unsupported and not
recommended. See https://www.ruby-lang.org/en/downloads/branches/ for details
about the Ruby support schedule.

## License

Expand Down
3 changes: 2 additions & 1 deletion googleauth.gemspec
Expand Up @@ -24,8 +24,9 @@ Gem::Specification.new do |gem|
File.basename f
end
gem.require_paths = ["lib"]

gem.platform = Gem::Platform::RUBY
gem.required_ruby_version = ">= 2.4.0"
gem.required_ruby_version = ">= 2.5"

gem.add_dependency "faraday", ">= 0.17.3", "< 2.0"
gem.add_dependency "jwt", ">= 1.4", "< 3.0"
Expand Down
11 changes: 8 additions & 3 deletions lib/googleauth/credentials.rb
Expand Up @@ -369,9 +369,10 @@ def initialize keyfile, options = {}
verify_keyfile_provided! keyfile
@project_id = options["project_id"] || options["project"]
@quota_project_id = options["quota_project_id"]
if keyfile.is_a? Signet::OAuth2::Client
case keyfile
when Signet::OAuth2::Client
update_from_signet keyfile
elsif keyfile.is_a? Hash
when Hash
update_from_hash keyfile, options
else
update_from_filepath keyfile, options
Expand Down Expand Up @@ -503,9 +504,11 @@ def init_client keyfile, connection_options = {}

# returns a new Hash with string keys instead of symbol keys.
def stringify_hash_keys hash
Hash[hash.map { |k, v| [k.to_s, v] }]
hash.to_h.transform_keys(&:to_s)
end

# rubocop:disable Metrics/AbcSize

def client_options options
# Keyfile options have higher priority over constructor defaults
options["token_credential_uri"] ||= self.class.token_credential_uri
Expand All @@ -527,6 +530,8 @@ def client_options options
signing_key: OpenSSL::PKey::RSA.new(options["private_key"]) }
end

# rubocop:enable Metrics/AbcSize

def update_from_signet client
@project_id ||= client.project_id if client.respond_to? :project_id
@quota_project_id ||= client.quota_project_id if client.respond_to? :quota_project_id
Expand Down
2 changes: 1 addition & 1 deletion lib/googleauth/credentials_loader.rb
Expand Up @@ -103,7 +103,7 @@ def from_env scope = nil, options = {}
return make_creds options.merge(json_key_io: f)
end
elsif service_account_env_vars? || authorized_user_env_vars?
return make_creds options
make_creds options
end
rescue StandardError => e
raise "#{NOT_FOUND_ERROR}: #{e}"
Expand Down
2 changes: 1 addition & 1 deletion lib/googleauth/iam.rb
Expand Up @@ -68,7 +68,7 @@ def apply a_hash
# Returns a reference to the #apply method, suitable for passing as
# a closure
def updater_proc
lambda(&method(:apply))
proc { |a_hash, _opts = {}| apply a_hash }
end
end
end
Expand Down
12 changes: 7 additions & 5 deletions lib/googleauth/id_tokens/key_sources.rb
Expand Up @@ -171,7 +171,9 @@ def extract_ec_key jwk
curve_name = CURVE_NAME_MAP[jwk[:crv]]
raise KeySourceError, "Unsupported EC curve #{jwk[:crv]}" unless curve_name
group = OpenSSL::PKey::EC::Group.new curve_name
bn = OpenSSL::BN.new ["04" + x_data.unpack1("H*") + y_data.unpack1("H*")].pack("H*"), 2
x_hex = x_data.unpack1 "H*"
y_hex = y_data.unpack1 "H*"
bn = OpenSSL::BN.new ["04#{x_hex}#{y_hex}"].pack("H*"), 2
key = OpenSSL::PKey::EC.new curve_name
key.public_key = OpenSSL::PKey::EC::Point.new group, bn
key
Expand Down Expand Up @@ -284,10 +286,10 @@ def refresh_keys
raise KeySourceError, "Unable to retrieve data from #{uri}" unless response.is_a? Net::HTTPSuccess

data = begin
JSON.parse response.body
rescue JSON::ParserError
raise KeySourceError, "Unable to parse JSON"
end
JSON.parse response.body
rescue JSON::ParserError
raise KeySourceError, "Unable to parse JSON"
end

@current_keys = Array(interpret_json(data))
end
Expand Down
16 changes: 7 additions & 9 deletions lib/googleauth/id_tokens/verifier.rb
Expand Up @@ -105,15 +105,13 @@ def verify token,
def decode_token token, keys, aud, azp, iss
payload = nil
keys.find do |key|
begin
options = { algorithms: key.algorithm }
decoded_token = JWT.decode token, key.key, true, options
payload = decoded_token.first
rescue JWT::ExpiredSignature
raise ExpiredTokenError, "Token signature is expired"
rescue JWT::DecodeError
nil # Try the next key
end
options = { algorithms: key.algorithm }
decoded_token = JWT.decode token, key.key, true, options
payload = decoded_token.first
rescue JWT::ExpiredSignature
raise ExpiredTokenError, "Token signature is expired"
rescue JWT::DecodeError
nil # Try the next key
end

normalize_and_verify_payload payload, aud, azp, iss
Expand Down
2 changes: 1 addition & 1 deletion lib/googleauth/scope_util.rb
Expand Up @@ -51,7 +51,7 @@ def self.as_array scope
when Array
scope
when String
scope.split " "
scope.split
else
raise "Invalid scope value. Must be string or array"
end
Expand Down
2 changes: 1 addition & 1 deletion lib/googleauth/service_account.rb
Expand Up @@ -203,7 +203,7 @@ def apply a_hash, opts = {}
# Returns a reference to the #apply method, suitable for passing as
# a closure
def updater_proc
lambda(&method(:apply))
proc { |a_hash, opts = {}| apply a_hash, opts }
end

protected
Expand Down
2 changes: 1 addition & 1 deletion lib/googleauth/signet.rb
Expand Up @@ -63,7 +63,7 @@ def apply a_hash, opts = {}
# Returns a reference to the #apply method, suitable for passing as
# a closure
def updater_proc
lambda(&method(:apply))
proc { |a_hash, opts = {}| apply a_hash, opts }
end

def on_refresh &block
Expand Down
1 change: 1 addition & 0 deletions lib/googleauth/stores/file_token_store.rb
Expand Up @@ -40,6 +40,7 @@ class FileTokenStore < Google::Auth::TokenStore
# @param [String, File] file
# Path to storage file
def initialize options = {}
super()
path = options[:file]
@store = YAML::Store.new path
end
Expand Down
1 change: 1 addition & 0 deletions lib/googleauth/stores/redis_token_store.rb
Expand Up @@ -49,6 +49,7 @@ class RedisTokenStore < Google::Auth::TokenStore
# the options passed through. You may include any other keys accepted
# by `Redis.new`
def initialize options = {}
super()
redis = options.delete :redis
prefix = options.delete :prefix
@redis = case redis
Expand Down
2 changes: 1 addition & 1 deletion lib/googleauth/web_user_authorizer.rb
Expand Up @@ -189,7 +189,7 @@ def get_authorization_url options = {}
# May raise an error if an authorization code is present in the session
# and exchange of the code fails
def get_credentials user_id, request = nil, scope = nil
if request && request.session.key?(CALLBACK_STATE_KEY)
if request&.session&.key? CALLBACK_STATE_KEY
# Note - in theory, no need to check required scope as this is
# expected to be called immediately after a return from authorization
state_json = request.session.delete CALLBACK_STATE_KEY
Expand Down

0 comments on commit 6644806

Please sign in to comment.