nulogy_sso 1.0.0 → 2.0.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 +34 -2
- data/app/controllers/nulogy_sso/authentication_controller.rb +17 -22
- data/app/services/nulogy_sso/authenticator.rb +8 -3
- data/app/services/nulogy_sso/cookie_token_store.rb +57 -0
- data/config/routes.rb +1 -1
- data/lib/nulogy_sso/controller_helper.rb +4 -4
- data/lib/nulogy_sso/test_utilities/auth0_mock.rb +1 -1
- data/lib/nulogy_sso/version.rb +1 -1
- data/lib/nulogy_sso.rb +4 -2
- data/spec/dummy/app/controllers/api_controller.rb +12 -0
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/features/nulogy_sso/sso_login_spec.rb +38 -0
- data/spec/integration/services/nulogy_sso/authenticator_spec.rb +3 -3
- data/spec/integration/services/nulogy_sso/cookie_token_store_spec.rb +44 -0
- data/spec/spec_helper.rb +3 -0
- metadata +8 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 025625d2b1b251f2687e574aeebf1739c94ae6a672580f05164ba7e558ba5fdf
|
4
|
+
data.tar.gz: a987372dba2b6fd08ca877118e024e3e7a10eb16f34cac995d8f493c837dbaaa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3481d3605b625db5259b08a210932fac512cf45c7d4a4751c8d41e5229044c44711e53eb083693cd4b8c424579c0609c816eba8299fd07acacef82ab90e786fd
|
7
|
+
data.tar.gz: 54008fdb8cfb1fcfa350cd51f00865f09603517feeb33952fc7032f9f90a63b3aa20c73da19e5703fe7132a155d0dedc705927609a8820cf221755762d98cacb
|
data/README.md
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
[![Gem](https://img.shields.io/gem/v/nulogy_sso?label=nulogy_sso)](https://rubygems.org/gems/nulogy_sso "View this project in Rubygems")
|
4
4
|
|
5
|
+
## Auth0
|
6
|
+
For more information on Auth0 see the [Auth0 documentation](https://auth0.com/docs/flows/concepts/auth-code#how-it-works).
|
7
|
+
|
5
8
|
## Installation
|
6
9
|
|
7
10
|
This gem is a Rails Engine. It follows best practices [documented here](https://guides.rubyonrails.org/engines.html).
|
@@ -28,7 +31,31 @@ get "login", to: redirect("sso/login")
|
|
28
31
|
get "logout", to: redirect("sso/logout")
|
29
32
|
```
|
30
33
|
|
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.
|
34
|
+
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. An example configuration for local development would look like:
|
35
|
+
|
36
|
+
```yaml
|
37
|
+
default: &default
|
38
|
+
audience: <%= ENV.fetch("SSO_AUDIENCE", "auth.nulogy.net") %>
|
39
|
+
client_id: <%= ENV.fetch("SSO_CLIENT_ID", "SSO CLIENT ID FROM AUTH0") %>
|
40
|
+
client_secret: <%= ENV.fetch("SSO_CLIENT_SECRET", "SSO CLIENT SECRET FROM AUTH0") %>
|
41
|
+
base_uri: <%= ENV.fetch("SSO_BASE_URI", "") %>
|
42
|
+
cookie_prefix: <%= ENV.fetch("SSO_COOKIE_PREFIX", "") %>
|
43
|
+
login_uri: <%= ENV.fetch("SSO_LOGIN_URI", "") %>
|
44
|
+
redirect_uri: <%= ENV.fetch("SSO_REDIRECT_URI", "") %>
|
45
|
+
|
46
|
+
development:
|
47
|
+
<<: *default
|
48
|
+
base_uri: <%= ENV.fetch("SSO_BASE_URI", "https://auth-dev.nulogy.net") %>
|
49
|
+
cookie_prefix: <%= ENV.fetch("SSO_COOKIE_PREFIX", "dev") %>
|
50
|
+
login_uri: <%= ENV.fetch("SSO_LOGIN_URI", "http://localhost:3000/sso/validate_authentication_code") %>
|
51
|
+
redirect_uri: <%= ENV.fetch("SSO_REDIRECT_URI", "http://localhost:3000") %>
|
52
|
+
|
53
|
+
test:
|
54
|
+
<<: *default
|
55
|
+
|
56
|
+
production:
|
57
|
+
<<: *default
|
58
|
+
```
|
32
59
|
|
33
60
|
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 `sso_config`, refer to [nulogy_sso.rb](lib/nulogy_sso.rb) for a list of required keys and [sso_config.yml](spec/dummy/config/sso_config.yml) for an example config file.
|
34
61
|
|
@@ -43,7 +70,12 @@ NulogySSO.find_user_by_email = ->(email) { nil }
|
|
43
70
|
# Handle errors from the SSO authentication flow, according to the app's design.
|
44
71
|
# 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
72
|
# 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) { }
|
73
|
+
NulogySSO.handle_sso_error = ->(controller: , error:) { }
|
74
|
+
|
75
|
+
# Handle how unauthenticated requests should be responded to. The default is to redirect to the defined login page.
|
76
|
+
# For API based applications this should be overriden to provide a meaningful error as per your API's contract (i.e. an HTTP 401 error code)
|
77
|
+
# Additionally, this could be overriden if an application should bypass SSO when running tests.
|
78
|
+
NulogySSO.handle_unauthenticated_request = ->(controller) { controller.redirect_to sso_engine.login_path }
|
47
79
|
```
|
48
80
|
|
49
81
|
The app is now ready to authenticate a user with Auth0! With NulogySSO 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`:
|
@@ -16,32 +16,32 @@ module NulogySSO
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def login
|
19
|
-
raw_access_token =
|
19
|
+
raw_access_token = token_store.fetch
|
20
20
|
|
21
21
|
authenticator.validate_token(
|
22
22
|
raw_access_token,
|
23
23
|
on_success: method(:on_authentication_success),
|
24
|
-
on_invalid_token: -> { redirect_to auth0_authorize_path }
|
24
|
+
on_invalid_token: ->(_e) { redirect_to auth0_authorize_path }
|
25
25
|
)
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
28
|
+
def verify_authentication_code
|
29
29
|
code = params.require(:code)
|
30
30
|
begin
|
31
|
-
raw_access_token =
|
31
|
+
raw_access_token = fetch_token_from_auth0(code)
|
32
32
|
rescue Auth0::Exception => e
|
33
|
-
return sso_error
|
33
|
+
return sso_error(e)
|
34
34
|
end
|
35
35
|
|
36
36
|
authenticator.validate_token(
|
37
37
|
raw_access_token,
|
38
38
|
on_success: method(:on_authentication_success),
|
39
|
-
on_invalid_token: -> { sso_error }
|
39
|
+
on_invalid_token: ->(e) { sso_error(e) }
|
40
40
|
)
|
41
41
|
end
|
42
42
|
|
43
43
|
def logout
|
44
|
-
|
44
|
+
token_store.forget!
|
45
45
|
|
46
46
|
query_params = {
|
47
47
|
returnTo: sso_config.redirect_uri, # Yes, this must be camelCased
|
@@ -54,37 +54,32 @@ module NulogySSO
|
|
54
54
|
|
55
55
|
delegate :sso_config, to: :NulogySSO
|
56
56
|
|
57
|
-
def sso_error
|
58
|
-
NulogySSO.handle_sso_error.call(self)
|
57
|
+
def sso_error(error)
|
58
|
+
NulogySSO.handle_sso_error.call(controller: self, error: error)
|
59
59
|
end
|
60
60
|
|
61
61
|
def authenticator
|
62
62
|
@authenticator ||= Authenticator.new
|
63
63
|
end
|
64
64
|
|
65
|
+
def token_store
|
66
|
+
@token_store ||= CookieTokenStore.new(request, response)
|
67
|
+
end
|
68
|
+
|
65
69
|
def on_authentication_success(access_token)
|
66
|
-
|
70
|
+
token_store.store!(access_token)
|
67
71
|
|
68
72
|
redirect_to params["origin"].presence || sso_config.redirect_uri
|
69
73
|
end
|
70
74
|
|
71
|
-
def
|
72
|
-
exchange_auth_code_for_tokens(
|
75
|
+
def fetch_token_from_auth0(code)
|
76
|
+
response = exchange_auth_code_for_tokens(
|
73
77
|
code,
|
74
78
|
redirect_uri: sso_config.login_uri,
|
75
79
|
client_id: sso_config.client_id,
|
76
80
|
client_secret: sso_config.client_secret
|
77
81
|
)
|
78
|
-
|
79
|
-
|
80
|
-
def respond_with_cookies(access_token_value)
|
81
|
-
cookies[NulogySSO.sso_cookie_key] = {
|
82
|
-
value: access_token_value,
|
83
|
-
domain: :all,
|
84
|
-
expires: 36_000.seconds, # TODO: Fetch this value from the JWT
|
85
|
-
httponly: true,
|
86
|
-
secure: request.ssl?
|
87
|
-
}
|
82
|
+
response["access_token"]
|
88
83
|
end
|
89
84
|
|
90
85
|
def auth0_authorize_path
|
@@ -10,6 +10,10 @@ module NulogySSO
|
|
10
10
|
jwks_url: "#{NulogySSO.sso_config.base_uri}/.well-known/jwks.json"
|
11
11
|
)
|
12
12
|
|
13
|
+
MissingUserError = Class.new(StandardError)
|
14
|
+
MissingTokenError = Class.new(StandardError)
|
15
|
+
InvalidTokenError = Class.new(StandardError)
|
16
|
+
|
13
17
|
def initialize(verifier: ACCESS_TOKEN_VERIFIER, find_user_by_email: NulogySSO.find_user_by_email)
|
14
18
|
@verifier = verifier
|
15
19
|
@find_user_by_email = find_user_by_email
|
@@ -17,12 +21,13 @@ module NulogySSO
|
|
17
21
|
|
18
22
|
# Validated the provided JWT, ensuring that an authenticated Auth0 user can be associated to the token and matches an existing app user
|
19
23
|
def validate_token(raw_access_token, on_success:, on_invalid_token:)
|
20
|
-
|
24
|
+
return on_invalid_token.call(MissingTokenError.new) if raw_access_token.blank?
|
21
25
|
|
22
|
-
|
26
|
+
access_token = decoded_validated_access_token(raw_access_token)
|
27
|
+
return on_invalid_token.call(InvalidTokenError.new(raw_access_token)) if access_token.nil?
|
23
28
|
|
24
29
|
user = fetch_user(access_token)
|
25
|
-
return on_invalid_token.call if user.blank?
|
30
|
+
return on_invalid_token.call(MissingUserError.new(access_token)) if user.blank?
|
26
31
|
|
27
32
|
on_success.call(access_token)
|
28
33
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module NulogySSO
|
2
|
+
# A class for storing the SSO token in cookies
|
3
|
+
#
|
4
|
+
# This uses the Rack level API instead of going through the Rails API because
|
5
|
+
# we have found that for our GraphQL based applications, using the cookiejar API
|
6
|
+
# has not been working. The cookies are not being set correctly, likely because
|
7
|
+
# the requests are resulting in 302 redirects.
|
8
|
+
class CookieTokenStore
|
9
|
+
def initialize(request, response)
|
10
|
+
@request = request
|
11
|
+
@response = response
|
12
|
+
end
|
13
|
+
|
14
|
+
def fetch
|
15
|
+
@request.cookie_jar[NulogySSO.sso_cookie_key]
|
16
|
+
end
|
17
|
+
|
18
|
+
def store!(access_token_value)
|
19
|
+
@response.set_cookie(
|
20
|
+
NulogySSO.sso_cookie_key,
|
21
|
+
value: access_token_value,
|
22
|
+
path: "/",
|
23
|
+
domain: all_domains,
|
24
|
+
expires: 36_000.seconds.from_now, # TODO: Fetch this value from the JWT
|
25
|
+
httponly: true,
|
26
|
+
secure: @request.ssl?
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def forget!
|
31
|
+
@response.delete_cookie(
|
32
|
+
NulogySSO.sso_cookie_key,
|
33
|
+
path: "/",
|
34
|
+
domain: all_domains
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/
|
41
|
+
|
42
|
+
##
|
43
|
+
# This is copied from the Rails Cookie Helper at:
|
44
|
+
# https://github.com/rails/rails/blob/6-0-stable/actionpack/lib/action_dispatch/middleware/cookies.rb#L357
|
45
|
+
#
|
46
|
+
# This simulates the same { domain: :all } option which exists for interacting with the cookie jar
|
47
|
+
# even though not all clients will have access to the same cookie jar API (i.e. if you are building
|
48
|
+
# an API controller).
|
49
|
+
def all_domains
|
50
|
+
# If there is a provided tld length then we use it otherwise default domain regexp.
|
51
|
+
domain_regexp = DOMAIN_REGEXP
|
52
|
+
# If host is not ip and matches domain regexp.
|
53
|
+
# (ip confirms to domain regexp so we explicitly check for ip)
|
54
|
+
".#{$&}" if (@request.host !~ /^[\d.]+$/) && (@request.host =~ domain_regexp)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/config/routes.rb
CHANGED
@@ -11,16 +11,16 @@ module NulogySSO
|
|
11
11
|
# Makes the commonly used @current_user variable available to controllers and views.
|
12
12
|
# This emulates a code pattern popular in Rails apps using Devise.
|
13
13
|
attr_reader :current_user
|
14
|
-
helper_method :current_user
|
14
|
+
helper_method :current_user if defined?(helper_method)
|
15
15
|
before_action :store_previous_url_in_session
|
16
16
|
end
|
17
17
|
|
18
18
|
def authenticate_sso_user
|
19
|
-
raw_token =
|
20
|
-
return
|
19
|
+
raw_token = CookieTokenStore.new(request, response).fetch
|
20
|
+
return NulogySSO.handle_unauthenticated_request.call(self) if raw_token.blank?
|
21
21
|
|
22
22
|
@current_user = Authenticator.new.authenticated_user(raw_token)
|
23
|
-
return
|
23
|
+
return NulogySSO.handle_unauthenticated_request.call(self) if @current_user.blank?
|
24
24
|
end
|
25
25
|
|
26
26
|
def store_previous_url_in_session
|
@@ -40,7 +40,7 @@ module NulogySSO
|
|
40
40
|
httpResponse: {
|
41
41
|
statusCode: 302,
|
42
42
|
headers: {
|
43
|
-
Location: ["#{capybara_current_host}#{engine_path}/
|
43
|
+
Location: ["#{capybara_current_host}#{engine_path}/verify_authentication_code?#{redirect_query_params}"]
|
44
44
|
}
|
45
45
|
}
|
46
46
|
)
|
data/lib/nulogy_sso/version.rb
CHANGED
data/lib/nulogy_sso.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "nulogy_sso/engine"
|
4
|
-
require "immutable-struct"
|
5
4
|
|
6
5
|
module NulogySSO
|
7
6
|
# Config variables for the engine
|
8
7
|
mattr_accessor :sso_config, :find_user_by_email, :handle_sso_error
|
8
|
+
mattr_accessor :handle_unauthenticated_request, default: lambda { |controller|
|
9
|
+
controller.redirect_to NulogySSO::Engine.routes.url_helpers.login_path
|
10
|
+
}
|
9
11
|
|
10
12
|
# Public Constants
|
11
13
|
JWT_EMAIL_KEY = "https://nulogy.net/email"
|
@@ -32,7 +34,7 @@ module NulogySSO
|
|
32
34
|
]
|
33
35
|
private_constant :REQUIRED_SSO_CONFIG_KEYS
|
34
36
|
|
35
|
-
SSOConfig =
|
37
|
+
SSOConfig = Struct.new(*REQUIRED_SSO_CONFIG_KEYS, keyword_init: true)
|
36
38
|
|
37
39
|
def self.sso_cookie_key
|
38
40
|
"#{sso_config.cookie_prefix}_access_token"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This controller is essential for running Capybara feature tests against the NulogySSO engine
|
4
|
+
class ApiController < ActionController::API
|
5
|
+
include NulogySSO::ControllerHelper
|
6
|
+
|
7
|
+
before_action :authenticate_sso_user
|
8
|
+
|
9
|
+
def api_endpoint
|
10
|
+
render json: {text: "Hello World"}
|
11
|
+
end
|
12
|
+
end
|
@@ -35,7 +35,7 @@ module Dummy
|
|
35
35
|
# These functions are mostly used for testing.
|
36
36
|
NulogySSO.sso_config = config_for(:sso)
|
37
37
|
NulogySSO.find_user_by_email = ->(email) { User.find_by(email: email) }
|
38
|
-
NulogySSO.handle_sso_error = ->(controller) { controller.render plain: "An SSO error has occurred :(" }
|
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/config/routes.rb
CHANGED
@@ -74,6 +74,44 @@ module NulogySSO
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
+
describe "authenticated APIs" do
|
78
|
+
let!(:user) { create_user }
|
79
|
+
|
80
|
+
before do
|
81
|
+
auth0_mock.mockserver_reset
|
82
|
+
auth0_mock.setup_jwks
|
83
|
+
|
84
|
+
# have to visit an unauthenticated endpoint in order for capybara to have something to have a tab to set the cookie on
|
85
|
+
visit "/robots.txt"
|
86
|
+
end
|
87
|
+
|
88
|
+
it "allows a user with a valid JWT to visit a secured endpoint" do
|
89
|
+
set_access_token_cookie(jwt_test_helper.jwt(email))
|
90
|
+
|
91
|
+
visit "/api_endpoint"
|
92
|
+
|
93
|
+
expect(page).to have_content("Hello World")
|
94
|
+
end
|
95
|
+
|
96
|
+
it "prevents sessions with invalid JWTs from accessing secured endpoints" do
|
97
|
+
set_access_token_cookie(jwt_test_helper.jwt(email, "exp" => (Time.now - 1.day).to_i))
|
98
|
+
|
99
|
+
visit "/api_endpoint"
|
100
|
+
|
101
|
+
expect(current_path).to eq("/authorize")
|
102
|
+
end
|
103
|
+
|
104
|
+
it "prevents sessions with no JWT from accessing secured endpoints" do
|
105
|
+
visit "/api_endpoint"
|
106
|
+
|
107
|
+
expect(current_path).to eq("/authorize")
|
108
|
+
end
|
109
|
+
|
110
|
+
def set_access_token_cookie(token)
|
111
|
+
page.driver.browser.manage.add_cookie(name: NulogySSO.sso_cookie_key, value: token)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
77
115
|
def create_user
|
78
116
|
User.create!(email: email)
|
79
117
|
end
|
@@ -25,7 +25,7 @@ module NulogySSO
|
|
25
25
|
it "calls on_invalid_token when the access token is blank" do
|
26
26
|
[nil, "", false].each(&method(:validate_token))
|
27
27
|
|
28
|
-
expect(on_invalid_token).to have_received(:call).exactly(3).times
|
28
|
+
expect(on_invalid_token).to have_received(:call).exactly(3).times.with(NulogySSO::Authenticator::MissingTokenError)
|
29
29
|
end
|
30
30
|
|
31
31
|
context "JWT passes verification" do
|
@@ -43,7 +43,7 @@ module NulogySSO
|
|
43
43
|
|
44
44
|
validate_token(valid_signed_token, authenticator: authenticator)
|
45
45
|
|
46
|
-
expect(on_invalid_token).to have_received(:call).once
|
46
|
+
expect(on_invalid_token).to have_received(:call).once.with(NulogySSO::Authenticator::MissingUserError)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -51,7 +51,7 @@ module NulogySSO
|
|
51
51
|
it "calls the invalid token handler" do
|
52
52
|
validate_token(invalid_signed_token)
|
53
53
|
|
54
|
-
expect(on_invalid_token).to have_received(:call).once
|
54
|
+
expect(on_invalid_token).to have_received(:call).once.with(NulogySSO::Authenticator::InvalidTokenError)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NulogySSO
|
4
|
+
RSpec.describe CookieTokenStore do
|
5
|
+
let(:request) { double(host: "some_app.nulogy.net", ssl?: false) }
|
6
|
+
let(:response) { double(set_cookie: spy, delete_cookie: spy) }
|
7
|
+
|
8
|
+
subject(:token_store) { CookieTokenStore.new(request, response) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
freeze_time
|
12
|
+
end
|
13
|
+
|
14
|
+
it "extracts the top level domain from a domain name" do
|
15
|
+
allow(request).to receive(:host).and_return("some.app.nulogy.net")
|
16
|
+
token_store.store!("anything")
|
17
|
+
expect(response).to have_received(:set_cookie).with(anything, hash_including(domain: ".nulogy.net"))
|
18
|
+
end
|
19
|
+
|
20
|
+
it "stores the cookie value with the correct settings" do
|
21
|
+
token_store.store!("cookie value")
|
22
|
+
|
23
|
+
expect(response).to have_received(:set_cookie).with(
|
24
|
+
"mock_cookie_prefix_access_token",
|
25
|
+
value: "cookie value",
|
26
|
+
path: "/",
|
27
|
+
domain: ".nulogy.net",
|
28
|
+
expires: 36_000.seconds.from_now,
|
29
|
+
httponly: true,
|
30
|
+
secure: false
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "deletes the cookie matching the path, domain and key" do
|
35
|
+
token_store.forget!
|
36
|
+
|
37
|
+
expect(response).to have_received(:delete_cookie).with(
|
38
|
+
"mock_cookie_prefix_access_token",
|
39
|
+
path: "/",
|
40
|
+
domain: ".nulogy.net",
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'active_support/testing/time_helpers'
|
2
3
|
|
3
4
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
4
5
|
RSpec.configure do |config|
|
@@ -40,4 +41,6 @@ RSpec.configure do |config|
|
|
40
41
|
|
41
42
|
# Seed global randomization in this process using the `--seed` CLI option.
|
42
43
|
Kernel.srand config.seed
|
44
|
+
|
45
|
+
config.include ActiveSupport::Testing::TimeHelpers
|
43
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nulogy_sso
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nulogy Corporation
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: auth0
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.0.2
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: immutable-struct
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '2.4'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '2.4'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: rails
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -167,6 +153,7 @@ files:
|
|
167
153
|
- Rakefile
|
168
154
|
- app/controllers/nulogy_sso/authentication_controller.rb
|
169
155
|
- app/services/nulogy_sso/authenticator.rb
|
156
|
+
- app/services/nulogy_sso/cookie_token_store.rb
|
170
157
|
- config/initializers/inflections.rb
|
171
158
|
- config/routes.rb
|
172
159
|
- lib/nulogy_sso.rb
|
@@ -183,6 +170,7 @@ files:
|
|
183
170
|
- spec/dummy/app/assets/stylesheets/application.css
|
184
171
|
- spec/dummy/app/channels/application_cable/channel.rb
|
185
172
|
- spec/dummy/app/channels/application_cable/connection.rb
|
173
|
+
- spec/dummy/app/controllers/api_controller.rb
|
186
174
|
- spec/dummy/app/controllers/application_controller.rb
|
187
175
|
- spec/dummy/app/helpers/application_helper.rb
|
188
176
|
- spec/dummy/app/jobs/application_job.rb
|
@@ -327,6 +315,7 @@ files:
|
|
327
315
|
- spec/feature_spec_helper.rb
|
328
316
|
- spec/features/nulogy_sso/sso_login_spec.rb
|
329
317
|
- spec/integration/services/nulogy_sso/authenticator_spec.rb
|
318
|
+
- spec/integration/services/nulogy_sso/cookie_token_store_spec.rb
|
330
319
|
- spec/rails_helper.rb
|
331
320
|
- spec/spec_helper.rb
|
332
321
|
- spec/support/mock_auth0_verifier.rb
|
@@ -341,7 +330,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
341
330
|
requirements:
|
342
331
|
- - ">="
|
343
332
|
- !ruby/object:Gem::Version
|
344
|
-
version: '
|
333
|
+
version: '2.5'
|
345
334
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
346
335
|
requirements:
|
347
336
|
- - ">="
|
@@ -358,6 +347,7 @@ test_files:
|
|
358
347
|
- spec/dummy/app/models/user.rb
|
359
348
|
- spec/dummy/app/jobs/application_job.rb
|
360
349
|
- spec/dummy/app/controllers/application_controller.rb
|
350
|
+
- spec/dummy/app/controllers/api_controller.rb
|
361
351
|
- spec/dummy/app/views/layouts/application.html.erb
|
362
352
|
- spec/dummy/app/assets/config/manifest.js
|
363
353
|
- spec/dummy/app/assets/javascripts/application.js
|
@@ -502,6 +492,7 @@ test_files:
|
|
502
492
|
- spec/dummy/tmp/cache/assets/sprockets/v3.0/qj/qjq5Ug3S2i5pydfGSIfUa7Y0s8s0FwqXzt0kkFijToI.cache
|
503
493
|
- spec/examples.txt
|
504
494
|
- spec/integration/services/nulogy_sso/authenticator_spec.rb
|
495
|
+
- spec/integration/services/nulogy_sso/cookie_token_store_spec.rb
|
505
496
|
- spec/features/nulogy_sso/sso_login_spec.rb
|
506
497
|
- spec/support/mock_auth0_verifier.rb
|
507
498
|
- spec/feature_spec_helper.rb
|