nulogy_sso 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +12 -6
- data/app/controllers/nulogy_sso/{auth_controller.rb → authentication_controller.rb} +4 -2
- data/app/services/nulogy_sso/authenticator.rb +5 -9
- data/config/routes.rb +3 -3
- data/lib/nulogy_sso/controller_helper.rb +0 -7
- data/lib/nulogy_sso/engine.rb +9 -9
- data/lib/nulogy_sso/version.rb +1 -1
- data/lib/nulogy_sso.rb +3 -2
- data/spec/dummy/config/application.rb +3 -3
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/test.log +3125 -0
- data/spec/examples.txt +14 -17
- data/spec/features/nulogy_sso/sso_login_spec.rb +8 -39
- data/spec/integration/services/nulogy_sso/authenticator_spec.rb +1 -9
- metadata +35 -30
- data/app/assets/images/nulogy_sso/favicon.png +0 -0
- data/app/assets/stylesheets/nulogy_sso/sso_error.css +0 -214
- data/app/views/sso_error.html.erb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 228ee96856caa782a84562d241a407a995eff6f036e143be561f0bbc0ad762ea
|
4
|
+
data.tar.gz: 0bfa85d89f0df4fc65d543737cf7f9f5f28d3617702b1503558b8239b0db2362
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5afdd2da157f46ab113a271fa605bd1265a86ba733ef7012e0b4106e9ca9b287ce74dc56c36e5aa45496a9a3ed74e97c80c92a0472cf312a52944f75cbbd297
|
7
|
+
data.tar.gz: fd869720b8d14f1e6666888436b243879127fbe229531605b40db32522f9f548d3af607f733aacf5c8cc8c7cdea85fcebbe04607a59b96078c83d9bd7179c421
|
data/README.md
CHANGED
@@ -30,15 +30,20 @@ get "logout", to: redirect("sso/logout")
|
|
30
30
|
|
31
31
|
The engine now needs to be configured. First create a YAML config file, perhaps named `config/auth_sso.yml`, to configure your app's Auth0 settings. This assumes that the necessary Auth0 applications have been created in the correct Auth0 tenants. The [CPI auth_sso.yml file](https://github.com/nulogy/Common-Platform-Interface/blob/master/config/auth_sso.yml) is a good starting place.
|
32
32
|
|
33
|
-
With that available, you can configure the engine with an initializer file. This is where _NulogySSO_ can be customized according to your application's needs. Put
|
33
|
+
With that available, you can configure the engine with an initializer file. This is where _NulogySSO_ can be customized according to your application's needs. Put the below code into `config/initializers/nulogy_sso.rb`, with the appropriate modifications implemented. For `auth_config`, refer to [nulogy_sso.rb](lib/nulogy_sso.rb) for a list of required keys and [auth_sso.yml](spec/dummy/config/auth_sso.yml) for an example config file.
|
34
34
|
|
35
35
|
```ruby
|
36
|
-
# Compiles config/auth_sso.yml into a Ruby object
|
36
|
+
# Compiles config/auth_sso.yml into a Ruby object. An error is thrown if required keys are missing.
|
37
|
+
# See lib/nulogy_sso.rb for required keys.
|
37
38
|
NulogySSO.auth_config = Rails::Application.config_for(:auth_sso)
|
38
|
-
|
39
|
+
|
40
|
+
# Return the user matching the provided email, or nil if not found.
|
39
41
|
NulogySSO.find_user_by_email = ->(email) { nil }
|
40
|
-
|
41
|
-
|
42
|
+
|
43
|
+
# Handle errors from the SSO authentication flow, according to the app's design.
|
44
|
+
# This includes internal errors from the Auth0 gem (ie, token signature mismatch) and no user from the app DB matching the email from the JWT.
|
45
|
+
# The controller is passed as an argument to give the handler access to the "controller context", which is useful for tasks such as rendering a view.
|
46
|
+
NulogySSO.handle_sso_error = ->(controller) { }
|
42
47
|
```
|
43
48
|
|
44
49
|
The app is now ready to authenticate a user with Auth0! With NulogyAuth and Auth0, the user's identity is maintained across requests (and apps!) via a [JWT](https://auth0.com/docs/jwt) stored as a browser cookie. Add this code to the `ApplicationController`:
|
@@ -51,7 +56,7 @@ class ApplicationController < ActionController::Base
|
|
51
56
|
end
|
52
57
|
```
|
53
58
|
|
54
|
-
As an added bonus, NulogySSO also emulates the common Devise pattern of making the current User's user model object available via `current_user`. This is made available through
|
59
|
+
As an added bonus, NulogySSO also emulates the common Devise pattern of making the current User's user model object available via `current_user`. This is made available through including `ControllerHelper`.
|
55
60
|
|
56
61
|
## Development
|
57
62
|
|
@@ -88,3 +93,4 @@ This project follows [Semver Versioning](https://semver.org/). Please add an ent
|
|
88
93
|
* Buildkite pipeline
|
89
94
|
* Rubocop
|
90
95
|
* Rake install task (ie, generate required files automatically, instead of requiring a heavy amount of manual work to integrate nulogy_sso into a Rails app)
|
96
|
+
* Add additional hooks, as necessitated by unique use cases for new apps using this engine
|
@@ -3,7 +3,9 @@
|
|
3
3
|
require "auth0"
|
4
4
|
|
5
5
|
module NulogySSO
|
6
|
-
|
6
|
+
|
7
|
+
# This controller adds routes to power SSO authentication when this engine is mounted into a Rails app.
|
8
|
+
class AuthenticationController < ActionController::Base
|
7
9
|
include Auth0::Api::AuthenticationEndpoints
|
8
10
|
include Auth0::Mixins::HTTPProxy
|
9
11
|
|
@@ -53,7 +55,7 @@ module NulogySSO
|
|
53
55
|
delegate :auth_config, to: :NulogySSO
|
54
56
|
|
55
57
|
def sso_error
|
56
|
-
|
58
|
+
NulogySSO.handle_sso_error.call(self)
|
57
59
|
end
|
58
60
|
|
59
61
|
def authenticator
|
@@ -10,14 +10,9 @@ module NulogySSO
|
|
10
10
|
jwks_url: "#{NulogySSO.auth_config.base_uri}/.well-known/jwks.json"
|
11
11
|
)
|
12
12
|
|
13
|
-
def initialize(
|
14
|
-
verifier: ACCESS_TOKEN_VERIFIER,
|
15
|
-
find_user_by_email: NulogySSO.find_user_by_email,
|
16
|
-
validate_user: NulogySSO.validate_user
|
17
|
-
)
|
13
|
+
def initialize(verifier: ACCESS_TOKEN_VERIFIER, find_user_by_email: NulogySSO.find_user_by_email)
|
18
14
|
@verifier = verifier
|
19
15
|
@find_user_by_email = find_user_by_email
|
20
|
-
@validate_user = validate_user
|
21
16
|
end
|
22
17
|
|
23
18
|
# Authorizes the provided JWT, ensuring that a valid user can be associated to the token
|
@@ -27,12 +22,13 @@ module NulogySSO
|
|
27
22
|
return on_invalid_token.call if access_token.nil?
|
28
23
|
|
29
24
|
user = fetch_user(access_token)
|
30
|
-
return on_invalid_token.call if user.blank?
|
25
|
+
return on_invalid_token.call if user.blank?
|
31
26
|
|
32
27
|
on_success.call(access_token)
|
33
28
|
end
|
34
29
|
|
35
|
-
# Returns the authenticated user that matches the provided JWT, or nil if the
|
30
|
+
# Returns the authenticated user that matches the provided JWT, or nil if the token is invalid
|
31
|
+
# or no such user can be found.
|
36
32
|
def authenticated_user(raw_access_token)
|
37
33
|
access_token = decoded_validated_access_token(raw_access_token)
|
38
34
|
|
@@ -43,7 +39,7 @@ module NulogySSO
|
|
43
39
|
|
44
40
|
private
|
45
41
|
|
46
|
-
attr_reader :verifier, :find_user_by_email
|
42
|
+
attr_reader :verifier, :find_user_by_email
|
47
43
|
|
48
44
|
def decoded_validated_access_token(raw_access_token)
|
49
45
|
if raw_access_token.present? && verifier.verify(raw_access_token).valid?
|
data/config/routes.rb
CHANGED
@@ -20,13 +20,6 @@ module NulogySSO
|
|
20
20
|
|
21
21
|
@current_user = Authenticator.new.authenticated_user(raw_token)
|
22
22
|
return redirect_to nulogy_sso.login_path if @current_user.blank?
|
23
|
-
return render status: :forbidden, template: "sso_error" unless valid_user?(@current_user)
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def valid_user?(user)
|
29
|
-
NulogySSO.validate_user.call(user)
|
30
23
|
end
|
31
24
|
end
|
32
25
|
end
|
data/lib/nulogy_sso/engine.rb
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# List all files that should be automatically loaded for apps using the Engine here (besides files in app/)
|
4
|
+
# There are multiple ways to accomplish this via autoloading or eagerloading,
|
5
|
+
# but using `require` seems to be the simplest, least-error-prone way.
|
6
|
+
require "nulogy_sso/controller_helper"
|
7
|
+
|
1
8
|
module NulogySSO
|
2
9
|
class Engine < ::Rails::Engine
|
3
10
|
isolate_namespace NulogySSO
|
@@ -5,13 +12,6 @@ module NulogySSO
|
|
5
12
|
# Load all gems in the gemspec, as opposed to explicit require calls
|
6
13
|
Bundler.require(*Rails.groups)
|
7
14
|
|
8
|
-
config.autoload_paths << File.expand_path("lib/nulogy_sso/controller_helper", __dir__)
|
9
|
-
|
10
|
-
# Instruct apps using Sprockets to include assets from NulogySSO
|
11
|
-
initializer "nulogy_sso.assets.precompile" do |app|
|
12
|
-
app.config.assets.precompile += ["nulogy_sso/sso_error.css", "nulogy_sso/favicon.png"]
|
13
|
-
end
|
14
|
-
|
15
15
|
config.after_initialize do
|
16
16
|
if NulogySSO.auth_config.blank?
|
17
17
|
raise "Missing auth_config config object. Consider using config_for() to load a YAML config file."
|
@@ -21,8 +21,8 @@ module NulogySSO
|
|
21
21
|
raise "Missing find_user_by_email config lambda."
|
22
22
|
end
|
23
23
|
|
24
|
-
if NulogySSO.
|
25
|
-
raise "Missing
|
24
|
+
if NulogySSO.handle_sso_error.blank?
|
25
|
+
raise "Missing handle_sso_error config lambda."
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
data/lib/nulogy_sso/version.rb
CHANGED
data/lib/nulogy_sso.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "nulogy_sso/engine"
|
2
|
-
require "nulogy_sso/controller_helper"
|
3
4
|
require "immutable-struct"
|
4
5
|
|
5
6
|
module NulogySSO
|
6
7
|
# Config variables for the engine
|
7
|
-
mattr_accessor :auth_config, :find_user_by_email, :
|
8
|
+
mattr_accessor :auth_config, :find_user_by_email, :handle_sso_error
|
8
9
|
|
9
10
|
# Public Constants
|
10
11
|
JWT_EMAIL_KEY = "https://nulogy.net/email"
|
@@ -10,7 +10,7 @@ require "action_controller/railtie"
|
|
10
10
|
# require "action_mailer/railtie"
|
11
11
|
require "action_view/railtie"
|
12
12
|
require "action_cable/engine"
|
13
|
-
require "sprockets/railtie"
|
13
|
+
# require "sprockets/railtie"
|
14
14
|
# require "rails/test_unit/railtie"
|
15
15
|
|
16
16
|
Bundler.require(*Rails.groups)
|
@@ -32,10 +32,10 @@ module Dummy
|
|
32
32
|
# the framework and any gems in your application.
|
33
33
|
|
34
34
|
# Load required NulogySSO config so that the dummy can boot up without error.
|
35
|
-
# These functions are
|
35
|
+
# These functions are mostly used for testing.
|
36
36
|
NulogySSO.auth_config = config_for(:auth_sso)
|
37
37
|
NulogySSO.find_user_by_email = ->(email) { User.find_by(email: email) }
|
38
|
-
NulogySSO.
|
38
|
+
NulogySSO.handle_sso_error = ->(controller) { controller.render plain: "An SSO error has occurred :(" }
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
data/spec/dummy/db/test.sqlite3
CHANGED
Binary file
|
File without changes
|