signet 0.11.0 → 0.14.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 +51 -15
- data/Gemfile +5 -4
- data/README.md +4 -6
- data/Rakefile +107 -37
- data/lib/signet.rb +17 -14
- data/lib/signet/errors.rb +4 -4
- data/lib/signet/oauth_1.rb +129 -154
- data/lib/signet/oauth_1/client.rb +309 -343
- data/lib/signet/oauth_1/credential.rb +40 -37
- data/lib/signet/oauth_1/server.rb +197 -203
- data/lib/signet/oauth_1/signature_methods/hmac_sha1.rb +11 -10
- data/lib/signet/oauth_1/signature_methods/plaintext.rb +8 -7
- data/lib/signet/oauth_1/signature_methods/rsa_sha1.rb +11 -11
- data/lib/signet/oauth_2.rb +41 -43
- data/lib/signet/oauth_2/client.rb +328 -313
- data/lib/signet/version.rb +2 -73
- data/signet.gemspec +37 -39
- data/spec/signet/oauth_1/client_spec.rb +313 -315
- data/spec/signet/oauth_1/credential_spec.rb +64 -56
- data/spec/signet/oauth_1/server_spec.rb +362 -362
- data/spec/signet/oauth_1/signature_methods/hmac_sha1_spec.rb +26 -26
- data/spec/signet/oauth_1/signature_methods/plaintext_spec.rb +28 -28
- data/spec/signet/oauth_1/signature_methods/rsa_sha1_spec.rb +34 -35
- data/spec/signet/oauth_1_spec.rb +553 -524
- data/spec/signet/oauth_2/client_spec.rb +652 -576
- data/spec/signet/oauth_2_spec.rb +88 -89
- data/spec/signet_spec.rb +41 -41
- data/spec/spec_helper.rb +7 -7
- data/spec/spec_helper_spec.rb +8 -8
- metadata +64 -52
- data/tasks/clobber.rake +0 -2
- data/tasks/gem.rake +0 -34
- data/tasks/git.rake +0 -40
- data/tasks/metrics.rake +0 -41
- data/tasks/spec.rake +0 -34
- data/tasks/wiki.rake +0 -38
- data/tasks/yard.rake +0 -21
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: c94f4ee9a5ea982bba69826873be998a4cbf833af8c70920fd2384558efe33e5
         | 
| 4 | 
            +
              data.tar.gz: 211e019a051159858a4e18cbe64efe9989a13df08b2d449e67ac4057f91f4332
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: d8e5ac7a7977d89976275a4988e62139622436dea9f539a934b99e94f32832e57c8c522a91647449f9b5ea199fa561ad62680803f7d1dbe5b40946087b95dae4
         | 
| 7 | 
            +
              data.tar.gz: 2b6476b3b89d09d66c0274fa9bd1b5da6aebb68932e7e15325cf34ccca14b5d5f5a16f76a22330bbcb9f6b66882e016eeccb54977e7a87cc4ce6f32568361808
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,27 +1,63 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            # Release History
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            ## [0.14.1](https://www.github.com/googleapis/signet/compare/v0.14.0...v0.14.1) (2021-01-27)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
             | 
