diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 4c3762d..d22b722 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - ruby-version: ['2.6', '2.7', '3.0', '3.2'] + ruby-version: ['3.0', '3.1', '3.2', '3.3'] steps: - uses: actions/checkout@v4 - name: Set up Ruby diff --git a/.rubocop.yml b/.rubocop.yml index da7eef1..41544f0 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,32 +1,20 @@ -inherit_from: [] - -inherit_gem: - standard: config/base.yml - require: - standard + - standard-custom + - standard-performance - rubocop-performance +inherit_gem: + standard: config/base.yml + standard-custom: config/base.yml + standard-performance: config/base.yml + AllCops: + TargetRubyVersion: 3.0 + NewCops: enable SuggestExtensions: false Exclude: - 'node_modules/**/*' - 'tmp/**/*' - 'vendor/**/*' - '.git/**/*' - -Style/TrailingCommaInArguments: - Enabled: true - EnforcedStyleForMultiline: consistent_comma - -Style/TrailingCommaInArrayLiteral: - Enabled: true - EnforcedStyleForMultiline: consistent_comma - -Style/TrailingCommaInHashLiteral: - Enabled: true - EnforcedStyleForMultiline: consistent_comma - -Style/Alias: - Enabled: true - EnforcedStyle: prefer_alias_method diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cbbfde..fba9a66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +* Change: update Faraday to 2.x, released about two years ago. The public API of this gem doesn't change, therefore this is not a major release. However, if you manipulate directly faraday's objects, you may encounter breaking changes. Refer to [Faraday's website](https://lostisland.github.io/faraday/) for how to migrate. + ## 3.4.0 - 2023-01-26 * New: Add `databases#upgrade` endpoint for database API ([#51](https://github.com/Scalingo/scalingo-ruby-api/pull/51)) diff --git a/lib/scalingo/api/client.rb b/lib/scalingo/api/client.rb index 1b406cc..0d4d929 100644 --- a/lib/scalingo/api/client.rb +++ b/lib/scalingo/api/client.rb @@ -29,11 +29,11 @@ def self.register_handlers!(handlers) def self.register_handler!(method_name, klass) define_method(method_name) do - value = instance_variable_get("@#{method_name}") + value = instance_variable_get(:"@#{method_name}") if value.nil? value = klass.new(self) - instance_variable_set("@#{method_name}", value) + instance_variable_set(:"@#{method_name}", value) end value @@ -54,7 +54,7 @@ def inspect def headers hash = { "User-Agent" => config.user_agent, - "Accept" => "application/json", + "Accept" => "application/json" } if (extra = config.additional_headers).present? @@ -67,7 +67,7 @@ def headers def connection_options { url: url, - headers: headers, + headers: headers } end @@ -106,11 +106,7 @@ def authenticated_connection @connection = Faraday.new(connection_options) { |conn| conn.response :json, content_type: /\bjson$/, parser_options: {symbolize_names: true} conn.request :json - - if token_holder.token&.value - auth_header = Faraday::Request::Authorization.header "Bearer", token_holder.token.value - conn.headers[Faraday::Request::Authorization::KEY] = auth_header - end + conn.request :authorization, "Bearer", -> { token_holder.token&.value } conn.adapter(config.faraday_adapter) if config.faraday_adapter } @@ -123,12 +119,7 @@ def database_connection(database_id) @database_connections[database_id] ||= Faraday.new(connection_options) { |conn| conn.response :json, content_type: /\bjson$/, parser_options: {symbolize_names: true} conn.request :json - - bearer_token = token_holder.database_tokens[database_id]&.value - if bearer_token - auth_header = Faraday::Request::Authorization.header "Bearer", bearer_token - conn.headers[Faraday::Request::Authorization::KEY] = auth_header - end + conn.request :authorization, "Bearer", -> { token_holder.database_tokens[database_id]&.value } conn.adapter(config.faraday_adapter) if config.faraday_adapter } diff --git a/lib/scalingo/api/response.rb b/lib/scalingo/api/response.rb index 4f9cae4..f145663 100644 --- a/lib/scalingo/api/response.rb +++ b/lib/scalingo/api/response.rb @@ -1,8 +1,8 @@ module Scalingo module API class Response - def self.unpack(client, key: nil, keys: nil, &block) - response = block.call + def self.unpack(client, key: nil, keys: nil) + response = yield body = response.body has_hash_body = body.present? && body.respond_to?(:key) @@ -24,7 +24,7 @@ def self.unpack(client, key: nil, keys: nil, &block) headers: response.headers, data: data, meta: meta, - full_body: body, + full_body: body ) end diff --git a/lib/scalingo/auth.rb b/lib/scalingo/auth.rb index 5bda9f1..c8ee2bc 100644 --- a/lib/scalingo/auth.rb +++ b/lib/scalingo/auth.rb @@ -13,7 +13,7 @@ class Auth < API::Client scm_integrations: ScmIntegrations, tokens: Tokens, two_factor_auth: TwoFactorAuth, - user: User, + user: User ) alias_method :tfa, :two_factor_auth diff --git a/lib/scalingo/auth/tokens.rb b/lib/scalingo/auth/tokens.rb index cbd1e43..6d1167f 100644 --- a/lib/scalingo/auth/tokens.rb +++ b/lib/scalingo/auth/tokens.rb @@ -5,10 +5,10 @@ class Auth::Tokens < API::Endpoint def exchange(token, headers = nil, &block) data = nil - authorization = Faraday::Request::BasicAuthentication.header("", token) + authorization = Faraday::Utils.basic_header_from("", token) request_headers = { - Faraday::Request::Authorization::KEY => authorization, + Faraday::Request::Authorization::KEY => authorization } request_headers.update(headers) if headers diff --git a/lib/scalingo/billing.rb b/lib/scalingo/billing.rb index 5b0e3c8..fa65bb2 100644 --- a/lib/scalingo/billing.rb +++ b/lib/scalingo/billing.rb @@ -5,7 +5,7 @@ class Billing < API::Client require "scalingo/billing/profile" register_handlers!( - profile: Profile, + profile: Profile ) end end diff --git a/lib/scalingo/client.rb b/lib/scalingo/client.rb index 0c97402..8bd5cc1 100644 --- a/lib/scalingo/client.rb +++ b/lib/scalingo/client.rb @@ -10,21 +10,21 @@ class Client < CoreClient def auth @auth ||= Auth.new( "https://auth.scalingo.com/v1", - scalingo: self, + scalingo: self ) end def billing @billing ||= Billing.new( "https://cashmachine.scalingo.com", - scalingo: self, + scalingo: self ) end def osc_fr1 @osc_fr1 ||= Regional.new( "https://api.osc-fr1.scalingo.com/v1", - scalingo: self, + scalingo: self ) end alias_method :apps_api_osc_fr1, :osc_fr1 @@ -32,7 +32,7 @@ def osc_fr1 def osc_secnum_fr1 @osc_secnum_fr1 ||= Regional.new( "https://api.osc-secnum-fr1.scalingo.com/v1", - scalingo: self, + scalingo: self ) end alias_method :apps_api_osc_secnum_fr1, :osc_secnum_fr1 @@ -40,14 +40,14 @@ def osc_secnum_fr1 def db_api_osc_fr1 @db_api_osc_fr1 ||= RegionalDatabase.new( "https://db-api.osc-fr1.scalingo.com/api", - scalingo: self, + scalingo: self ) end def db_api_osc_secnum_fr1 @db_api_osc_secnum_fr1 ||= RegionalDatabase.new( "https://db-api.osc-secnum-fr1.scalingo.com/api", - scalingo: self, + scalingo: self ) end end diff --git a/lib/scalingo/configuration.rb b/lib/scalingo/configuration.rb index 5330990..d748d69 100644 --- a/lib/scalingo/configuration.rb +++ b/lib/scalingo/configuration.rb @@ -37,7 +37,7 @@ class Configuration :additional_headers, # Specify an adapter for faraday. Leave nil for the default one (Net::HTTP) - :faraday_adapter, + :faraday_adapter ] ATTRIBUTES.each { |attr| attr_accessor(attr) } @@ -49,13 +49,13 @@ def self.default exchanged_token_validity: 1.hour, raise_on_missing_authentication: true, raise_on_expired_token: false, - additional_headers: {}, + additional_headers: {} ) end def initialize(attributes = {}, parent = nil) ATTRIBUTES.each do |name| - public_send("#{name}=", attributes.fetch(name, parent&.public_send(name))) + public_send(:"#{name}=", attributes.fetch(name, parent&.public_send(name))) end end end diff --git a/lib/scalingo/core_client.rb b/lib/scalingo/core_client.rb index 108de5f..21c655c 100644 --- a/lib/scalingo/core_client.rb +++ b/lib/scalingo/core_client.rb @@ -1,6 +1,5 @@ require "forwardable" require "faraday" -require "faraday_middleware" require "scalingo/token_holder" require "scalingo/errors" @@ -67,7 +66,7 @@ def authenticate_with(access_token: nil, bearer_token: nil, expires_at: nil) self.token = BearerToken.new( response.data[:token], expires_at: expiration, - raise_on_expired: config.raise_on_expired_token, + raise_on_expired: config.raise_on_expired_token ) end @@ -78,7 +77,7 @@ def authenticate_with(access_token: nil, bearer_token: nil, expires_at: nil) authenticate_with_bearer_token( bearer_token, expires_at: expires_at, - raise_on_expired_token: config.raise_on_expired_token, + raise_on_expired_token: config.raise_on_expired_token ) true diff --git a/lib/scalingo/regional.rb b/lib/scalingo/regional.rb index 051ab77..4692081 100644 --- a/lib/scalingo/regional.rb +++ b/lib/scalingo/regional.rb @@ -31,7 +31,7 @@ class Regional < API::Client metrics: Metrics, notifiers: Notifiers, operations: Operations, - scm_repo_links: ScmRepoLinks, + scm_repo_links: ScmRepoLinks ) end end diff --git a/lib/scalingo/regional/addons.rb b/lib/scalingo/regional/addons.rb index e6a0b52..ac9967d 100644 --- a/lib/scalingo/regional/addons.rb +++ b/lib/scalingo/regional/addons.rb @@ -89,7 +89,7 @@ def authenticate!(app_id, addon_id, headers = nil, &block) addon_id, token, expires_at: Time.now + 1.hour, - raise_on_expired_token: client.config.raise_on_expired_token, + raise_on_expired_token: client.config.raise_on_expired_token ) response diff --git a/lib/scalingo/regional_database.rb b/lib/scalingo/regional_database.rb index b7887d7..20fe7e6 100644 --- a/lib/scalingo/regional_database.rb +++ b/lib/scalingo/regional_database.rb @@ -7,7 +7,7 @@ class RegionalDatabase < API::Client register_handlers!( databases: Databases, - backups: Backups, + backups: Backups ) end end diff --git a/lib/scalingo/token_holder.rb b/lib/scalingo/token_holder.rb index db60938..b3d8cf7 100644 --- a/lib/scalingo/token_holder.rb +++ b/lib/scalingo/token_holder.rb @@ -55,7 +55,7 @@ def build_bearer_token(bearer_token, expires_at:, raise_on_expired_token:) BearerToken.new( token, expires_at: expires_at, - raise_on_expired: raise_on_expired_token, + raise_on_expired: raise_on_expired_token ) end end diff --git a/scalingo.gemspec b/scalingo.gemspec index 83a647f..e2fbfbd 100644 --- a/scalingo.gemspec +++ b/scalingo.gemspec @@ -19,7 +19,7 @@ Gem::Specification.new do |s| "changelog_uri" => "https://github.com/Scalingo/scalingo-ruby-api/blob/master/CHANGELOG.md", "documentation_uri" => "https://developers.scalingo.com/", "homepage_uri" => "https://www.scalingo.com/", - "source_code_uri" => "https://github.com/Scalingo/scalingo-ruby-api", + "source_code_uri" => "https://github.com/Scalingo/scalingo-ruby-api" } # Specify which files should be added to the gem when it is released. @@ -32,18 +32,15 @@ Gem::Specification.new do |s| s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) } s.require_paths = ["lib"] - s.test_files = Dir["spec/**/*_spec.rb"] - s.add_dependency "activesupport", [">= 5", "< 8"] - s.add_dependency "faraday", "~> 1.0" - s.add_dependency "faraday_middleware", "~> 1.0" + s.add_dependency "faraday", "~> 2.0" s.add_dependency "multi_json", ">= 1.0.3", "~> 1.0" s.add_development_dependency "bundler", "~> 2.0" s.add_development_dependency "rake", "~> 13.0" s.add_development_dependency "rspec", "~> 3.0" - s.add_development_dependency "standard", "~> 1.1.0" + s.add_development_dependency "standard", "~> 1.32" s.add_development_dependency "rubocop-rspec" s.add_development_dependency "pry", "~> 0.14.1" - s.add_development_dependency "webmock", "~> 3.12.2" + s.add_development_dependency "webmock", "~> 3.19" end diff --git a/spec/scalingo/api/client_spec.rb b/spec/scalingo/api/client_spec.rb index cd2d8c5..62a6512 100644 --- a/spec/scalingo/api/client_spec.rb +++ b/spec/scalingo/api/client_spec.rb @@ -164,8 +164,13 @@ end context "with bearer token" do + before { stub_request(:any, "localhost") } + it "has an authentication header set with a bearer scheme" do - expect(subject.connection.headers["Authorization"]).to eq "Bearer #{subject.token_holder.token.value}" + request_headers = subject.connection.get("/").env.request_headers + expected = "Bearer #{subject.token_holder.token.value}" + + expect(request_headers["Authorization"]).to eq(expected) end end end @@ -184,14 +189,20 @@ end context "with bearer token" do + before { stub_request(:any, "localhost") } + it "has an authentication header set with a bearer scheme" do scalingo.authenticate_database_with_bearer_token( database_id, "1234", expires_at: Time.now + 1.hour, - raise_on_expired_token: false, + raise_on_expired_token: false ) - expect(subject.database_connection(database_id).headers["Authorization"]).to eq "Bearer #{subject.token_holder.database_tokens[database_id].value}" + + request_headers = subject.database_connection(database_id).get("/").env.request_headers + expected = "Bearer #{subject.token_holder.database_tokens[database_id].value}" + + expect(request_headers["Authorization"]).to eq(expected) end end @@ -202,7 +213,7 @@ database_id_2, "1234", expires_at: Time.now + 1.hour, - raise_on_expired_token: false, + raise_on_expired_token: false ) expect { subject.database_connection(database_id) diff --git a/spec/scalingo/api/response_spec.rb b/spec/scalingo/api/response_spec.rb index e208b18..3a6318f 100644 --- a/spec/scalingo/api/response_spec.rb +++ b/spec/scalingo/api/response_spec.rb @@ -15,7 +15,7 @@ headers: headers, data: data, full_body: full_body, - meta: meta_object, + meta: meta_object ) } @@ -28,7 +28,7 @@ body: body, status: status, headers: headers, - success?: success, + success?: success ) } diff --git a/spec/scalingo/client_spec.rb b/spec/scalingo/client_spec.rb index 8169e89..7ae6d31 100644 --- a/spec/scalingo/client_spec.rb +++ b/spec/scalingo/client_spec.rb @@ -52,7 +52,7 @@ it "is successful with valid token" do fake_response = OpenStruct.new( successful?: true, - data: {token: "response token"}, + data: {token: "response token"} ) expect(subject.auth.tokens).to receive(:exchange).and_return(fake_response) @@ -64,7 +64,7 @@ it "fails with invalid token" do fake_response = OpenStruct.new( - successful?: false, + successful?: false ) expect(subject.auth.tokens).to receive(:exchange).and_return(fake_response) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 6c74adc..e1a4edc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,6 @@ require "bundler/setup" require "scalingo" +require "active_support/all" pattern = File.join(File.expand_path(__dir__), "support", "**", "*.rb") diff --git a/spec/support/scalingo.rb b/spec/support/scalingo.rb index 45ec449..e8aa5dc 100644 --- a/spec/support/scalingo.rb +++ b/spec/support/scalingo.rb @@ -6,7 +6,7 @@ module Scalingo auth: "https://auth.scalingo.test", billing: "https://billing.scalingo.test", regional: "https://regional.scalingo.test", - regional_database: "https://regional-database.scalingo.test", + regional_database: "https://regional-database.scalingo.test" } class SpecClient < CoreClient @@ -59,8 +59,7 @@ def register_stubs!(pattern = "**/*", api: nil, folder: nil) url = stub_data[:url] || File.join(endpoint, stub_data[:path]) method = (stub_data[:method] || :get).to_sym - request_options = { - } + request_options = {} if stub_data[:request].present? req = stub_data[:request] @@ -79,7 +78,7 @@ def register_stubs!(pattern = "**/*", api: nil, folder: nil) response_options = { status: stub_data.dig(:response, :status) || 200, - headers: {}, + headers: {} } if stub_data.dig(:response, :json_body).present? @@ -142,7 +141,7 @@ module Common if described_class < Scalingo::API::Endpoint api = described_class.to_s.split("::")[-2].downcase - described_class.new(send("#{api}_guest")) + described_class.new(send(:"#{api}_guest")) end end