nulogy_sso 2.6.0 → 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.
@@ -1 +1 @@
1
- 984597f29bf049179392b783ade7587338fc831e64166e267faaa19e7fad825f429c8bdeb7f65ae411c10435d459e01b7c87e4d90086245fd1d9f73b3531b30d
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] | failed | 0.0206 seconds |
4
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:1:2] | failed | 0.0083 seconds |
5
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:1:3] | failed | 0.00638 seconds |
6
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:2:1] | failed | 0.01991 seconds |
7
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:2:2] | failed | 0.00738 seconds |
8
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:2:3] | failed | 0.00719 seconds |
9
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:3:1] | failed | 0.00808 seconds |
10
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:3:2] | failed | 0.00898 seconds |
11
- ./spec/features/nulogy_sso/sso_login_spec.rb[1:3:3] | failed | 0.00904 seconds |
12
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:1] | passed | 0.00369 seconds |
13
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:2:1] | failed | 0.40264 seconds |
14
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:2:2] | failed | 0.40014 seconds |
15
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:1:3:1] | failed | 0.45297 seconds |
16
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:1] | failed | 4.39 seconds |
17
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:2] | failed | 0.62803 seconds |
18
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:3] | passed | 0.0044 seconds |
19
- ./spec/unit/services/nulogy_sso/authenticator_spec.rb[1:2:4] | failed | 6.35 seconds |
20
- ./spec/unit/services/nulogy_sso/cookie_token_store_spec.rb[1:1] | passed | 0.00965 seconds |
21
- ./spec/unit/services/nulogy_sso/cookie_token_store_spec.rb[1:2] | passed | 0.00143 seconds |
22
- ./spec/unit/services/nulogy_sso/cookie_token_store_spec.rb[1:3] | passed | 0.00034 seconds |
23
- ./spec/unit/services/nulogy_sso/origin_redirector_spec.rb[1:1:1] | passed | 0.00192 seconds |
24
- ./spec/unit/services/nulogy_sso/origin_redirector_spec.rb[1:1:2] | passed | 0.0002 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.6.0
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: 2025-01-07 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,39 +31,53 @@ 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: '7.0'
67
+ version: '7.2'
54
68
  - - "<"
55
69
  - !ruby/object:Gem::Version
56
- version: '8.1'
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: '7.0'
77
+ version: '7.2'
64
78
  - - "<"
65
79
  - !ruby/object:Gem::Version
66
- version: '8.1'
80
+ version: '8.2'
67
81
  - !ruby/object:Gem::Dependency
68
82
  name: appraisal
69
83
  requirement: !ruby/object:Gem::Requirement
@@ -163,19 +177,19 @@ dependencies:
163
177
  - !ruby/object:Gem::Version
164
178
  version: '3.24'
165
179
  - !ruby/object:Gem::Dependency
166
- name: webrick
180
+ name: puma
167
181
  requirement: !ruby/object:Gem::Requirement
168
182
  requirements:
169
183
  - - "~>"
170
184
  - !ruby/object:Gem::Version
171
- version: '1.9'
185
+ version: '7.0'
172
186
  type: :development
173
187
  prerelease: false
174
188
  version_requirements: !ruby/object:Gem::Requirement
175
189
  requirements:
176
190
  - - "~>"
177
191
  - !ruby/object:Gem::Version
178
- version: '1.9'
192
+ version: '7.0'
179
193
  description:
180
194
  email:
181
195
  - engineering@nulogy.com
@@ -241,11 +255,9 @@ files:
241
255
  - spec/dummy/config/spring.rb
242
256
  - spec/dummy/config/sso.yml
243
257
  - spec/dummy/config/storage.yml
244
- - spec/dummy/db/development.sqlite3
245
258
  - spec/dummy/db/migrate/20190912211120_create_users.rb
246
259
  - spec/dummy/db/schema.rb
247
260
  - spec/dummy/db/test.sqlite3
248
- - spec/dummy/log/development.log
249
261
  - spec/dummy/log/test.log
250
262
  - spec/dummy/package.json
251
263
  - spec/dummy/public/404.html
@@ -257,16 +269,16 @@ files:
257
269
  - spec/dummy/public/robots.txt
258
270
  - spec/dummy/tmp/local_secret.txt
259
271
  - spec/examples.txt
260
- - spec/feature_spec_helper.rb
261
- - spec/features/nulogy_sso/sso_login_spec.rb
262
272
  - spec/rails_helper.rb