| 6 | 
            +
            ### Bug Fixes
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            * Fix OAuth1 signature with duplicate query param names ([9f5b81a](https://www.github.com/googleapis/signet/commit/9f5b81a60625a6e6f0e5bca24c67b90e73d7479b))
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            ## 0.14.0 / 2020-03-31
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            * Support for fetching ID tokens from google oauth2 endpoint.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            ## 0.13.2 / 2020-03-25
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            Rerelease of 0.13.1.
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            ## 0.13.1 / 2020-03-24
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            * Update github url
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            ## 0.13.0 / 2020-02-24
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            * Support Faraday 1.x
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            ## 0.12.0 / 2019-10-08
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            * This version now requires Ruby 2.4.
         | 
| 29 | 
            +
            * Support array values of the "aud" field.
         | 
| 30 | 
            +
            * Normalize the version constant to match related gems.
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            ## 0.11.0 / 2018-10-08
         | 
| 33 | 
            +
             | 
| 2 34 | 
             
            * Add constant time comparison for oauth signatures.
         | 
| 3 35 |  | 
| 4 | 
            -
            ## 0.10.0  | 
| 36 | 
            +
            ## 0.10.0 / 2018-09-21
         | 
| 37 | 
            +
             | 
| 5 38 | 
             
            * Add UnexpectedStatusError class for http status errors that are not handled.
         | 
| 6 39 |  | 
| 7 | 
            -
            ## 0.9.2  | 
| 40 | 
            +
            ## 0.9.2 / 2018-09-12
         | 
| 41 | 
            +
             | 
| 8 42 | 
             
            * Update issued_at correctly when it is set simultaneously with expires_in.
         | 
| 9 43 |  | 
| 10 | 
            -
            ## 0.9.1  | 
| 44 | 
            +
            ## 0.9.1 / 2018-08-29
         | 
| 45 | 
            +
             | 
| 11 46 | 
             
            * Warn on EOL ruby versions.
         | 
| 12 47 | 
             
            * Fix DateTime normalization.
         | 
| 13 48 |  | 
| 14 | 
            -
            ## 0.9.0  | 
| 49 | 
            +
            ## 0.9.0 / 2018-08-20
         | 
| 50 | 
            +
             | 
| 15 51 | 
             
            * Add RemoteServerError class for 5xx level errors.
         | 
| 16 52 | 
             
            * Allow to_json to be called with arguments
         | 
| 17 53 | 
             
            * Expires_in now sets and reflects current expires_at value
         | 
| 18 54 | 
             
            * Expires_within(0) now returns false when expires_at is nil.
         | 
| 19 55 |  | 
| 20 | 
            -
            ## 0.8.1  | 
| 56 | 
            +
            ## 0.8.1 / 2017-10-13
         | 
| 21 57 |  | 
| 22 58 | 
             
            * Restore support for Ruby 1.9.3
         | 
| 23 59 |  | 
| 24 | 
            -
            ## 0.8.0  | 
| 60 | 
            +
            ## 0.8.0 / 2017-10-12
         | 
| 25 61 |  | 
| 26 62 | 
             
            * Ensure the "expires_at" attribute is recalculated on refresh (chutzimir)
         | 
| 27 63 | 
             
            * Fix warnings on Ruby 2.4 (koic)
         | 
| @@ -29,20 +65,20 @@ | |
| 29 65 | 
             
            * Provide signature verification algorithm for compatibility with ruby-jwt 2.0 (jurriaan)
         | 
| 30 66 | 
             
            * Signet::OAuth2::Client#decoded_id_token can take a keyfinder block (mvastola)
         | 
| 31 67 |  | 
| 32 | 
            -
            ## 0.7.3  | 
| 68 | 
            +
            ## 0.7.3 / 2016-06-20
         | 
| 33 69 |  | 
| 34 70 | 
             
            * Fix timestamp parsing on 32-bit systems
         | 
| 35 71 | 
             
            * Fix expiration check when issue/expiry times are nil
         | 
| 36 72 |  | 
| 37 | 
            -
            ## 0.7.2  | 
| 73 | 
            +
            ## 0.7.2 / 2015-12-21
         | 
| 38 74 |  | 
| 39 75 | 
             
            * Don't assume Faraday form encoding middleware is present
         | 
| 40 76 |  | 
| 41 | 
            -
            ## 0.7.1  | 
| 77 | 
            +
            ## 0.7.1 / 2015-12-17
         | 
| 42 78 |  | 
| 43 79 | 
             
            * Fix an issue with date parsing
         | 
| 44 80 |  | 
| 45 | 
            -
            ## 0.7  | 
| 81 | 
            +
            ## 0.7 / 2015-12-06
         | 
| 46 82 |  | 
| 47 83 | 
             
            * No longer overwrite SSL environment variables.
         | 
| 48 84 | 
             
            * Tighten up date & URL (de)serialization for OAuth2 client
         | 
| @@ -51,7 +87,7 @@ | |
| 51 87 | 
             
            * Add expires_within(sec) method to oauth2 client to facilitate proactive
         | 
| 52 88 | 
             
              refreshes
         | 
| 53 89 |  | 
| 54 | 
            -
            ## 0.6.1  | 
| 90 | 
            +
            ## 0.6.1 / 2015-06-08
         | 
| 55 91 |  | 
| 56 92 | 
             
            * Fix language warnings for unused & shadowed variables ((@blowmage)[])
         | 
| 57 93 | 
             
            * Update SSL cert path for OSX ((@gambaroff)[])
         | 
| @@ -59,14 +95,14 @@ | |
| 59 95 | 
             
            * Fix incorrect parameter name in OAuth2 client docs ((@samuelreh)[])
         | 
| 60 96 | 
             
            * Fix symbolization of URL parameter keys ((@swifthand)[])
         | 
| 61 97 |  | 
| 62 | 
            -
            ## 0.6.0  | 
| 98 | 
            +
            ## 0.6.0 / 2014-12-05
         | 
| 63 99 |  | 
| 64 100 | 
             
            * Drop support for ruby versions < 1.9.3
         | 
| 65 101 | 
             
            * Update gem dependencies and lock down versions tighter
         | 
| 66 102 | 
             
            * Allow form encoded responses when exchanging OAuth 2 authorization codes
         | 
| 67 103 | 
             
            * Normalize options keys for indifferent access
         | 
| 68 104 |  | 
| 69 | 
            -
            ## 0.5.1  | 
| 105 | 
            +
            ## 0.5.1 / 2014-06-08
         | 
| 70 106 |  | 
| 71 107 | 
             
            * Allow Hash objects to be used to initialize authorization URI
         | 
| 72 108 | 
             
            * Added PLAINTEXT and RSA-SHA1 signature methods to OAuth 1 support
         | 
| @@ -74,7 +110,7 @@ | |
| 74 110 | 
             
            * The `approval_prompt` option no longer defaults to `:force`
         | 
| 75 111 | 
             
            * The `approval_prompt` and `prompt` are now mutually exclusive.
         | 
| 76 112 |  | 
| 77 | 
            -
            ## 0.5.0  | 
| 113 | 
            +
            ## 0.5.0 / 2013-05-31
         | 
| 78 114 |  | 
| 79 115 | 
             
            * Switched to faraday 0.9.0
         | 
| 80 116 | 
             
            * Added `expires_at` option
         | 
    
        data/Gemfile
    CHANGED
    
    | @@ -1,7 +1,8 @@ | |
| 1 | 
            -
            source  | 
| 1 | 
            +
            source "https://rubygems.org"
         | 
| 2 2 |  | 
| 3 3 | 
             
            gemspec
         | 
| 4 4 |  | 
| 5 | 
            -
            gem  | 
| 6 | 
            -
            gem  | 
| 7 | 
            -
            gem  | 
| 5 | 
            +
            gem "bundler", ">= 1.15"
         | 
| 6 | 
            +
            gem "gems", "~> 1.2"
         | 
| 7 | 
            +
            gem "hurley"
         | 
| 8 | 
            +
            gem "jruby-openssl", platforms: :jruby
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,14 +1,13 @@ | |
| 1 1 | 
             
            # Signet
         | 
| 2 2 |  | 
| 3 3 | 
             
            <dl>
         | 
| 4 | 
            -
              <dt>Homepage</dt><dd><a href=" | 
| 4 | 
            +
              <dt>Homepage</dt><dd><a href="https://github.com/googleapis/signet/">https://github.com/googleapis/signet/</a></dd>
         | 
| 5 5 | 
             
              <dt>Author</dt><dd><a href="mailto:bobaman@google.com">Bob Aman</a></dd>
         | 
| 6 6 | 
             
              <dt>Copyright</dt><dd>Copyright © 2010 Google, Inc.</dd>
         | 
| 7 7 | 
             
              <dt>License</dt><dd>Apache 2.0</dd>
         | 
| 8 8 | 
             
            </dl>
         | 
| 9 9 |  | 
| 10 10 | 
             
            [](https://badge.fury.io/rb/signet)
         | 
| 11 | 
            -
            [](http://travis-ci.org/google/signet)
         | 
| 12 11 |  | 
| 13 12 | 
             
            ## Description
         | 
| 14 13 |  | 
| @@ -59,10 +58,9 @@ client.fetch_access_token! | |
| 59 58 | 
             
            Be sure `https://rubygems.org` is in your gem sources.
         | 
| 60 59 |  | 
| 61 60 | 
             
            ## Supported Ruby Versions
         | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
            official support only for Ruby versions that are considered current and
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            This library requires Ruby 2.4 or later.
         | 
| 63 | 
            +
            In general, this library supports Ruby versions that are considered current and
         | 
| 66 64 | 
             
            supported by Ruby Core (that is, Ruby versions that are either in normal
         | 
| 67 65 | 
             
            maintenance or in security maintenance).
         | 
| 68 66 | 
             
            See https://www.ruby-lang.org/en/downloads/branches/ for further details.
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -1,42 +1,112 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
            require 'rubygems'
         | 
| 6 | 
            -
            require 'rake'
         | 
| 1 | 
            +
            require "rubygems"
         | 
| 2 | 
            +
            require "json"
         | 
| 3 | 
            +
            require "rake"
         | 
| 7 4 | 
             
            require "bundler/gem_tasks"
         | 
| 8 5 |  | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
               | 
| 6 | 
            +
            task :release_gem, :tag do |_t, args|
         | 
| 7 | 
            +
              tag = args[:tag]
         | 
| 8 | 
            +
              raise "You must provide a tag to release." if tag.nil?
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              # Verify the tag format "vVERSION"
         | 
| 11 | 
            +
              m = tag.match /v(?<version>\S*)/
         | 
| 12 | 
            +
              raise "Tag #{tag} does not match the expected format." if m.nil?
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              version = m[:version]
         | 
| 15 | 
            +
              raise "You must provide a version." if version.nil?
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              api_token = ENV["RUBYGEMS_API_TOKEN"]
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              require "gems"
         | 
| 20 | 
            +
              if api_token
         | 
| 21 | 
            +
                ::Gems.configure do |config|
         | 
| 22 | 
            +
                  config.key = api_token
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              Bundler.with_clean_env do
         | 
| 27 | 
            +
                sh "rm -rf pkg"
         | 
| 28 | 
            +
                sh "bundle update"
         | 
| 29 | 
            +
                sh "bundle exec rake build"
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              path_to_be_pushed = "pkg/signet-#{version}.gem"
         | 
| 33 | 
            +
              gem_was_published = nil
         | 
| 34 | 
            +
              if File.file? path_to_be_pushed
         | 
| 35 | 
            +
                begin
         | 
| 36 | 
            +
                  response = ::Gems.push File.new(path_to_be_pushed)
         | 
| 37 | 
            +
                  puts response
         | 
| 38 | 
            +
                  raise unless response.include? "Successfully registered gem:"
         | 
| 39 | 
            +
                  gem_was_published = true
         | 
| 40 | 
            +
                  puts "Successfully built and pushed signet for version #{version}"
         | 
| 41 | 
            +
                rescue StandardError => e
         | 
| 42 | 
            +
                  gem_was_published = false
         | 
| 43 | 
            +
                  puts "Error while releasing signet version #{version}: #{e.message}"
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              else
         | 
| 46 | 
            +
                raise "Cannot build signet for version #{version}"
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
              Rake::Task["kokoro:publish_docs"].invoke if gem_was_published
         | 
| 50 | 
            +
            end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            task :ci do
         | 
| 53 | 
            +
              header "Using Ruby - #{RUBY_VERSION}"
         | 
| 54 | 
            +
              sh "bundle exec rubocop"
         | 
| 55 | 
            +
              sh "bundle exec rspec"
         | 
| 37 56 | 
             
            end
         | 
| 38 57 |  | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 58 | 
            +
            namespace :kokoro do
         | 
| 59 | 
            +
              task :load_env_vars do
         | 
| 60 | 
            +
                service_account = "#{ENV['KOKORO_GFILE_DIR']}/service-account.json"
         | 
| 61 | 
            +
                ENV["GOOGLE_APPLICATION_CREDENTIALS"] = service_account
         | 
| 62 | 
            +
                filename = "#{ENV['KOKORO_GFILE_DIR']}/env_vars.json"
         | 
| 63 | 
            +
                env_vars = JSON.parse File.read(filename)
         | 
| 64 | 
            +
                env_vars.each { |k, v| ENV[k] = v }
         | 
| 65 | 
            +
              end
         | 
| 41 66 |  | 
| 42 | 
            -
             | 
| 67 | 
            +
              task :presubmit do
         | 
| 68 | 
            +
                Rake::Task["ci"].invoke
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
              task :continuous do
         | 
| 72 | 
            +
                Rake::Task["ci"].invoke
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              task :nightly do
         | 
| 76 | 
            +
                Rake::Task["ci"].invoke
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              task :release do
         | 
| 80 | 
            +
                version = "0.1.0"
         | 
| 81 | 
            +
                Bundler.with_clean_env do
         | 
| 82 | 
            +
                  version = `bundle exec gem list`
         | 
| 83 | 
            +
                            .split("\n").select { |line| line.include? "signet" }
         | 
| 84 | 
            +
                            .first.split("(").last.split(")").first || "0.1.0"
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
                Rake::Task["kokoro:load_env_vars"].invoke
         | 
| 87 | 
            +
                Rake::Task["release_gem"].invoke "v#{version}"
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
              task :post do
         | 
| 91 | 
            +
                require_relative "rakelib/link_checker.rb"
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                link_checker = LinkChecker.new
         | 
| 94 | 
            +
                link_checker.run
         | 
| 95 | 
            +
                exit link_checker.exit_status
         | 
| 96 | 
            +
              end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
              task :publish_docs do
         | 
| 99 | 
            +
                require_relative "rakelib/devsite_builder.rb"
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                DevsiteBuilder.new(__dir__).publish
         | 
| 102 | 
            +
              end
         | 
| 103 | 
            +
            end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
            def header str, token = "#"
         | 
| 106 | 
            +
              line_length = str.length + 8
         | 
| 107 | 
            +
              puts ""
         | 
| 108 | 
            +
              puts token * line_length
         | 
| 109 | 
            +
              puts "#{token * 3} #{str} #{token * 3}"
         | 
| 110 | 
            +
              puts token * line_length
         | 
| 111 | 
            +
              puts ""
         | 
| 112 | 
            +
            end
         | 
    
        data/lib/signet.rb
    CHANGED
    
    | @@ -12,13 +12,15 @@ | |
| 12 12 | 
             
            #    See the License for the specific language governing permissions and
         | 
| 13 13 | 
             
            #    limitations under the License.
         | 
| 14 14 |  | 
| 15 | 
            -
            require  | 
| 15 | 
            +
            require "signet/version"
         | 
| 16 16 |  | 
| 17 17 | 
             
            module Signet #:nodoc:
         | 
| 18 | 
            -
               | 
| 18 | 
            +
              # rubocop:disable Metrics/AbcSize
         | 
| 19 | 
            +
              # rubocop:disable Metrics/MethodLength
         | 
| 20 | 
            +
              def self.parse_auth_param_list auth_param_string
         | 
| 19 21 | 
             
                # Production rules from:
         | 
| 20 22 | 
             
                # http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-12
         | 
| 21 | 
            -
                token = /[ | 
| 23 | 
            +
                token = /[-!#{$OUTPUT_RECORD_SEPARATOR}%&'*+.^_`|~0-9a-zA-Z]+/
         | 
| 22 24 | 
             
                d_qdtext = /[\s\x21\x23-\x5B\x5D-\x7E\x80-\xFF]/n
         | 
| 23 25 | 
             
                d_quoted_pair = /\\[\s\x21-\x7E\x80-\xFF]/n
         | 
| 24 26 | 
             
                d_qs = /"(?:#{d_qdtext}|#{d_quoted_pair})*"/
         | 
| @@ -36,10 +38,10 @@ module Signet #:nodoc: | |
| 36 38 | 
             
                #
         | 
| 37 39 | 
             
                # This would be way easier in Ruby 1.9, but we want backwards
         | 
| 38 40 | 
             
                # compatibility.
         | 
| 39 | 
            -
                while (match = remainder.match | 
| 41 | 
            +
                while (match = remainder.match auth_param)
         | 
| 40 42 | 
             
                  if match.pre_match && match.pre_match !~ /^[\s,]*$/
         | 
| 41 43 | 
             
                    raise ParseError,
         | 
| 42 | 
            -
             | 
| 44 | 
            +
                          "Unexpected auth param format: '#{auth_param_string}'."
         | 
| 43 45 | 
             
                  end
         | 
| 44 46 | 
             
                  auth_param_pairs << match.captures[0] # Appending pair
         | 
| 45 47 | 
             
                  remainder = match.post_match
         | 
| @@ -47,24 +49,25 @@ module Signet #:nodoc: | |
| 47 49 | 
             
                end
         | 
| 48 50 | 
             
                if last_match.post_match && last_match.post_match !~ /^[\s,]*$/
         | 
| 49 51 | 
             
                  raise ParseError,
         | 
| 50 | 
            -
             | 
| 52 | 
            +
                        "Unexpected auth param format: '#{auth_param_string}'."
         | 
| 51 53 | 
             
                end
         | 
| 52 54 | 
             
                # Now parse the auth-param pair strings & turn them into key-value pairs.
         | 
| 53 | 
            -
                 | 
| 54 | 
            -
                  name, value = pair.split | 
| 55 | 
            +
                (auth_param_pairs.each_with_object [] do |pair, accu|
         | 
| 56 | 
            +
                  name, value = pair.split "=", 2
         | 
| 55 57 | 
             
                  if value =~ /^".*"$/
         | 
| 56 58 | 
             
                    value = value.gsub(/^"(.*)"$/, '\1').gsub(/\\(.)/, '\1')
         | 
| 57 59 | 
             
                  elsif value =~ /^'.*'$/
         | 
| 58 60 | 
             
                    value = value.gsub(/^'(.*)'$/, '\1').gsub(/\\(.)/, '\1')
         | 
| 59 | 
            -
                  elsif value =~  | 
| 61 | 
            +
                  elsif value =~ %r{[\(\)<>@,;:\\\"/\[\]?={}]}
         | 
| 60 62 | 
             
                    # Certain special characters are not allowed
         | 
| 61 | 
            -
                    raise ParseError, | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 63 | 
            +
                    raise ParseError,
         | 
| 64 | 
            +
                          "Unexpected characters in auth param " \
         | 
| 65 | 
            +
                          "list: '#{auth_param_string}'."
         | 
| 66 | 
            +
             | 
| 65 67 | 
             
                  end
         | 
| 66 68 | 
             
                  accu << [name, value]
         | 
| 67 | 
            -
                  accu
         | 
| 68 69 | 
             
                end)
         | 
| 69 70 | 
             
              end
         | 
| 71 | 
            +
              # rubocop:enable Metrics/AbcSize
         | 
| 72 | 
            +
              # rubocop:enable Metrics/MethodLength
         | 
| 70 73 | 
             
            end
         | 
    
        data/lib/signet/errors.rb
    CHANGED
    
    | @@ -12,7 +12,7 @@ | |
| 12 12 | 
             
            #    See the License for the specific language governing permissions and
         | 
| 13 13 | 
             
            #    limitations under the License.
         | 
| 14 14 |  | 
| 15 | 
            -
            require  | 
| 15 | 
            +
            require "addressable/uri"
         | 
| 16 16 |  | 
| 17 17 | 
             
            module Signet
         | 
| 18 18 | 
             
              ##
         | 
| @@ -66,14 +66,14 @@ module Signet | |
| 66 66 | 
             
                #   - <code>:uri</code> -
         | 
| 67 67 | 
             
                #     A URI identifying a human-readable web page with additional
         | 
| 68 68 | 
             
                #     information about the error, indended for the resource owner.
         | 
| 69 | 
            -
                def initialize | 
| 70 | 
            -
                  super | 
| 69 | 
            +
                def initialize message, options = {}
         | 
| 70 | 
            +
                  super message
         | 
| 71 71 | 
             
                  @options = options
         | 
| 72 72 | 
             
                  @request = options[:request]
         | 
| 73 73 | 
             
                  @response = options[:response]
         | 
| 74 74 | 
             
                  @code = options[:code]
         | 
| 75 75 | 
             
                  @description = options[:description]
         | 
| 76 | 
            -
                  @uri = Addressable::URI.parse | 
| 76 | 
            +
                  @uri = Addressable::URI.parse options[:uri]
         | 
| 77 77 | 
             
                end
         | 
| 78 78 |  | 
| 79 79 | 
             
                ##
         | 
    
        data/lib/signet/oauth_1.rb
    CHANGED
    
    | @@ -1,11 +1,11 @@ | |
| 1 | 
            -
            require  | 
| 2 | 
            -
            require  | 
| 1 | 
            +
            require "addressable/uri"
         | 
| 2 | 
            +
            require "signet"
         | 
| 3 3 |  | 
| 4 | 
            -
            require  | 
| 4 | 
            +
            require "securerandom"
         | 
| 5 5 |  | 
| 6 6 | 
             
            module Signet #:nodoc:
         | 
| 7 7 | 
             
              module OAuth1
         | 
| 8 | 
            -
                OUT_OF_BAND =  | 
| 8 | 
            +
                OUT_OF_BAND = "oob".freeze
         | 
| 9 9 |  | 
| 10 10 | 
             
                ##
         | 
| 11 11 | 
             
                # Converts a value to a percent-encoded <code>String</code> according to
         | 
| @@ -15,9 +15,9 @@ module Signet #:nodoc: | |
| 15 15 | 
             
                # @param [Symbol, #to_str] value The value to be encoded.
         | 
| 16 16 | 
             
                #
         | 
| 17 17 | 
             
                # @return [String] The percent-encoded value.
         | 
| 18 | 
            -
                def self.encode | 
| 19 | 
            -
                  value = value.to_s if value. | 
| 20 | 
            -
                   | 
| 18 | 
            +
                def self.encode value
         | 
| 19 | 
            +
                  value = value.to_s if value.is_a? Symbol
         | 
| 20 | 
            +
                  Addressable::URI.encode_component(
         | 
| 21 21 | 
             
                    value,
         | 
| 22 22 | 
             
                    Addressable::URI::CharacterClasses::UNRESERVED
         | 
| 23 23 | 
             
                  )
         | 
| @@ -30,8 +30,8 @@ module Signet #:nodoc: | |
| 30 30 | 
             
                #   The percent-encoded <code>String</code> to be unencoded.
         | 
| 31 31 | 
             
                #
         | 
| 32 32 | 
             
                # @return [String] The unencoded value.
         | 
| 33 | 
            -
                def self.unencode | 
| 34 | 
            -
                   | 
| 33 | 
            +
                def self.unencode value
         | 
| 34 | 
            +
                  Addressable::URI.unencode_component value
         | 
| 35 35 | 
             
                end
         | 
| 36 36 |  | 
| 37 37 | 
             
                ##
         | 
| @@ -39,8 +39,8 @@ module Signet #:nodoc: | |
| 39 39 | 
             
                # value.
         | 
| 40 40 | 
             
                #
         | 
| 41 41 | 
             
                # @return [String] The current timestamp.
         | 
| 42 | 
            -
                def self.generate_timestamp | 
| 43 | 
            -
                   | 
| 42 | 
            +
                def self.generate_timestamp
         | 
| 43 | 
            +
                  Time.now.to_i.to_s
         | 
| 44 44 | 
             
                end
         | 
| 45 45 |  | 
| 46 46 | 
             
                ##
         | 
| @@ -48,9 +48,10 @@ module Signet #:nodoc: | |
| 48 48 | 
             
                # value.
         | 
| 49 49 | 
             
                #
         | 
| 50 50 | 
             
                # @return [String] A random nonce.
         | 
| 51 | 
            -
                def self.generate_nonce | 
| 52 | 
            -
                   | 
| 51 | 
            +
                def self.generate_nonce
         | 
| 52 | 
            +
                  SecureRandom.random_bytes(16).unpack("H*").join ""
         | 
| 53 53 | 
             
                end
         | 
| 54 | 
            +
                # rubocop:disable Metrics/MethodLength
         | 
| 54 55 |  | 
| 55 56 | 
             
                ##
         | 
| 56 57 | 
             
                # Processes an options <code>Hash</code> to find a credential key value.
         | 
| @@ -62,36 +63,36 @@ module Signet #:nodoc: | |
| 62 63 | 
             
                #   or <code>:access</code>.
         | 
| 63 64 | 
             
                #
         | 
| 64 65 | 
             
                # @return [String] The credential key value.
         | 
| 65 | 
            -
                def self.extract_credential_key_option | 
| 66 | 
            +
                def self.extract_credential_key_option credential_type, options
         | 
| 66 67 | 
             
                  # Normalize key to String to allow indifferent access.
         | 
| 67 | 
            -
                  options = options. | 
| 68 | 
            +
                  options = options.each_with_object({}) { |(k, v), accu| accu[k.to_s] = v; }
         | 
| 68 69 | 
             
                  credential_key = "#{credential_type}_credential_key"
         | 
| 69 70 | 
             
                  credential = "#{credential_type}_credential"
         | 
| 70 71 | 
             
                  if options[credential_key]
         | 
| 71 72 | 
             
                    credential_key = options[credential_key]
         | 
| 72 73 | 
             
                  elsif options[credential]
         | 
| 73 | 
            -
                    require  | 
| 74 | 
            -
                     | 
| 74 | 
            +
                    require "signet/oauth_1/credential"
         | 
| 75 | 
            +
                    unless options[credential].respond_to? :key
         | 
| 75 76 | 
             
                      raise TypeError,
         | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 77 | 
            +
                            "Expected Signet::OAuth1::Credential, " \
         | 
| 78 | 
            +
                            "got #{options[credential].class}."
         | 
| 78 79 | 
             
                    end
         | 
| 79 80 | 
             
                    credential_key = options[credential].key
         | 
| 80 81 | 
             
                  elsif options["client"]
         | 
| 81 | 
            -
                    require  | 
| 82 | 
            -
                     | 
| 82 | 
            +
                    require "signet/oauth_1/client"
         | 
| 83 | 
            +
                    unless options["client"].is_a? ::Signet::OAuth1::Client
         | 
| 83 84 | 
             
                      raise TypeError,
         | 
| 84 | 
            -
             | 
| 85 | 
            +
                            "Expected Signet::OAuth1::Client, got #{options['client'].class}."
         | 
| 85 86 | 
             
                    end
         | 
| 86 | 
            -
                    credential_key = options["client"].send | 
| 87 | 
            +
                    credential_key = options["client"].send credential_key
         | 
| 87 88 | 
             
                  else
         | 
| 88 89 | 
             
                    credential_key = nil
         | 
| 89 90 | 
             
                  end
         | 
| 90 | 
            -
                  if credential_key | 
| 91 | 
            +
                  if !credential_key.nil? && !credential_key.is_a?(String)
         | 
| 91 92 | 
             
                    raise TypeError,
         | 
| 92 | 
            -
             | 
| 93 | 
            +
                          "Expected String, got #{credential_key.class}."
         | 
| 93 94 | 
             
                  end
         | 
| 94 | 
            -
                   | 
| 95 | 
            +
                  credential_key
         | 
| 95 96 | 
             
                end
         | 
| 96 97 |  | 
| 97 98 | 
             
                ##
         | 
| @@ -104,37 +105,38 @@ module Signet #:nodoc: | |
| 104 105 | 
             
                #   or <code>:access</code>.
         | 
| 105 106 | 
             
                #
         | 
| 106 107 | 
             
                # @return [String] The credential secret value.
         | 
| 107 | 
            -
                def self.extract_credential_secret_option | 
| 108 | 
            +
                def self.extract_credential_secret_option credential_type, options
         | 
| 108 109 | 
             
                  # Normalize key to String to allow indifferent access.
         | 
| 109 | 
            -
                  options = options. | 
| 110 | 
            +
                  options = options.each_with_object({}) { |(k, v), accu| accu[k.to_s] = v; }
         | 
| 110 111 | 
             
                  credential_secret = "#{credential_type}_credential_secret"
         | 
| 111 112 | 
             
                  credential = "#{credential_type}_credential"
         | 
| 112 113 | 
             
                  if options[credential_secret]
         | 
| 113 114 | 
             
                    credential_secret = options[credential_secret]
         | 
| 114 115 | 
             
                  elsif options[credential]
         | 
| 115 | 
            -
                    require  | 
| 116 | 
            -
                     | 
| 116 | 
            +
                    require "signet/oauth_1/credential"
         | 
| 117 | 
            +
                    unless options[credential].respond_to? :secret
         | 
| 117 118 | 
             
                      raise TypeError,
         | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 119 | 
            +
                            "Expected Signet::OAuth1::Credential, " \
         | 
| 120 | 
            +
                            "got #{options[credential].class}."
         | 
| 120 121 | 
             
                    end
         | 
| 121 122 | 
             
                    credential_secret = options[credential].secret
         | 
| 122 123 | 
             
                  elsif options["client"]
         | 
| 123 | 
            -
                    require  | 
| 124 | 
            -
                     | 
| 124 | 
            +
                    require "signet/oauth_1/client"
         | 
| 125 | 
            +
                    unless options["client"].is_a? ::Signet::OAuth1::Client
         | 
| 125 126 | 
             
                      raise TypeError,
         | 
| 126 | 
            -
             | 
| 127 | 
            +
                            "Expected Signet::OAuth1::Client, got #{options['client'].class}."
         | 
| 127 128 | 
             
                    end
         | 
| 128 | 
            -
                    credential_secret = options["client"].send | 
| 129 | 
            +
                    credential_secret = options["client"].send credential_secret
         | 
| 129 130 | 
             
                  else
         | 
| 130 131 | 
             
                    credential_secret = nil
         | 
| 131 132 | 
             
                  end
         | 
| 132 | 
            -
                  if credential_secret | 
| 133 | 
            +
                  if !credential_secret.nil? && !credential_secret.is_a?(String)
         | 
| 133 134 | 
             
                    raise TypeError,
         | 
| 134 | 
            -
             | 
| 135 | 
            +
                          "Expected String, got #{credential_secret.class}."
         | 
| 135 136 | 
             
                  end
         | 
| 136 | 
            -
                   | 
| 137 | 
            +
                  credential_secret
         | 
| 137 138 | 
             
                end
         | 
| 139 | 
            +
                # rubocop:enable Metrics/MethodLength
         | 
| 138 140 |  | 
| 139 141 | 
             
                ##
         | 
| 140 142 | 
             
                # Normalizes a set of OAuth parameters according to the algorithm given
         | 
| @@ -145,16 +147,14 @@ module Signet #:nodoc: | |
| 145 147 | 
             
                # @param [Enumerable] parameters The OAuth parameter list.
         | 
| 146 148 | 
             
                #
         | 
| 147 149 | 
             
                # @return [String] The normalized parameter list.
         | 
| 148 | 
            -
                def self.normalize_parameters | 
| 149 | 
            -
                   | 
| 150 | 
            -
                    raise TypeError, "Expected Enumerable, got #{parameters.class}."
         | 
| 151 | 
            -
                  end
         | 
| 150 | 
            +
                def self.normalize_parameters parameters
         | 
| 151 | 
            +
                  raise TypeError, "Expected Enumerable, got #{parameters.class}." unless parameters.is_a? Enumerable
         | 
| 152 152 | 
             
                  parameter_list = parameters.map do |k, v|
         | 
| 153 153 | 
             
                    next if k == "oauth_signature"
         | 
| 154 154 | 
             
                    # This is probably the wrong place to try to exclude the realm
         | 
| 155 | 
            -
                    "#{ | 
| 155 | 
            +
                    "#{encode k}=#{encode v}"
         | 
| 156 156 | 
             
                  end
         | 
| 157 | 
            -
                   | 
| 157 | 
            +
                  parameter_list.compact.sort.join "&"
         | 
| 158 158 | 
             
                end
         | 
| 159 159 |  | 
| 160 160 | 
             
                ##
         | 
| @@ -167,29 +167,27 @@ module Signet #:nodoc: | |
| 167 167 | 
             
                # @param [Enumerable] parameters The OAuth parameter list.
         | 
| 168 168 | 
             
                #
         | 
| 169 169 | 
             
                # @return [String] The signature base string.
         | 
| 170 | 
            -
                def self.generate_base_string | 
| 171 | 
            -
                   | 
| 172 | 
            -
                    raise TypeError, "Expected Enumerable, got #{parameters.class}."
         | 
| 173 | 
            -
                  end
         | 
| 170 | 
            +
                def self.generate_base_string method, uri, parameters
         | 
| 171 | 
            +
                  raise TypeError, "Expected Enumerable, got #{parameters.class}." unless parameters.is_a? Enumerable
         | 
| 174 172 | 
             
                  method = method.to_s.upcase
         | 
| 175 | 
            -
                  parsed_uri = Addressable::URI.parse | 
| 173 | 
            +
                  parsed_uri = Addressable::URI.parse uri
         | 
| 176 174 | 
             
                  uri = Addressable::URI.new(
         | 
| 177 | 
            -
                    : | 
| 178 | 
            -
                    : | 
| 179 | 
            -
                    : | 
| 180 | 
            -
                    : | 
| 181 | 
            -
                    : | 
| 175 | 
            +
                    scheme:    parsed_uri.normalized_scheme,
         | 
| 176 | 
            +
                    authority: parsed_uri.normalized_authority,
         | 
| 177 | 
            +
                    path:      parsed_uri.path,
         | 
| 178 | 
            +
                    query:     parsed_uri.query,
         | 
| 179 | 
            +
                    fragment:  parsed_uri.fragment
         | 
| 182 180 | 
             
                  )
         | 
| 183 | 
            -
                  uri_parameters = uri.query_values | 
| 181 | 
            +
                  uri_parameters = uri.query_values(Array) || []
         | 
| 184 182 | 
             
                  uri = uri.omit(:query, :fragment).to_s
         | 
| 185 183 | 
             
                  merged_parameters =
         | 
| 186 184 | 
             
                    uri_parameters.concat(parameters.map { |k, v| [k, v] })
         | 
| 187 | 
            -
                  parameter_string =  | 
| 188 | 
            -
                   | 
| 189 | 
            -
                     | 
| 190 | 
            -
                     | 
| 191 | 
            -
                     | 
| 192 | 
            -
                  ].join( | 
| 185 | 
            +
                  parameter_string = normalize_parameters merged_parameters
         | 
| 186 | 
            +
                  [
         | 
| 187 | 
            +
                    encode(method),
         | 
| 188 | 
            +
                    encode(uri),
         | 
| 189 | 
            +
                    encode(parameter_string)
         | 
| 190 | 
            +
                  ].join("&")
         | 
| 193 191 | 
             
                end
         | 
| 194 192 |  | 
| 195 193 | 
             
                ##
         | 
| @@ -201,48 +199,45 @@ module Signet #:nodoc: | |
| 201 199 | 
             
                #   The <code>Authorization</code> realm.  See RFC 2617.
         | 
| 202 200 | 
             
                #
         | 
| 203 201 | 
             
                # @return [String] The <code>Authorization</code> header.
         | 
| 204 | 
            -
                def self.generate_authorization_header | 
| 205 | 
            -
                  if !parameters. | 
| 202 | 
            +
                def self.generate_authorization_header parameters, realm = nil
         | 
| 203 | 
            +
                  if !parameters.is_a?(Enumerable) || parameters.is_a?(String)
         | 
| 206 204 | 
             
                    raise TypeError, "Expected Enumerable, got #{parameters.class}."
         | 
| 207 205 | 
             
                  end
         | 
| 208 206 | 
             
                  parameter_list = parameters.map do |k, v|
         | 
| 209 | 
            -
                    if k ==  | 
| 207 | 
            +
                    if k == "realm"
         | 
| 210 208 | 
             
                      raise ArgumentError,
         | 
| 211 | 
            -
             | 
| 209 | 
            +
                            'The "realm" parameter must be specified as a separate argument.'
         | 
| 212 210 | 
             
                    end
         | 
| 213 | 
            -
                    "#{ | 
| 211 | 
            +
                    "#{encode k}=\"#{encode v}\""
         | 
| 214 212 | 
             
                  end
         | 
| 215 213 | 
             
                  if realm
         | 
| 216 | 
            -
                    realm = realm.gsub | 
| 217 | 
            -
                    parameter_list.unshift | 
| 214 | 
            +
                    realm = realm.gsub '"', '\"'
         | 
| 215 | 
            +
                    parameter_list.unshift "realm=\"#{realm}\""
         | 
| 218 216 | 
             
                  end
         | 
| 219 | 
            -
                   | 
| 217 | 
            +
                  "OAuth " + parameter_list.join(", ")
         | 
| 220 218 | 
             
                end
         | 
| 221 219 |  | 
| 222 220 | 
             
                ##
         | 
| 223 221 | 
             
                # Parses an <code>Authorization</code> header into its component
         | 
| 224 222 | 
             
                # parameters.  Parameter keys and values are decoded according to the
         | 
| 225 223 | 
             
                # rules given in RFC 5849.
         | 
| 226 | 
            -
                def self.parse_authorization_header | 
| 227 | 
            -
                   | 
| 228 | 
            -
                    raise TypeError, "Expected String, got #{field_value.class}."
         | 
| 229 | 
            -
                  end
         | 
| 224 | 
            +
                def self.parse_authorization_header field_value
         | 
| 225 | 
            +
                  raise TypeError, "Expected String, got #{field_value.class}." unless field_value.is_a? String
         | 
| 230 226 | 
             
                  auth_scheme = field_value[/^([-._0-9a-zA-Z]+)/, 1]
         | 
| 231 227 | 
             
                  case auth_scheme
         | 
| 232 228 | 
             
                  when /^OAuth$/i
         | 
| 233 229 | 
             
                    # Other token types may be supported eventually
         | 
| 234 230 | 
             
                    pairs = Signet.parse_auth_param_list(field_value[/^OAuth\s+(.*)$/i, 1])
         | 
| 235 | 
            -
                    return (pairs. | 
| 236 | 
            -
                      if k !=  | 
| 237 | 
            -
                        k =  | 
| 238 | 
            -
                        v =  | 
| 231 | 
            +
                    return (pairs.each_with_object [] do |(k, v), accu|
         | 
| 232 | 
            +
                      if k != "realm"
         | 
| 233 | 
            +
                        k = unencode k
         | 
| 234 | 
            +
                        v = unencode v
         | 
| 239 235 | 
             
                      end
         | 
| 240 236 | 
             
                      accu << [k, v]
         | 
| 241 | 
            -
                      accu
         | 
| 242 237 | 
             
                    end)
         | 
| 243 238 | 
             
                  else
         | 
| 244 239 | 
             
                    raise ParseError,
         | 
| 245 | 
            -
             | 
| 240 | 
            +
                          "Parsing non-OAuth Authorization headers is out of scope."
         | 
| 246 241 | 
             
                  end
         | 
| 247 242 | 
             
                end
         | 
| 248 243 |  | 
| @@ -253,11 +248,9 @@ module Signet #:nodoc: | |
| 253 248 | 
             
                # @param [String] body The response body.
         | 
| 254 249 | 
             
                #
         | 
| 255 250 | 
             
                # @return [Signet::OAuth1::Credential] The OAuth credentials.
         | 
| 256 | 
            -
                def self.parse_form_encoded_credentials | 
| 257 | 
            -
                   | 
| 258 | 
            -
             | 
| 259 | 
            -
                  end
         | 
| 260 | 
            -
                  return Signet::OAuth1::Credential.new(
         | 
| 251 | 
            +
                def self.parse_form_encoded_credentials body
         | 
| 252 | 
            +
                  raise TypeError, "Expected String, got #{body.class}." unless body.is_a? String
         | 
| 253 | 
            +
                  Signet::OAuth1::Credential.new(
         | 
| 261 254 | 
             
                    Addressable::URI.form_unencode(body)
         | 
| 262 255 | 
             
                  )
         | 
| 263 256 | 
             
                end
         | 
| @@ -275,33 +268,33 @@ module Signet #:nodoc: | |
| 275 268 | 
             
                #   The token credential secret.  Omitted when unavailable.
         | 
| 276 269 | 
             
                #
         | 
| 277 270 | 
             
                # @return [String] The signature.
         | 
| 278 | 
            -
                def self.sign_parameters | 
| 279 | 
            -
             | 
| 271 | 
            +
                def self.sign_parameters method, uri, parameters,
         | 
| 272 | 
            +
                                         client_credential_secret, token_credential_secret = nil
         | 
| 280 273 | 
             
                  # Technically, the token_credential_secret parameter here may actually
         | 
| 281 274 | 
             
                  # be a temporary credential secret when obtaining a token credential
         | 
| 282 275 | 
             
                  # for the first time
         | 
| 283 | 
            -
                  base_string =  | 
| 284 | 
            -
                  parameters = parameters. | 
| 285 | 
            -
                  signature_method = parameters[ | 
| 276 | 
            +
                  base_string = generate_base_string method, uri, parameters
         | 
| 277 | 
            +
                  parameters = parameters.each_with_object({}) { |(k, v), h| h[k.to_s] = v; }
         | 
| 278 | 
            +
                  signature_method = parameters["oauth_signature_method"]
         | 
| 286 279 | 
             
                  case signature_method
         | 
| 287 | 
            -
                  when  | 
| 288 | 
            -
                    require  | 
| 280 | 
            +
                  when "HMAC-SHA1"
         | 
| 281 | 
            +
                    require "signet/oauth_1/signature_methods/hmac_sha1"
         | 
| 289 282 | 
             
                    return Signet::OAuth1::HMACSHA1.generate_signature(
         | 
| 290 283 | 
             
                      base_string, client_credential_secret, token_credential_secret
         | 
| 291 284 | 
             
                    )
         | 
| 292 | 
            -
                  when  | 
| 293 | 
            -
                    require  | 
| 285 | 
            +
                  when "RSA-SHA1"
         | 
| 286 | 
            +
                    require "signet/oauth_1/signature_methods/rsa_sha1"
         | 
| 294 287 | 
             
                    return Signet::OAuth1::RSASHA1.generate_signature(
         | 
| 295 288 | 
             
                      base_string, client_credential_secret, token_credential_secret
         | 
| 296 289 | 
             
                    )
         | 
| 297 | 
            -
                  when  | 
| 298 | 
            -
                    require  | 
| 290 | 
            +
                  when "PLAINTEXT"
         | 
| 291 | 
            +
                    require "signet/oauth_1/signature_methods/plaintext"
         | 
| 299 292 | 
             
                    return Signet::OAuth1::PLAINTEXT.generate_signature(
         | 
| 300 293 | 
             
                      base_string, client_credential_secret, token_credential_secret
         | 
| 301 294 | 
             
                    )
         | 
| 302 295 | 
             
                  else
         | 
| 303 296 | 
             
                    raise NotImplementedError,
         | 
| 304 | 
            -
             | 
| 297 | 
            +
                          "Unsupported signature method: #{signature_method}"
         | 
| 305 298 | 
             
                  end
         | 
| 306 299 | 
             
                end
         | 
| 307 300 |  | 
| @@ -322,22 +315,20 @@ module Signet #:nodoc: | |
| 322 315 | 
             
                #
         | 
| 323 316 | 
             
                # @return [Array]
         | 
| 324 317 | 
             
                #   The parameter list as an <code>Array</code> of key/value pairs.
         | 
| 325 | 
            -
                def self.unsigned_temporary_credential_parameters | 
| 318 | 
            +
                def self.unsigned_temporary_credential_parameters options = {}
         | 
| 326 319 | 
             
                  options = {
         | 
| 327 | 
            -
                    : | 
| 328 | 
            -
                    : | 
| 329 | 
            -
                    : | 
| 320 | 
            +
                    callback:              ::Signet::OAuth1::OUT_OF_BAND,
         | 
| 321 | 
            +
                    signature_method:      "HMAC-SHA1",
         | 
| 322 | 
            +
                    additional_parameters: []
         | 
| 330 323 | 
             
                  }.merge(options)
         | 
| 331 324 | 
             
                  client_credential_key =
         | 
| 332 | 
            -
                     | 
| 333 | 
            -
                   | 
| 334 | 
            -
                    raise ArgumentError, "Missing :client_credential_key parameter."
         | 
| 335 | 
            -
                  end
         | 
| 325 | 
            +
                    extract_credential_key_option :client, options
         | 
| 326 | 
            +
                  raise ArgumentError, "Missing :client_credential_key parameter." if client_credential_key.nil?
         | 
| 336 327 | 
             
                  parameters = [
         | 
| 337 328 | 
             
                    ["oauth_consumer_key", client_credential_key],
         | 
| 338 329 | 
             
                    ["oauth_signature_method", options[:signature_method]],
         | 
| 339 | 
            -
                    ["oauth_timestamp",  | 
| 340 | 
            -
                    ["oauth_nonce",  | 
| 330 | 
            +
                    ["oauth_timestamp", generate_timestamp],
         | 
| 331 | 
            +
                    ["oauth_nonce", generate_nonce],
         | 
| 341 332 | 
             
                    ["oauth_version", "1.0"],
         | 
| 342 333 | 
             
                    ["oauth_callback", options[:callback]]
         | 
| 343 334 | 
             
                  ]
         | 
| @@ -345,7 +336,7 @@ module Signet #:nodoc: | |
| 345 336 | 
             
                  options[:additional_parameters].each do |key, value|
         | 
| 346 337 | 
             
                    parameters << [key, value]
         | 
| 347 338 | 
             
                  end
         | 
| 348 | 
            -
                   | 
| 339 | 
            +
                  parameters
         | 
| 349 340 | 
             
                end
         | 
| 350 341 |  | 
| 351 342 | 
             
                ##
         | 
| @@ -356,28 +347,24 @@ module Signet #:nodoc: | |
| 356 347 | 
             
                #   The base authorization URI.
         | 
| 357 348 | 
             
                #
         | 
| 358 349 | 
             
                # @return [String] The authorization URI to redirect the user to.
         | 
| 359 | 
            -
                def self.generate_authorization_uri | 
| 350 | 
            +
                def self.generate_authorization_uri authorization_uri, options = {}
         | 
| 360 351 | 
             
                  options = {
         | 
| 361 | 
            -
                    : | 
| 362 | 
            -
                    : | 
| 352 | 
            +
                    callback:              nil,
         | 
| 353 | 
            +
                    additional_parameters: {}
         | 
| 363 354 | 
             
                  }.merge(options)
         | 
| 364 355 | 
             
                  temporary_credential_key =
         | 
| 365 | 
            -
                     | 
| 356 | 
            +
                    extract_credential_key_option :temporary, options
         | 
| 366 357 | 
             
                  parsed_uri = Addressable::URI.parse(authorization_uri).dup
         | 
| 367 358 | 
             
                  query_values = parsed_uri.query_values || {}
         | 
| 368 359 | 
             
                  if options[:additional_parameters]
         | 
| 369 360 | 
             
                    query_values = query_values.merge(
         | 
| 370 | 
            -
                      options[:additional_parameters]. | 
| 361 | 
            +
                      options[:additional_parameters].each_with_object({}) { |(k, v), h| h[k] = v; }
         | 
| 371 362 | 
             
                    )
         | 
| 372 363 | 
             
                  end
         | 
| 373 | 
            -
                  if temporary_credential_key
         | 
| 374 | 
            -
             | 
| 375 | 
            -
                  end
         | 
| 376 | 
            -
                  if options[:callback]
         | 
| 377 | 
            -
                    query_values['oauth_callback'] = options[:callback]
         | 
| 378 | 
            -
                  end
         | 
| 364 | 
            +
                  query_values["oauth_token"] = temporary_credential_key if temporary_credential_key
         | 
| 365 | 
            +
                  query_values["oauth_callback"] = options[:callback] if options[:callback]
         | 
| 379 366 | 
             
                  parsed_uri.query_values = query_values
         | 
| 380 | 
            -
                   | 
| 367 | 
            +
                  parsed_uri.normalize.to_s
         | 
| 381 368 | 
             
                end
         | 
| 382 369 |  | 
| 383 370 | 
             
                ##
         | 
| @@ -397,35 +384,29 @@ module Signet #:nodoc: | |
| 397 384 | 
             
                #
         | 
| 398 385 | 
             
                # @return [Array]
         | 
| 399 386 | 
             
                #   The parameter list as an <code>Array</code> of key/value pairs.
         | 
| 400 | 
            -
                def self.unsigned_token_credential_parameters | 
| 387 | 
            +
                def self.unsigned_token_credential_parameters options = {}
         | 
| 401 388 | 
             
                  options = {
         | 
| 402 | 
            -
                    : | 
| 403 | 
            -
                    : | 
| 389 | 
            +
                    signature_method: "HMAC-SHA1",
         | 
| 390 | 
            +
                    verifier:         nil
         | 
| 404 391 | 
             
                  }.merge(options)
         | 
| 405 392 | 
             
                  client_credential_key =
         | 
| 406 | 
            -
                     | 
| 393 | 
            +
                    extract_credential_key_option :client, options
         | 
| 407 394 | 
             
                  temporary_credential_key =
         | 
| 408 | 
            -
                     | 
| 409 | 
            -
                   | 
| 410 | 
            -
             | 
| 411 | 
            -
                   | 
| 412 | 
            -
                  if temporary_credential_key == nil
         | 
| 413 | 
            -
                    raise ArgumentError, "Missing :temporary_credential_key parameter."
         | 
| 414 | 
            -
                  end
         | 
| 415 | 
            -
                  if options[:verifier] == nil
         | 
| 416 | 
            -
                    raise ArgumentError, "Missing :verifier parameter."
         | 
| 417 | 
            -
                  end
         | 
| 395 | 
            +
                    extract_credential_key_option :temporary, options
         | 
| 396 | 
            +
                  raise ArgumentError, "Missing :client_credential_key parameter." if client_credential_key.nil?
         | 
| 397 | 
            +
                  raise ArgumentError, "Missing :temporary_credential_key parameter." if temporary_credential_key.nil?
         | 
| 398 | 
            +
                  raise ArgumentError, "Missing :verifier parameter." if options[:verifier].nil?
         | 
| 418 399 | 
             
                  parameters = [
         | 
| 419 400 | 
             
                    ["oauth_consumer_key", client_credential_key],
         | 
| 420 401 | 
             
                    ["oauth_token", temporary_credential_key],
         | 
| 421 402 | 
             
                    ["oauth_signature_method", options[:signature_method]],
         | 
| 422 | 
            -
                    ["oauth_timestamp",  | 
| 423 | 
            -
                    ["oauth_nonce",  | 
| 403 | 
            +
                    ["oauth_timestamp", generate_timestamp],
         | 
| 404 | 
            +
                    ["oauth_nonce", generate_nonce],
         | 
| 424 405 | 
             
                    ["oauth_verifier", options[:verifier]],
         | 
| 425 406 | 
             
                    ["oauth_version", "1.0"]
         | 
| 426 407 | 
             
                  ]
         | 
| 427 408 | 
             
                  # No additional parameters allowed here
         | 
| 428 | 
            -
                   | 
| 409 | 
            +
                  parameters
         | 
| 429 410 | 
             
                end
         | 
| 430 411 |  | 
| 431 412 | 
             
                ##
         | 
| @@ -445,35 +426,29 @@ module Signet #:nodoc: | |
| 445 426 | 
             
                #
         | 
| 446 427 | 
             
                # @return [Array]
         | 
| 447 428 | 
             
                #   The parameter list as an <code>Array</code> of key/value pairs.
         | 
| 448 | 
            -
                def self.unsigned_resource_parameters | 
| 429 | 
            +
                def self.unsigned_resource_parameters options = {}
         | 
| 449 430 | 
             
                  options = {
         | 
| 450 | 
            -
                    : | 
| 451 | 
            -
                    : | 
| 431 | 
            +
                    signature_method: "HMAC-SHA1",
         | 
| 432 | 
            +
                    two_legged:       false
         | 
| 452 433 | 
             
                  }.merge(options)
         | 
| 453 434 | 
             
                  client_credential_key =
         | 
| 454 | 
            -
                     | 
| 455 | 
            -
                   | 
| 456 | 
            -
                    raise ArgumentError, "Missing :client_credential_key parameter."
         | 
| 457 | 
            -
                  end
         | 
| 435 | 
            +
                    extract_credential_key_option :client, options
         | 
| 436 | 
            +
                  raise ArgumentError, "Missing :client_credential_key parameter." if client_credential_key.nil?
         | 
| 458 437 | 
             
                  unless options[:two_legged]
         | 
| 459 438 | 
             
                    token_credential_key =
         | 
| 460 | 
            -
                       | 
| 461 | 
            -
                     | 
| 462 | 
            -
                      raise ArgumentError, "Missing :token_credential_key parameter."
         | 
| 463 | 
            -
                    end
         | 
| 439 | 
            +
                      extract_credential_key_option :token, options
         | 
| 440 | 
            +
                    raise ArgumentError, "Missing :token_credential_key parameter." if token_credential_key.nil?
         | 
| 464 441 | 
             
                  end
         | 
| 465 442 | 
             
                  parameters = [
         | 
| 466 443 | 
             
                    ["oauth_consumer_key", client_credential_key],
         | 
| 467 444 | 
             
                    ["oauth_signature_method", options[:signature_method]],
         | 
| 468 | 
            -
                    ["oauth_timestamp",  | 
| 469 | 
            -
                    ["oauth_nonce",  | 
| 445 | 
            +
                    ["oauth_timestamp", generate_timestamp],
         | 
| 446 | 
            +
                    ["oauth_nonce", generate_nonce],
         | 
| 470 447 | 
             
                    ["oauth_version", "1.0"]
         | 
| 471 448 | 
             
                  ]
         | 
| 472 | 
            -
                  unless options[:two_legged]
         | 
| 473 | 
            -
                    parameters << ["oauth_token", token_credential_key]
         | 
| 474 | 
            -
                  end
         | 
| 449 | 
            +
                  parameters << ["oauth_token", token_credential_key] unless options[:two_legged]
         | 
| 475 450 | 
             
                  # No additional parameters allowed here
         | 
| 476 | 
            -
                   | 
| 451 | 
            +
                  parameters
         | 
| 477 452 | 
             
                end
         | 
| 478 453 | 
             
              end
         | 
| 479 454 | 
             
            end
         |