nulogy_sso 2.5.1 → 3.0.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.
@@ -0,0 +1 @@
1
+ fbd7ec478b18e938597866d54ece09ed83775658f0b661085699e48972ae2e1aeee86de5babcd5c94d3caa5e38d0da6a5abc2d163b78ac3d28144bfadbd938be
data/spec/examples.txt CHANGED
@@ -1,24 +1,24 @@
1
1
  example_id | status | run_time |
2
2
  ---------------------------------------------------------------- | ------ | --------------- |
3
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:1:1] | passed | 0.28901 seconds |
4
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:1:2] | passed | 2.99 seconds |
5
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:1:3] | passed | 0.23871 seconds |
6
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:2:1] | passed | 0.29212 seconds |
7
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:2:2] | passed | 0.54982 seconds |
8
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:2:3] | passed | 0.5163 seconds |
9
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:3:1] | passed | 0.28679 seconds |
10
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:3:2] | passed | 0.60938 seconds |
11
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:3:3] | passed | 0.47863 seconds |
12
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:1] | passed | 0.00536 seconds |
13
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:2:1] | passed | 0.01413 seconds |
14
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:2:2] | passed | 0.01025 seconds |
15
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:3:1] | passed | 0.01694 seconds |
16
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:1] | passed | 0.01042 seconds |
17
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:2] | passed | 0.00946 seconds |
18
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:3] | passed | 0.00209 seconds |
19
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:4] | passed | 0.01879 seconds |
20
- ./spec/unit/services/nulogy_sso/cookie_token_store_spec.rb[1:1] | passed | 0.01289 seconds |
21
- ./spec/unit/services/nulogy_sso/cookie_token_store_spec.rb[1:2] | passed | 0.00152 seconds |
22
- ./spec/unit/services/nulogy_sso/cookie_token_store_spec.rb[1:3] | passed | 0.00199 seconds |
23
- ./spec/unit/services/nulogy_sso/origin_redirector_spec.rb[1:1:1] | passed | 0.00096 seconds |
24
- ./spec/unit/services/nulogy_sso/origin_redirector_spec.rb[1:1:2] | passed | 0.00114 seconds |
3
+ ./spec/system/nulogy_sso/sso_login_spec.rb[1:1:1] | passed | 0.15002 seconds |
4
+ ./spec/system/nulogy_sso/sso_login_spec.rb[1:1:2] | passed | 2.23 seconds |
5
+ ./spec/system/nulogy_sso/sso_login_spec.rb[1:1:3] | passed | 0.09708 seconds |
6
+ ./spec/system/nulogy_sso/sso_login_spec.rb[1:2:1] | passed | 0.09063 seconds |
7
+ ./spec/system/nulogy_sso/sso_login_spec.rb[1:2:2] | passed | 0.22381 seconds |
8
+ ./spec/system/nulogy_sso/sso_login_spec.rb[1:2:3] | passed | 0.14889 seconds |
9
+ ./spec/system/nulogy_sso/sso_login_spec.rb[1:3:1] | passed | 0.07893 seconds |
10
+ ./spec/system/nulogy_sso/sso_login_spec.rb[1:3:2] | passed | 0.16209 seconds |
11
+ ./spec/system/nulogy_sso/sso_login_spec.rb[1:3:3] | passed | 0.16081 seconds |
12
+ ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:1] | passed | 0.0044 seconds |
13
+ ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:2:1] | passed | 0.01292 seconds |
14
+ ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:2:2] | passed | 0.0096 seconds |
15
+ ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:3:1] | passed | 0.00551 seconds |
16
+ ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:1] | passed | 0.0058 seconds |
17
+ ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:2] | passed | 0.00512 seconds |
18
+ ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:3] | passed | 0.00228 seconds |
19
+ ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:4] | passed | 0.00549 seconds |
20
+ ./spec/unit/services/nulogy_sso/cookie_token_store_spec.rb[1:1] | passed | 0.00522 seconds |
21
+ ./spec/unit/services/nulogy_sso/cookie_token_store_spec.rb[1:2] | passed | 0.00052 seconds |
22
+ ./spec/unit/services/nulogy_sso/cookie_token_store_spec.rb[1:3] | passed | 0.00046 seconds |
23
+ ./spec/unit/services/nulogy_sso/origin_redirector_spec.rb[1:1:1] | passed | 0.00024 seconds |
24
+ ./spec/unit/services/nulogy_sso/origin_redirector_spec.rb[1:1:2] | passed | 0.00014 seconds |
data/spec/rails_helper.rb CHANGED
@@ -25,4 +25,25 @@ RSpec.configure do |config|
25
25
 
