Skip to content

Commit

Permalink
Merge pull request #3083 from DFE-Digital/TEVA-2192
Browse files Browse the repository at this point in the history
[TEVA-2192] Authentication fallback to use organisation publishers
  • Loading branch information
cesidio committed Mar 16, 2021
2 parents 28e8fac + b7e2eaf commit a284fb9
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 202 deletions.
10 changes: 10 additions & 0 deletions app/controllers/concerns/publishers/authentication_concerns.rb
Expand Up @@ -10,8 +10,18 @@ def current_organisation
end

def sign_out_publisher!
session.delete(:publisher_id)
session.delete(:publisher_organisation_id)
session.delete(:publisher_dsi_token)
sign_out(:publisher)
end

def trigger_publisher_sign_in_event(success_or_failure, sign_in_type, publisher_oid = nil)
request_event.trigger(
:publisher_sign_in_attempt,
user_anonymised_publisher_id: StringAnonymiser.new(publisher_oid),
success: success_or_failure == :success,
sign_in_type: sign_in_type,
)
end
end
8 changes: 4 additions & 4 deletions app/controllers/jobseekers/sessions_controller.rb
Expand Up @@ -5,7 +5,7 @@ class Jobseekers::SessionsController < Devise::SessionsController
before_action :replace_devise_alert_flash_with_notice!, only: %i[new]
after_action :replace_devise_notice_flash_with_success!, only: %i[create destroy]
after_action only: %i[create] do
trigger_sign_in_event(:success)
trigger_jobseeker_sign_in_event(:success)
end

