Skip to content

Commit

Permalink
Standardise origin param as returnTo (#47)
Browse files Browse the repository at this point in the history
This ties in our existing use of the `returnTo` param, allowing apps to have consistent interfaces.
  • Loading branch information
patch0 authored May 9, 2023
2 parents 70888ca + b7769ea commit 1ae8b79
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 11 deletions.
23 changes: 18 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
## [Unreleased]

### Added
- Added dummy route for `/auth/rpi` to add path helper `rpi_auth_login` (#44)
Expand All @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Refactored `RpiAuth::Models::Authenticatable` to fix "include"/"extend" issues (#44)
- Refactored `RpiAuth::AuthController#callback` to reduce its complexity (#44)
- Refactored how auth bypass is enabled (#44)
- OmniAuth origin parameter name set as `returnTo` (#47)

## Updated

Expand Down Expand Up @@ -46,18 +47,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- omniauth-rpi gem updated to fix nil user ID in returned user object

## [v1.0.0]
## [v1.1.0]

### Added
- Defaults to setting the `user_id` param on the model rather than id (so that the application can use an internal ID structure for the user model).

- Rails 7 / Ruby 3.1 support (these are the only officially supported versions)
## [v1.0.1]

## [Unreleased]
- Updates Omniauth-rpi to latest version (fixing a bug where the returbed uid was empty)

## [v1.0.0]

### Added

- Rails 7 / Ruby 3.1 support (these are the only officially supported versions)
- omniauth-rpi strategy to auth via Hydra1
- include omniauth rails csrf protection
- configuration to allow setting endpoints and credentials for auth
- rails model concern to allow host app to add auth behaviour to a model
- callback, logout and failure routes to handle auth

[Unreleased]: https://github.com/RaspberryPiFoundation/rpi-auth/compare/v1.4.0...HEAD
[v1.4.0]: https://github.com/RaspberryPiFoundation/rpi-auth/releases/tag/v1.4.0
[v1.3.0]: https://github.com/RaspberryPiFoundation/rpi-auth/releases/tag/v1.3.0
[v1.2.1]: https://github.com/RaspberryPiFoundation/rpi-auth/releases/tag/v1.2.1
[v1.2.0]: https://github.com/RaspberryPiFoundation/rpi-auth/releases/tag/v1.2.0
[v1.1.0]: https://github.com/RaspberryPiFoundation/rpi-auth/releases/tag/v1.1.0
[v1.0.1]: https://github.com/RaspberryPiFoundation/rpi-auth/releases/tag/v1.0.1
[v1.0.0]: https://github.com/RaspberryPiFoundation/rpi-auth/releases/tag/v1.0.0
43 changes: 38 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,27 +81,60 @@ This model needs to be the same one defined in the initializer, an instance will
To login via Hydra your app needs to send the user to `/auth/rpi` via a POST request:

```ruby
<%= link_to 'Log in', '/auth/rpi', method: :post %>
link_to 'Log in', '/auth/rpi', method: :post
# or:
<%= button_to 'Log in', '/auth/rpi' %>
button_to 'Log in', '/auth/rpi'
```

A GET request will be blocked by the CSRF protection gem.

Alternatively you can use the path helpers:

```ruby
<%= link_to 'Log in', rpi_auth_login_path, method: :post %>
link_to 'Log in', rpi_auth_login_path, method: :post
# or:
<%= button_to 'Log in', rpi_auth_login_path %>
button_to 'Log in', rpi_auth_login_path
```

There is also a helper for the logout route:

```ruby
<%= link_to 'Log out', rpi_auth_logout_path %>
link_to 'Log out', rpi_auth_logout_path
```

### Sin

### Redirecting users to the "next step"

There are a three possible places the user will end up at following logging in,
in the following order:

1. The `success_redirect` URL.
2. The specified `returnTo` URL.
3. The page the user was on (if the Referer header is sent in).
4. The root path of the application.

Note that none of these places can be on a different host, i.e. they have to be
inside your application.

The `success_redirect` set in the RpiAuth configuration block will trump
everything, so only use this configuration option if you always want your users
to end up at the same place.

If you wish to redirect users to the next step in the process, e.g. to a
registration form, then you should supply a parameter called `returnTo` which
is then used to redirect after log in/sign up are successful.

```ruby
button_to 'Log in to start registraion', rpi_auth_login_path, params: { returnTo: '/registration_form' }
```

If this parameter is missing [Omniauth uses the HTTP Referer
header](https://github.com/omniauth/omniauth/blob/d2fd0fc80b0342046484b99102fa00ec5b5392ff/lib/omniauth/strategy.rb#L252-L256)
meaning (most) users will end up back on the page where they started the auth flow (this is often the most preferable situation).

Finally, if none of these things are set, we end up back at the application root.

### Globbed/catch-all routes

If your app has a catch-all route at the end of the routing table, you must
Expand Down
3 changes: 2 additions & 1 deletion lib/rpi_auth/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class Engine < ::Rails::Engine
authorize_url: "#{RpiAuth.configuration.auth_url}/oauth2/auth",
token_url: "#{RpiAuth.configuration.auth_token_url || RpiAuth.configuration.auth_url}/oauth2/token"
},
authorize_params: { brand: RpiAuth.configuration.brand }
authorize_params: { brand: RpiAuth.configuration.brand },
origin_param: 'returnTo'
)

OmniAuth.config.on_failure = RpiAuth::AuthController.action(:failure)
Expand Down
10 changes: 10 additions & 0 deletions spec/dummy/spec/requests/auth_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,16 @@
end
end

context 'when returnTo param is set' do
it 'redirects back to the original page' do
post '/auth/rpi', params: { returnTo: 'http://www.example.com/bar' }
expect(response).to redirect_to('/rpi_auth/auth/callback')
follow_redirect!

expect(response).to redirect_to('/bar')
end
end

context 'when success_redirect is set in config' do
before do
RpiAuth.configuration.success_redirect = 'http://www.example.com/success'
Expand Down

0 comments on commit 1ae8b79

Please sign in to comment.