26
26
  # Filter lines from Rails gems in backtraces.
27
27
  config.filter_rails_from_backtrace!
28
+
29
+ # Use transactional fixtures for all tests except system tests
30
+ # System tests run in separate threads and need truncation
31
+ config.use_transactional_fixtures = true
32
+
33
+ # Configure system tests to run headless
34
+ config.before(:each, type: :system) do
35
+ driven_by :selenium_chrome_headless
36
+ configure_webmock
37
+ end
38
+
39
+ # Clean database between system tests
40
+ config.before(:each, type: :system) do
41
+ # Truncate all tables except schema_migrations
42
+ ActiveRecord::Base.connection_pool.with_connection do |conn|
43
+ conn.tables.each do |table|
44
+ next if table == "schema_migrations"
45
+ conn.execute("DELETE FROM #{table}")
46
+ end
47
+ end
48
+ end
28
49
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require 'active_support/testing/time_helpers'
3
+ require 'webmock/rspec'
3
4
 
4
5
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
5
6
  RSpec.configure do |config|
@@ -44,3 +45,11 @@ RSpec.configure do |config|
44
45
 
45
46
  config.include ActiveSupport::Testing::TimeHelpers
46
47
  end
48
+
49
+ def configure_webmock(overrides: [])
50
+ allowed_hosts = (overrides + [ENV["NULOGY_SSO_MOCKSERVER_HOST"]]).compact
51
+ WebMock.disable_net_connect!(
52
+ allow_localhost: true,
53
+ allow: allowed_hosts
54
+ )
55
+ end
@@ -1,26 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This is a mock verifier that allows the auth0_rs256_jwt_verifier gem
4
- # to still be used for verifying JWTs, but with a localhost JWKS specified.
5
- # This code was adapted from the gem's test suite:
6
- # https://github.com/DroidsOnRoids/auth0_rs256_jwt_verifier/blob/master/test/auth0_rs256_jwt_verifier_test.rb
3
+ require "jwt"
4
+ require "json"
5
+
6
+ # Mock verifier for testing that uses ruby-jwt with a provided JWKS
7
7
  class MockAuth0Verifier
8
- def initialize(issuer:, audience:, jwks:)
9
- @internal_verifier = Auth0RS256JWTVerifier.new(
10
- issuer: issuer,
11
- audience: audience,
12
- jwks_url: "https://do.not.care",
13
- http: http_stub(jwks)
14
- )
8
+ VerificationResult = Struct.new(:valid?, :payload) do
9
+ alias_method :valid?, :valid?
15
10
  end
16
11
 
17
- delegate :verify, to: :@internal_verifier
18
-
19
- private
12
+ def initialize(issuer:, audience:, jwks:)
13
+ @issuer = issuer
14
+ @audience = audience
15
+ @jwks = JWT::JWK::Set.new(JSON.parse(jwks))
16
+ end
20
17
 
21
- def http_stub(jwks)
22
- http_stub = Object.new
23
- http_stub.define_singleton_method(:get) { |*_| jwks }
24
- http_stub
18
+ def verify(token)
19
+ begin
20
+ payload, = JWT.decode(
21
+ token,
22
+ nil,
23
+ true,
24
+ {
25
+ jwks: @jwks,
26
+ algorithms: ["RS256"],
27
+ iss: @issuer,
28
+ verify_iss: true,
29
+ aud: @audience,
30
+ verify_aud: true
31
+ }
32
+ )
33
+ VerificationResult.new(true, payload)
34
+ rescue JWT::DecodeError, JWT::InvalidIssuerError, JWT::InvalidAudienceError, JWT::ExpiredSignature, JWT::JWKError
35
+ VerificationResult.new(false, nil)
36
+ end
25
37
  end
26
38
  end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+
