Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CAPT-1766 one login bypass #3023

Merged
merged 5 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ADMIN_ALLOWED_IPS=::1,127.0.0.1
ENVIRONMENT_NAME=local

BYPASS_DFE_SIGN_IN=true
BYPASS_ONELOGIN_SIGN_IN=true
SUPPRESS_DFE_ANALYTICS_INIT=true

HMRC_API_BASE_URL=https://test-api.service.hmrc.gov.uk
Expand All @@ -21,3 +22,5 @@ TID_SIGN_IN_API_ENDPOINT=https://preprod.teaching-identity.education.gov.uk:433
TID_BASE_URL=https://localhost:3000
TID_SIGN_IN_CLIENT_ID=claim

ONELOGIN_SIGN_IN_ISSUER=https://oidc.integration.account.gov.uk/
ONELOGIN_REDIRECT_BASE_URL=http://localhost:3000
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ TID_SIGN_IN_ISSUER=https://preprod.teaching-identity.education.gov.uk/
TID_SIGN_IN_API_ENDPOINT=https://preprod.teaching-identity.education.gov.uk:433
TID_SIGN_IN_CLIENT_ID=claim

BYPASS_ONELOGIN_SIGN_IN=true
72 changes: 72 additions & 0 deletions app/controllers/omniauth_callbacks_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
class OmniauthCallbacksController < ApplicationController
include JourneyConcern

ONELOGIN_JWT_CORE_IDENTITY_HASH_KEY = "https://vocab.account.gov.uk/v1/coreIdentityJWT".freeze

def callback
auth = request.env["omniauth.auth"]

Expand All @@ -25,6 +27,20 @@ def failure
render layout: false
end

def onelogin
auth = if OneLoginSignIn.bypass?
test_user_auth_hash
else
request.env["omniauth.auth"]
end

core_identity_jwt = auth.extra.raw_info[ONELOGIN_JWT_CORE_IDENTITY_HASH_KEY]
return process_one_login_identity_verification_callback(core_identity_jwt) if core_identity_jwt
process_one_login_authentication_callback(auth)
rescue Rack::OAuth2::Client::Error => e
render plain: e.message
end

private

def current_journey_routing_name
Expand All @@ -36,4 +52,60 @@ def current_journey_routing_name
Journeys::TeacherStudentLoanReimbursement::ROUTING_NAME
end
end

def process_one_login_authentication_callback(auth)
onelogin_user_info_attributes = auth.info.to_h.slice(
*SignInForm::OneloginUserInfoForm::ONELOGIN_USER_INFO_ATTRIBUTES.map(&:to_s)
)

journey_session.answers.assign_attributes(onelogin_user_info: onelogin_user_info_attributes)
journey_session.save!

redirect_to(
claim_path(
journey: current_journey_routing_name,
slug: "sign-in",
claim: {
logged_in_with_onelogin: true
}
)
)
end

def process_one_login_identity_verification_callback(core_identity_jwt)
first_name, surname = extract_name_from_jwt(core_identity_jwt)
redirect_to(
claim_path(
journey: current_journey_routing_name,
slug: "sign-in",
claim: {
identity_confirmed_with_onelogin: true,
first_name: first_name,
surname: surname
}
)
)
end

def extract_name_from_jwt(jwt)
if OneLoginSignIn.bypass?
first_name = "TEST"
surname = "USER"
else
identity_jwt_public_key = OpenSSL::PKey::EC.new(Base64.decode64(ENV["ONELOGIN_IDENTITY_JWT_PUBLIC_KEY_BASE64"]))
decoded_jwt = JSON::JWT.decode(jwt, identity_jwt_public_key)
name_parts = decoded_jwt["vc"]["credentialSubject"]["name"][0]["nameParts"]
first_name = name_parts.find { |part| part["type"] == "GivenName" }["value"]
surname = name_parts.find { |part| part["type"] == "FamilyName" }["value"]
end
[first_name, surname]
end