263
273
  - spec/spec_helper.rb
264
274
  - spec/support/mock_auth0_verifier.rb
275
+ - spec/system/nulogy_sso/sso_login_spec.rb
265
276
  - spec/unit/services/nulogy_sso/authenticator_spec.rb
266
277
  - spec/unit/services/nulogy_sso/cookie_token_store_spec.rb
267
278
  - spec/unit/services/nulogy_sso/origin_redirector_spec.rb
268
279
  homepage: https://nulogy.com
269
- licenses: []
280
+ licenses:
281
+ - MIT
270
282
  metadata: {}
271
283
  post_install_message:
272
284
  rdoc_options: []
@@ -276,14 +288,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
276
288
  requirements:
277
289
  - - ">="
278
290
  - !ruby/object:Gem::Version
279
- version: '2.5'
291
+ version: '3.1'
280
292
  required_rubygems_version: !ruby/object:Gem::Requirement
281
293
  requirements:
282
294
  - - ">="
283
295
  - !ruby/object:Gem::Version
284
296
  version: '0'
285
297
  requirements: []
286
- rubygems_version: 3.5.23
298
+ rubygems_version: 3.5.22
287
299
  signing_key:
288
300
  specification_version: 4
289
301
  summary: Rails Engine For Nulogy's SSO Integration
@@ -330,11 +342,9 @@ test_files:
330
342
  - spec/dummy/config/sso.yml
331
343
  - spec/dummy/config/storage.yml
332
344
  - spec/dummy/config.ru
333
- - spec/dummy/db/development.sqlite3
334
345
  - spec/dummy/db/migrate/20190912211120_create_users.rb
335
346
  - spec/dummy/db/schema.rb
336
347
  - spec/dummy/db/test.sqlite3
337
- - spec/dummy/log/development.log
338
348
  - spec/dummy/log/test.log
339
349
  - spec/dummy/package.json
340
350
  - spec/dummy/public/404.html
@@ -346,11 +356,10 @@ test_files:
346
356
  - spec/dummy/public/robots.txt
347
357
  - spec/dummy/tmp/local_secret.txt
348
358
  - spec/examples.txt
349
- - spec/feature_spec_helper.rb
350
- - spec/features/nulogy_sso/sso_login_spec.rb
351
359
  - spec/rails_helper.rb
352
360
  - spec/spec_helper.rb
353
361
  - spec/support/mock_auth0_verifier.rb
362
+ - spec/system/nulogy_sso/sso_login_spec.rb
354
363
  - spec/unit/services/nulogy_sso/authenticator_spec.rb
355
364
  - spec/unit/services/nulogy_sso/cookie_token_store_spec.rb
356
365
  - spec/unit/services/nulogy_sso/origin_redirector_spec.rb
Binary file
@@ -1,12 +0,0 @@
1
-  (0.7ms) DROP TABLE IF EXISTS "users"
2
-  (0.7ms) CREATE TABLE "users" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar, "active" boolean DEFAULT 0 NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL)
3
-  (0.3ms) CREATE TABLE "schema_migrations" ("version" varchar NOT NULL PRIMARY KEY)
4
- ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
5
-  (0.1ms) INSERT INTO "schema_migrations" (version) VALUES (20190912211120)
6
-  (0.2ms) CREATE TABLE "ar_internal_metadata" ("key" varchar NOT NULL PRIMARY KEY, "value" varchar, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL)
7
- ActiveRecord::InternalMetadata Load (0.1ms) SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = ? ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1 [[nil, "environment"]]
8
- ActiveRecord::InternalMetadata Create (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ('environment', 'development', '2024-12-30 15:43:21.538370', '2024-12-30 15:43:21.538373') RETURNING "key"
9
- ActiveRecord::InternalMetadata Load (0.3ms) SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = ? ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1 [[nil, "environment"]]
10
- ActiveRecord::InternalMetadata Update (0.2ms) UPDATE "ar_internal_metadata" SET "value" = 'test', "updated_at" = '2024-12-30 15:43:21.541149' WHERE "ar_internal_metadata"."key" = 'environment'
11
- ActiveRecord::InternalMetadata Load (0.4ms) SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = ? ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1 [[nil, "schema_sha1"]]
12
- ActiveRecord::InternalMetadata Create (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ('schema_sha1', '2b01fa59c4c74162736a2cb624389712cfa71fdb', '2024-12-30 15:43:21.543796', '2024-12-30 15:43:21.543798') RETURNING "key"
@@ -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