5
+ RSpec.describe "SSO login process", type: :system do
6
+ let(:email) { "test@nulogy.com" }
7
+ let(:auth0_mock) {
8
+ NulogySSO::TestUtilities::Auth0Mock.new(
9
+ mockserver_host: ENV.fetch("NULOGY_SSO_MOCKSERVER_HOST", "localhost"),
10
+ mockserver_port: ENV.fetch("NULOGY_SSO_MOCKSERVER_PORT", "1080").to_i
11
+ )
12
+ }
13
+ let(:jwt_test_helper) { NulogySSO::TestUtilities::JwtTestHelper.new }
14
+
15
+ describe "login flow" do
16
+ it "can successfully login" do
17
+ auth0_mock.setup(email: email, redirect_path: "/hello_world")
18
+ create_user
19
+
20
+ visit "/hello_world"
21
+
22
+ expect(page).to have_content("Hello World")
23
+ end
24
+
25
+ it "shows an error page when the user can authorize with Auth0 but not exist in the app" do
26
+ auth0_mock.setup(email: email, redirect_path: "/hello_world")
27
+
28
+ visit "/hello_world"
29
+
30
+ expect(page).to have_content("An SSO error has occurred :(")
31
+ end
32
+
33
+ it "shows an error page when Auth0 throws an error" do
34
+ auth0_mock.setup(email: email, redirect_path: "/hello_world", status_code: 403)
35
+ create_user
36
+
37
+ visit "/hello_world"
38
+
39
+ expect(page).to have_content("An SSO error has occurred :(")
40
+ end
41
+ end
42
+
43
+ shared_examples "JWT authentication" do |endpoint:|
44
+ let!(:user) { create_user }
45
+
46
+ before do
47
+ auth0_mock.mockserver_reset
48
+ auth0_mock.setup_jwks
49
+
50
+ # have to visit an unauthenticated endpoint in order for capybara to have something to have a tab to set the cookie on
51
+ visit "/robots.txt"
52
+ end
53
+
54
+ it "allows a user with a valid JWT to visit a secured endpoint" do
55
+ set_access_token_cookie(jwt_test_helper.jwt(email))
56
+
57
+ visit endpoint
58
+
59
+ expect(page).to have_content("Hello World")
60
+ end
61
+
62
+ it "prevents sessions with invalid JWTs from accessing secured endpoints" do
63
+ set_access_token_cookie(jwt_test_helper.jwt(email, "exp" => (Time.now - 1.day).to_i))
64
+
65
+ visit endpoint
66
+
67
+ expect(current_path).to eq("/authorize")
68
+ end
69
+
70
+ it "prevents sessions with no JWT from accessing secured endpoints" do
71
+ visit endpoint
72
+
73
+ expect(current_path).to eq("/authorize")
74
+ end
75
+
76
+ def set_access_token_cookie(token)
77
+ page.driver.browser.manage.add_cookie(name: NulogySSO.sso_cookie_key, value: token)
78
+ end
79
+ end
80
+
81
+ describe "web app authentication" do
82
+ include_examples "JWT authentication", endpoint: "/hello_world"
83
+ end
84
+
85
+ describe "API authentication" do
86
+ include_examples "JWT authentication", endpoint: "/api_endpoint"
87
+ end
88
+
89
+ def create_user
90
+ User.create!(email: email)
91
+ end
92
+ 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: 2.5.1
4
+ version: 3.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: 2022-10-06 00:00:00.000000000 Z
11
+ date: 2025-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: auth0
@@ -31,137 +31,165 @@ dependencies:
31
31
  - !ruby/object:Gem::Version
32
32
  version: '5.5'
33
33
  - !ruby/object:Gem::Dependency
34
- name: auth0_rs256_jwt_verifier
34
+ name: base64
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 0.0.2
39
+ version: 0.3.0
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: 0.0.2
46
+ version: 0.3.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: jwt
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.10'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.10'
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: rails
49
63
  requirement: !ruby/object:Gem::Requirement
50
64
  requirements:
51
65
  - - ">="
52
66
  - !ruby/object:Gem::Version
53
- version: '5.1'
67
+ version: '7.2'
54
68
  - - "<"
55
69
  - !ruby/object:Gem::Version
56
- version: '8.0'
70
+ version: '8.2'
57
71
  type: :runtime
58
72
  prerelease: false
59
73
  version_requirements: !ruby/object:Gem::Requirement
