Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add optional `on_login_success` callback (#90)

### Fixed

### Removed
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ link_to 'Log out', rpi_auth_logout_path, params: { returnTo: '/thanks-dude' }

This has to be a relative URL, i.e. it has to start with a slash. This is to ensure there's no open redirect.

### Callback on successful login

If the RpiAuth configuration option `on_login_success` is set to a `Proc`, this will be called in the context of the `RpiAuth::AuthController#callback` action, i.e. `current_user` will be available. This is intended to allow apps to record successful logins.

### Globbed/catch-all routes

If your app has a catch-all route at the end of the routing table, you must
Expand Down
12 changes: 12 additions & 0 deletions app/controllers/rpi_auth/auth_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ def callback
auth = request.env['omniauth.auth']
self.current_user = RpiAuth.user_model.from_omniauth(auth)

run_login_success_callback

redirect_to ensure_relative_url(login_redirect_path)
end

Expand All @@ -53,6 +55,16 @@ def failure

private

def run_login_success_callback
return unless RpiAuth.configuration.on_login_success.is_a?(Proc)

begin
instance_exec(&RpiAuth.configuration.on_login_success)
rescue StandardError => e
Rails.logger.warn("Caught #{e} while processing on_login_success proc.")
end
end

def login_redirect_path
unless RpiAuth.configuration.success_redirect.is_a?(Proc)
return RpiAuth.configuration.success_redirect || request.env['omniauth.origin']
Expand Down
3 changes: 2 additions & 1 deletion lib/rpi_auth/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class Configuration
:session_keys_to_persist,
:success_redirect,
:user_model,
:setup
:setup,
:on_login_success

def initialize
@bypass_auth = false
Expand Down
41 changes: 41 additions & 0 deletions spec/dummy/spec/requests/auth_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

require 'spec_helper'

class Foo
cattr_accessor :successful_logins
self.successful_logins = []
end

RSpec.describe 'Authentication' do
let(:user) do
User.new(
Expand Down Expand Up @@ -311,6 +316,42 @@
end
end
end

context 'when on_login_success is set as a proc in config' do
before do
allow(Rails.logger).to receive(:warn).and_call_original

RpiAuth.configuration.on_login_success = lambda do
Rails.logger.warn "Successful login: #{current_user.user_id}"
end
end

it 'calls the proc making the current user available' do
post '/auth/rpi'
follow_redirect!

expect(Rails.logger).to have_received(:warn).with(
"Successful login: #{user.user_id}"
)
end

context 'when the proc raises an exception' do
before do
RpiAuth.configuration.on_login_success = lambda do
raise 'boom!'
end
end

it 'logs a warning error' do
post '/auth/rpi'
follow_redirect!

expect(Rails.logger).to have_received(:warn).with(
'Caught boom! while processing on_login_success proc.'
)
end
end
end
end

describe 'and toggling the scope at runtime' do
Expand Down
4 changes: 4 additions & 0 deletions spec/rpi_auth/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,8 @@
it_behaves_like 'sets up the token url defaults'
end
end

it 'sets on_login_success to nil by default' do
expect(configuration.on_login_success).to be_nil
end
end