From bb31400cfeda25a17ee397beb027a06255c4bfbb Mon Sep 17 00:00:00 2001 From: Jaedon Farrugia Date: Mon, 10 Jun 2024 13:13:17 +1000 Subject: [PATCH] refactor gem authorization code was no longer working due to omniauth / omniauth-oauth2 updates, there were also conflicts with other gems using a later version of omniauth-oauth2 (1.8), meaning this gem could not be used in combination with google/microsoft strategies --- lib/omniauth/strategies/xero_oauth2.rb | 84 ++++++++++++++++++-------- lib/xero-oauth2/version.rb | 2 +- omniauth-xero-oauth2.gemspec | 31 +++++----- 3 files changed, 75 insertions(+), 42 deletions(-) diff --git a/lib/omniauth/strategies/xero_oauth2.rb b/lib/omniauth/strategies/xero_oauth2.rb index 7a1a342..007fbb5 100755 --- a/lib/omniauth/strategies/xero_oauth2.rb +++ b/lib/omniauth/strategies/xero_oauth2.rb @@ -6,28 +6,18 @@ module Strategies class XeroOauth2 < OmniAuth::Strategies::OAuth2 option :name, :xero_oauth2 - option :authorize_options, %i[login_hint state redirect_uri scope] + option :client_options, { + site: 'https://api.xero.com/api.xro/2.0', + authorize_url: 'https://login.xero.com/identity/connect/authorize', + token_url: 'https://identity.xero.com/connect/token' + } - option( - :client_options, - { - site: 'https://api.xero.com/api.xro/2.0', - authorize_url: 'https://login.xero.com/identity/connect/authorize', - token_url: 'https://identity.xero.com/connect/token', - }, - ) + option :authorize_options, %i[login_hint state redirect_uri callback_url scope] - 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]) - end - end - end + option :token_params, {} + option :scope, 'openid email profile' - def callback_url - options[:redirect_uri] || (full_host + callback_path) - end + uid { raw_info['xero_userid'] } extra do { @@ -46,29 +36,71 @@ def callback_url } end - uid { raw_info['xero_userid'] } + 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]) + end + + session['omniauth.state'] = params[:state] if params[:state] + end + end + + def callback_url + options[:redirect_uri] || (full_host + callback_path) + end private + def id_token @id_token ||= access_token['id_token'] end def raw_info - if access_token['id_token'] == nil + if access_token['id_token'].nil? @raw_info = { - 'xero_userid'=> '', + 'xero_userid' => '', 'given_name' => '', 'family_name' => '', - 'email' => '', + 'email' => '' } else - decoded_info ||= JWT.decode access_token['id_token'], nil, false - @raw_info ||= decoded_info[0] + begin + decoded_info = JWT.decode access_token['id_token'], nil, false + @raw_info ||= decoded_info[0] + rescue JWT::DecodeError => e + logger.warn "JWT Decode Error: #{e.message}" + @raw_info = {} + end end end def xero_tenants - @xero_tenants ||= JSON.parse(access_token.get("https://api.xero.com/connections", {'Authorization'=>('Bearer ' + access_token.token),'Accept'=>'application/json'}).body) + @xero_tenants ||= begin + response = access_token.get( + "https://api.xero.com/connections", + { 'Authorization' => "Bearer #{access_token.token}", 'Accept' => 'application/json' } + ) + JSON.parse(response.body) + rescue StandardError => e + logger.warn "Error fetching Xero tenants: #{e.message}" + [] + end + end + + def build_access_token + redirect_uri = request.params['redirect_uri'] || callback_url + authorization_code = request.params['code'] || JSON.parse(request.body.read)['code'] + + client.auth_code.get_token( + authorization_code, + { redirect_uri: redirect_uri }.merge(token_params.to_hash(symbolize_keys: true)), + deep_symbolize(options.auth_token_params || {}) + ) + rescue JSON::ParserError => e + raise(OmniAuth::Error, 'Error parsing authorization code.') + rescue StandardError => e + raise(OmniAuth::Error, e) end end end diff --git a/lib/xero-oauth2/version.rb b/lib/xero-oauth2/version.rb index a0b6f0b..eab3efa 100755 --- a/lib/xero-oauth2/version.rb +++ b/lib/xero-oauth2/version.rb @@ -1,5 +1,5 @@ module OmniAuth module XeroOauth2 - VERSION = '1.1.0' + VERSION = '1.1.1' end end diff --git a/omniauth-xero-oauth2.gemspec b/omniauth-xero-oauth2.gemspec index a394d03..7f29d1c 100755 --- a/omniauth-xero-oauth2.gemspec +++ b/omniauth-xero-oauth2.gemspec @@ -1,19 +1,20 @@ require_relative 'lib/xero-oauth2/version' -Gem::Specification.new do |s| - s.name = 'omniauth-xero-oauth2' - s.version = OmniAuth::XeroOauth2::VERSION - s.licenses = ['MIT'] - s.summary = 'OAuth2 Omniauth strategy for Xero.' - s.description = 'OAuth2 Omniauth straetgy for Xero API.' - s.authors = ['Xero API'] - s.email = 'api@xero.com' - s.homepage = 'https://rubygems.org/gems/omniauth-xero-oauth2' - s.metadata = { 'source_code_uri' => 'https://github.com/XeroAPI/xero-oauth2-omniauth-strategy' } - s.files = ['lib/omniauth-xero-oauth2.rb','lib/xero-oauth2/version.rb','lib/omniauth/strategies/xero_oauth2.rb'] +Gem::Specification.new do |spec| + spec.name = 'omniauth-xero-oauth2' + spec.version = OmniAuth::XeroOauth2::VERSION + spec.licenses = ['MIT'] + spec.summary = 'OAuth2 Omniauth strategy for Xero.' + spec.description = 'OAuth2 Omniauth straetgy for Xero API.' + spec.authors = ['Xero API'] + spec.email = 'api@xero.com' + spec.homepage = 'https://rubygems.org/gems/omniauth-xero-oauth2' + spec.metadata = { 'source_code_uri' => 'https://github.com/XeroAPI/xero-oauth2-omniauth-strategy' } + spec.files = ['lib/omniauth-xero-oauth2.rb','lib/xero-oauth2/version.rb','lib/omniauth/strategies/xero_oauth2.rb'] - s.add_dependency 'omniauth', '>= 2.0.0', '< 2.2.0' - s.add_dependency 'omniauth-oauth2', '~> 1.7.1' + spec.add_runtime_dependency 'jwt', '~> 2.0' + spec.add_runtime_dependency 'omniauth', '>= 2.0.0', '< 2.2.0' + spec.add_runtime_dependency 'omniauth-oauth2', '~> 1.8.0' - s.add_development_dependency 'rspec', '~> 3.6' -end \ No newline at end of file + spec.add_development_dependency 'rspec', '~> 3.6' +end