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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4758a2972294221b9dc3fc1bcc3e6cc6bd6b08fb62649c42473947733eac8a26
4
- data.tar.gz: 3c367990340d32e800658cb5893e50b239e72b7e647b5e14e7d48eddf58ed50c
3
+ metadata.gz: 228ee96856caa782a84562d241a407a995eff6f036e143be561f0bbc0ad762ea
4
+ data.tar.gz: 0bfa85d89f0df4fc65d543737cf7f9f5f28d3617702b1503558b8239b0db2362
5
5
  SHA512:
6
- metadata.gz: d78af9ca9ae3db0346c647841a132fbcc49b07849934e84b205fa6742d1f7baffe8ae49c842715a9d327291577adcdd1eb3b8f835544798d27f685e6ce1f0fc0
7
- data.tar.gz: '0927826539422b8428f4d5c2956b40dbc291d7e558dbe009579cb32468418bfaa24239228550c4d40aefd9b298edf5ac97a78c46d288d7d034849619e393bbe4'
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 this code into `config/initializers/nulogy_sso.rb`, with the appropriate modifications implemented:
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
- # Return the user matching the provided email
39
+
40
+ # Return the user matching the provided email, or nil if not found.
39
41
  NulogySSO.find_user_by_email = ->(email) { nil }
40
- # Return a boolean to indicate if the Auth0 user is valid for this app, or true if this step is not necessary
41
- NulogySSO.validate_user = ->(user) { true }
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 inclusion of `ControllerHelper`.
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
- class AuthController < ActionController::Base
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
- render status: :forbidden, template: "sso_error"
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? || !validate_user.call(user)
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 user cannot be authenticated
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, :validate_user
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
@@ -1,5 +1,5 @@
1
1
  NulogySSO::Engine.routes.draw do
2
- get "login", to: "auth#login"
3
- get "logout", to: "auth#logout"
4
- get "code", to: "auth#code"
2
+ get "login", to: "authentication#login"
3
+ get "logout", to: "authentication#logout"
4
+ get "code", to: "authentication#code"
5
5
  end
@@ -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
@@ -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.validate_user.blank?
25
- raise "Missing validate_user config lambda."
24
+ if NulogySSO.handle_sso_error.blank?
25
+ raise "Missing handle_sso_error config lambda."
26
26
  end
27
27
  end
28
28
  end
@@ -1,3 +1,3 @@
1
1
  module NulogySSO
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
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, :validate_user
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 based on the dummy app User class, mostly used for testing.
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.validate_user = ->(user) { user.active? }
38
+ NulogySSO.handle_sso_error = ->(controller) { controller.render plain: "An SSO error has occurred :(" }
39
39
  end
40
40
  end
41
41
 
Binary file
File without changes