diff --git a/Gemfile.lock b/Gemfile.lock
index 7f815c7..1aa2a8e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -98,7 +98,7 @@ GEM
base64 (0.1.1)
bcrypt (3.1.19)
bindata (2.4.15)
- blacklight (7.33.1)
+ blacklight (7.34.0)
deprecation
globalid
hashdiff
@@ -107,7 +107,7 @@ GEM
kaminari (>= 0.15)
ostruct (>= 0.3.2)
rails (>= 5.1, < 7.1)
- view_component (~> 2.66)
+ view_component (>= 2.66, < 4)
brakeman (6.0.1)
builder (3.2.4)
bundler-audit (0.9.1)
@@ -134,7 +134,7 @@ GEM
reline (>= 0.3.1)
deprecation (1.1.0)
activesupport
- devise (4.9.2)
+ devise (4.9.3)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
@@ -171,7 +171,7 @@ GEM
i18n (1.14.1)
concurrent-ruby (~> 1.0)
io-console (0.6.0)
- irb (1.8.1)
+ irb (1.8.3)
rdoc
reline (>= 0.3.8)
jbuilder (2.11.5)
@@ -199,7 +199,7 @@ GEM
kaminari-core (1.2.2)
language_server-protocol (3.17.0.3)
lint_roller (1.1.0)
- loofah (2.21.3)
+ loofah (2.21.4)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
mail (2.8.1)
@@ -215,14 +215,14 @@ GEM
multi_json (1.15.0)
multi_xml (0.6.0)
mysql2 (0.5.5)
- net-imap (0.3.7)
+ net-imap (0.4.1)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.2.1)
timeout
- net-smtp (0.3.3)
+ net-smtp (0.4.0)
net-protocol
nio4r (2.5.9)
nokogiri (1.15.4-arm64-darwin)
@@ -254,13 +254,13 @@ GEM
orm_adapter (0.5.0)
ostruct (0.5.5)
parallel (1.23.0)
- parser (3.2.2.3)
+ parser (3.2.2.4)
ast (~> 2.4.1)
racc
- psych (5.1.0)
+ psych (5.1.1)
stringio
public_suffix (5.0.3)
- puma (6.3.1)
+ puma (6.4.0)
nio4r (~> 2.0)
racc (1.7.1)
rack (2.2.8)
@@ -306,10 +306,10 @@ GEM
rake (13.0.6)
rdoc (6.5.0)
psych (>= 4.0.0)
- regexp_parser (2.8.1)
- reline (0.3.8)
+ regexp_parser (2.8.2)
+ reline (0.3.9)
io-console (~> 0.5)
- responders (3.1.0)
+ responders (3.1.1)
actionpack (>= 5.2)
railties (>= 5.2)
rexml (3.2.6)
@@ -333,7 +333,7 @@ GEM
rspec-mocks (~> 3.12)
rspec-support (~> 3.12)
rspec-support (3.12.1)
- rubocop (1.56.3)
+ rubocop (1.56.4)
base64 (~> 0.1.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
@@ -354,18 +354,18 @@ GEM
rubocop-performance (1.19.1)
rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0)
- rubocop-rails (2.21.1)
+ rubocop-rails (2.21.2)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
- rubocop-rspec (2.24.0)
+ rubocop-rspec (2.24.1)
rubocop (~> 1.33)
rubocop-capybara (~> 2.17)
rubocop-factory_bot (~> 2.22)
ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
- selenium-webdriver (4.12.0)
+ selenium-webdriver (4.14.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
@@ -390,28 +390,28 @@ GEM
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
- standard (1.31.1)
+ standard (1.31.2)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.0)
- rubocop (~> 1.56.2)
+ rubocop (~> 1.56.4)
standard-custom (~> 1.0.0)
standard-performance (~> 1.2)
standard-custom (1.0.2)
lint_roller (~> 1.0)
rubocop (~> 1.50)
- standard-performance (1.2.0)
+ standard-performance (1.2.1)
lint_roller (~> 1.1)
- rubocop-performance (~> 1.19.0)
+ rubocop-performance (~> 1.19.1)
stringio (3.0.8)
- strong_migrations (1.6.2)
+ strong_migrations (1.6.3)
activerecord (>= 5.2)
thor (1.2.2)
timeout (0.4.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
- unicode-display_width (2.4.2)
+ unicode-display_width (2.5.0)
version_gem (1.1.3)
- view_component (2.82.0)
+ view_component (3.6.0)
activesupport (>= 5.2.0, < 8.0)
concurrent-ruby (~> 1.0)
method_source (~> 1.0)
@@ -427,7 +427,7 @@ GEM
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
- zeitwerk (2.6.11)
+ zeitwerk (2.6.12)
zk (1.10.0)
zookeeper (~> 1.5.0)
zookeeper (1.5.5)
diff --git a/app/controllers/concerns/auth_session_concern.rb b/app/controllers/concerns/auth_session_concern.rb
new file mode 100644
index 0000000..8836075
--- /dev/null
+++ b/app/controllers/concerns/auth_session_concern.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module AuthSessionConcern
+ extend ActiveSupport::Concern
+
+ def new_session_path(_scope)
+ new_user_session_path
+ end
+end
diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb
index 6ab37e2..ed93dfb 100644
--- a/app/controllers/users/omniauth_callbacks_controller.rb
+++ b/app/controllers/users/omniauth_callbacks_controller.rb
@@ -22,6 +22,13 @@ def catalogue_shared
sign_in_and_redirect @user, event: :authentication
end
+ def catalogue_patron
+ Rails.logger.debug(request.env["omniauth.auth"])
+ @user = User.from_keycloak_patron(request.env["omniauth.auth"])
+ store_keycloak_data(request.env["omniauth.auth"])
+ sign_in_and_redirect @user, event: :authentication
+ end
+
# Keycloak will display its own error page when there is a failure to login.
# :nocov:
def failure
diff --git a/app/models/user.rb b/app/models/user.rb
index 74c2492..3da843d 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -31,8 +31,12 @@ class User < PatronsRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
- devise :user_reg_authenticatable, :timeoutable,
- :omniauthable, omniauth_providers: %i[catalogue_sol catalogue_spl catalogue_shared]
+ if ENV["KC_PATRON_REALM"]
+ devise :timeoutable, :omniauthable, omniauth_providers: %i[catalogue_patron catalogue_sol catalogue_spl catalogue_shared]
+ else
+ devise :user_reg_authenticatable, :timeoutable,
+ :omniauthable, omniauth_providers: %i[catalogue_patron catalogue_sol catalogue_spl catalogue_shared]
+ end
attr_accessor :username, :password, :session_token
@@ -68,6 +72,31 @@ def self.from_keycloak(auth)
end
end
+ def self.from_keycloak_patron(auth)
+ ActiveRecord::Base.transaction do
+ user = find_or_create_by!(folio_id: auth.extra.raw_info.preferred_username) do |user|
+ # We don't really care about the password since auth is via Keycloak, so we're just
+ # putting a dummy value here.
+ user.encrypted_password = SecureRandom.hex(14)
+ end
+ # set/update values from Keycloak in case they've changed
+ user.email = auth.info.email.present? ? auth.info.email : ""
+ user.provider = auth.provider
+ user.uid = auth.uid
+ user.name_given = auth.info.first_name
+ user.name_family = auth.info.last_name
+
+ # TODO: send request to catalogue services to determine active state of user account in FOLIO
+
+ # this is required for backchannel logout
+ user.session_token = auth.extra.raw_info.sid
+
+ # reload user with updated values from database
+ user.save!
+ user.reload
+ end
+ end
+
# Method added by Blacklight; Blacklight uses #to_s on your
# user class to get a user-displayable login/identifier for
# the account.
@@ -80,6 +109,8 @@ def to_s
"#{name} (SPL)"
elsif provider == "catalogue_shared"
"#{name} (TOL)"
+ else
+ name
end
end
name
diff --git a/app/views/users/sessions/new.html.erb b/app/views/users/sessions/new.html.erb
index 4c455c3..daa910b 100644
--- a/app/views/users/sessions/new.html.erb
+++ b/app/views/users/sessions/new.html.erb
@@ -1,21 +1,25 @@
Login
-<%= form_for(resource, as: resource_name, html: {'data-turbo' => "false"}, url: session_path(resource_name)) do |f| %>
-
- <%= f.label :username, "User ID" %>
- <%= f.text_field :username, autofocus: true, autocomplete: "username",class: "form-control col-md-4" %>
-
+<% if ENV["KC_PATRON_REALM"] %>
+ <%= button_to t("auth.patron_login"), user_catalogue_patron_omniauth_authorize_path, class: "btn btn-primary", data: { turbo: false } %>
+<% else %>
+ <%= form_for(resource, as: resource_name, html: {'data-turbo' => "false"}, url: session_path(resource_name)) do |f| %>
+
+ <%= f.label :username, "User ID" %>
+ <%= f.text_field :username, autofocus: true, autocomplete: "username",class: "form-control col-md-4" %>
+
-
- <%= f.label :password, "Family Name" %>
- <%= f.text_field :password, autocomplete: "off",class: "form-control col-md-4" %>
-
+
+ <%= f.label :password, "Family Name" %>
+ <%= f.text_field :password, autocomplete: "off",class: "form-control col-md-4" %>
+
- <%= t("devise.registrations.register", url: ENV["NATIONAL_LIBRARY_CARD_URL"]).html_safe %>
+ <%= t("devise.registrations.register", url: ENV["NATIONAL_LIBRARY_CARD_URL"]).html_safe %>
-
- <%= f.submit "Login", class: "btn btn-primary" %>
-
+
+ <%= f.submit "Login", class: "btn btn-primary" %>
+
+ <% end %>
<% end %>
<%= render "users/shared/links" %>
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index bb5eaf5..5c81b89 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -90,7 +90,9 @@ def recall
# session. If you need permissions, you should implement that in a before filter.
# You can also supply a hash where the value is a boolean determining whether
# or not authentication should be aborted when the value is not present.
- config.authentication_keys = {username: true, password: true}
+ unless ENV["KC_PATRON_REALM"]
+ config.authentication_keys = {username: true, password: true}
+ end
# Configure parameters from the request object used for authentication. Each entry
# given should be a request method and it will automatically be passed to the
@@ -107,7 +109,9 @@ def recall
# Configure which authentication keys should have whitespace stripped.
# These keys will have whitespace before and after removed upon creating or
# modifying a user and when used to authenticate or find a user. Default is :email.
- config.strip_whitespace_keys = [:username, :password]
+ unless ENV["KC_PATRON_REALM"]
+ config.strip_whitespace_keys = [:username, :password]
+ end
# Tell if authentication through request.params is enabled. True by default.
# It can be set to an array that will enable params authentication only for the
@@ -321,9 +325,11 @@ def recall
# If you want to use other strategies, that are not supported by Devise, or
# change the failure app, you can configure them inside the config.warden block.
#
- config.warden do |manager|
- manager.failure_app = CatalogueFailureApp
- manager.default_strategies(scope: :user).unshift :user_reg_authenticatable
+ unless ENV["KC_PATRON_REALM"]
+ config.warden do |manager|
+ manager.failure_app = CatalogueFailureApp
+ manager.default_strategies(scope: :user).unshift :user_reg_authenticatable
+ end
end
# ==> Mountable engine configurations
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index b47638d..876bb45 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -22,4 +22,12 @@
strategy_class: OmniAuth::Strategies::KeycloakOpenId,
authorize_params: {scope: "openid"},
name: "catalogue_shared"
+
+ provider :keycloak_openid,
+ ENV.fetch("KC_PATRON_CLIENT", "patron"),
+ ENV.fetch("KC_PATRON_SECRET", "default secret"),
+ client_options: {site: ENV.fetch("KEYCLOAK_URL", "http://localhost:9090"), realm: ENV.fetch("KC_PATRON_REALM", "nla-patron")},
+ strategy_class: OmniAuth::Strategies::KeycloakOpenId,
+ authorize_params: {scope: "openid"},
+ name: "catalogue_patron"
end
diff --git a/config/locales/auth.en.yml b/config/locales/auth.en.yml
index ff75b21..74ea6e4 100644
--- a/config/locales/auth.en.yml
+++ b/config/locales/auth.en.yml
@@ -6,3 +6,4 @@ en:
sol_login: "Staff Official Loan"
spl_login: "Staff Personal Loan"
shared_login: "Team Official Loan"
+ patron_login: "Patron Login"
diff --git a/config/routes.rb b/config/routes.rb
index 8d14baf..2551fce 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -51,6 +51,10 @@
}
devise_scope(:user) do
+ if ENV["KC_PATRON_REALM"]
+ get "sign_in", to: "users/sessions#new", as: :new_user_session
+ delete "sign_out", to: "users/sessions#destroy", as: :destroy_user_session
+ end
post "/backchannel_logout", to: "users/sessions#backchannel_logout", as: :backchannel_logout
end
end
diff --git a/spec/dummy/app/controllers/application_controller.rb b/spec/dummy/app/controllers/application_controller.rb
index 1652e22..d45ad21 100644
--- a/spec/dummy/app/controllers/application_controller.rb
+++ b/spec/dummy/app/controllers/application_controller.rb
@@ -1,3 +1,7 @@
class ApplicationController < ActionController::Base
# Attempt to find the mapped route for devise based on request path
+
+ if ENV["KC_PATRON_REALM"]
+ include AuthSessionConcern
+ end
end
diff --git a/spec/dummy/app/views/pages/about.html.erb b/spec/dummy/app/views/pages/about.html.erb
index 3453cf2..56bfe1f 100644
--- a/spec/dummy/app/views/pages/about.html.erb
+++ b/spec/dummy/app/views/pages/about.html.erb
@@ -1,2 +1,2 @@
-Pages#home
-Find me in app/views/pages/home.html.erb
+Pages#about
+Find me in app/views/pages/about.html.erb
diff --git a/spec/dummy/app/views/pages/home.html.erb b/spec/dummy/app/views/pages/home.html.erb
index 3453cf2..b528a86 100644
--- a/spec/dummy/app/views/pages/home.html.erb
+++ b/spec/dummy/app/views/pages/home.html.erb
@@ -1,2 +1,6 @@
Pages#home
Find me in app/views/pages/home.html.erb
+
+<% if current_user.present? %>
+ Logged in as <%= current_user %>
+<% end %>
diff --git a/spec/dummy/app/views/shared/_user_links.html.erb b/spec/dummy/app/views/shared/_user_links.html.erb
index b9a7ca2..ff6ca8e 100644
--- a/spec/dummy/app/views/shared/_user_links.html.erb
+++ b/spec/dummy/app/views/shared/_user_links.html.erb
@@ -3,7 +3,7 @@
<%= link_to "About", about_path, class: "#{active_link_class_controller(%w[pages])}" %>
<% if current_user %>
- <%= link_to t('blacklight.header_links.logout'), destroy_user_session_path, method: :delete, data: { turbo_method: :delete } %>
+ <%= link_to t('blacklight.header_links.logout'), destroy_user_session_url, method: :delete, data: { turbo_method: :delete } %>
<% unless current_user.to_s.blank? %>
diff --git a/spec/factories/users.rb b/spec/factories/users.rb
index 9701389..95ea94d 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -32,12 +32,18 @@
name_given { "Test" }
name_family { "User" }
+ if ENV["KC_PATRON_REALM"]
+ uid { SecureRandom.uuid }
+ provider { "catalogue_patron" }
+ session_token { SecureRandom.hex }
+ end
+
trait :staff do
provider { "catalogue_sol" }
uid { "603e26dd-b2d4-4a88-ad9d-406eaec31463" }
name_given { "Staff" }
name_family { "User" }
- email { "staff@nla.gov.au" }
+ sequence(:email) { |n| "staff-#{n.to_s.rjust(3, "0")}@nla.gov.au" }
session_token { SecureRandom.hex }
end
diff --git a/spec/features/active_link_spec.rb b/spec/features/active_link_spec.rb
index 2322ad4..6b09478 100644
--- a/spec/features/active_link_spec.rb
+++ b/spec/features/active_link_spec.rb
@@ -33,5 +33,24 @@
expect(page).to have_css("a.active", text: "blacklight test")
end
+
+ context "when Keycloak patron authentication is enabled" do
+ before do
+ allow(ENV).to receive(:[]).and_call_original
+ allow(ENV).to receive(:[]).with("KC_PATRON_REALM").and_return("patron_realm")
+ end
+
+ it "returns active given the controller and action" do
+ visit root_path
+ click_link "Login"
+ expect(page).to have_content("Login")
+
+ click_button "Patron Login"
+
+ visit account_path
+
+ expect(page).to have_css("a.active", text: "Blacklight Test")
+ end
+ end
end
end
diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb
index 5dffe14..80f893e 100644
--- a/spec/features/login_spec.rb
+++ b/spec/features/login_spec.rb
@@ -9,67 +9,88 @@
# rubocop:enable RSpec/AnyInstance
end
- it "creates a new session for the user" do
- visit root_path
- click_link "Login"
- expect(page).to have_content("Login")
-
- fill_in "user_username", with: "bltest"
- fill_in "user_password", with: "test"
- click_button "Login"
-
- expect(page).to have_content(I18n.t("devise.sessions.signed_in"))
- expect(page).to have_content("blacklight test")
- end
-
- it "displays a registration link" do
- visit new_user_session_path
+ context "when Keycloak patron authentication is enabled" do
+ before do
+ allow(ENV).to receive(:[]).and_call_original
+ allow(ENV).to receive(:[]).with("KC_PATRON_REALM").and_return("patron_realm")
+ end
- expect(page).to have_link("here", href: ENV["NATIONAL_LIBRARY_CARD_URL"])
- end
+ it "displays a login link" do
+ visit root_path
- it "disables Turbo" do
- visit new_user_session_path
+ expect(page).to have_link("Login", href: new_user_session_path)
+ end
- expect(page).to have_css("form[data-turbo]")
+ it "displays the patron login button" do
+ visit root_path
+ click_link "Login"
+ expect(page).to have_content(I18n.t("auth.patron_login"))
+ end
end
- context "when user is inactive" do
- it "displays an error message" do
+ context "when Keycloak patron authentication is disabled" do
+ it "creates a new session for the user" do
visit root_path
click_link "Login"
expect(page).to have_content("Login")
fill_in "user_username", with: "bltest"
- fill_in "user_password", with: "blacklight"
+ fill_in "user_password", with: "test"
click_button "Login"
- expect(page).to have_content(I18n.t("devise.failure.expired"))
- expect(page).to have_content("Login")
+ expect(page).to have_content(I18n.t("devise.sessions.signed_in"))
+ expect(page).to have_content("blacklight test")
end
- end
-
- context "when user has the wrong credentials" do
- it "displays an error message" do
- visit root_path
- click_link "Login"
- expect(page).to have_content("Login")
- fill_in "user_username", with: "0000"
- fill_in "user_password", with: "failure"
- click_button "Login"
+ it "displays a registration link" do
+ visit new_user_session_path
- expect(page).to have_link("Ask a Librarian", href: ENV["ASK_LIBRARIAN_URL"])
- expect(page).to have_content("Login")
+ expect(page).to have_link("here", href: ENV["NATIONAL_LIBRARY_CARD_URL"])
end
- end
- context "when user does not enter a username or password" do
- it "displays an error message" do
+ it "disables Turbo" do
visit new_user_session_path
- click_button "Login"
- expect(page).to have_link("Ask a Librarian", href: ENV["ASK_LIBRARIAN_URL"])
+ expect(page).to have_css("form[data-turbo]")
+ end
+
+ context "when user is inactive" do
+ it "displays an error message" do
+ visit root_path
+ click_link "Login"
+ expect(page).to have_content("Login")
+
+ fill_in "user_username", with: "bltest"
+ fill_in "user_password", with: "blacklight"
+ click_button "Login"
+
+ expect(page).to have_content(I18n.t("devise.failure.expired"))
+ expect(page).to have_content("Login")
+ end
+ end
+
+ context "when user has the wrong credentials" do
+ it "displays an error message" do
+ visit root_path
+ click_link "Login"
+ expect(page).to have_content("Login")
+
+ fill_in "user_username", with: "0000"
+ fill_in "user_password", with: "failure"
+ click_button "Login"
+
+ expect(page).to have_link("Ask a Librarian", href: ENV["ASK_LIBRARIAN_URL"])
+ expect(page).to have_content("Login")
+ end
+ end
+
+ context "when user does not enter a username or password" do
+ it "displays an error message" do
+ visit new_user_session_path
+ click_button "Login"
+
+ expect(page).to have_link("Ask a Librarian", href: ENV["ASK_LIBRARIAN_URL"])
+ end
end
end
end
diff --git a/spec/features/logout_spec.rb b/spec/features/logout_spec.rb
deleted file mode 100644
index f54bb1d..0000000
--- a/spec/features/logout_spec.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_state_literal: true
-
-require "rails_helper"
-
-RSpec.describe "Logout" do
- before do
- # rubocop:disable RSpec/AnyInstance
- allow_any_instance_of(PatronHelper).to receive(:user_location).and_return(:offsite)
- # rubocop:enable RSpec/AnyInstance
- end
-
- it "destroys the user session" do
- visit new_user_session_path
- fill_in "user_username", with: "bltest"
- fill_in "user_password", with: "test"
- click_button "Login"
-
- visit root_path
- click_link "Log Out"
-
- expect(page).to have_content(I18n.t("devise.sessions.signed_out"))
- expect(page).not_to have_content("blacklight test")
- end
-end
diff --git a/spec/features/staff_login_spec.rb b/spec/features/staff_login_spec.rb
deleted file mode 100644
index 51a6618..0000000
--- a/spec/features/staff_login_spec.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-RSpec.describe "Staff login" do
- context "when in public network" do
- # rubocop:disable RSpec/AnyInstance
- before do
- allow_any_instance_of(PatronHelper).to receive(:user_location).and_return(:offsite)
- end
- # rubocop:enable RSpec/AnyInstance
-
- it "display login links" do
- visit root_path
- click_link "Login"
- expect(page).to have_content("Login")
-
- expect(page).not_to have_content(I18n.t("auth.staff.sol_login"))
- expect(page).not_to have_content(I18n.t("auth.staff.spl_login"))
- expect(page).not_to have_content(I18n.t("auth.staff.shared_login"))
- end
- end
-
- context "when inside local network" do
- # rubocop:disable RSpec/AnyInstance
- before do
- allow_any_instance_of(PatronHelper).to receive(:user_location).and_return(:onsite)
- end
- # rubocop:enable RSpec/AnyInstance
-
- it "display login links" do
- visit root_path
- click_link "Login"
- expect(page).to have_content("Login")
-
- expect(page).not_to have_content(I18n.t("auth.staff.sol_login"))
- expect(page).not_to have_content(I18n.t("auth.staff.spl_login"))
- expect(page).not_to have_content(I18n.t("auth.staff.shared_login"))
- end
- end
-
- context "when inside staff network" do
- # rubocop:disable RSpec/AnyInstance
- before do
- allow_any_instance_of(PatronHelper).to receive(:user_location).and_return(:staff)
- end
- # rubocop:enable RSpec/AnyInstance
-
- it "display login links" do
- visit root_path
- click_link "Login"
- expect(page).to have_content("Login")
-
- expect(page).to have_content(I18n.t("auth.staff.sol_login"))
- expect(page).to have_content(I18n.t("auth.staff.spl_login"))
- expect(page).to have_content(I18n.t("auth.staff.shared_login"))
- end
- end
-end
diff --git a/spec/files/auth/auth_hash.json b/spec/files/auth/auth_hash.json
index 1babc18..81198d4 100644
--- a/spec/files/auth/auth_hash.json
+++ b/spec/files/auth/auth_hash.json
@@ -2,28 +2,28 @@
"provider": "keycloakopenid",
"uid": "603e26dd-b2d4-4a88-ad9d-406eaec31463",
"info": {
- "name": "Staff User",
- "email": "staff@nla.gov.au",
- "first_name": "Staff",
- "last_name": "User"
+ "name": "Blacklight Test",
+ "email": "test@example.com",
+ "first_name": "Blacklight",
+ "last_name": "Test"
},
"credentials": {
- "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImYyZjVmYjc3OWY4YjhhNjM2NDVlYjcxMTEzOWJhN2VhIn0.eyJleHAiOjE2NzM4NDAyOTYsImlhdCI6MTY3MzgzNjY5NiwiYXV0aF90aW1lIjoxNjczODM2Njk2LCJqdGkiOiI4ZGJmMDg4NS1kNzI3LTQ1YzQtODYwYS05ODE2YWUxOWZmNWYiLCJpc3MiOiJodHRwczovL2xvZ2luLmV4YW1wbGUuY29tL2F1dGgvcmVhbG1zL2V4YW1wbGUiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiZjVhZmFkODEtMDZjNC00OWE2LTgyN2UtMmVmMmRkM2I4ZmRhIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiY2F0YWxvZ3VlIiwic2Vzc2lvbl9zdGF0ZSI6IjgwMjQyNDYwLWVlMjEtNGUyYy1iZmY2LTNjZmM1M2JjOGVmYiIsImFsbG93ZWQtb3JpZ2lucyI6WyJsb2NhbGhvc3QiLCIwLjAuMC4wIiwiY2F0YWxvZ3VlLm5sYS5nb3YuYXUiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InByb2ZpbGUgZW1haWwgcm9sZXMiLCJzaWQiOiI4MDI0MjQ2MC1lZTIxLTRlMmMtYmZmNi0zY2ZjNTNiYzhlZmIiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXSwibmFtZSI6IlN0YWZmIFVzZXIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzdGFmZiIsImdpdmVuX25hbWUiOiJTdGFmZiIsImZhbWlseV9uYW1lIjoiVXNlciIsImVtYWlsIjoic3RhZmZAbmxhLmdvdi5hdSJ9.cjKwwSfeFvujsEduYtzDfoZSBnPHVb3vvc7mYwOoa2Ji_LYd7UNRz7iXzCqQG149_UlyrBfk8f9-JU6AVp_izTYt58H9p8FjgkE6p1U-C-SXKk8TdbM0Lf4GMbZs2spQNK4LTZYTjduGS8nU3ao30O8RQvtdd1XvucCTmEBFLlKG8U6j1IfxVEtNzHBtqJFyWvKQdfruVfgWfi2QpgkH-X-Hjr6PS5OKNsZhx6N6d9iTS8MMzZGZtIuHd9Ho-A3iL8dj6ReUAxXLAF_qFXCnp5xZZ0RtUsmr38XDl6A-iqhfD19vh3L1JZUboRgDaX85ViOkTkU5s-JJi7oC3e39OrAk2o_brDT5FM8AvkJjOB_d9xIZaMScgVgPHI3cueP0yiXgmYNxaJ8NtF0LlV4qrec3DB2y4FvF7kYGnXjof5_P3urC8MrT4c1xigfM6alXmkNUuKTTooDL9l9SpivV7c7WUrJ1nNmH3511ObmKjJWZIggJphfOpGBq9CqJ8nCr",
+ "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImYyZjVmYjc3OWY4YjhhNjM2NDVlYjcxMTEzOWJhN2VhIn0.eyJleHAiOjE2NzM4NDAyOTYsImlhdCI6MTY3MzgzNjY5NiwiYXV0aF90aW1lIjoxNjczODM2Njk2LCJqdGkiOiI4ZGJmMDg4NS1kNzI3LTQ1YzQtODYwYS05ODE2YWUxOWZmNWYiLCJpc3MiOiJodHRwczovL2xvZ2luLmV4YW1wbGUuY29tL2F1dGgvcmVhbG1zL2V4YW1wbGUiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiZjVhZmFkODEtMDZjNC00OWE2LTgyN2UtMmVmMmRkM2I4ZmRhIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiY2F0YWxvZ3VlIiwic2Vzc2lvbl9zdGF0ZSI6IjgwMjQyNDYwLWVlMjEtNGUyYy1iZmY2LTNjZmM1M2JjOGVmYiIsImFsbG93ZWQtb3JpZ2lucyI6WyJsb2NhbGhvc3QiLCIwLjAuMC4wIiwiY2F0YWxvZ3VlLm5sYS5nb3YuYXUiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InByb2ZpbGUgZW1haWwgcm9sZXMiLCJzaWQiOiI4MDI0MjQ2MC1lZTIxLTRlMmMtYmZmNi0zY2ZjNTNiYzhlZmIiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXSwibmFtZSI6IkJsYWNrbGlnaHQgVGVzdCIsInByZWZlcnJlZF91c2VybmFtZSI6ImMyMDJhN2Q1LTNkMzAtNDExYS1iMGE3LTUzNzUzODAxYmY5OCIsImdpdmVuX25hbWUiOiJCbGFja2xpZ2h0IiwiZmFtaWx5X25hbWUiOiJUZXN0IiwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUuY29tIn0.lMGOYGiMroCMtmDF9LORZoPMzkj40mKB5Ee1c_cCdCYdzZCXygeED4eSAewtCexID-Dfc8-F-CaKr4I-mXjjtn2G5FKjfhvQGLmDvQ9pnpSsfHrK7V4c3AQgpgeEHw_aiW6uXicbp9yNLhuAOWJ0nKwGjFPQRMP9MOK1uQ_KWHBmdniz5XJ-E6C_KmFib-_Tzo2QVlGZsjIcankJ-cUEkyvrVmJ0y6JfaC6Nguf2YbwBELrpJgSATrWNQLicQ-yzA_pkKjCLQwRIOqkQU7s25Ty3a2CtVAJnjxMTOgpMbKoiy79Pzw8QVC_HJyL0vXEP9fDNNA9uHJIGxcHIjdcpBw",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJjNjRhZTM5OS1hYmFmLTQ0MDQtYTUwNS04MDgwZmFkM2UzZTAifQ.eyJleHAiOjE2NzQwMDk0OTYsImlhdCI6MTY3MzgzNjY5NiwianRpIjoiZDE4ODViNzctMGUxNi00MzBjLWEyOTctNGE3NTA1ZWY0ZDFmIiwiaXNzIjoiaHR0cHM6Ly9sb2dpbi1kZXZlbC5ubGEuZ292LmF1L2F1dGgvcmVhbG1zL3NoaXJlIiwiYXVkIjoiaHR0cHM6Ly9sb2dpbi1kZXZlbC5ubGEuZ292LmF1L2F1dGgvcmVhbG1zL3NoaXJlIiwic3ViIjoiZjVhZmFkODEtMDZjNC00OWE2LTgyN2UtMmVmMmRkM2I4ZmRhIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImNhdGFsb2d1ZSIsInNlc3Npb25fc3RhdGUiOiI4MDI0MjQ2MC1lZTIxLTRlMmMtYmZmNi0zY2ZjNTNiYzhlZmIiLCJzY29wZSI6InByb2ZpbGUgZW1haWwgcm9sZXMiLCJzaWQiOiI4MDI0MjQ2MC1lZTIxLTRlMmMtYmZmNi0zY2ZjNTNiYzhlZmIifQ.q_P4zHKyeEHnhlu0FFENX9c6n_YimkaokX7AV9MC-Ag",
- "expires_at": 1673840296,
+ "expires_at": 1728943716,
"expires": true
},
"extra": {
"raw_info": {
- "exp": 1673840296,
- "iat": 1673836696,
+ "exp": 1728943716,
+ "iat": 1697407716,
"auth_time": 1673836696,
"jti": "8dbf0885-d727-45c4-860a-9816ae19ff5f",
- "iss": "https://login.example.com/auth/realms/staff",
+ "iss": "https://login.example.com/auth/realms/example",
"aud": "account",
"sub": "603e26dd-b2d4-4a88-ad9d-406eaec31463",
"typ": "Bearer",
- "azp": "catalogue",
+ "azp": "join-us",
"session_state": "80242460-ee21-4e2c-bff6-3cfc53bc8efb",
"allowed-origins": [
"localhost",
@@ -52,11 +52,11 @@
"offline_access",
"uma_authorization"
],
- "name": "Staff User",
- "preferred_username": "staff",
- "given_name": "Staff",
- "family_name": "User",
- "email": "staff@nla.gov.au"
+ "name": "Blacklight Test",
+ "preferred_username": "c202a7d5-3d30-411a-b0a7-53753801bf98",
+ "given_name": "Blacklight",
+ "family_name": "Test",
+ "email": "test@example.com"
},
"id_token": null
}
diff --git a/spec/requests/staff_logout_spec.rb b/spec/requests/logout_spec.rb
similarity index 88%
rename from spec/requests/staff_logout_spec.rb
rename to spec/requests/logout_spec.rb
index 6335a32..012ad8e 100644
--- a/spec/requests/staff_logout_spec.rb
+++ b/spec/requests/logout_spec.rb
@@ -2,15 +2,15 @@
require "rails_helper"
-RSpec.describe "Staff logout" do
+RSpec.describe "Logout" do
include Devise::Test::IntegrationHelpers
let(:file) { IO.read("spec/files/auth/staff_auth_hash.json") }
let(:auth_hash) { OmniAuth::AuthHash.new(JSON.parse(file)) }
before do
- staff = create(:user, :staff)
- sign_in staff
+ patron = create(:user, :staff)
+ sign_in patron
end
it "redirects to Keycloak's logout URL" do
@@ -34,19 +34,19 @@
jwt = JWT.decode(logout_token, nil, false)
jwt[0]["sid"]
end
- let(:staff) do
+ let(:patron) do
user = create(:user, :staff)
user.update_column(:session_token, session_id)
user.reload
end
before do
- sign_in staff
+ sign_in patron
end
it "updates the session_token for the logged out user" do
post "/backchannel_logout", params: {logout_token: logout_token}
- expect(staff.session_token).not_to eq session_id
+ expect(patron.session_token).not_to eq session_id
end
end
end
diff --git a/spec/simplecov_helper.rb b/spec/simplecov_helper.rb
index 19e769d..dfeb33b 100644
--- a/spec/simplecov_helper.rb
+++ b/spec/simplecov_helper.rb
@@ -23,4 +23,6 @@
# these will be removed soon
add_filter "lib/devise/models/getalibrarycard_authenticatable.rb"
add_filter "lib/devise/strategies/getalibrarycard_authenticatable.rb"
+ add_filter "lib/devise/models/user_reg_authenticatable.rb"
+ add_filter "lib/devise/strategies/user_reg_authenticatable.rb"
end
diff --git a/spec/support/omniauth.rb b/spec/support/omniauth.rb
new file mode 100644
index 0000000..14ec3fd
--- /dev/null
+++ b/spec/support/omniauth.rb
@@ -0,0 +1,9 @@
+require "omniauth"
+
+OmniAuth.config.test_mode = true
+
+RSpec.configure do |config|
+ config.before do
+ OmniAuth.config.add_mock(:catalogue_patron, JSON.parse(IO.read("spec/files/auth/auth_hash.json")))
+ end
+end