60
74
  requirements:
61
75
  - - ">="
62
76
  - !ruby/object:Gem::Version
63
- version: '5.1'
77
+ version: '7.2'
64
78
  - - "<"
65
79
  - !ruby/object:Gem::Version
66
- version: '8.0'
80
+ version: '8.2'
81
+ - !ruby/object:Gem::Dependency
82
+ name: appraisal
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '2.5'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '2.5'
67
95
  - !ruby/object:Gem::Dependency
68
96
  name: capybara
69
97
  requirement: !ruby/object:Gem::Requirement
70
98
  requirements:
71
99
  - - "~>"
72
100
  - !ruby/object:Gem::Version
73
- version: '3.29'
101
+ version: '3.40'
74
102
  type: :development
75
103
  prerelease: false
76
104
  version_requirements: !ruby/object:Gem::Requirement
77
105
  requirements:
78
106
  - - "~>"
79
107
  - !ruby/object:Gem::Version
80
- version: '3.29'
108
+ version: '3.40'
81
109
  - !ruby/object:Gem::Dependency
82
110
  name: dotenv-rails
83
111
  requirement: !ruby/object:Gem::Requirement
84
112
  requirements:
85
113
  - - "~>"
86
114
  - !ruby/object:Gem::Version
87
- version: '2.7'
115
+ version: '3.1'
88
116
  type: :development
89
117
  prerelease: false
90
118
  version_requirements: !ruby/object:Gem::Requirement
91
119
  requirements:
92
120
  - - "~>"
93
121
  - !ruby/object:Gem::Version
94
- version: '2.7'
122
+ version: '3.1'
95
123
  - !ruby/object:Gem::Dependency
96
124
  name: rspec-rails
97
125
  requirement: !ruby/object:Gem::Requirement
98
126
  requirements:
99
127
  - - "~>"
100
128
  - !ruby/object:Gem::Version
101
- version: '4.0'
129
+ version: '7.1'
102
130
  type: :development
103
131
  prerelease: false
104
132
  version_requirements: !ruby/object:Gem::Requirement
105
133
  requirements:
106
134
  - - "~>"
107
135
  - !ruby/object:Gem::Version
108
- version: '4.0'
136
+ version: '7.1'
109
137
  - !ruby/object:Gem::Dependency
110
138
  name: selenium-webdriver
111
139
  requirement: !ruby/object:Gem::Requirement
112
140
  requirements:
113
141
  - - "~>"
114
142
  - !ruby/object:Gem::Version
115
- version: '3.142'
143
+ version: '4.27'
116
144
  type: :development
117
145
  prerelease: false
118
146
  version_requirements: !ruby/object:Gem::Requirement
119
147
  requirements:
120
148
  - - "~>"
121
149
  - !ruby/object:Gem::Version
122
- version: '3.142'
150
+ version: '4.27'
123
151
  - !ruby/object:Gem::Dependency
124
152
  name: sqlite3
125
153
  requirement: !ruby/object:Gem::Requirement
126
154
  requirements:
127
155
  - - "~>"
128
156
  - !ruby/object:Gem::Version
129
- version: '1.4'
157
+ version: '2.5'
130
158
  type: :development
131
159
  prerelease: false
132
160
  version_requirements: !ruby/object:Gem::Requirement
133
161
  requirements:
134
162
  - - "~>"
135
163
  - !ruby/object:Gem::Version
136
- version: '1.4'
164
+ version: '2.5'
137
165
  - !ruby/object:Gem::Dependency
138
166
  name: webmock
139
167
  requirement: !ruby/object:Gem::Requirement
140
168
  requirements:
141
169
  - - "~>"
142
170
  - !ruby/object:Gem::Version
143
- version: '3.7'
171
+ version: '3.24'
144
172
  type: :development
145
173
  prerelease: false
146
174
  version_requirements: !ruby/object:Gem::Requirement
147
175
  requirements:
148
176
  - - "~>"
149
177
  - !ruby/object:Gem::Version
150
- version: '3.7'
178
+ version: '3.24'
151
179
  - !ruby/object:Gem::Dependency
152
- name: webrick
180
+ name: puma
153
181
  requirement: !ruby/object:Gem::Requirement
154
182
  requirements:
