diff --git a/.rubocop.yml b/.rubocop.yml index fe3bc03..c84a565 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -8,13 +8,17 @@ AllCops: - "Rakefile" - "yard/**/*" - "website/**/*" +Metrics/AbcSize: + Enabled: false Metrics/ClassLength: - Exclude: - - "lib/signet/oauth_1/client.rb" - - "lib/signet/oauth_1/server.rb" - - "lib/signet/oauth_2/client.rb" + Enabled: false +Metrics/CyclomaticComplexity: + Max: 30 +Metrics/MethodLength: + Enabled: false Metrics/ModuleLength: - Exclude: - - "lib/signet/oauth_1.rb" + Enabled: false +Metrics/PerceivedComplexity: + Max: 30 Style/Documentation: Enabled: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 647435f..9a6357c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,8 @@ # Release History -## [0.14.1](https://www.github.com/googleapis/signet/compare/v0.14.0...v0.14.1) (2021-01-27) +## 0.14.1 / 2021-01-27 - -### Bug Fixes - -* Fix OAuth1 signature with duplicate query param names ([9f5b81a](https://www.github.com/googleapis/signet/commit/9f5b81a60625a6e6f0e5bca24c67b90e73d7479b)) +* Fix OAuth1 signature with duplicate query param names ## 0.14.0 / 2020-03-31 diff --git a/README.md b/README.md index f3e5fda..c9f851c 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,8 @@ require 'signet/oauth_2/client' client = Signet::OAuth2::Client.new( :authorization_uri => 'https://accounts.google.com/o/oauth2/auth', :token_credential_uri => 'https://oauth2.googleapis.com/token', - :client_id => '44410190108-74nkm6jc5e3vvjqis803frkvmu88cu3a.apps.googleusercontent.com', - :client_secret => 'X1NUhvO-rQr9sm8uUSMY8i7v', + :client_id => "#{YOUR_CLIENT_ID}.apps.googleusercontent.com", + :client_secret => YOUR_CLIENT_SECRET, :scope => 'email profile', :redirect_uri => 'https://example.client.com/oauth' ) @@ -59,8 +59,11 @@ Be sure `https://rubygems.org` is in your gem sources. ## 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. diff --git a/lib/signet.rb b/lib/signet.rb index 77c0d0e..b3462a8 100644 --- a/lib/signet.rb +++ b/lib/signet.rb @@ -15,8 +15,6 @@ require "signet/version" module Signet #:nodoc: - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/MethodLength def self.parse_auth_param_list auth_param_string # Production rules from: # http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-12 @@ -54,11 +52,12 @@ def self.parse_auth_param_list auth_param_string # Now parse the auth-param pair strings & turn them into key-value pairs. (auth_param_pairs.each_with_object [] do |pair, accu| name, value = pair.split "=", 2 - if value =~ /^".*"$/ + case value + when /^".*"$/ value = value.gsub(/^"(.*)"$/, '\1').gsub(/\\(.)/, '\1') - elsif value =~ /^'.*'$/ + when /^'.*'$/ value = value.gsub(/^'(.*)'$/, '\1').gsub(/\\(.)/, '\1') - elsif value =~ %r{[\(\)<>@,;:\\\"/\[\]?={}]} + when %r{[()<>@,;:\\"/\[\]?={}]} # Certain special characters are not allowed raise ParseError, "Unexpected characters in auth param " \ @@ -68,6 +67,4 @@ def self.parse_auth_param_list auth_param_string accu << [name, value] end) end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/MethodLength end diff --git a/lib/signet/oauth_1.rb b/lib/signet/oauth_1.rb index f267b9e..018e99b 100644 --- a/lib/signet/oauth_1.rb +++ b/lib/signet/oauth_1.rb @@ -49,9 +49,8 @@ def self.generate_timestamp # # @return [String] A random nonce. def self.generate_nonce - SecureRandom.random_bytes(16).unpack("H*").join "" + SecureRandom.random_bytes(16).unpack("H*").join end - # rubocop:disable Metrics/MethodLength ## # Processes an options Hash to find a credential key value. @@ -65,7 +64,7 @@ def self.generate_nonce # @return [String] The credential key value. def self.extract_credential_key_option credential_type, options # Normalize key to String to allow indifferent access. - options = options.each_with_object({}) { |(k, v), accu| accu[k.to_s] = v; } + options = options.to_h.transform_keys(&:to_s) credential_key = "#{credential_type}_credential_key" credential = "#{credential_type}_credential" if options[credential_key] @@ -107,7 +106,7 @@ def self.extract_credential_key_option credential_type, options # @return [String] The credential secret value. def self.extract_credential_secret_option credential_type, options # Normalize key to String to allow indifferent access. - options = options.each_with_object({}) { |(k, v), accu| accu[k.to_s] = v; } + options = options.to_h.transform_keys(&:to_s) credential_secret = "#{credential_type}_credential_secret" credential = "#{credential_type}_credential" if options[credential_secret] @@ -136,7 +135,6 @@ def self.extract_credential_secret_option credential_type, options end credential_secret end - # rubocop:enable Metrics/MethodLength ## # Normalizes a set of OAuth parameters according to the algorithm given @@ -214,7 +212,7 @@ def self.generate_authorization_header parameters, realm = nil realm = realm.gsub '"', '\"' parameter_list.unshift "realm=\"#{realm}\"" end - "OAuth " + parameter_list.join(", ") + "OAuth #{parameter_list.join ', '}" end ## @@ -228,7 +226,7 @@ def self.parse_authorization_header field_value when /^OAuth$/i # Other token types may be supported eventually pairs = Signet.parse_auth_param_list(field_value[/^OAuth\s+(.*)$/i, 1]) - return (pairs.each_with_object [] do |(k, v), accu| + (pairs.each_with_object [] do |(k, v), accu| if k != "realm" k = unencode k v = unencode v @@ -274,24 +272,18 @@ def self.sign_parameters method, uri, parameters, # be a temporary credential secret when obtaining a token credential # for the first time base_string = generate_base_string method, uri, parameters - parameters = parameters.each_with_object({}) { |(k, v), h| h[k.to_s] = v; } + parameters = parameters.to_h.transform_keys(&:to_s) signature_method = parameters["oauth_signature_method"] case signature_method when "HMAC-SHA1" require "signet/oauth_1/signature_methods/hmac_sha1" - return Signet::OAuth1::HMACSHA1.generate_signature( - base_string, client_credential_secret, token_credential_secret - ) + Signet::OAuth1::HMACSHA1.generate_signature base_string, client_credential_secret, token_credential_secret when "RSA-SHA1" require "signet/oauth_1/signature_methods/rsa_sha1" - return Signet::OAuth1::RSASHA1.generate_signature( - base_string, client_credential_secret, token_credential_secret - ) + Signet::OAuth1::RSASHA1.generate_signature base_string, client_credential_secret, token_credential_secret when "PLAINTEXT" require "signet/oauth_1/signature_methods/plaintext" - return Signet::OAuth1::PLAINTEXT.generate_signature( - base_string, client_credential_secret, token_credential_secret - ) + Signet::OAuth1::PLAINTEXT.generate_signature base_string, client_credential_secret, token_credential_secret else raise NotImplementedError, "Unsupported signature method: #{signature_method}" @@ -396,7 +388,7 @@ def self.unsigned_token_credential_parameters options = {} raise ArgumentError, "Missing :client_credential_key parameter." if client_credential_key.nil? raise ArgumentError, "Missing :temporary_credential_key parameter." if temporary_credential_key.nil? raise ArgumentError, "Missing :verifier parameter." if options[:verifier].nil? - parameters = [ + [ ["oauth_consumer_key", client_credential_key], ["oauth_token", temporary_credential_key], ["oauth_signature_method", options[:signature_method]], @@ -405,8 +397,6 @@ def self.unsigned_token_credential_parameters options = {} ["oauth_verifier", options[:verifier]], ["oauth_version", "1.0"] ] - # No additional parameters allowed here - parameters end ## diff --git a/lib/signet/oauth_1/client.rb b/lib/signet/oauth_1/client.rb index 7956a27..ce25935 100644 --- a/lib/signet/oauth_1/client.rb +++ b/lib/signet/oauth_1/client.rb @@ -89,7 +89,7 @@ def initialize options = {} # @see Signet::OAuth1::Client#initialize def update! options = {} # Normalize key to String to allow indifferent access. - options = options.each_with_object({}) { |(k, v), accu| accu[k.to_s] = v; } + options = options.to_h.transform_keys(&:to_s) self.temporary_credential_uri = options["temporary_credential_uri"] self.authorization_uri = options["authorization_uri"] self.token_credential_uri = options["token_credential_uri"] @@ -128,12 +128,12 @@ def temporary_credential_uri # new_temporary_credential_uri # The temporary credentials URI. def temporary_credential_uri= new_temporary_credential_uri - if !new_temporary_credential_uri.nil? + if new_temporary_credential_uri.nil? + @temporary_credential_uri = nil + else new_temporary_credential_uri = Addressable::URI.parse new_temporary_credential_uri @temporary_credential_uri = new_temporary_credential_uri - else - @temporary_credential_uri = nil end end alias request_token_uri= temporary_credential_uri= @@ -163,14 +163,14 @@ def authorization_uri options = {} # @param [Addressable::URI, String, #to_str] new_authorization_uri # The authorization URI. def authorization_uri= new_authorization_uri - if !new_authorization_uri.nil? + if new_authorization_uri.nil? + @authorization_uri = nil + else new_authorization_uri = Addressable::URI.send( new_authorization_uri.is_a?(Hash) ? :new : :parse, new_authorization_uri ) @authorization_uri = new_authorization_uri - else - @authorization_uri = nil end end @@ -189,14 +189,14 @@ def token_credential_uri # @param [Addressable::URI, Hash, String, #to_str] new_token_credential_uri # The token credential URI. def token_credential_uri= new_token_credential_uri - if !new_token_credential_uri.nil? + if new_token_credential_uri.nil? + @token_credential_uri = nil + else new_token_credential_uri = Addressable::URI.send( new_token_credential_uri.is_a?(Hash) ? :new : :parse, new_token_credential_uri ) @token_credential_uri = new_token_credential_uri - else - @token_credential_uri = nil end end alias access_token_uri= token_credential_uri= @@ -217,8 +217,7 @@ def client_credential elsif !client_credential_key && !client_credential_secret nil else - raise ArgumentError, - "The client credential key and secret must be set." + raise ArgumentError, "The client credential key and secret must be set." end end alias consumer_token client_credential @@ -229,7 +228,10 @@ def client_credential # @param [Signet::OAuth1::Credential] new_client_credential # The client credentials. def client_credential= new_client_credential - if !new_client_credential.nil? + if new_client_credential.nil? + @client_credential_key = nil + @client_credential_secret = nil + else unless new_client_credential.is_a? ::Signet::OAuth1::Credential raise TypeError, "Expected Signet::OAuth1::Credential, " \ @@ -237,9 +239,6 @@ def client_credential= new_client_credential end @client_credential_key = new_client_credential.key @client_credential_secret = new_client_credential.secret - else - @client_credential_key = nil - @client_credential_secret = nil end end alias consumer_token= client_credential= @@ -259,15 +258,15 @@ def client_credential_key # @param [String, #to_str] new_client_credential_key # The client credential key. def client_credential_key= new_client_credential_key - if !new_client_credential_key.nil? + if new_client_credential_key.nil? + @client_credential_key = nil + else unless new_client_credential_key.respond_to? :to_str raise TypeError, "Can't convert #{new_client_credential_key.class} into String." end new_client_credential_key = new_client_credential_key.to_str @client_credential_key = new_client_credential_key - else - @client_credential_key = nil end end alias consumer_key= client_credential_key= @@ -287,7 +286,9 @@ def client_credential_secret # @param [String, #to_str] new_client_credential_secret # The client credential secret. def client_credential_secret= new_client_credential_secret - if !new_client_credential_secret.nil? + if new_client_credential_secret.nil? + @client_credential_secret = nil + else unless new_client_credential_secret.respond_to? :to_str raise TypeError, "Can't convert #{new_client_credential_secret.class} " \ @@ -295,8 +296,6 @@ def client_credential_secret= new_client_credential_secret end new_client_credential_secret = new_client_credential_secret.to_str @client_credential_secret = new_client_credential_secret - else - @client_credential_secret = nil end end alias consumer_secret= client_credential_secret= @@ -311,12 +310,10 @@ def temporary_credential temporary_credential_key, temporary_credential_secret ) - elsif !temporary_credential_key && - !temporary_credential_secret + elsif !temporary_credential_key && !temporary_credential_secret nil else - raise ArgumentError, - "The temporary credential key and secret must be set." + raise ArgumentError, "The temporary credential key and secret must be set." end end alias request_token temporary_credential @@ -327,7 +324,10 @@ def temporary_credential # @param [Signet::OAuth1::Credential] new_temporary_credential # The temporary credentials. def temporary_credential= new_temporary_credential - if !new_temporary_credential.nil? + if new_temporary_credential.nil? + @temporary_credential_key = nil + @temporary_credential_secret = nil + else unless new_temporary_credential.is_a? ::Signet::OAuth1::Credential raise TypeError, "Expected Signet::OAuth1::Credential, " \ @@ -335,9 +335,6 @@ def temporary_credential= new_temporary_credential end @temporary_credential_key = new_temporary_credential.key @temporary_credential_secret = new_temporary_credential.secret - else - @temporary_credential_key = nil - @temporary_credential_secret = nil end end alias request_token= temporary_credential= @@ -357,7 +354,9 @@ def temporary_credential_key # @param [String, #to_str] new_temporary_credential_key # The temporary credential key. def temporary_credential_key= new_temporary_credential_key - if !new_temporary_credential_key.nil? + if new_temporary_credential_key.nil? + @temporary_credential_key = nil + else unless new_temporary_credential_key.respond_to? :to_str raise TypeError, "Can't convert #{new_temporary_credential_key.class} " \ @@ -365,8 +364,6 @@ def temporary_credential_key= new_temporary_credential_key end new_temporary_credential_key = new_temporary_credential_key.to_str @temporary_credential_key = new_temporary_credential_key - else - @temporary_credential_key = nil end end alias request_token_key= temporary_credential_key= @@ -386,7 +383,9 @@ def temporary_credential_secret # @param [String, #to_str] new_temporary_credential_secret # The temporary credential secret. def temporary_credential_secret= new_temporary_credential_secret - if !new_temporary_credential_secret.nil? + if new_temporary_credential_secret.nil? + @temporary_credential_secret = nil + else unless new_temporary_credential_secret.respond_to? :to_str raise TypeError, "Can't convert #{new_temporary_credential_secret.class} " \ @@ -395,8 +394,6 @@ def temporary_credential_secret= new_temporary_credential_secret new_temporary_credential_secret = new_temporary_credential_secret.to_str @temporary_credential_secret = new_temporary_credential_secret - else - @temporary_credential_secret = nil end end alias request_token_secret= temporary_credential_secret= @@ -411,12 +408,10 @@ def token_credential token_credential_key, token_credential_secret ) - elsif !token_credential_key && - !token_credential_secret + elsif !token_credential_key && !token_credential_secret nil else - raise ArgumentError, - "The token credential key and secret must be set." + raise ArgumentError, "The token credential key and secret must be set." end end alias access_token token_credential @@ -427,7 +422,10 @@ def token_credential # @param [Signet::OAuth1::Credential] new_token_credential # The token credentials. def token_credential= new_token_credential - if !new_token_credential.nil? + if new_token_credential.nil? + @token_credential_key = nil + @token_credential_secret = nil + else unless new_token_credential.is_a? ::Signet::OAuth1::Credential raise TypeError, "Expected Signet::OAuth1::Credential, " \ @@ -435,9 +433,6 @@ def token_credential= new_token_credential end @token_credential_key = new_token_credential.key @token_credential_secret = new_token_credential.secret - else - @token_credential_key = nil - @token_credential_secret = nil end end alias access_token= token_credential= @@ -457,7 +452,9 @@ def token_credential_key # @param [String, #to_str] new_token_credential_key # The token credential key. def token_credential_key= new_token_credential_key - if !new_token_credential_key.nil? + if new_token_credential_key.nil? + @token_credential_key = nil + else unless new_token_credential_key.respond_to? :to_str raise TypeError, "Can't convert #{new_token_credential_key.class} " \ @@ -465,8 +462,6 @@ def token_credential_key= new_token_credential_key end new_token_credential_key = new_token_credential_key.to_str @token_credential_key = new_token_credential_key - else - @token_credential_key = nil end end alias access_token_key= token_credential_key= @@ -486,7 +481,9 @@ def token_credential_secret # @param [String, #to_str] new_token_credential_secret # The token credential secret. def token_credential_secret= new_token_credential_secret - if !new_token_credential_secret.nil? + if new_token_credential_secret.nil? + @token_credential_secret = nil + else unless new_token_credential_secret.respond_to? :to_str raise TypeError, "Can't convert #{new_token_credential_secret.class} " \ @@ -495,8 +492,6 @@ def token_credential_secret= new_token_credential_secret new_token_credential_secret = new_token_credential_secret.to_str @token_credential_secret = new_token_credential_secret - else - @token_credential_secret = nil end end alias access_token_secret= token_credential_secret= @@ -515,15 +510,15 @@ def callback # @param [String, #to_str] new_callback # The OAuth callback. def callback= new_callback - if !new_callback.nil? + if new_callback.nil? + @callback = nil + else unless new_callback.respond_to? :to_str raise TypeError, "Can't convert #{new_callback.class} into String." end new_callback = new_callback.to_str @callback = new_callback - else - @callback = nil end end @@ -556,7 +551,7 @@ def two_legged= new_two_legged # @note A serialized client contains sensitive information. Persist or transmit with care. # # @return [String] A serialized JSON representation of the client. - def to_json + def to_json *_args MultiJson.dump( "temporary_credential_uri" => temporary_credential_uri, "authorization_uri" => authorization_uri, @@ -571,8 +566,6 @@ def to_json "token_credential_secret" => token_credential_secret ) end - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/MethodLength ## # Generates a request for temporary credentials. @@ -635,8 +628,6 @@ def generate_temporary_credential_request options = {} req.headers = Faraday::Utils::Headers.new headers end end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/MethodLength alias generate_request_token_request generate_temporary_credential_request ## @@ -709,8 +700,6 @@ def fetch_temporary_credential! options = {} self.temporary_credential = credential end alias fetch_request_token! fetch_temporary_credential! - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/MethodLength ## # Generates a request for token credentials. @@ -776,7 +765,6 @@ def generate_token_credential_request options = {} req.headers = Faraday::Utils::Headers.new headers end end - # rubocop:enable Metrics/MethodLength alias generate_access_token_request generate_token_credential_request ## @@ -818,7 +806,6 @@ def fetch_token_credential options = {} message, request: request, response: response ) end - # rubocop:enable Metrics/AbcSize alias fetch_access_token fetch_token_credential ## @@ -846,10 +833,6 @@ def fetch_token_credential! options = {} self.token_credential = credential end alias fetch_access_token! fetch_token_credential! - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/CyclomaticComplexity - # rubocop:disable Metrics/MethodLength - # rubocop:disable Metrics/PerceivedComplexity ## # Generates an authenticated request for protected resources. @@ -950,7 +933,7 @@ def generate_authenticated_request options = {} request.body = env[:body] post_parameters = Addressable::URI.form_unencode env[:body] - parameters = parameters.concat post_parameters + parameters.concat post_parameters end # No need to attach URI query parameters, the .sign_parameters @@ -970,10 +953,6 @@ def generate_authenticated_request options = {} request["Cache-Control"] = "no-store" request end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/CyclomaticComplexity - # rubocop:enable Metrics/MethodLength - # rubocop:enable Metrics/PerceivedComplexity ## # Transmits a request for a protected resource. diff --git a/lib/signet/oauth_1/credential.rb b/lib/signet/oauth_1/credential.rb index b3a4ec5..c02fe9c 100644 --- a/lib/signet/oauth_1/credential.rb +++ b/lib/signet/oauth_1/credential.rb @@ -15,11 +15,6 @@ module Signet #:nodoc: module OAuth1 class Credential - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/CyclomaticComplexity - # rubocop:disable Metrics/MethodLength - # rubocop:disable Metrics/PerceivedComplexity - ## # Creates a token object from a key and secret. # @@ -95,12 +90,9 @@ def initialize *args raise TypeError, "Expected String, got #{@secret.class}." unless @secret.respond_to? :to_str @secret = @secret.to_str end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/CyclomaticComplexity - # rubocop:enable Metrics/MethodLength - # rubocop:enable Metrics/PerceivedComplexity - attr_accessor :key, :secret + attr_accessor :key + attr_accessor :secret def to_hash { diff --git a/lib/signet/oauth_1/server.rb b/lib/signet/oauth_1/server.rb index 0e62a9a..0287640 100644 --- a/lib/signet/oauth_1/server.rb +++ b/lib/signet/oauth_1/server.rb @@ -55,15 +55,13 @@ def initialize options = {} instance_variable_set "@#{attr}", options[attr] end end - # rubocop:disable Naming/UncommunicativeMethodParamName # Constant time string comparison. - def safe_equals? a, b - check = a.bytesize ^ b.bytesize - a.bytes.zip(b.bytes) { |x, y| check |= x ^ y.to_i } + def safe_equals? left, right + check = left.bytesize ^ right.bytesize + left.bytes.zip(right.bytes) { |x, y| check |= x ^ y.to_i } check.zero? end - # rubocop:enable Naming/UncommunicativeMethodParamName ## # Determine if the supplied nonce/timestamp pair is valid by calling @@ -141,8 +139,6 @@ def find_verifier verifier verified = @verifier.call verifier if @verifier.respond_to? :call verified ? true : false end - # rubocop:disable Metrics/MethodLength - # rubocop:disable Metrics/PerceivedComplexity ## # Validate and normalize the components from an HTTP request. @@ -188,8 +184,6 @@ def verify_request_components options = {} request_components[:body] = body request_components end - # rubocop:enable Metrics/MethodLength - # rubocop:enable Metrics/PerceivedComplexity ## # Validate and normalize the HTTP Authorization header. @@ -199,11 +193,7 @@ def verify_request_components options = {} def verify_auth_header_components headers auth_header = headers.find { |x| x[0] == "Authorization" } raise MalformedAuthorizationError, "Authorization header is missing" if auth_header.nil? || auth_header[1] == "" - auth_hash = ::Signet::OAuth1.parse_authorization_header( - auth_header[1] - ).each_with_object({}) { |(key, val), acc| acc[key.downcase] = val; } - - auth_hash + ::Signet::OAuth1.parse_authorization_header(auth_header[1]).to_h.transform_keys(&:downcase) end ## @@ -232,14 +222,9 @@ def request_realm options = {} auth_header = request_components[:headers].find { |x| x[0] == "Authorization" } raise MalformedAuthorizationError, "Authorization header is missing" if auth_header.nil? || auth_header[1] == "" - auth_hash = ::Signet::OAuth1.parse_authorization_header( - auth_header[1] - ).each_with_object({}) { |(key, val), acc| acc[key.downcase] = val; } + auth_hash = ::Signet::OAuth1.parse_authorization_header(auth_header[1]).to_h.transform_keys(&:downcase) auth_hash["realm"] end - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/MethodLength - # rubocop:disable Metrics/PerceivedComplexity ## # Authenticates a temporary credential request. If no oauth_callback is @@ -308,7 +293,6 @@ def authenticate_temporary_credential_request options = {} false end end - # rubocop:enable Metrics/PerceivedComplexity ## # Authenticates a token credential request. @@ -379,8 +363,6 @@ def authenticate_token_credential_request options = {} temporary_credential: temporary_credential, realm: auth_hash["realm"] } end - # rubocop:disable Metrics/CyclomaticComplexity - # rubocop:disable Metrics/PerceivedComplexity ## # Authenticates a request for a protected resource. @@ -496,10 +478,6 @@ def authenticate_resource_request options = {} token_credential: token_credential, realm: auth_hash["realm"] } end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/CyclomaticComplexity - # rubocop:enable Metrics/MethodLength - # rubocop:enable Metrics/PerceivedComplexity end end end diff --git a/lib/signet/oauth_1/signature_methods/rsa_sha1.rb b/lib/signet/oauth_1/signature_methods/rsa_sha1.rb index 5f59958..5a1c3a5 100644 --- a/lib/signet/oauth_1/signature_methods/rsa_sha1.rb +++ b/lib/signet/oauth_1/signature_methods/rsa_sha1.rb @@ -11,7 +11,7 @@ def self.generate_signature \ private_key = OpenSSL::PKey::RSA.new client_credential_secret - signature = private_key.sign OpenSSL::Digest::SHA1.new, base_string + signature = private_key.sign OpenSSL::Digest.new("SHA1"), base_string # using strict_encode64 because the encode64 method adds newline characters after ever 60 chars Base64.strict_encode64(signature).strip end diff --git a/lib/signet/oauth_2.rb b/lib/signet/oauth_2.rb index 9d8b693..7f805e9 100644 --- a/lib/signet/oauth_2.rb +++ b/lib/signet/oauth_2.rb @@ -28,10 +28,10 @@ def self.parse_authorization_header field_value case auth_scheme when /^Basic$/i # HTTP Basic is allowed in OAuth 2 - return parse_basic_credentials(field_value[/^Basic\s+(.*)$/i, 1]) + parse_basic_credentials(field_value[/^Basic\s+(.*)$/i, 1]) when /^OAuth$/i # Other token types may be supported eventually - return parse_bearer_credentials(field_value[/^OAuth\s+(.*)$/i, 1]) + parse_bearer_credentials(field_value[/^OAuth\s+(.*)$/i, 1]) else raise ParseError, "Parsing non-OAuth Authorization headers is out of scope." @@ -43,7 +43,7 @@ def self.parse_www_authenticate_header field_value case auth_scheme when /^OAuth$/i # Other token types may be supported eventually - return parse_oauth_challenge(field_value[/^OAuth\s+(.*)$/i, 1]) + parse_oauth_challenge(field_value[/^OAuth\s+(.*)$/i, 1]) else raise ParseError, "Parsing non-OAuth WWW-Authenticate headers is out of scope." @@ -76,9 +76,9 @@ def self.parse_credentials body, content_type raise TypeError, "Expected String, got #{body.class}." unless body.is_a? String case content_type when %r{^application/json.*} - return MultiJson.load body + MultiJson.load body when %r{^application/x-www-form-urlencoded.*} - return Hash[Addressable::URI.form_unencode(body)] + Hash[Addressable::URI.form_unencode(body)] else raise ArgumentError, "Invalid content type '#{content_type}'" end @@ -100,9 +100,8 @@ def self.generate_basic_authorization_header client_id, client_password raise ArgumentError, "A client identifier may not contain a ':' character." end - "Basic " + Base64.encode64( - client_id + ":" + client_password - ).delete("\n") + token = Base64.encode64("#{client_id}:#{client_password}").delete("\n") + "Basic #{token}" end ## @@ -121,11 +120,8 @@ def self.generate_bearer_authorization_header \ # TODO: escaping? header = "Bearer #{access_token}" if auth_params && !auth_params.empty? - header += (", " + - (auth_params.each_with_object [] do |(key, value), accu| - accu << "#{key}=\"#{value}\"" - end).join(", ") - ) + additional_headers = auth_params.map { |key, value| "#{key}=\"#{value}\"" } + header = ([header] + additional_headers).join ", " end header end diff --git a/lib/signet/oauth_2/client.rb b/lib/signet/oauth_2/client.rb index 10cbe00..f6ad0c0 100644 --- a/lib/signet/oauth_2/client.rb +++ b/lib/signet/oauth_2/client.rb @@ -110,9 +110,6 @@ def initialize options = {} @access_type = nil update! options end - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/CyclomaticComplexity - # rubocop:disable Metrics/PerceivedComplexity ## # Updates an OAuth 2.0 client. @@ -202,13 +199,10 @@ def update! options = {} self.signing_key = options[:signing_key] if options.key? :signing_key self.extension_parameters = options[:extension_parameters] || {} self.additional_parameters = options[:additional_parameters] || {} - self.access_type = options.fetch(:access_type) { :offline } + self.access_type = options.fetch :access_type, :offline update_token! options self end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/CyclomaticComplexity - # rubocop:enable Metrics/PerceivedComplexity ## # Updates an OAuth 2.0 client. @@ -261,10 +255,6 @@ def update_token! options = {} self end - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/CyclomaticComplexity - # rubocop:disable Metrics/MethodLength - # rubocop:disable Metrics/PerceivedComplexity ## # Returns the authorization URI that the user should be redirected to. @@ -290,9 +280,7 @@ def authorization_uri options = {} options[:state] = state unless options[:state] options.merge!(additional_parameters.merge(options[:additional_parameters] || {})) options.delete :additional_parameters - options = Hash[options.map do |key, option| - [key.to_s, option] - end] + options = options.transform_keys(&:to_s) uri = Addressable::URI.parse( ::Signet::OAuth2.generate_authorization_uri( @authorization_uri, options @@ -304,10 +292,6 @@ def authorization_uri options = {} end uri end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/CyclomaticComplexity - # rubocop:enable Metrics/MethodLength - # rubocop:enable Metrics/PerceivedComplexity ## # Sets the authorization URI for this client. @@ -423,7 +407,7 @@ def scope= new_scope end @scope = new_scope when String - @scope = new_scope.split " " + @scope = new_scope.split when nil @scope = nil else @@ -793,12 +777,12 @@ def expires_in # @param [String, Integer, nil] new_expires_in # The access token lifetime. def expires_in= new_expires_in - if !new_expires_in.nil? - @issued_at = Time.now - @expires_at = @issued_at + new_expires_in.to_i - else + if new_expires_in.nil? @expires_at = nil @issued_at = nil + else + @issued_at = Time.now + @expires_at = @issued_at + new_expires_in.to_i end end @@ -922,8 +906,6 @@ def to_jwt options = {} assertion["sub"] = sub unless sub.nil? JWT.encode assertion, signing_key, signing_algorithm end - # rubocop:disable Style/MethodDefParentheses - # rubocop:disable Metrics/AbcSize ## # Serialize the client object to JSON. @@ -931,7 +913,7 @@ def to_jwt options = {} # @note A serialized client contains sensitive information. Persist or transmit with care. # # @return [String] A serialized JSON representation of the client. - def to_json(*) + def to_json *_args MultiJson.dump( "authorization_uri" => authorization_uri ? authorization_uri.to_s : nil, "token_credential_uri" => token_credential_uri ? token_credential_uri.to_s : nil, @@ -956,10 +938,6 @@ def to_json(*) "extension_parameters" => extension_parameters ) end - # rubocop:enable Style/MethodDefParentheses - # rubocop:disable Metrics/CyclomaticComplexity - # rubocop:disable Metrics/MethodLength - # rubocop:disable Metrics/PerceivedComplexity ## # Generates a request for token credentials. @@ -1005,8 +983,6 @@ def generate_access_token_request options = {} additional.each { |k, v| parameters[k.to_s] = v } parameters end - # rubocop:enable Metrics/CyclomaticComplexity - # rubocop:enable Metrics/PerceivedComplexity def fetch_access_token options = {} raise ArgumentError, "Missing token endpoint URI." if token_credential_uri.nil? @@ -1035,20 +1011,16 @@ def fetch_access_token options = {} message = " Server message:\n#{response.body.to_s.strip}" unless body.to_s.strip.empty? if [400, 401, 403].include? status - message = "Authorization failed." + message - raise ::Signet::AuthorizationError.new( - message, response: response - ) + message = "Authorization failed.#{message}" + raise ::Signet::AuthorizationError.new message, response: response elsif status.to_s[0] == "5" - message = "Remote server error." + message + message = "Remote server error.#{message}" raise ::Signet::RemoteServerError, message else - message = "Unexpected status code: #{response.status}." + message + message = "Unexpected status code: #{response.status}.#{message}" raise ::Signet::UnexpectedStatusError, message end end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/MethodLength def fetch_access_token! options = {} token_hash = fetch_access_token options @@ -1068,9 +1040,6 @@ def fetch_access_token! options = {} def refresh! options = {} fetch_access_token! options end - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/MethodLength - # rubocop:disable Metrics/PerceivedComplexity ## # Generates an authenticated request for protected resources. @@ -1137,9 +1106,6 @@ def generate_authenticated_request options = {} request["Cache-Control"] = "no-store" request end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/MethodLength - # rubocop:enable Metrics/PerceivedComplexity ## # Transmits a request for a protected resource. diff --git a/rakelib/devsite_builder.rb b/rakelib/devsite_builder.rb index 06ebb7a..3b25cd6 100644 --- a/rakelib/devsite_builder.rb +++ b/rakelib/devsite_builder.rb @@ -1,6 +1,6 @@ require "pathname" -require_relative "repo_metadata.rb" +require_relative "repo_metadata" class DevsiteBuilder def initialize master_dir = "." diff --git a/rakelib/repo_metadata.rb b/rakelib/repo_metadata.rb index f371230..3fb8cc1 100644 --- a/rakelib/repo_metadata.rb +++ b/rakelib/repo_metadata.rb @@ -23,7 +23,7 @@ def build output_directory end def normalize_data! - require_relative "../lib/signet/version.rb" + require_relative "../lib/signet/version" @data.delete_if { |k, _| !allowed_fields.include?(k) } @data["version"] = "v#{Signet::VERSION}" diff --git a/signet.gemspec b/signet.gemspec index 4e22c90..2f5ed35 100644 --- a/signet.gemspec +++ b/signet.gemspec @@ -21,14 +21,15 @@ Gem::Specification.new do |gem| gem.homepage = "https://github.com/googleapis/signet" gem.rdoc_options = ["--main", "README.md"] gem.summary = "Signet is an OAuth 1.0 / OAuth 2.0 implementation." - gem.required_ruby_version = ">= 2.4.0" + + gem.required_ruby_version = ">= 2.5" gem.add_runtime_dependency "addressable", "~> 2.3" gem.add_runtime_dependency "faraday", ">= 0.17.3", "< 2.0" gem.add_runtime_dependency "jwt", ">= 1.5", "< 3.0" gem.add_runtime_dependency "multi_json", "~> 1.10" - gem.add_development_dependency "google-style", "~> 0.3" + gem.add_development_dependency "google-style", "~> 1.25.1" gem.add_development_dependency "kramdown", "~> 1.5" gem.add_development_dependency "launchy", "~> 2.4" gem.add_development_dependency "rake", "~> 12.0"