def test_user_auth_hash
if request.path == "/auth/onelogin"
OmniAuth::AuthHash.new(info: {email: "[email protected]"}, extra: {raw_info: {}})
elsif request.path == "/auth/onelogin_identity"
OmniAuth::AuthHash.new(info: {email: ""}, extra: {raw_info: {ONELOGIN_JWT_CORE_IDENTITY_HASH_KEY => "test"}})
end
end
end
48 changes: 48 additions & 0 deletions app/forms/sign_in_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class SignInForm < Form
class OneloginUserInfoForm
include ActiveModel::Model
include ActiveModel::Attributes

ONELOGIN_USER_INFO_ATTRIBUTES = %i[
email
phone
]

ONELOGIN_USER_INFO_ATTRIBUTES.each do |attribute_name|
attribute attribute_name
end
end

attribute :logged_in_with_onelogin, :boolean, default: false
attribute :identity_confirmed_with_onelogin, :boolean, default: false
attribute :onelogin_user_info_attributes
attribute :first_name
attribute :surname

def onelogin_user_info_attributes=(attributes)
onelogin_user_info.assign_attributes(
journey_session.answers.onelogin_user_info
)
end

def onelogin_user_info
@onelogin_user_info ||= OneloginUserInfoForm.new
end

def save
journey_session.answers.assign_attributes(
onelogin_user_info: onelogin_user_info.attributes,
first_name: first_name,
surname: surname
)
journey_session.save!
end

private