155
183
  - - "~>"
156
184
  - !ruby/object:Gem::Version
157
- version: '1.7'
185
+ version: '7.0'
158
186
  type: :development
159
187
  prerelease: false
160
188
  version_requirements: !ruby/object:Gem::Requirement
161
189
  requirements:
162
190
  - - "~>"
163
191
  - !ruby/object:Gem::Version
164
- version: '1.7'
192
+ version: '7.0'
165
193
  description:
166
194
  email:
167
195
  - engineering@nulogy.com
@@ -239,18 +267,18 @@ files:
239
267
  - spec/dummy/public/apple-touch-icon.png
240
268
  - spec/dummy/public/favicon.ico
241
269
  - spec/dummy/public/robots.txt
242
- - spec/dummy/tmp/development_secret.txt
270
+ - spec/dummy/tmp/local_secret.txt
243
271
  - spec/examples.txt
244
- - spec/feature_spec_helper.rb
245
- - spec/features/nulogy_sso/sso_login_spec.rb
246
272
  - spec/rails_helper.rb
247
273
  - spec/spec_helper.rb
248
274
  - spec/support/mock_auth0_verifier.rb
275
+ - spec/system/nulogy_sso/sso_login_spec.rb
249
276
  - spec/unit/services/nulogy_sso/authenticator_spec.rb
250
277
  - spec/unit/services/nulogy_sso/cookie_token_store_spec.rb
251
278
  - spec/unit/services/nulogy_sso/origin_redirector_spec.rb
252
279
  homepage: https://nulogy.com
253
- licenses: []
280
+ licenses:
281
+ - MIT
254
282
  metadata: {}
255
283
  post_install_message:
256
284
  rdoc_options: []
@@ -260,14 +288,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
260
288
  requirements:
261
289
  - - ">="
262
290
  - !ruby/object:Gem::Version
263
- version: '2.5'
291
+ version: '3.1'
264
292
  required_rubygems_version: !ruby/object:Gem::Requirement
265
293
  requirements:
266
294
  - - ">="
267
295
  - !ruby/object:Gem::Version
268
296
  version: '0'
269
297
  requirements: []
270
- rubygems_version: 3.3.7
298
+ rubygems_version: 3.5.22
271
299
  signing_key:
272
300
  specification_version: 4
273
301
  summary: Rails Engine For Nulogy's SSO Integration
@@ -326,13 +354,12 @@ test_files:
326
354
  - spec/dummy/public/apple-touch-icon.png
327
355
  - spec/dummy/public/favicon.ico
328
356
  - spec/dummy/public/robots.txt
329
- - spec/dummy/tmp/development_secret.txt
357
+ - spec/dummy/tmp/local_secret.txt
330
358
  - spec/examples.txt
331
- - spec/feature_spec_helper.rb
332
- - spec/features/nulogy_sso/sso_login_spec.rb
333
359
  - spec/rails_helper.rb
334
360
  - spec/spec_helper.rb
335
361
  - spec/support/mock_auth0_verifier.rb
362
+ - spec/system/nulogy_sso/sso_login_spec.rb
336
363
  - spec/unit/services/nulogy_sso/authenticator_spec.rb
337
364
  - spec/unit/services/nulogy_sso/cookie_token_store_spec.rb
338
365
  - spec/unit/services/nulogy_sso/origin_redirector_spec.rb
