From 0599058d8caec7c1bbb8c354fc8c243b8458cf62 Mon Sep 17 00:00:00 2001 From: Regis David Souza Mesquita Date: Mon, 7 Oct 2024 16:09:20 +0100 Subject: [PATCH 1/9] Ruby 3.0 and oauth2 support --- apple_auth.gemspec | 2 +- spec/token_spec.rb | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apple_auth.gemspec b/apple_auth.gemspec index e3fdd7b..56e3195 100644 --- a/apple_auth.gemspec +++ b/apple_auth.gemspec @@ -28,7 +28,7 @@ Gem::Specification.new do |spec| # Production dependencies spec.add_dependency 'jwt', '~> 2.2' - spec.add_dependency 'oauth2', '~> 1.4' + spec.add_dependency 'oauth2', '~> 2.0' # Development dependencies spec.add_development_dependency 'generator_spec', '~> 0.9.4' diff --git a/spec/token_spec.rb b/spec/token_spec.rb index d31549e..bf74b02 100644 --- a/spec/token_spec.rb +++ b/spec/token_spec.rb @@ -3,39 +3,39 @@ RSpec.describe AppleAuth::Token do subject(:token_service) { described_class.new(code) } + # ostruct is deprecated, so we use a Struct instead + MockedData = Struct.new(:token, :expired?, :expires?, :refresh_token, :expires_at) do + def refresh! + self + end + end + context '#authenticate!' do context 'when parameters are valid' do let(:code) { 'valid_code' } before do AppleAuth.config.apple_client_id = 'client_id' - AppleAuth.config.apple_private_key = OpenSSL::PKey::EC.new('prime256v1').generate_key! + AppleAuth.config.apple_private_key = OpenSSL::PKey::EC.generate('prime256v1') AppleAuth.config.apple_key_id = 'apple_kid' AppleAuth.config.apple_team_id = 'team_id' AppleAuth.config.redirect_uri = 'www.example.com' end - context 'when the acces token is not expired' do + context 'when the access token is not expired' do before do - mocked_data = OpenStruct.new(token: '1234', 'expired?': false) + mocked_data = MockedData.new('1234', false) allow(token_service).to receive(:apple_access_token).and_return(mocked_data) end it 'returns a hash with the corresponding access_token and expired value' do - expect(token_service.authenticate!).to include( - { - access_token: '1234' - } - ) + expect(token_service.authenticate!).to include({ access_token: '1234' }) end end - context 'when the acces token is expired' do + context 'when the access token is expired' do before do - mocked_data = OpenStruct.new('expired?': true, - 'expires?': true, - refresh_token: '4321', - expires_at: 1_594_667_034) + mocked_data = MockedData.new(nil, true, true, '4321', 1_594_667_034) allow(token_service).to receive(:apple_access_token).and_return(mocked_data) end From c967e4b134a28076042d27f582238a8b795a57c9 Mon Sep 17 00:00:00 2001 From: Regis David Souza Mesquita Date: Mon, 7 Oct 2024 16:41:07 +0100 Subject: [PATCH 2/9] Fixes multiple rubocop complaints and disable cop --- .rubocop.yml | 7 ++++++- apple_auth.gemspec | 15 +++++++++------ lib/apple_auth/token.rb | 2 +- spec/token_spec.rb | 1 - 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index b15ffca..9a0ade5 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,7 +1,8 @@ AllCops: - TargetRubyVersion: 2.5 + TargetRubyVersion: 3.0 Exclude: - lib/generators/apple_auth/apple_auth_controller/templates/** + NewCops: disable Style/Documentation: Enabled: false @@ -13,6 +14,10 @@ Lint/AmbiguousBlockAssociation: Exclude: - spec/**/* +Lint/ConstantDefinitionInBlock: + Exclude: + - spec/**/* + Metrics/AbcSize: # The ABC size is a calculated magnitude, so this number can be an Integer or # a Float. diff --git a/apple_auth.gemspec b/apple_auth.gemspec index 56e3195..f102f53 100644 --- a/apple_auth.gemspec +++ b/apple_auth.gemspec @@ -6,12 +6,15 @@ Gem::Specification.new do |spec| spec.name = 'apple_auth' spec.version = AppleAuth::Base::VERSION spec.authors = ['Timothy Peraza, Antonieta Alvarez, Martín Morón'] - spec.email = ['timothy@rootstrap.com, antonieta.alvarez@rootstrap.com, martin.jaime@rootstrap.com'] + spec.email = ['timothy@rootstrap.com, ' \ + 'antonieta.alvarez@rootstrap.com ,' \ + 'martin.jaime@rootstrap.com'] - spec.summary = 'Integration with Apple Sign In and Devise for backend. Validate and Verify user token.' + spec.summary = 'Integration with Apple Sign In and Devise for backend.' \ + 'Validate and Verify user token.' spec.homepage = 'https://github.com/rootstrap/apple_auth' spec.license = 'MIT' - spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0') + spec.required_ruby_version = Gem::Requirement.new('>= 3.0.0') spec.metadata['homepage_uri'] = spec.homepage spec.metadata['source_code_uri'] = 'https://github.com/rootstrap/apple_auth' @@ -19,7 +22,7 @@ Gem::Specification.new do |spec| # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. - spec.files = Dir.chdir(File.expand_path(__dir__)) do + spec.files = Dir.chdir(File.expand_path(__dir__)) do `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } end spec.bindir = 'exe' @@ -31,14 +34,14 @@ Gem::Specification.new do |spec| spec.add_dependency 'oauth2', '~> 2.0' # Development dependencies - spec.add_development_dependency 'generator_spec', '~> 0.9.4' spec.add_development_dependency 'byebug', '~> 11.1' + spec.add_development_dependency 'generator_spec', '~> 0.9.4' + spec.add_development_dependency 'parser', '~> 2.7.1.1' spec.add_development_dependency 'railties', '~> 6.0' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'reek', '~> 5.6' spec.add_development_dependency 'rspec', '~> 3.9' spec.add_development_dependency 'rubocop', '~> 0.80' - spec.add_development_dependency 'parser', '~> 2.7.1.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.8' end diff --git a/lib/apple_auth/token.rb b/lib/apple_auth/token.rb index edf2295..e2a4d98 100644 --- a/lib/apple_auth/token.rb +++ b/lib/apple_auth/token.rb @@ -63,7 +63,7 @@ def request_header def gen_private_key key = AppleAuth.config.apple_private_key - key = OpenSSL::PKey::EC.new(key) unless key.class == OpenSSL::PKey::EC + key = OpenSSL::PKey::EC.new(key) unless key.instance_of?(OpenSSL::PKey::EC) key end diff --git a/spec/token_spec.rb b/spec/token_spec.rb index bf74b02..9ea8fcb 100644 --- a/spec/token_spec.rb +++ b/spec/token_spec.rb @@ -3,7 +3,6 @@ RSpec.describe AppleAuth::Token do subject(:token_service) { described_class.new(code) } - # ostruct is deprecated, so we use a Struct instead MockedData = Struct.new(:token, :expired?, :expires?, :refresh_token, :expires_at) do def refresh! self From d212bc8cf2bd8c4a47aefd9f0d4d797acb75edac Mon Sep 17 00:00:00 2001 From: Regis David Souza Mesquita Date: Mon, 7 Oct 2024 16:50:32 +0100 Subject: [PATCH 3/9] Updates reek and rubocop for fixing requirements --- .reek.yml | 1 - .rubocop.yml | 2 +- apple_auth.gemspec | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.reek.yml b/.reek.yml index d251813..2250c8e 100644 --- a/.reek.yml +++ b/.reek.yml @@ -53,7 +53,6 @@ detectors: enabled: true exclude: [] max_allowed_nesting: 2 - ignore_iterators: [] NilCheck: enabled: false exclude: [] diff --git a/.rubocop.yml b/.rubocop.yml index 9a0ade5..0209379 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -30,7 +30,7 @@ Metrics/BlockLength: - '*.gemspec' - config/**/* - spec/**/* - ExcludedMethods: + AllowedMethods: - class_methods Metrics/BlockNesting: diff --git a/apple_auth.gemspec b/apple_auth.gemspec index f102f53..142fd7f 100644 --- a/apple_auth.gemspec +++ b/apple_auth.gemspec @@ -36,12 +36,12 @@ Gem::Specification.new do |spec| # Development dependencies spec.add_development_dependency 'byebug', '~> 11.1' spec.add_development_dependency 'generator_spec', '~> 0.9.4' - spec.add_development_dependency 'parser', '~> 2.7.1.1' + spec.add_development_dependency 'parser', '~> 3.0' spec.add_development_dependency 'railties', '~> 6.0' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'reek', '~> 5.6' + spec.add_development_dependency 'reek', '~> 6.1' spec.add_development_dependency 'rspec', '~> 3.9' - spec.add_development_dependency 'rubocop', '~> 0.80' + spec.add_development_dependency 'rubocop', '~> 1.3' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.8' end From 530ddd94383bcf8a6a5c87476755bbd4f68257c5 Mon Sep 17 00:00:00 2001 From: Regis David Souza Mesquita Date: Mon, 7 Oct 2024 16:52:27 +0100 Subject: [PATCH 4/9] Major version update --- lib/apple_auth/base/version.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/apple_auth/base/version.rb b/lib/apple_auth/base/version.rb index 059fc39..058a852 100644 --- a/lib/apple_auth/base/version.rb +++ b/lib/apple_auth/base/version.rb @@ -2,6 +2,7 @@ module AppleAuth module Base - VERSION = '1.1.0' + # Updated major version as the gem is now compatible with Ruby 3.0 and OAuth2 2.0 + VERSION = '2.0.0' end end From d8e8854592ce88eda8d9f27c9204198342167f6a Mon Sep 17 00:00:00 2001 From: Regis David Souza Mesquita Date: Mon, 7 Oct 2024 20:10:29 +0100 Subject: [PATCH 5/9] Adds support for JWT 2.9.3 --- apple_auth.gemspec | 2 +- lib/apple_auth/helpers/jwt_conditions.rb | 4 ++-- spec/helpers/jwt_conditions_spec.rb | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apple_auth.gemspec b/apple_auth.gemspec index 142fd7f..018c6fb 100644 --- a/apple_auth.gemspec +++ b/apple_auth.gemspec @@ -30,7 +30,7 @@ Gem::Specification.new do |spec| spec.require_paths = ['lib'] # Production dependencies - spec.add_dependency 'jwt', '~> 2.2' + spec.add_dependency 'jwt', '~> 2.9.3' spec.add_dependency 'oauth2', '~> 2.0' # Development dependencies diff --git a/lib/apple_auth/helpers/jwt_conditions.rb b/lib/apple_auth/helpers/jwt_conditions.rb index d5ee1b9..a28d577 100644 --- a/lib/apple_auth/helpers/jwt_conditions.rb +++ b/lib/apple_auth/helpers/jwt_conditions.rb @@ -19,8 +19,8 @@ def initialize(user_identity, decoded_jwt) end def validate! - JWT::ClaimsValidator.new(decoded_jwt).validate! && validate_sub! && jwt_conditions_validate! - rescue JWT::InvalidPayload => e + ::JWT::Claims.verify_payload!(decoded_jwt, :exp, :iat).nil? && validate_sub! && jwt_conditions_validate! + rescue JWT::DecodeError => e raise JWTValidationError, e.message end diff --git a/spec/helpers/jwt_conditions_spec.rb b/spec/helpers/jwt_conditions_spec.rb index 5a08484..034d9bb 100644 --- a/spec/helpers/jwt_conditions_spec.rb +++ b/spec/helpers/jwt_conditions_spec.rb @@ -39,7 +39,7 @@ context 'when jwt has incorrect type attributes' do context 'when exp is not a integer' do - let(:jwt_exp) { Time.now + 5.minutes } + let(:jwt_exp) { "Invalid" } # Dates are now valid on JWT library it 'raises an exception' do expect { jwt_conditions_helper.validate! }.to raise_error( @@ -94,7 +94,7 @@ it 'raises an exception' do expect { jwt_conditions_helper.validate! }.to raise_error( - AppleAuth::Conditions::JWTValidationError, 'Expired jwt_exp' + AppleAuth::Conditions::JWTValidationError, 'Signature has expired' ) end end @@ -104,7 +104,7 @@ it 'raises an exception' do expect { jwt_conditions_helper.validate! }.to raise_error( - AppleAuth::Conditions::JWTValidationError, 'jwt_iat is greater than now' + AppleAuth::Conditions::JWTValidationError, 'Invalid iat' ) end end From 7a9c8cf3a94de6e8f03db46bcbf9fe0f72139721 Mon Sep 17 00:00:00 2001 From: Regis David Souza Mesquita Date: Mon, 7 Oct 2024 22:01:16 +0100 Subject: [PATCH 6/9] JWT update and fixes --- apple_auth.gemspec | 2 ++ lib/apple_auth/helpers/jwt_server_conditions.rb | 4 ++-- spec/helpers/jwt_server_conditions_spec.rb | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apple_auth.gemspec b/apple_auth.gemspec index 018c6fb..3395fed 100644 --- a/apple_auth.gemspec +++ b/apple_auth.gemspec @@ -35,7 +35,9 @@ Gem::Specification.new do |spec| # Development dependencies spec.add_development_dependency 'byebug', '~> 11.1' + spec.add_development_dependency 'drb' # Will be removed from the standard library in Ruby 3.4 spec.add_development_dependency 'generator_spec', '~> 0.9.4' + spec.add_development_dependency 'mutex_m' # Will be removed from the standard library in Ruby 3.4 spec.add_development_dependency 'parser', '~> 3.0' spec.add_development_dependency 'railties', '~> 6.0' spec.add_development_dependency 'rake', '~> 13.0' diff --git a/lib/apple_auth/helpers/jwt_server_conditions.rb b/lib/apple_auth/helpers/jwt_server_conditions.rb index 76ec2dc..c727175 100644 --- a/lib/apple_auth/helpers/jwt_server_conditions.rb +++ b/lib/apple_auth/helpers/jwt_server_conditions.rb @@ -17,8 +17,8 @@ def initialize(decoded_jwt) end def validate! - JWT::ClaimsValidator.new(decoded_jwt).validate! && jwt_conditions_validate! - rescue JWT::InvalidPayload => e + ::JWT::Claims.verify_payload!(decoded_jwt, :iat).nil? && jwt_conditions_validate! + rescue JWT::DecodeError => e raise JWTValidationError, e.message end diff --git a/spec/helpers/jwt_server_conditions_spec.rb b/spec/helpers/jwt_server_conditions_spec.rb index a207f14..fb3f751 100644 --- a/spec/helpers/jwt_server_conditions_spec.rb +++ b/spec/helpers/jwt_server_conditions_spec.rb @@ -74,7 +74,7 @@ it 'raises an exception' do expect { jwt_conditions_helper.validate! }.to raise_error( - AppleAuth::Conditions::JWTValidationError, 'jwt_iat is greater than now' + AppleAuth::Conditions::JWTValidationError, 'Invalid iat' ) end end From 6fae111da3e5b7df6a32fd8f38a9fa3ba4131198 Mon Sep 17 00:00:00 2001 From: Regis David Souza Mesquita Date: Mon, 7 Oct 2024 22:33:12 +0100 Subject: [PATCH 7/9] Was getting 403s, authscheme must be on the request body --- lib/apple_auth/token.rb | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/apple_auth/token.rb b/lib/apple_auth/token.rb index e2a4d98..63065a6 100644 --- a/lib/apple_auth/token.rb +++ b/lib/apple_auth/token.rb @@ -75,6 +75,18 @@ def client_urls } end + # Apple seems to expect the auth_scheme to be on + # the body, the default is :basic_auth + def auth_scheme + { + auth_scheme: :request_body + } + end + + def oauth_options + client_urls.merge(auth_scheme) + end + def reponse_hash(access_token) token_hash = { access_token: access_token.token } @@ -91,8 +103,11 @@ def reponse_hash(access_token) def apple_access_token client = ::OAuth2::Client.new(APPLE_CONFIG.apple_client_id, client_secret_from_jwt, - client_urls) + oauth_options) client.auth_code.get_token(code, { redirect_uri: APPLE_CONFIG.redirect_uri }, {}) + rescue StandardError => e + puts "#{e.message} #{e.backtrace}" + raise e end end end From 0ed69cafce77bb7037b22f711d34af17d5a285b5 Mon Sep 17 00:00:00 2001 From: Regis David Souza Mesquita Date: Tue, 8 Oct 2024 15:04:04 +0100 Subject: [PATCH 8/9] rubocop fixes --- lib/apple_auth/helpers/jwt_conditions.rb | 3 ++- spec/helpers/jwt_conditions_spec.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/apple_auth/helpers/jwt_conditions.rb b/lib/apple_auth/helpers/jwt_conditions.rb index a28d577..dda3d00 100644 --- a/lib/apple_auth/helpers/jwt_conditions.rb +++ b/lib/apple_auth/helpers/jwt_conditions.rb @@ -19,7 +19,8 @@ def initialize(user_identity, decoded_jwt) end def validate! - ::JWT::Claims.verify_payload!(decoded_jwt, :exp, :iat).nil? && validate_sub! && jwt_conditions_validate! + ::JWT::Claims.verify_payload!(decoded_jwt, :exp, + :iat).nil? && validate_sub! && jwt_conditions_validate! rescue JWT::DecodeError => e raise JWTValidationError, e.message end diff --git a/spec/helpers/jwt_conditions_spec.rb b/spec/helpers/jwt_conditions_spec.rb index 034d9bb..6d68fd0 100644 --- a/spec/helpers/jwt_conditions_spec.rb +++ b/spec/helpers/jwt_conditions_spec.rb @@ -39,7 +39,7 @@ context 'when jwt has incorrect type attributes' do context 'when exp is not a integer' do - let(:jwt_exp) { "Invalid" } # Dates are now valid on JWT library + let(:jwt_exp) { 'Invalid' } # Dates are now valid on JWT library it 'raises an exception' do expect { jwt_conditions_helper.validate! }.to raise_error( From 2c4a175135131efc036f50aeab8a36701d03b341 Mon Sep 17 00:00:00 2001 From: Regis David Souza Mesquita Date: Tue, 8 Oct 2024 15:09:44 +0100 Subject: [PATCH 9/9] removes dev debug code --- lib/apple_auth/token.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/apple_auth/token.rb b/lib/apple_auth/token.rb index 63065a6..1aa490a 100644 --- a/lib/apple_auth/token.rb +++ b/lib/apple_auth/token.rb @@ -105,9 +105,6 @@ def apple_access_token client_secret_from_jwt, oauth_options) client.auth_code.get_token(code, { redirect_uri: APPLE_CONFIG.redirect_uri }, {}) - rescue StandardError => e - puts "#{e.message} #{e.backtrace}" - raise e end end end