diff --git a/.travis.yml b/.travis.yml index 60b2eb2..2b663d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,4 +3,5 @@ rvm: - 2.2.6 - 2.3.3 - 2.4.1 + - 3.2.2 script: bundle exec rspec diff --git a/README.md b/README.md index f73f9a7..8c836ba 100644 --- a/README.md +++ b/README.md @@ -3,21 +3,22 @@ Omniauth strategy for using Swedbank as an authentication service provider. [![Gem Version](https://badge.fury.io/rb/omniauth-swedbank.png)](http://badge.fury.io/rb/omniauth-swedbank) -[![Build Status](https://travis-ci.org/mak-it/omniauth-swedbank.svg?branch=master)](https://travis-ci.org/mak-it/omniauth-swedbank) +[![Build Status](https://travis-ci.org/mitigate-dev/omniauth-swedbank.svg?branch=master)](https://travis-ci.org/mitigate-dev/omniauth-swedbank) Supported Ruby versions: 2.2+ ## Related projects -- [omniauth-citadele](https://github.com/mak-it/omniauth-citadele) - strategy for authenticating with Citadele -- [omniauth-dnb](https://github.com/mak-it/omniauth-dnb) - strategy for authenticating with DNB -- [omniauth-nordea](https://github.com/mak-it/omniauth-nordea) - strategy for authenticating with Nordea -- [omniauth-seb-elink](https://github.com/mak-it/omniauth-seb-elink) - strategy for authenticating with SEB +- [omniauth-citadele](https://github.com/mitigate-dev/omniauth-citadele) - strategy for authenticating with Citadele +- [omniauth-dnb](https://github.com/mitigate-dev/omniauth-dnb) - strategy for authenticating with DNB +- [omniauth-nordea](https://github.com/mitigate-dev/omniauth-nordea) - strategy for authenticating with Nordea +- [omniauth-seb-elink](https://github.com/mitigate-dev/omniauth-seb-elink) - strategy for authenticating with SEB ## Installation -Add this line to your application's Gemfile: +Add these lines to your application's Gemfile (omniauth-rails_csrf_protection is required if using Rails): + gem 'omniauth-rails_csrf_protection' gem 'omniauth-swedbank' And then execute: @@ -26,7 +27,7 @@ And then execute: Or install it yourself as: - $ gem install omniauth-swedbank + $ gem install omniauth-rails_csrf_protection omniauth-swedbank ## Usage diff --git a/lib/omniauth/strategies/swedbank.rb b/lib/omniauth/strategies/swedbank.rb index 934d824..ff88517 100644 --- a/lib/omniauth/strategies/swedbank.rb +++ b/lib/omniauth/strategies/swedbank.rb @@ -9,6 +9,14 @@ class Swedbank AUTH_SERVICE = '4002' AUTH_VERSION = '008' + def self.render_nonce? + defined?(ActionDispatch::ContentSecurityPolicy::Request) != nil + end + if render_nonce? + include ActionDispatch::ContentSecurityPolicy::Request + delegate :get_header, :set_header, to: :request + end + args [:private_key, :public_key, :snd_id, :rec_id] option :private_key, nil @@ -102,6 +110,8 @@ def request_phase return fail!(:private_key_load_err, e) end + set_locale_from_query_param + form = OmniAuth::Form.new(:title => I18n.t('omniauth.swedbank.please_wait'), :url => options.site) { @@ -112,18 +122,45 @@ def request_phase 'VK_NONCE' => stamp, 'VK_RETURN' => callback_url, 'VK_MAC' => signature(priv_key), - 'VK_LANG' => 'LAT', + 'VK_LANG' => resolve_bank_ui_language, 'VK_ENCODING' => 'UTF-8' }.each do |name, val| - form.html "" + form.html "" end form.button I18n.t('omniauth.swedbank.click_here_if_not_redirected') + nonce_attribute = nil + if self.class.render_nonce? + nonce_attribute = " nonce='#{escape(content_security_policy_nonce)}'" + end form.instance_variable_set('@html', - form.to_html.gsub('', '')) + form.to_html.gsub('', "")) form.to_response end + + private + + def set_locale_from_query_param + locale = request.params['locale'] + if (locale != nil && locale.strip != '' && I18n.locale_available?(locale)) + I18n.locale = locale + end + end + + def resolve_bank_ui_language + case I18n.locale + when :ru then 'RUS' + when :en then 'ENG' + when :et then 'EST' + when :lt then 'LIT' + else 'LAT' + end + end + + def escape(html_attribute_value) + CGI.escapeHTML(html_attribute_value) unless html_attribute_value.nil? + end end end end diff --git a/omniauth-swedbank.gemspec b/omniauth-swedbank.gemspec index af82002..ed2a7f5 100644 --- a/omniauth-swedbank.gemspec +++ b/omniauth-swedbank.gemspec @@ -6,11 +6,11 @@ require 'omniauth/swedbank/version' Gem::Specification.new do |spec| spec.name = 'omniauth-swedbank' spec.version = Omniauth::Swedbank::VERSION - spec.authors = ['MAK IT', 'Jānis Kiršteins', 'Kristaps Ērglis'] - spec.email = ['admin@makit.lv', 'janis@montadigital.com', 'kristaps.erglis@gmail.com' ] + spec.authors = ['Mitigate', 'Jānis Kiršteins', 'Kristaps Ērglis'] + spec.email = ['admin@mitigate.dev', 'janis@montadigital.com', 'kristaps.erglis@gmail.com' ] spec.description = %q{OmniAuth strategy for Swedbank Banklink} spec.summary = %q{OmniAuth strategy for Swedbank Banklink} - spec.homepage = 'https://github.com/mak-it/omniauth-swedbank' + spec.homepage = 'https://github.com/mitigate-dev/omniauth-swedbank' spec.license = 'MIT' spec.files = `git ls-files`.split($/) @@ -20,11 +20,12 @@ Gem::Specification.new do |spec| spec.required_ruby_version = '>= 2.2.2' - spec.add_runtime_dependency 'omniauth', '~> 1.0' - spec.add_runtime_dependency "i18n" + spec.add_runtime_dependency 'omniauth', '~> 2.1' + spec.add_runtime_dependency 'i18n' + spec.add_development_dependency 'rack', '~> 2.0' spec.add_development_dependency 'rack-test' - spec.add_development_dependency 'rspec', '~> 2.7' - spec.add_development_dependency "bundler", "~> 1.3" - spec.add_development_dependency "rake" + spec.add_development_dependency 'rspec' + spec.add_development_dependency 'bundler' + spec.add_development_dependency 'rake' end diff --git a/spec/omniauth/strategies/swedbank_spec.rb b/spec/omniauth/strategies/swedbank_spec.rb index 1055972..28d07b4 100644 --- a/spec/omniauth/strategies/swedbank_spec.rb +++ b/spec/omniauth/strategies/swedbank_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' +require 'rack-protection' describe OmniAuth::Strategies::Swedbank do @@ -11,6 +12,8 @@ b.run lambda{|env| [404, {}, ['Not Found']]} end.to_app } + let(:token){ Rack::Protection::AuthenticityToken.random_token } + let(:last_response_nonce) { last_response.body.match(/name="VK_NONCE" value="([^"]*)"/)[1] } let(:last_response_mac) { last_response.body.match(/name="VK_MAC" value="([^"]*)"/)[1] } @@ -23,7 +26,14 @@ 'VK_RETURN' => 'http://example.org/auth/swedbank/callback' } - before(:each){ get '/auth/swedbank' } + before(:each) do + post( + '/auth/swedbank', + {}, + 'rack.session' => {csrf: token}, + 'HTTP_X_CSRF_TOKEN' => token + ) + end it 'displays a single form' do expect(last_response.status).to eq(200)