@@ -1 +0,0 @@
1
- ab92fd0ece8b30044343553f055464ba07c174e3aff5891025f0160b9e6134b1c77cc8e2acff77f8e6b50969505afb86b5795ea6cfedae93b0700ee7eacc5f39
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rails_helper"
4
- require "capybara/rspec"
5
- require "webmock/rspec"
6
- require "resolv"
7
- require "socket"
8
-
9
- def configure_webmock(overrides: [])
10
- allowed_hosts = (overrides + [ENV["NULOGY_SSO_MOCKSERVER_HOST"]]).compact
11
- WebMock.disable_net_connect!(
12
- allow_localhost: true,
13
- allow: allowed_hosts
14
- )
15
- end
16
-
17
- Capybara.server = :webrick
18
-
19
- if ENV["REMOTE_SELENIUM_HOST"].present?
20
- ip = Socket.ip_address_list.detect(&:ipv4_private?)
21
- rails_server_host = ip.ip_address
22
- remote_selenium_host = Resolv.getaddress(ENV.fetch("REMOTE_SELENIUM_HOST"))
23
- remote_selenium_port = ENV.fetch("REMOTE_SELENIUM_PORT")
24
-
25
- Capybara.register_driver :remote do |app|
26
- Capybara.server_host = rails_server_host
27
- Capybara::Selenium::Driver.new(
28
- app,
29
- browser: :remote,
30
- url: "http://#{remote_selenium_host}:#{remote_selenium_port}/wd/hub",
31
- desired_capabilities: :chrome
32
- )
33
- end
34
-
35
- Capybara.javascript_driver = :remote
36
- configure_webmock(overrides: [rails_server_host, remote_selenium_host])
37
- else
38
- Capybara.javascript_driver = :selenium_chrome
39
- configure_webmock
40
- end
41
-
42
- RSpec.configure do |config|
43
- config.use_transactional_fixtures = true
44
- end
@@ -1,94 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "feature_spec_helper"
4
-
5
- module NulogySSO
6
- RSpec.describe "the SSO login process", type: :feature, js: true do
7
- let(:email) { "test@nulogy.com" }
8
- let(:auth0_mock) {
9
- TestUtilities::Auth0Mock.new(
10
- mockserver_host: ENV.fetch("NULOGY_SSO_MOCKSERVER_HOST", "localhost"),
11
- mockserver_port: ENV.fetch("NULOGY_SSO_MOCKSERVER_PORT", 1080)
12
- )
13
- }
14
- let(:jwt_test_helper) { TestUtilities::JwtTestHelper.new }
15
-
16
- describe "login flow" do
17
- it "can successfully login" do
18
- auth0_mock.setup(email: email, redirect_path: "/hello_world")
19
- create_user
20
-
21
- visit "/hello_world"
22
-
23
- expect(page).to have_content("Hello World")
24
- end
25
-
26
- it "shows an error page when the user can authorize with Auth0 but not exist in the app" do
27
- auth0_mock.setup(email: email, redirect_path: "/hello_world")
28
-
29
- visit "/hello_world"
30
-
31
- expect(page).to have_content("An SSO error has occurred :(")
32
- end
33
-
34
- it "shows an error page when Auth0 throws an error" do
35
- auth0_mock.setup(email: email, redirect_path: "/hello_world", status_code: 403)
36
- create_user
37
-
38
- visit "/hello_world"
39
-
40
- expect(page).to have_content("An SSO error has occurred :(")
41
- end
42
- end
43
-
44
- shared_examples "JWT authentication" do |endpoint:|
45
- let!(:user) { create_user }
46
-
47
- before do
48
- auth0_mock.mockserver_reset
49
- auth0_mock.setup_jwks
50
-
51
- # have to visit an unauthenticated endpoint in order for capybara to have something to have a tab to set the cookie on
52
- visit "/robots.txt"
53
- end
54
-
55
- it "allows a user with a valid JWT to visit a secured endpoint" do
56
- set_access_token_cookie(jwt_test_helper.jwt(email))
57
-
58
- visit endpoint
59
-
60
- expect(page).to have_content("Hello World")
61
- end
62
-
63
- it "prevents sessions with invalid JWTs from accessing secured endpoints" do
64
- set_access_token_cookie(jwt_test_helper.jwt(email, "exp" => (Time.now - 1.day).to_i))
65
-
66
- visit endpoint
67
-
68
- expect(current_path).to eq("/authorize")
69
- end
70
-
71
- it "prevents sessions with no JWT from accessing secured endpoints" do
72
- visit endpoint
73
-
74
- expect(current_path).to eq("/authorize")
75
- end
76
-
77
- def set_access_token_cookie(token)
78
- page.driver.browser.manage.add_cookie(name: NulogySSO.sso_cookie_key, value: token)
79
- end
80
- end
81
-
82
- describe "web app authentication" do
83
- include_examples "JWT authentication", endpoint: "/hello_world"
84
- end
85
-
86
- describe "API authentication" do
87
- include_examples "JWT authentication", endpoint: "/api_endpoint"
88
- end
89
-
90
- def create_user
91
- User.create!(email: email)
92
- end
93
- end
94
- end