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

Check validity of User when using DfE Sign in callback #10020

Merged
merged 4 commits into from
Nov 4, 2024

Conversation

dcyoung-dev
Copy link
Collaborator

Context

We have ActiveRecord::RecordNotUnique errors appearing in Sentry related to the email address of a DfE Sign in user already being used.
The current implementation does not handle this error.

Changes proposed in this pull request

  • We have added email uniqueness and presence validation to SupportUser and ProviderUser.
  • We have updated the DfESignInController#callback to check for a successful update before redirecting appropriately

Guidance to review

  • 🤔

Things to check

  • If the code removes any existing feature flags, a data migration has also been added to delete the entry from the database
  • This code does not rely on migrations in the same Pull Request
  • If this code includes a migration adding or changing columns, it also backfills existing records for consistency
  • If this code adds a column to the DB, decide whether it needs to be in analytics yml file or analytics blocklist
  • API release notes have been updated if necessary
  • If it adds a significant user-facing change, is it documented in the CHANGELOG?
  • Required environment variables have been updated added to the Azure KeyVault
  • Inform data insights team due to database changes
  • Make sure all information from the Trello card is in here
  • Rebased main
  • Cleaned commit history
  • Tested by running locally
  • Add PR link to Trello card

@dcyoung-dev
Copy link
Collaborator Author

@@ -2,9 +2,8 @@

RSpec.describe DsiProfile do
describe '#update_profile_from_dfe_sign_in' do
let(:provider_user) { create(:provider_user) }
let(:support_user) { create(:provider_user) }
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

support_user was never used in this spec

@@ -41,6 +41,17 @@
described_class.update_profile_from_dfe_sign_in dfe_user: dfe_user_no_email, local_user: provider_user
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was tempted to update all the specs in this context to be in the same format

  • setup
  • result
  • expectation
    Do you think it'd be worth while?

@@ -1,6 +1,13 @@
require 'rails_helper'

RSpec.describe ProviderUser do
describe 'validations' do
let!(:existing_provider_user) { create(:provider_user) }
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Required for the validate_uniqueness_of check - ShouldaMatchers will use the email address from an existing ProviderUser when testing for uniqueness

Comment on lines -5 to -8
it 'flags email addresses that differ only by case as duplicates' do
create(:support_user, email_address: '[email protected]')
duplicate_support_user = build(:support_user, email_address: '[email protected]')
expect(duplicate_support_user).not_to be_valid
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now covered by

it { is_expected.to validate_uniqueness_of(:email_address).case_insensitive

context 'there are no DfE sign omniauth values set' do
let(:omni_auth_hash) { nil }

it 'is forbidden by default' do
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before changes in this PR - this spec fails with

Failure/Error: 'id_token' => omniauth_payload['credentials']['id_token'],
NoMethodError: undefined method `[]' for nil

get support_interface_sign_in_path # makes sure the session[:post_dfe_sign_in_path] is set
get auth_dfe_callback_path

expect(response).to have_http_status(:forbidden)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before changes in this PR - this spec fails with

expected the response to have status code :forbidden (403) but it was :unprocessable_entity (422)

let!(:provider_user) { create(:provider_user, dfe_sign_in_uid: 'DFE_SIGN_IN_UID') }
let!(:existing_provider_user) { create(:provider_user, email_address: '[email protected]') }

it 'does not sign the Provider User in' do
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before changes in this PR - this spec fails with

ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_provider_users_on_email_address"
DETAIL: Key (email_address)=([email protected]) already exists.

Added email presence and uniqueness validations to Support and Provider Users.
Also replaced `before` callbacks with Rails `normalizes` for downcasing email addresses
Using the new validation rules we now check that the `DsiProfile.update_profile_from_dfe_sign_in` has happened before continuing.

There seems to be a lack of tests around the request which will be added in another commit
Added several scenarios to ensure the correct behaviours take place when signing in using DfE Sign in (OAuth)
@dcyoung-dev dcyoung-dev force-pushed the dy-bug-dsi-sign-in-duplicate-email-error branch from d1e323e to 3bcdc5f Compare November 1, 2024 13:02
@dcyoung-dev dcyoung-dev merged commit f9683cd into main Nov 4, 2024
24 checks passed
@dcyoung-dev dcyoung-dev deleted the dy-bug-dsi-sign-in-duplicate-email-error branch November 4, 2024 15:10
dcyoung-dev added a commit that referenced this pull request Nov 5, 2024
## Context

A bug was introduced in #10020 which stops the sign in by-pass from
working locally or on review apps.

## Changes proposed in this pull request

- Removed conditional that would return `nil` if there are no updates to
be done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants