diff --git a/lib/rpi_auth/configuration.rb b/lib/rpi_auth/configuration.rb index 79f4310..95aa78f 100644 --- a/lib/rpi_auth/configuration.rb +++ b/lib/rpi_auth/configuration.rb @@ -18,7 +18,8 @@ class Configuration :scope, :session_keys_to_persist, :success_redirect, - :user_model + :user_model, + :setup def initialize @bypass_auth = false diff --git a/lib/rpi_auth/engine.rb b/lib/rpi_auth/engine.rb index 3201c70..55b4e30 100644 --- a/lib/rpi_auth/engine.rb +++ b/lib/rpi_auth/engine.rb @@ -23,30 +23,32 @@ class Engine < ::Rails::Engine initializer 'RpiAuth.add_middleware' do |app| # rubocop:disable Metrics/BlockLength next unless RpiAuth.configuration + openid_connect_options = { + name: :rpi, + setup: RpiAuth.configuration.setup, + issuer: RpiAuth.configuration.issuer, + scope: RpiAuth.configuration.scope, + callback_path: CALLBACK_PATH, + response_type: RpiAuth.configuration.response_type, + client_auth_method: RpiAuth.configuration.client_auth_method, + client_options: { + identifier: RpiAuth.configuration.auth_client_id, + secret: RpiAuth.configuration.auth_client_secret, + scheme: RpiAuth.configuration.token_endpoint.scheme, + host: RpiAuth.configuration.token_endpoint.host, + port: RpiAuth.configuration.token_endpoint.port, + authorization_endpoint: RpiAuth.configuration.authorization_endpoint, + token_endpoint: RpiAuth.configuration.token_endpoint, + jwks_uri: RpiAuth.configuration.jwks_uri, + redirect_uri: URI.join(RpiAuth.configuration.host_url, CALLBACK_PATH) + }, + extra_authorize_params: { brand: RpiAuth.configuration.brand }, + allow_authorize_params: [:login_options], + origin_param: 'returnTo' + } + app.middleware.use OmniAuth::Builder do - provider( - :openid_connect, - name: :rpi, - issuer: RpiAuth.configuration.issuer, - scope: RpiAuth.configuration.scope, - callback_path: CALLBACK_PATH, - response_type: RpiAuth.configuration.response_type, - client_auth_method: RpiAuth.configuration.client_auth_method, - client_options: { - identifier: RpiAuth.configuration.auth_client_id, - secret: RpiAuth.configuration.auth_client_secret, - scheme: RpiAuth.configuration.token_endpoint.scheme, - host: RpiAuth.configuration.token_endpoint.host, - port: RpiAuth.configuration.token_endpoint.port, - authorization_endpoint: RpiAuth.configuration.authorization_endpoint, - token_endpoint: RpiAuth.configuration.token_endpoint, - jwks_uri: RpiAuth.configuration.jwks_uri, - redirect_uri: URI.join(RpiAuth.configuration.host_url, CALLBACK_PATH) - }, - extra_authorize_params: { brand: RpiAuth.configuration.brand }, - allow_authorize_params: [:login_options], - origin_param: 'returnTo' - ) + provider(:openid_connect, openid_connect_options) OmniAuth.config.on_failure = RpiAuth::AuthController.action(:failure) diff --git a/spec/dummy/config/initializers/rpi_auth.rb b/spec/dummy/config/initializers/rpi_auth.rb index d3355c4..5dce79d 100644 --- a/spec/dummy/config/initializers/rpi_auth.rb +++ b/spec/dummy/config/initializers/rpi_auth.rb @@ -1,4 +1,11 @@ RpiAuth.configure do |config| + config.setup = lambda do |env| + request = Rack::Request.new(env) + + if custom_scope = request.params['add-custom-scope'] + env['omniauth.strategy'].options[:scope] += [custom_scope] + end + end config.auth_url = 'http://localhost:9001/' config.auth_client_id = 'gem-dev' config.auth_client_secret = 'secret' diff --git a/spec/dummy/spec/requests/auth_request_spec.rb b/spec/dummy/spec/requests/auth_request_spec.rb index 9476af1..20e6941 100644 --- a/spec/dummy/spec/requests/auth_request_spec.rb +++ b/spec/dummy/spec/requests/auth_request_spec.rb @@ -312,5 +312,35 @@ end end end + + describe 'and toggling the scope at runtime' do + let(:custom_scope) { 'custom-scope' } + + before do + OmniAuth.config.test_mode = false + end + + it 'does not append a custom scope' do + post '/auth/rpi' + + scopes = extract_scopes_from_redirect_location(response) + + expect(scopes).not_to include(custom_scope) + end + + it 'appends a custom scope' do + post "/auth/rpi?add-custom-scope=#{custom_scope}" + + scopes = extract_scopes_from_redirect_location(response) + + expect(scopes).to include(custom_scope) + end + + def extract_scopes_from_redirect_location(response) + location = response.headers['location'] + params = CGI.parse(URI.parse(location).query) + params['scope'].first.split + end + end end end diff --git a/spec/support/omniauth.rb b/spec/support/omniauth.rb index 8f5c115..e1ef0d4 100644 --- a/spec/support/omniauth.rb +++ b/spec/support/omniauth.rb @@ -1,3 +1,14 @@ # frozen_string_literal: true require 'omniauth' + +RSpec.configure do |config| + config.around do |example| + original_value = OmniAuth.config.test_mode + begin + example.run + ensure + OmniAuth.config.test_mode = original_value + end + end +end