nulogy_sso 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|