def permitted_attributes
super + [
onelogin_user_info_attributes: OneloginUserInfoForm::ONELOGIN_USER_INFO_ATTRIBUTES
]
end
end
1 change: 1 addition & 0 deletions app/models/journeys/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Journeys
module Base
SHARED_FORMS = {
"claims" => {
"sign-in" => SignInForm,
"sign-in-or-continue" => SignInOrContinueForm,
"current-school" => CurrentSchoolForm,
"gender" => GenderForm,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class SlugSequence
]

PERSONAL_DETAILS_SLUGS = %w[
one-login-placeholder
sign-in
information-provided
personal-details
postcode-search
Expand Down
2 changes: 2 additions & 0 deletions app/models/journeys/session_answers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ class SessionAnswers
attribute :hmrc_bank_validation_succeeded, :boolean
attribute :hmrc_bank_validation_responses, default: []
attribute :logged_in_with_tid, :boolean
attribute :logged_in_with_onelogin, :boolean
attribute :details_check, :boolean
attribute :teacher_id_user_info, default: {}
attribute :onelogin_user_info, default: {}
attribute :email_address_check, :boolean
attribute :mobile_check, :string
attribute :qualifications_details_check, :boolean
Expand Down
49 changes: 49 additions & 0 deletions app/views/claims/_sign_in.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<h1 class="govuk-heading-l">
<% if @form.logged_in_with_onelogin %>
You've successfully signed in to GOV.UK One Login
<% elsif @form.identity_confirmed_with_onelogin %>
You've successfully proved your identity with GOV.UK One Login
<% else %>
You're now going to GOV.UK One Login
<% end %>
</h1>

<% if @form.logged_in_with_onelogin %>
<p>
Before you can continue your application, you'll need to prove your identity through GOV.UK One Login.
</p>
<p>
When you've proved your identity through GOV.UK One Login, you'll return to this service to complete your applciation.
</p>
<% elsif @form.identity_confirmed_with_onelogin %>
<p>
You can now continue your application
</p>
<% else %>
<p>
To continue your application, you'll need to create a GOV.UK One Login or sign in.
</p>
<p>
When you've signed in through GOV.UK One Login, your progress will be saved
and you'll be able to return to complete your application.
</p>
<% end %>

<div class="govuk-button-group">
<% if @form.logged_in_with_onelogin %>
<%= button_to "Continue", "/auth/onelogin_identity", class: "govuk-button", method: :post %>
<% elsif @form.identity_confirmed_with_onelogin %>
<%= form_for @form, url: claim_path(current_journey_routing_name) do |f| %>
<%= f.fields_for :onelogin_user_info do |ff| %>
<% ff.object.attribute_names.each do |attribute| %>
<%= ff.hidden_field attribute %>
<% end %>
<% end %>
<%= f.hidden_field :first_name %>
<%= f.hidden_field :surname %>
<%= f.submit "Continue", class: "govuk-button", data: {module: "govuk-button"} %>
<% end %>
<% else %>
<%= button_to "Continue", "/auth/onelogin", class: "govuk-button", method: :post %>
<% end %>
</div>
16 changes: 16 additions & 0 deletions app/views/claims/sign_in.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<% if @form.errors.any? %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= render(
"shared/error_summary",
instance: @form,
errored_field_id_overrides: { details_check: "claim_details_check_true" }) %>
</div>
</div>
<% end %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds govuk-body">
<%= render partial: "sign_in" %>
</div>
</div>

This file was deleted.

79 changes: 35 additions & 44 deletions app/views/get_a_teacher_relocation_payment/landing_page.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-full">
<p class="govuk-body">
The international relocation payment (IRP) is a single payment of £10,000,
funded by the UK government, which is available to eligible non-UK trainees and teachers of:
The international relocation payment (IRP) is a payment of up to
£10,000, funded by the UK government, which is available to eligible
non-UK teachers of:
</p>

<ul class="govuk-list govuk-list--bullet">
<li>languages</li>
<li>physics</li>
<li>general or combined science when that includes physics</li>
</ul>
<%= govuk_list [
"languages",
"physics",
"general or combined science when that includes physics"
], type: :bullet %>

<p class="govuk-body">
Only teachers and salaried trainees need to complete this form.
Eligible teachers will receive their IRP in 2 instalments of £5,000
spread over 2 years. Teachers must make separate applications for each
eligible year showing they meet the eligibility requirements to receive
each instalment.
</p>

<p class="govuk-body">
Expand All @@ -44,27 +48,15 @@
You will need:
</p>

<ul class="govuk-list govuk-list--bullet">
<li>
if you are a teacher, your teaching subject and the terms of your employment contract
</li>
<li>
if you are a salaried trainee, details of your teacher training course, including
teaching subject and start date
</li>
<li>
your visa type and when you entered the UK
</li>
<li>
your passport
</li>
<li>
your address in England
</li>
<li>
contact details for the school where you are employed as a teacher or trainee
</li>
</ul>
<%= govuk_list [
"your teaching subject and the terms of your employment contract",
"your visa type and when you entered the UK",
"your passport",
"your address in England",
"your national insurance number",
"your UK bank account details",
"contact details for the school where you are employed"
], type: :bullet %>

<p class="govuk-body">
<a href="<%= claim_path(current_journey_routing_name, "claim") %>" role="button" draggable="false" class="govuk-button govuk-button--start" data-module="govuk-button">
Expand All @@ -82,32 +74,31 @@
</p>

<ul class="govuk-list govuk-list--bullet">
<li>2 April to 16 June 2024</li>
<li>30 September 2024 to the end March 2025</li>
</ul>

<p class="govuk-body">
If you have started your teaching job or salaried teacher training
course, you should apply now. If you are eligible, you should receive
the money by 30 September 2024.
If you start your teaching job between 1 March 2024 and 28 February 2025
you should apply now. If you are eligible, you should receive the money
following successful completion of our eligibility checks. You must
apply before the end March 2025 to remain eligible.
</p>

<p class="govuk-body">
To remain eligible for the IRP, you must apply in either the first or
second term of your employment as a teacher or salaried trainee.
If you start your teaching job between the 1 April 2025 and 31 May 2025
you can apply when applications re-open in September 2025.
</p>

<p class="govuk-body">
Applications will re-open later in 2024.
If you start your teaching job in March 2025 you can either apply before
applications close at the end of March 2025 or when they open again in
September 2025.
</p>

<h2 class="govuk-heading-l">Not ready to apply?</h2>
<p class="govuk-body">
If you have not started your job or course, please visit
<%= govuk_link_to(
"Get an international relocation payment",
"https://getintoteaching.education.gov.uk/non-uk-teachers/get-an-international-relocation-payment",
target: "_blank"
) %>
for information about future applications.
Late applications for the IRP will not be accepted. If you fail to apply
during the correct window, we will be unable to process your
application.
</p>

<h2 class="govuk-heading-m">Contact us</h2>
Expand Down
Loading
Loading