From 43e90f3256740381921a3664ea1f401cc93bf012 Mon Sep 17 00:00:00 2001 From: Josh K Date: Thu, 14 Sep 2023 11:42:32 -0500 Subject: [PATCH] Add support for Ruby 3.2 Upgrade omniauth and oauth2 gems. --- .circleci/config.yml | 199 +++++++++++++++++++ .rubocop.yml | 27 +++ CHANGELOG.md | 6 + Gemfile | 11 + Guardfile | 4 +- README.md | 2 +- Rakefile | 2 + bin/console | 11 + bin/setup | 10 + lib/omniauth-bigcommerce.rb | 2 + lib/omniauth/bigcommerce/version.rb | 2 +- lib/omniauth/strategies/bigcommerce.rb | 21 +- omniauth-bigcommerce.gemspec | 10 +- spec/omniauth/strategies/bigcommerce_spec.rb | 44 ++-- spec/spec_helper.rb | 3 +- 15 files changed, 317 insertions(+), 37 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 .rubocop.yml mode change 100644 => 100755 Rakefile create mode 100755 bin/console create mode 100755 bin/setup diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..6039268 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,199 @@ +version: 2.1 + +ruby_env: &ruby_env + working_directory: ~/repo + environment: + BUNDLE_JOBS: 4 + BUNDLE_RETRY: 3 + BUNDLE_PATH: vendor/bundle + RACK_ENV: test + RAILS_ENV: test + RUBY_VERSION: <> + docker: + - image: cimg/ruby:<> + +gem_cache_key: &gem_cache_key + gem_cache_key: "gem-cache-v2" + +executors: + ruby_2_7: + <<: *ruby_env + parameters: + ruby-version: + type: string + default: "2.7" + ruby_3_0: + <<: *ruby_env + parameters: + ruby-version: + type: string + default: "3.0" + ruby_3_1: + <<: *ruby_env + parameters: + ruby-version: + type: string + default: "3.1" + ruby_3_2: + <<: *ruby_env + parameters: + ruby-version: + type: string + default: "3.2" + +commands: + pre-setup: + steps: + - add_ssh_keys + - checkout + bundle-install: + parameters: + gem_cache_key: + type: string + default: "gem-cache-v2" + grpc_ruby_build_procs: + type: integer + default: 4 + steps: + - restore_cache: + keys: + - <>-{{ arch }}-{{ .Branch }}-{{ checksum "Gemfile.lock" }} + - <>-{{ arch }}-{{ .Branch }} + - <> + - run: + name: "bundle install" + command: | + bundle config set --local path 'vendor/bundle' + bundle lock --add-platform x86_64-linux + bundle check || bundle install + bundle clean + - save_cache: + key: <>-{{ arch }}-{{ .Branch }}-{{ checksum "Gemfile.lock" }} + paths: + - vendor/bundle + rspec-unit: + parameters: + additional_args: + type: string + default: "" + glob: + type: string + default: "" + steps: + - run: mkdir ~/rspec + - run: + name: "Run rspec tests" + command: | + TESTFILES=$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings) + echo "Running: ${TESTFILES}" + bundle exec rspec --format progress --format RspecJunitFormatter -o ~/rspec/rspec.xml <> -- ${TESTFILES} + when: always + - store_test_results: + path: ~/rspec + bundle-audit: + parameters: + additional_args: + type: string + default: "" + steps: + - run: bundle exec bundle-audit update + - run: bundle exec bundle-audit check -v <> + rubocop: + steps: + - run: bundle exec rubocop -P + +jobs: + bundle-audit: + executor: <> + parameters: + e: + type: executor + default: "ruby_3_0" + steps: + - pre-setup + - bundle-install: + <<: *gem_cache_key + - bundle-audit + rubocop: + executor: <> + parameters: + e: + type: executor + default: "ruby_3_0" + steps: + - pre-setup + - bundle-install: + <<: *gem_cache_key + - rubocop + rspec-unit: + executor: <> + parameters: + e: + type: executor + default: "ruby_3_0" + code-climate: + type: boolean + default: false + steps: + - pre-setup + - bundle-install: + <<: *gem_cache_key + - rspec-unit: + code-climate: <> + +workflows: + version: 2 + ruby_2_7: + jobs: + - bundle-audit: + name: "ruby-2_7-bundle_audit" + e: "ruby_2_7" + - rubocop: + name: "ruby-2_7-rubocop" + e: "ruby_2_7" + - rspec-unit: + name: "ruby-2_7-rspec" + e: "ruby_2_7" + code-climate: false + - e2e: + name: "ruby-2_7-e2e" + e: "ruby_2_7" + ruby_3_0: + jobs: + - bundle-audit: + name: "ruby-3_0-bundle_audit" + e: "ruby_3_0" + - rubocop: + name: "ruby-3_0-rubocop" + e: "ruby_3_0" + - rspec-unit: + name: "ruby-3_0-rspec" + e: "ruby_3_0" + - e2e: + name: "ruby-3_0-e2e" + e: "ruby_3_0" + ruby_3_1: + jobs: + - bundle-audit: + name: "ruby-3_1-bundle_audit" + e: "ruby_3_1" + - rubocop: + name: "ruby-3_1-rubocop" + e: "ruby_3_1" + - rspec-unit: + name: "ruby-3_1-rspec" + e: "ruby_3_1" + - e2e: + name: "ruby-3_1-e2e" + e: "ruby_3_1" + ruby_3_2: + jobs: + - bundle-audit: + name: "ruby-3_2-bundle_audit" + e: "ruby_3_2" + - rubocop: + name: "ruby-3_2-rubocop" + e: "ruby_3_2" + - rspec-unit: + name: "ruby-3_2-rspec" + e: "ruby_3_2" diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..ca45712 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,27 @@ +AllCops: + TargetRubyVersion: 2.7.5 + NewCops: enable + SuggestExtensions: false + +require: + - rubocop-performance + - rubocop-thread_safety + +Style/StringLiterals: + Enabled: true + EnforcedStyle: single_quotes + +Style/StringLiteralsInInterpolation: + Enabled: true + EnforcedStyle: single_quotes + +Layout/LineLength: + Max: 120 + +Metrics/BlockLength: + Exclude: + - 'spec/**/*' + +Naming/FileName: + Exclude: + - 'lib/omniauth-bigcommerce.rb' diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a9e074..772b8d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ Changelog for the omniauth-bigcommerce gem. ### Pending release +- Add support for Ruby 3.0 and above +- Remove support for Ruby < 2.7.5 +- Upgrade `oauth2` gem >= 2.0 +- Upgrade `omniauth-oauth2` gem to >= 1.7 +- Add CircleCI support + ### 0.4.0 - Adds account_uuid to response payload diff --git a/Gemfile b/Gemfile index c6a6004..df9a6a8 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved # # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated @@ -16,3 +18,12 @@ source 'https://rubygems.org' gemspec + +gem 'bundler-audit', '>= 0.9' +gem 'rake', '~> 13.0' +gem 'rspec', '~> 3.0' +gem 'rspec_junit_formatter' +gem 'rubocop', '~> 1.21' +gem 'rubocop-performance', '~> 1.19.0' +gem 'rubocop-thread_safety', '~> 0.5.1' +gem 'simplecov' diff --git a/Guardfile b/Guardfile index d89ec90..848a79c 100644 --- a/Guardfile +++ b/Guardfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved # # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated @@ -16,7 +18,7 @@ guard 'rspec', version: 2 do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } - watch('spec/spec_helper.rb') { "spec" } + watch('spec/spec_helper.rb') { 'spec' } end guard 'bundler' do diff --git a/README.md b/README.md index f958425..96bad9d 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ The following response format is provided back to you for this provider: raw_info: {}, scopes: 'requested_scopes store_v2_settings' context: 'store/xyz123', - account_uuid: 'fooBar' + account_uuid: '3D2D8C24-8378-4180-9550-69A95ABDFAAF' } } ``` diff --git a/Rakefile b/Rakefile old mode 100644 new mode 100755 index 29d45a9..4e348c3 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,6 @@ #!/usr/bin/env rake +# frozen_string_literal: true + # Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved # # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/bin/console b/bin/console new file mode 100755 index 0000000..1628e46 --- /dev/null +++ b/bin/console @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'bundler/setup' +require 'omniauth-bigcommerce' + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +require 'irb' +IRB.start(__FILE__) diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..5407075 --- /dev/null +++ b/bin/setup @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install +bundle exec rspec -p +bundle exec rubocop -P +bundle audit update +bundle audit diff --git a/lib/omniauth-bigcommerce.rb b/lib/omniauth-bigcommerce.rb index 07f25b6..bf48390 100644 --- a/lib/omniauth-bigcommerce.rb +++ b/lib/omniauth-bigcommerce.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved # # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/lib/omniauth/bigcommerce/version.rb b/lib/omniauth/bigcommerce/version.rb index 5b2d0f1..2cfc29c 100644 --- a/lib/omniauth/bigcommerce/version.rb +++ b/lib/omniauth/bigcommerce/version.rb @@ -17,6 +17,6 @@ # module OmniAuth module BigCommerce - VERSION = '0.4.1.pre' + VERSION = '1.0.0.pre' end end diff --git a/lib/omniauth/strategies/bigcommerce.rb b/lib/omniauth/strategies/bigcommerce.rb index 96fa6fa..06d005d 100644 --- a/lib/omniauth/strategies/bigcommerce.rb +++ b/lib/omniauth/strategies/bigcommerce.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved # # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated @@ -24,13 +26,12 @@ class BigCommerce < OmniAuth::Strategies::OAuth2 option :name, 'bigcommerce' option :provider_ignores_state, true option :scope, 'users_basic_information' - option :authorize_options, [:scope, :context] - option :token_options, [:scope, :context, :account_uuid] + option :authorize_options, %i[scope context] + option :token_options, %i[scope context account_uuid] option :client_options, site: ENV.fetch('BC_AUTH_SERVICE', 'https://login.bigcommerce.com'), - authorize_url: '/oauth2/authorize', - token_url: '/oauth2/token' - + authorize_url: 'oauth2/authorize', + token_url: 'oauth2/token' uid { access_token.params['user']['id'] } @@ -63,7 +64,7 @@ def raw_info # Exclude query string in callback url. This used to be part of omniauth-oauth2, but was # removed in 1.4.0: https://github.com/intridea/omniauth-oauth2/pull/70 def callback_url - full_host + script_name + callback_path + full_host + callback_path end # Make sure to pass scope and context through to the authorize call @@ -71,7 +72,7 @@ def callback_url def authorize_params super.tap do |params| options[:authorize_options].each do |k| - params[k] = request.params[k.to_s] unless [nil, ''].include?(request.params[k.to_s]) + params[k] = request.params[k.to_s] unless blank?(request.params[k.to_s]) end end end @@ -80,10 +81,14 @@ def authorize_params def token_params super.tap do |params| options[:token_options].each do |k| - params[k] = request.params[k.to_s] unless [nil, ''].include?(request.params[k.to_s]) + params[k] = request.params[k.to_s] unless blank?(request.params[k.to_s]) end end end + + def blank?(value) + value.nil? || value.empty? + end end end end diff --git a/omniauth-bigcommerce.gemspec b/omniauth-bigcommerce.gemspec index edf41ac..5fffd69 100644 --- a/omniauth-bigcommerce.gemspec +++ b/omniauth-bigcommerce.gemspec @@ -27,14 +27,12 @@ Gem::Specification.new do |gem| gem.files = Dir['README.md', 'lib/**/*', 'omniauth-bigcommerce.gemspec', 'Gemfile'] gem.name = 'omniauth-bigcommerce' gem.require_paths = ['lib'] - gem.required_ruby_version = '>= 2.1' + gem.required_ruby_version = '>= 2.7.5' gem.version = OmniAuth::BigCommerce::VERSION gem.license = 'MIT' - gem.add_dependency 'oauth2', '>= 1.4.4' + gem.add_dependency 'oauth2', '>= 2.0.0' gem.add_dependency 'omniauth' - gem.add_dependency 'omniauth-oauth2', '>= 1.5' - gem.add_development_dependency 'rake' - gem.add_development_dependency 'rspec' - gem.add_development_dependency 'simplecov' + gem.add_dependency 'omniauth-oauth2', '>= 1.7' + gem.metadata['rubygems_mfa_required'] = 'true' end diff --git a/spec/omniauth/strategies/bigcommerce_spec.rb b/spec/omniauth/strategies/bigcommerce_spec.rb index 94d2a7b..ba935de 100644 --- a/spec/omniauth/strategies/bigcommerce_spec.rb +++ b/spec/omniauth/strategies/bigcommerce_spec.rb @@ -1,75 +1,81 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe OmniAuth::Strategies::BigCommerce do + subject { described_class.new({}) } + let(:store_hash) { 'abcdefg' } let(:context) { "stores/#{store_hash}" } let(:scope) { 'store_v2_products' } let(:account_uuid) { 'foobar' } - let(:request) { double('Request', params: { 'context' => context, 'scope' => scope, 'account_uuid' => account_uuid }, cookies: {}, env: {}) } + let(:request) do + instance_double(Rack::Request, params: { 'context' => context, 'scope' => scope, 'account_uuid' => account_uuid }, + cookies: {}, env: {}) + end before do OmniAuth.config.test_mode = true - allow(subject).to receive(:request).and_return(request) + allow(subject).to receive_messages(request: request, script_name: '') end + after { OmniAuth.config.test_mode = false } - subject { OmniAuth::Strategies::BigCommerce.new({}) } describe 'options' do - it 'should have correct name' do + it 'has correct name' do expect(subject.options.name).to eq('bigcommerce') end describe 'client options' do - it 'should have correct site' do + it 'has correct site' do # env variable set in spec_helper.rb # TODO: change this once we have bigcommerceapp.com url expect(subject.options.client_options.site).to eq('https://example.com') end - it 'should have correct authorize url' do - expect(subject.options.client_options.authorize_url).to eq('/oauth2/authorize') + it 'has correct authorize url' do + expect(subject.options.client_options.authorize_url).to eq('oauth2/authorize') end - it 'should have correct token url' do - expect(subject.options.client_options.token_url).to eq('/oauth2/token') + it 'has correct token url' do + expect(subject.options.client_options.token_url).to eq('oauth2/token') end end describe 'OAuth2 settings' do - it 'should ignore state' do - expect(subject.options.provider_ignores_state).to eq true + it 'ignores state' do + expect(subject.options.provider_ignores_state).to be true end end end describe 'callback url' do - it 'should have the correct path' do + it 'has the correct path' do expect(subject.callback_path).to eq('/auth/bigcommerce/callback') end context 'when callback url has a query string' do let(:host) { 'https://example.com' } let(:query_string) { 'foo=bar' } + before do - allow(subject).to receive(:full_host).and_return(host) - allow(subject).to receive(:script_name).and_return('') - allow(subject).to receive(:query_string).and_return(query_string) + allow(subject).to receive_messages(full_host: host, script_name: '', query_string: query_string) end - it 'query string should not be included in the callback url' do + it 'query string is not included in the callback url' do expect(subject.callback_url).to eq("#{host}#{subject.callback_path}") - expect(subject.callback_url).to_not include(query_string) + expect(subject.callback_url).not_to include(query_string) end end end describe 'extra params for authorize and token exchange' do - it 'should set the context and scope parameters in the authorize request' do + it 'sets the context and scope parameters in the authorize request' do expect(subject.authorize_params['context']).to eq(context) expect(subject.authorize_params['scope']).to eq(scope) end - it 'should set the context and scope parameters in the token request' do + it 'sets the context and scope parameters in the token request' do expect(subject.token_params['context']).to eq(context) expect(subject.token_params['scope']).to eq(scope) expect(subject.token_params['account_uuid']).to eq(account_uuid) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f0a26c9..b418c27 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ENV['BC_AUTH_SERVICE'] = 'https://example.com' require 'simplecov' @@ -10,4 +12,3 @@ config.order = :random Kernel.srand config.seed end -