AUTHENTICATION_FAILURE_MESSAGES = %w[
Expand All @@ -19,12 +19,12 @@ def render_resource_with_errors
form = Jobseekers::SignInForm.new(sign_in_params)
if params[:action] == "create" && form.invalid?
form.errors.each { |error| resource.errors.add(error.attribute, error.type) }
trigger_sign_in_event(:failure, resource.errors)
trigger_jobseeker_sign_in_event(:failure, resource.errors)
clear_flash_and_render(:new)
elsif AUTHENTICATION_FAILURE_MESSAGES.include?(flash[:alert])
resource.errors.add(:email, flash[:alert])
resource.errors.add(:password, "")
trigger_sign_in_event(:failure, resource.errors)
trigger_jobseeker_sign_in_event(:failure, resource.errors)
clear_flash_and_render(:new)
end
end
Expand All @@ -38,7 +38,7 @@ def clear_flash_and_render(view)
render view
end

def trigger_sign_in_event(success_or_failure, errors = nil)
def trigger_jobseeker_sign_in_event(success_or_failure, errors = nil)
request_event.trigger(
:jobseeker_sign_in_attempt,
email_identifier: StringAnonymiser.new(params[:jobseeker][:email]),
Expand Down
20 changes: 4 additions & 16 deletions app/controllers/publishers/omniauth_callbacks_controller.rb
Expand Up @@ -73,10 +73,10 @@ def perform_dfe_sign_in_authorisation
def check_authorisation(authorisation_permissions)
if authorisation_permissions.authorised? && allowed_user?
sign_in_publisher
trigger_sign_in_event(:success, :dsi, user_id)
trigger_publisher_sign_in_event(:success, :dsi)
redirect_to organisation_path
else
trigger_sign_in_event(:failure, :dsi, user_id)
trigger_publisher_sign_in_event(:failure, :dsi, user_id)
@identifier = identifier
render "not_authorised"
end
Expand Down Expand Up @@ -104,10 +104,6 @@ def organisation_from_request
end
end

def redirect_for_fallback_authentication
redirect_to new_auth_email_path if AuthenticationFallback.enabled?
end

def allowed_user?
school_urn.present? || trust_uid.present? || (local_authority_code.present? && allowed_la_user?)
end
Expand All @@ -128,15 +124,7 @@ def use_school_group_if_available
school_group = school&.school_groups&.first
return unless school_group

session.update(publisher_organisation_id: school_group.id) if publisher_trusts.include?(school_group.uid) || publisher_local_authorities.include?(school_group.local_authority_code)
end

def trigger_sign_in_event(success_or_failure, sign_in_type, publisher_oid = nil)
request_event.trigger(
:publisher_sign_in_attempt,
user_anonymised_publisher_id: StringAnonymiser.new(publisher_oid),
success: success_or_failure == :success,
sign_in_type: sign_in_type,
)
session.update(publisher_organisation_id: school_group.id) if
publisher_trusts.include?(school_group.uid) || publisher_local_authorities.include?(school_group.local_authority_code)
end
end
95 changes: 35 additions & 60 deletions app/controllers/publishers/sign_in/email/sessions_controller.rb
Expand Up @@ -2,13 +2,22 @@ class Publishers::SignIn::Email::SessionsController < ApplicationController
EMERGENCY_LOGIN_KEY_DURATION = 10.minutes

before_action :redirect_signed_in_publishers, only: %i[new create check_your_email choose_organisation]
before_action :redirect_for_dsi_authentication, only: %i[new create check_your_email change_organisation choose_organisation]
before_action :redirect_unauthorised_publishers, only: %i[create]
before_action :redirect_for_dsi_authentication, only: %i[new create check_your_email choose_organisation]

def create
session.update(publisher_organisation_id: params[:organisation_id])
trigger_sign_in_event(:success, :email)
redirect_to organisation_path
publisher = Publisher.find(session[:publisher_id])
organisation = publisher.organisations.find(params[:organisation_id])

if publisher.organisations.include?(organisation) && allowed_la_publisher?(organisation)
sign_in(publisher)
sign_out(:jobseeker)
session.update(publisher_organisation_id: organisation.id)
trigger_publisher_sign_in_event(:success, :email)
redirect_to organisation_path
else
trigger_publisher_sign_in_event(:failure, :email, publisher.oid)
redirect_to new_auth_email_path, notice: t(".not_authorised")
end
end

def check_your_email
Expand All @@ -17,18 +26,13 @@ def check_your_email
end

def choose_organisation
information = GetInformationFromLoginKey.new(get_key)
@reason_for_failing_sign_in = information.reason_for_failing_sign_in
@schools = information.schools
@trusts = information.trusts
@local_authorities = information.local_authorities
sign_in_publisher(information.details_to_update_in_session)

return if information.multiple_organisations? || @reason_for_failing_sign_in.present?

redirect_to auth_email_create_session_path(
organisation_id: (@schools&.first&.presence || @trusts&.first&.presence || @local_authorities&.first&.presence).id,
)
process_login_key
session.update(publisher_id: @publisher.id) if @publisher

@reason_for_failing_sign_in = "no_orgs" if @publisher&.organisations&.none?
return if @publisher&.organisations&.many? || @reason_for_failing_sign_in.present?

redirect_to auth_email_create_session_path(organisation_id: @publisher.organisations.first.id)
end

private
Expand All @@ -37,20 +41,19 @@ def redirect_signed_in_publishers
redirect_to organisation_path if current_organisation.present?
end

def sign_in_publisher(options)
return unless options[:oid]

publisher = Publisher.find_by(oid: options[:oid])
sign_in(publisher)
sign_out(:jobseeker)
def redirect_for_dsi_authentication
redirect_to new_publisher_session_path unless AuthenticationFallback.enabled?
end

def get_key
params_login_key = params[:login_key]
begin
EmergencyLoginKey.find(params_login_key)
rescue StandardError
nil
def process_login_key
login_key = EmergencyLoginKey.find_by(id: params[:login_key])
return @reason_for_failing_sign_in = "no_key" unless login_key

if login_key.expired?
@reason_for_failing_sign_in = "expired"
else
@publisher = Publisher.find(login_key.publisher_id)
login_key.destroy
end
end

Expand All @@ -65,38 +68,10 @@ def generate_login_key(publisher:)
publisher.emergency_login_keys.create(not_valid_after: Time.current + EMERGENCY_LOGIN_KEY_DURATION)
end

def redirect_for_dsi_authentication
redirect_to new_publisher_session_path unless AuthenticationFallback.enabled?
end

def redirect_unauthorised_publishers
return if publisher_authorised? && allowed_la_publisher?

trigger_sign_in_event(:failure, :email)
redirect_to new_auth_email_path, notice: t(".not_authorised")
end

def publisher_authorised?
@organisation = Organisation.find_by(id: params[:organisation_id])

current_publisher.dsi_data&.dig("la_codes")&.include?(@organisation.local_authority_code) ||
current_publisher.dsi_data&.dig("trust_uids")&.include?(@organisation.uid) ||
current_publisher.dsi_data&.dig("school_urns")&.include?(@organisation.urn)
end

def allowed_la_publisher?
def allowed_la_publisher?(organisation)
return true unless Rails.configuration.enforce_local_authority_allowlist
return true unless @organisation.local_authority_code

Rails.configuration.allowed_local_authorities.include?(@organisation.local_authority_code)
end
return true unless organisation.local_authority_code.present?

def trigger_sign_in_event(success_or_failure, sign_in_type, publisher_oid = nil)
request_event.trigger(
:publisher_sign_in_attempt,
user_anonymised_publisher_id: StringAnonymiser.new(publisher_oid),
success: success_or_failure == :success,
sign_in_type: sign_in_type,
)
Rails.configuration.allowed_local_authorities.include?(organisation.local_authority_code)
end
end
1 change: 1 addition & 0 deletions app/models/publisher.rb
Expand Up @@ -3,6 +3,7 @@ class Publisher < ApplicationRecord

has_many :organisation_publishers, dependent: :destroy
has_many :organisations, through: :organisation_publishers
accepts_nested_attributes_for :organisation_publishers

devise :omniauthable, :timeoutable, omniauth_providers: %i[dfe]
self.timeout_in = 60.minutes # Overrides default Devise configuration
Expand Down
68 changes: 0 additions & 68 deletions app/services/get_information_from_login_key.rb

This file was deleted.

Expand Up @@ -9,16 +9,9 @@

p = t("publishers.temp_login.choose_organisation.please_select")

- @local_authorities.each do |la|
= govuk_link_to(la.name, auth_email_create_session_path(organisation_id: la.id))
br
br

- @trusts.each do |trust|
= govuk_link_to(trust.name, auth_email_create_session_path(organisation_id: trust.id))
br
br

- @schools.each do |school|
= govuk_link_to(location(school), auth_email_create_session_path(organisation_id: school.id))
br
- @publisher.organisations.each do |organisation|
p
- if organisation.is_a?(School)
= govuk_link_to(location(organisation), auth_email_create_session_path(organisation_id: organisation.id))
- else
= govuk_link_to(organisation.name, auth_email_create_session_path(organisation_id: organisation.id))
8 changes: 8 additions & 0 deletions app/views/publishers/sign_in/email/sessions/new.html.slim
Expand Up @@ -3,17 +3,25 @@
.govuk-grid-row
.govuk-grid-column-full
= render(Shared::NotificationComponent.new(content: { title: t("publishers.temp_login.heading"), body: t("publishers.temp_login.please_use_email") }, style: "danger"))

.govuk-grid-column-two-thirds
h1.govuk-heading-l = t("publishers.sessions.new.sign_in.title")

p = t("publishers.sessions.new.sign_in.description")

= form_for Publisher.new, url: auth_email_check_your_email_path do |f|
= f.govuk_email_field :email

= f.govuk_submit t("buttons.continue"), classes: "fallback-authentication-submit-email-gtm govuk-!-margin-bottom-0"

hr.govuk-section-break.govuk-section-break--l.govuk-section-break--visible

h2.govuk-heading-m = t("publishers.sessions.new.request_account_title")

p = t("publishers.sessions.new.request_account_html", mail_to: govuk_mail_to(t("help.email"), t("help.email")))

.govuk-grid-column-one-third
.account-sidebar
h2.account-sidebar__heading = t("publishers.sessions.new.assistance.heading")

p.govuk-body-s = t("publishers.sessions.new.assistance.content_html", link: govuk_link_to(t("publishers.sessions.new.assistance.link_text"), new_jobseeker_session_path))
4 changes: 0 additions & 4 deletions config/routes.rb
Expand Up @@ -75,10 +75,6 @@
as: "auth_email_choose_organisation"
get "auth/email/sessions/sign-in", to: "publishers/sign_in/email/sessions#create",
as: "auth_email_create_session"
get "auth/email/sessions/sign-out", to: "publishers/sign_in/email/sessions#destroy",
as: "auth_email_sign_out"
get "auth/email/sessions/change-organisation", to: "publishers/sign_in/email/sessions#change_organisation",
as: "auth_email_change_organisation"
end

root "home#index"
Expand Down

0 comments on commit a284fb9

Please sign in to comment.