diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/AuthenticationState.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/AuthenticationState.cs index 375dd09f6..a38fba790 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/AuthenticationState.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/AuthenticationState.cs @@ -143,6 +143,8 @@ public AuthenticationState( public bool? RequiresTrnVerificationLevelElevation { get; private set; } public bool? TrnVerificationElevationSuccessful { get; set; } + public bool? Blocked { get; set; } + [JsonIgnore] public bool EmailAddressSet => EmailAddress is not null; [JsonIgnore] diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Controllers/AuthorizationController.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Controllers/AuthorizationController.cs index 963529aa8..1f53d45ce 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Controllers/AuthorizationController.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Controllers/AuthorizationController.cs @@ -26,6 +26,7 @@ public class AuthorizationController : Controller private readonly TeacherIdentityServerDbContext _dbContext; private readonly IClock _clock; private readonly TrnTokenHelper _trnTokenHelper; + private readonly UserHelper _userHelper; private readonly IConfiguration _configuration; public AuthorizationController( @@ -37,6 +38,7 @@ public AuthorizationController( TeacherIdentityServerDbContext dbContext, IClock clock, TrnTokenHelper trnTokenHelper, + UserHelper userHelper, IConfiguration configuration) { _applicationManager = applicationManager; @@ -47,6 +49,7 @@ public AuthorizationController( _dbContext = dbContext; _clock = clock; _trnTokenHelper = trnTokenHelper; + _userHelper = userHelper; _configuration = configuration; } @@ -544,18 +547,22 @@ private static IEnumerable GetDestinations(Claim claim, ClaimsPrincipal return signedInUser; } - private async Task InitializeAuthenticationState(User? signedInUser, EnhancedTrnToken? trnToken, + private async Task InitializeAuthenticationState( + User? signedInUser, + EnhancedTrnToken? trnToken, AuthenticationState authenticationState) { if (trnToken is null) { authenticationState.OnSignedInUserProvided(signedInUser); + await CheckCanAccessService(); return null; } if (signedInUser is not null) { _trnTokenHelper.InitializeAuthenticationStateForSignedInUser(signedInUser, authenticationState, trnToken); + await CheckCanAccessService(); return null; } @@ -566,6 +573,7 @@ private static IEnumerable GetDestinations(Claim claim, ClaimsPrincipal if (existingValidUser.Trn is null || existingValidUser.Trn == trnToken.Trn) { _trnTokenHelper.InitializeAuthenticationStateForExistingUser(existingValidUser, authenticationState, trnToken); + await CheckCanAccessService(); return await authenticationState.SignIn(HttpContext); } } @@ -574,8 +582,17 @@ private static IEnumerable GetDestinations(Claim claim, ClaimsPrincipal var existingAccountMatch = await _trnTokenHelper.GetExistingAccountMatchForToken(trnToken); authenticationState.OnExistingAccountSearch(existingAccountMatch); authenticationState.OnTrnTokenProvided(trnToken); + await CheckCanAccessService(); } return null; + + async Task CheckCanAccessService() + { + if (authenticationState.Trn is not null) + { + await _userHelper.CheckCanAccessService(authenticationState); + } + } } } diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/IdentityLinkGenerator.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/IdentityLinkGenerator.cs index 57e0cccce..ca24f30cf 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/IdentityLinkGenerator.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/IdentityLinkGenerator.cs @@ -40,6 +40,8 @@ protected virtual string Page(string pageName, string? handler = null, bool auth return url; } + public string Blocked() => Page("/SignIn/Blocked"); + public string CompleteAuthorization() => Page("/SignIn/Complete"); public string Reset() => Page("/SignIn/Reset"); diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/CoreSignInJourney.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/CoreSignInJourney.cs index aa3566875..c8e9f648a 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/CoreSignInJourney.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/CoreSignInJourney.cs @@ -30,6 +30,7 @@ public override bool CanAccessStep(string step) return step switch { Steps.Landing => true, + Steps.Blocked => AuthenticationState.Blocked == true, SignInJourney.Steps.Email => true, SignInJourney.Steps.EmailConfirmation => AuthenticationState is { EmailAddressSet: true, EmailAddressVerified: false }, Steps.NoAccount => AuthenticationState.EmailAddressVerified, @@ -148,6 +149,7 @@ public override string GetLastAccessibleStepUrl(string? requestedStep) SignInJourney.Steps.Email => LinkGenerator.Email(), SignInJourney.Steps.EmailConfirmation => LinkGenerator.EmailConfirmation(), Steps.Landing => LinkGenerator.Landing(), + Steps.Blocked => LinkGenerator.Blocked(), Steps.Email => LinkGenerator.RegisterEmail(), Steps.EmailConfirmation => LinkGenerator.RegisterEmailConfirmation(), Steps.InstitutionEmail => LinkGenerator.RegisterInstitutionEmail(), @@ -208,5 +210,6 @@ AuthenticationState is public const string ChangeEmailRequest = $"{nameof(CoreSignInJourney)}.{nameof(ChangeEmailRequest)}"; public const string CheckAnswers = $"{nameof(CoreSignInJourney)}.{nameof(CheckAnswers)}"; public const string NoAccount = $"{nameof(CoreSignInJourney)}.{nameof(NoAccount)}"; + public const string Blocked = $"{nameof(CoreSignInJourney)}.{nameof(Blocked)}"; } } diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/CoreSignInJourneyWithTrnLookup.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/CoreSignInJourneyWithTrnLookup.cs index 09ebc77d5..aae37f6b3 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/CoreSignInJourneyWithTrnLookup.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/CoreSignInJourneyWithTrnLookup.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using TeacherIdentity.AuthServer.Models; @@ -12,6 +13,7 @@ public class CoreSignInJourneyWithTrnLookup : CoreSignInJourney private readonly TrnLookupHelper _trnLookupHelper; private readonly TeacherIdentityApplicationManager _applicationManager; private readonly IBackgroundJobScheduler _backgroundJobScheduler; + private readonly ElevateTrnVerificationLevelJourney _elevateJourney; public CoreSignInJourneyWithTrnLookup( HttpContext httpContext, @@ -25,10 +27,21 @@ public CoreSignInJourneyWithTrnLookup( _trnLookupHelper = trnLookupHelper; _applicationManager = applicationManager; _backgroundJobScheduler = backgroundJobScheduler; + + _elevateJourney = new ElevateTrnVerificationLevelJourney(trnLookupHelper, httpContext, linkGenerator, userHelper); } public override async Task CreateUser(string currentStep) { + await UserHelper.CheckCanAccessService(AuthenticationState); + Debug.Assert(AuthenticationState.Blocked.HasValue); + + if (AuthenticationState.Blocked == true) + { + var nextPageUrl = GetStepUrl(CoreSignInJourney.Steps.Blocked); + return new RedirectResult(nextPageUrl); + } + using var suppressUniqueIndexViolationScope = SentryErrors.Suppress(ex => ex.IsUniqueIndexViolation(User.TrnUniqueIndexName)); try { @@ -129,7 +142,7 @@ public override bool IsCompleted() public override string GetNextStepUrl(string currentStep) => currentStep switch { - ElevateTrnVerificationLevelJourney.Steps.Landing => ElevateTrnVerificationLevelJourney.GetStartStepUrl(LinkGenerator), + ElevateTrnVerificationLevelJourney.Steps.Landing => _elevateJourney.GetStartStepUrl(), _ => base.GetNextStepUrl(currentStep) }; @@ -139,7 +152,7 @@ public override string GetNextStepUrl(string currentStep) => // but the user's TrnVerificationLevel is Low (or null) we need to switch to the 'elevate' journey if (IsFinished() && AuthenticationState.RequiresTrnVerificationLevelElevation == true) { - return ElevateTrnVerificationLevelJourney.GetStartStepUrl(LinkGenerator); + return _elevateJourney.GetStartStepUrl(); } var shouldCheckAnswers = (AreAllQuestionsAnswered() || FoundATrn) && !AuthenticationState.ExistingAccountFound; @@ -209,7 +222,7 @@ public override string GetLastAccessibleStepUrl(string? requestedStep) => _ => base.GetLastAccessibleStepUrl(requestedStep) }; - public override Task OnEmailVerified(User? user, string currentStep) + public override async Task OnEmailVerified(User? user, string currentStep) { if (user is not null && user.UserType == Models.UserType.Default && user.TrnLookupStatus is null) { @@ -218,7 +231,19 @@ public override Task OnEmailVerified(User? user, string currentSt throw new NotImplementedException("Cannot lookup a TRN for an existing user."); } - return base.OnEmailVerified(user, currentStep); + var result = await base.OnEmailVerified(user, currentStep); + + if (user is not null) + { + await UserHelper.CheckCanAccessService(AuthenticationState); + + if (AuthenticationState.Blocked == true) + { + return new RedirectResult(GetStepUrl(CoreSignInJourney.Steps.Blocked)); + } + } + + return result; } protected override bool AreAllQuestionsAnswered() => diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/ElevateTrnVerificationLevelJourney.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/ElevateTrnVerificationLevelJourney.cs index 395a5d751..945714d67 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/ElevateTrnVerificationLevelJourney.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/ElevateTrnVerificationLevelJourney.cs @@ -16,8 +16,6 @@ public ElevateTrnVerificationLevelJourney( _trnLookupHelper = trnLookupHelper; } - public static string GetStartStepUrl(IdentityLinkGenerator linkGenerator) => linkGenerator.ElevateLanding(); - public async Task LookupTrn() { var trn = await _trnLookupHelper.LookupTrn(AuthenticationState); @@ -41,6 +39,7 @@ public async Task LookupTrn() CoreSignInJourneyWithTrnLookup.Steps.NiNumber => true, CoreSignInJourneyWithTrnLookup.Steps.Trn => AuthenticationState.HasNationalInsuranceNumber.HasValue, Steps.CheckAnswers => AuthenticationState.HasNationalInsuranceNumber.HasValue && AuthenticationState.StatedTrn is not null, + CoreSignInJourney.Steps.Blocked => AuthenticationState.Blocked == true, _ => false }; @@ -60,10 +59,12 @@ public async Task LookupTrn() _ => null }; - protected override string GetStartStep() => Steps.Landing; + protected override string GetStartStep() => + AuthenticationState.Blocked == true ? CoreSignInJourney.Steps.Blocked : Steps.Landing; protected override string GetStepUrl(string step) => step switch { + CoreSignInJourney.Steps.Blocked => LinkGenerator.Blocked(), Steps.Landing => LinkGenerator.ElevateLanding(), CoreSignInJourneyWithTrnLookup.Steps.NiNumber => LinkGenerator.RegisterNiNumber(), CoreSignInJourneyWithTrnLookup.Steps.Trn => LinkGenerator.RegisterTrn(), diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/SignInJourney.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/SignInJourney.cs index 736a76c46..445f21173 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/SignInJourney.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/SignInJourney.cs @@ -137,7 +137,7 @@ private async Task SignInExistingUser(User user) { if (user.Trn is not null) { - await UserHelper.EnsureDqtUserNameMatch(user, AuthenticationState); + await UserHelper.SyncStateFromDqtRecord(user, AuthenticationState); } await AuthenticationState.SignIn(HttpContext); } diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/TrnTokenSignInJourney.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/TrnTokenSignInJourney.cs index 5727fb107..08a31b89e 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/TrnTokenSignInJourney.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/TrnTokenSignInJourney.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using Microsoft.AspNetCore.Mvc; using TeacherIdentity.AuthServer.Models; @@ -18,6 +19,16 @@ public TrnTokenSignInJourney( public override async Task CreateUser(string currentStep) { + await UserHelper.CheckCanAccessService(AuthenticationState); + Debug.Assert(AuthenticationState.Blocked.HasValue); + + if (AuthenticationState.Blocked == true) + { + var nextPageUrl = GetNextStepUrl(currentStep); + Debug.Assert(nextPageUrl == GetStepUrl(CoreSignInJourney.Steps.Blocked)); + return new RedirectResult(nextPageUrl); + } + var user = await UserHelper.CreateUserWithTrnToken(AuthenticationState); AuthenticationState.OnUserRegistered(user); diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/UserHelper.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/UserHelper.cs index 95f8ada58..b3fa6d5e6 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/UserHelper.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Journeys/UserHelper.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Text; using System.Text.Json; using Azure.Storage.Blobs; @@ -261,17 +262,43 @@ public async Task CreateTrnResolutionZendeskTicket( await _dbContext.SaveChangesAsync(); } - public async Task EnsureDqtUserNameMatch(User user, AuthenticationState authenticationState) + public async Task SyncStateFromDqtRecord(User user, AuthenticationState authenticationState) { - var dqtUser = await _dqtApiClient.GetTeacherByTrn(user.Trn!); + Debug.Assert(user.Trn is not null); + var dqtUser = await _dqtApiClient.GetTeacherByTrn(user.Trn!) ?? + throw new Exception($"Failed to lookup teacher by TRN: '{user.Trn}'."); - if (await CheckDqtTeacherRecordIsValid(dqtUser) && + if (await CheckDqtTeacherRecordHasValidNames(dqtUser) && NameHelper.GetFullName(user.FirstName, user.MiddleName, user.LastName) != NameHelper.GetFullName(dqtUser!.FirstName, dqtUser.MiddleName, dqtUser.LastName)) { - await AssignDqtUserName(user.UserId, dqtUser); + await SyncNameFromDqtRecord(user.UserId, dqtUser); authenticationState.OnNameSet(dqtUser.FirstName, dqtUser.MiddleName, dqtUser.LastName); } + + CheckCanAccessService(authenticationState, dqtUser); + } + + public async Task CheckCanAccessService(AuthenticationState authenticationState) + { + if (!(authenticationState is { Trn: not null, OAuthState: { TrnRequirementType: TrnRequirementType.Required, BlockProhibitedTeachers: true } })) + { + authenticationState.Blocked = false; + return; + } + + var dqtUser = await _dqtApiClient.GetTeacherByTrn(authenticationState.Trn!) ?? + throw new Exception($"Failed to lookup teacher by TRN: '{authenticationState.Trn}'."); + + CheckCanAccessService(authenticationState, dqtUser); + } + + private void CheckCanAccessService(AuthenticationState authenticationState, TeacherInfo teacherInfo) + { + authenticationState.Blocked = + authenticationState is { Trn: not null, OAuthState: { TrnRequirementType: TrnRequirementType.Required, BlockProhibitedTeachers: true } } && + teacherInfo.Alerts.Any(a => a.AlertType == AlertType.Prohibition) && + !teacherInfo.AllowIdSignInWithProhibitions; } public async Task ElevateTrnVerificationLevel(Guid userId, string trn, string nationalInsuranceNumber) @@ -323,7 +350,7 @@ public async Task SetNationalInsuranceNumber(Guid userId, string? nationalInsura } } - private async Task AssignDqtUserName(Guid userId, TeacherInfo dqtUser) + private async Task SyncNameFromDqtRecord(Guid userId, TeacherInfo dqtUser) { var existingUser = await _dbContext.Users.SingleAsync(u => u.UserId == userId); @@ -348,13 +375,8 @@ private async Task AssignDqtUserName(Guid userId, TeacherInfo dqtUser) await _dbContext.SaveChangesAsync(); } - private async Task CheckDqtTeacherRecordIsValid(TeacherInfo? teacher) + private async Task CheckDqtTeacherRecordHasValidNames(TeacherInfo teacher) { - if (teacher is null) - { - return false; - } - if (string.IsNullOrEmpty(teacher.FirstName) || string.IsNullOrEmpty(teacher.LastName)) { try diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Blocked.cshtml b/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Blocked.cshtml new file mode 100644 index 000000000..d1f2f5aaf --- /dev/null +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Blocked.cshtml @@ -0,0 +1,18 @@ +@page "/sign-in/blocked" +@inject IConfiguration Configuration +@model TeacherIdentity.AuthServer.Pages.SignIn.BlockedModel +@{ + ViewBag.Title = $"You cannot {Model.ClientName}"; +} + +
+
+
+

@ViewBag.Title

+ +

+ Email @(Configuration["SupportEmail"]) to find out how to @Model.ClientName. +

+
+
+
diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Blocked.cshtml.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Blocked.cshtml.cs new file mode 100644 index 000000000..ac9a9bd55 --- /dev/null +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Blocked.cshtml.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; +using TeacherIdentity.AuthServer.Journeys; +using TeacherIdentity.AuthServer.Oidc; +using TeacherIdentity.AuthServer.State; + +namespace TeacherIdentity.AuthServer.Pages.SignIn; + +[CheckCanAccessStep(CoreSignInJourney.Steps.Blocked)] +[AllowCompletedAuthenticationJourney] +public class BlockedModel : PageModel +{ + private readonly ICurrentClientProvider _currentClientProvider; + + public BlockedModel(ICurrentClientProvider currentClientProvider) + { + _currentClientProvider = currentClientProvider; + } + + public string? ClientName { get; set; } + + public async Task OnGet() + { + var client = await _currentClientProvider.GetCurrentClient(); + ClientName = client!.DisplayName; + } +} diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Complete.cshtml b/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Complete.cshtml index 7f07ebdc8..4dccef1e2 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Complete.cshtml +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Complete.cshtml @@ -5,7 +5,7 @@ @{ ViewBag.Title = Model.TrnVerificationElevationSuccessful == true ? "The information you gave has been verified" : Model.TrnVerificationElevationSuccessful == false ? "The information you gave could not be verified" : - !Model.CanAccessService ? $"You cannot {Model.ClientDisplayName} online" : + !Model.CanAccessService ? "You cannot access this service yet" : Model.FirstTimeSignInForEmail ? "You’ve created a DfE Identity account" : "You’ve signed in to your DfE Identity account"; @@ -50,19 +50,7 @@ } else if (Model.TrnRequirementType == TrnRequirementType.Required) { - if (Model.TrnLookupStatus == TrnLookupStatus.Found && !Model.CanAccessService) - { - if (Model.FirstTimeSignInForEmail) - { -

You’ve created a DfE Identity account but cannot use it for this service.

- } - -

- Email @(Configuration["SupportEmail"]) - to find out how to @Model.ClientDisplayName. -

- } - else if (Model.TrnLookupStatus == TrnLookupStatus.Found) + if (Model.TrnLookupStatus == TrnLookupStatus.Found) { if (Model.FirstTimeSignInForEmail) { diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Complete.cshtml.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Complete.cshtml.cs index 73edcd037..9aa3de85e 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Complete.cshtml.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Pages/SignIn/Complete.cshtml.cs @@ -5,7 +5,6 @@ using TeacherIdentity.AuthServer.Journeys; using TeacherIdentity.AuthServer.Models; using TeacherIdentity.AuthServer.Oidc; -using TeacherIdentity.AuthServer.Services.DqtApi; using TeacherIdentity.AuthServer.State; namespace TeacherIdentity.AuthServer.Pages.SignIn; @@ -16,18 +15,15 @@ public class CompleteModel : PageModel private readonly SignInJourney _journey; private readonly TeacherIdentityApplicationManager _applicationManager; private readonly TeacherIdentityServerDbContext _dbContext; - private readonly IDqtApiClient _dqtApiClient; public CompleteModel( SignInJourney journey, TeacherIdentityApplicationManager applicationManager, - TeacherIdentityServerDbContext dbContext, - IDqtApiClient dqtApiClient) + TeacherIdentityServerDbContext dbContext) { _journey = journey; _applicationManager = applicationManager; _dbContext = dbContext; - _dqtApiClient = dqtApiClient; } public string? Email { get; set; } @@ -64,6 +60,7 @@ public async Task OnGet() RedirectUri = authenticationState.OAuthState.RedirectUri; ResponseMode = authenticationState.OAuthState.AuthorizationResponseMode!; ResponseParameters = authenticationState.OAuthState.AuthorizationResponseParameters!; + CanAccessService = authenticationState.OAuthState.TrnRequirementType != Models.TrnRequirementType.Required || authenticationState.Trn is not null; Email = authenticationState.EmailAddress; FirstTimeSignInForEmail = authenticationState.FirstTimeSignInForEmail!.Value; Trn = authenticationState.Trn; @@ -76,29 +73,9 @@ public async Task OnGet() TrnLookupSupportTicketCreated = user?.TrnLookupSupportTicketCreated == true; var clientId = authenticationState.OAuthState.ClientId; - var client = await _applicationManager.FindByClientIdAsync(clientId!); + var client = await _applicationManager.FindByClientIdAsync(clientId); ClientDisplayName = await _applicationManager.GetDisplayNameAsync(client!); - CanAccessService = authenticationState.OAuthState.TrnRequirementType switch - { - Models.TrnRequirementType.Required => authenticationState.Trn is not null, - _ => true - }; - - if (authenticationState.OAuthState.TrnRequirementType == Models.TrnRequirementType.Required && - authenticationState.OAuthState.BlockProhibitedTeachers == true && - authenticationState.Trn is string trn && - CanAccessService) - { - var dqtUser = await _dqtApiClient.GetTeacherByTrn(trn) ?? - throw new Exception($"Failed to retreive teacher with TRN {trn} from DQT."); - - if (dqtUser.Alerts.Any(a => a.AlertType == AlertType.Prohibition)) - { - CanAccessService = false; - } - } - HttpContext.Features.Get()?.Event.AddTag(FirstTimeSignInForEmail ? "FirstTimeUser" : "ReturningUser"); } diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Services/DqtApi/DqtApiClient.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Services/DqtApi/DqtApiClient.cs index f7867bac1..0638274c8 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Services/DqtApi/DqtApiClient.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Services/DqtApi/DqtApiClient.cs @@ -44,7 +44,7 @@ public async Task FindTeachers(FindTeachersRequest request public async Task GetTeacherByTrn(string trn, CancellationToken cancellationToken) { - var response = await _client.GetAsync($"/v3/teachers/{trn}?include=PendingDetailChanges,Alerts", cancellationToken); + var response = await _client.GetAsync($"/v3/teachers/{trn}?include=PendingDetailChanges,Alerts,_AllowIdSignInWithProhibitions", cancellationToken); if ((int)response.StatusCode == StatusCodes.Status404NotFound) { diff --git a/dotnet-authserver/src/TeacherIdentity.AuthServer/Services/DqtApi/TeacherInfo.cs b/dotnet-authserver/src/TeacherIdentity.AuthServer/Services/DqtApi/TeacherInfo.cs index 65a38051a..5373c25ef 100644 --- a/dotnet-authserver/src/TeacherIdentity.AuthServer/Services/DqtApi/TeacherInfo.cs +++ b/dotnet-authserver/src/TeacherIdentity.AuthServer/Services/DqtApi/TeacherInfo.cs @@ -13,6 +13,7 @@ public record TeacherInfo public required bool PendingDateOfBirthChange { get; init; } public required string? Email { get; init; } public required IReadOnlyCollection Alerts { get; init; } + public required bool AllowIdSignInWithProhibitions { get; set; } } public record AlertInfo diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Account.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Account.cs index 344dc4f04..5806ef343 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Account.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Account.cs @@ -69,7 +69,8 @@ public async Task ChangeOfficialDateOfBirth() PendingNameChange = false, Trn = user.Trn!, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }; ConfigureDqtApiGetTeacherResponse(user.Trn!, dqtTeacherInfo); @@ -159,7 +160,8 @@ public async Task ChangeOfficialName() PendingNameChange = false, Trn = user.Trn!, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }; ConfigureDqtApiGetTeacherResponse(user.Trn!, dqtTeacherInfo); diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Elevate.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Elevate.cs index e8bab3a3f..730c8c7bb 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Elevate.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Elevate.cs @@ -22,6 +22,21 @@ public async Task UserSignsInWithLowVerificationLevel_IsRedirectedToElevateJourn var user = await _hostFixture.TestData.CreateUser(hasTrn: true, trnVerificationLevel: TrnVerificationLevel.Low); var nino = Faker.Identification.UkNationalInsuranceNumber(); + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new TeacherInfo() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = nino, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + await using var context = await _hostFixture.CreateBrowserContext(); var page = await context.NewPageAsync(); @@ -63,7 +78,8 @@ public async Task UserSignsInWithLowVerificationLevel_IsRedirectedToElevateJourn PendingDateOfBirthChange = false, PendingNameChange = false, Trn = user.Trn!, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); await page.SubmitElevateCheckAnswersPage(); @@ -84,6 +100,21 @@ public async Task UserSignsInWithLowVerificationLevel_IsRedirectedToElevateJourn var user = await _hostFixture.TestData.CreateUser(hasTrn: true, trnVerificationLevel: TrnVerificationLevel.Low); var nino = Faker.Identification.UkNationalInsuranceNumber(); + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = nino, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + await using var context = await _hostFixture.CreateBrowserContext(); var page = await context.NewPageAsync(); @@ -124,6 +155,21 @@ public async Task AlreadySignedInUserWithLowVerificationLevel_IsRedirectedToElev var user = await _hostFixture.TestData.CreateUser(hasTrn: true, trnVerificationLevel: TrnVerificationLevel.Low); var nino = Faker.Identification.UkNationalInsuranceNumber(); + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new TeacherInfo() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = nino, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + await using var context = await _hostFixture.CreateBrowserContext(); var page = await context.NewPageAsync(); @@ -173,7 +219,8 @@ public async Task AlreadySignedInUserWithLowVerificationLevel_IsRedirectedToElev PendingDateOfBirthChange = false, PendingNameChange = false, Trn = user.Trn!, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); await page.SubmitElevateCheckAnswersPage(); @@ -184,6 +231,90 @@ public async Task AlreadySignedInUserWithLowVerificationLevel_IsRedirectedToElev await page.AssertSignedInOnTestClient(user, expectTrn: true, expectNiNumber: true); } + [Fact] + public async Task UserSignsInWithLowVerificationLevelAndHasProhibitions_IsShownBlockedPageForServiceThatBlocksProhitiedTeachers() + { + var user = await _hostFixture.TestData.CreateUser(hasTrn: true, trnVerificationLevel: TrnVerificationLevel.Low); + var nino = Faker.Identification.UkNationalInsuranceNumber(); + + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new TeacherInfo() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = nino, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = new[] + { + new AlertInfo() { AlertType = AlertType.Prohibition, DqtSanctionCode = "G1" } + }, + AllowIdSignInWithProhibitions = false + }); + + await using var context = await _hostFixture.CreateBrowserContext(); + var page = await context.NewPageAsync(); + + await page.StartOAuthJourney(additionalScope: CustomScopes.DqtRead, trnMatchPolicy: TrnMatchPolicy.Strict, blockProhibitedTeachers: true); + + await page.SignInFromLandingPage(); + + await page.SubmitEmailPage(user.EmailAddress); + + await page.SubmitEmailConfirmationPage(); + + await page.AssertOnBlockedPage(); + } + + [Fact] + public async Task AlreadySignedInUserWithLowVerificationLevelHasProhibitions_IsShownBlockedPageForServiceThatBlocksProhitiedTeachers() + { + var user = await _hostFixture.TestData.CreateUser(hasTrn: true, trnVerificationLevel: TrnVerificationLevel.Low); + var nino = Faker.Identification.UkNationalInsuranceNumber(); + + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new TeacherInfo() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = nino, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = new[] + { + new AlertInfo() { AlertType = AlertType.Prohibition, DqtSanctionCode = "G1" } + }, + AllowIdSignInWithProhibitions = false + }); + + await using var context = await _hostFixture.CreateBrowserContext(); + var page = await context.NewPageAsync(); + + await page.StartOAuthJourney(additionalScope: CustomScopes.DqtRead, trnMatchPolicy: TrnMatchPolicy.Default); + + await page.SignInFromLandingPage(); + + await page.SubmitEmailPage(user.EmailAddress); + + await page.SubmitEmailConfirmationPage(); + + await page.SubmitCompletePageForExistingUser(); + + await page.AssertSignedInOnTestClient(user, expectNiNumber: false); + + await context.ClearCookiesForTestClient(); + + await page.StartOAuthJourney(additionalScope: CustomScopes.DqtRead, trnMatchPolicy: TrnMatchPolicy.Strict, blockProhibitedTeachers: true); + + await page.AssertOnBlockedPage(); + } + private void ConfigureDqtApiFindTeachersRequest(FindTeachersResponseResult? result) { var results = result is not null ? new[] { result } : Array.Empty(); diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/PageExtensions.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/PageExtensions.cs index 9fe67d6f8..7daac9ae1 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/PageExtensions.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/PageExtensions.cs @@ -39,7 +39,8 @@ public static async Task StartOAuthJourney( string? additionalScope = null, TrnRequirementType? trnRequirement = null, string? trnToken = null, - TrnMatchPolicy trnMatchPolicy = TrnMatchPolicy.Default) + TrnMatchPolicy trnMatchPolicy = TrnMatchPolicy.Default, + bool? blockProhibitedTeachers = null) { var allScopes = new List() { @@ -68,6 +69,11 @@ public static async Task StartOAuthJourney( url.SetQueryParam("trn_match_policy", trnMatchPolicy.ToString()); + if (blockProhibitedTeachers is not null) + { + url.SetQueryParam("block_prohibited_teachers", blockProhibitedTeachers.ToString()); + } + await page.GotoAsync(url); } @@ -154,6 +160,11 @@ public static async Task AssertOnAccountPage(this IPage page) await page.WaitForUrlPathAsync("/account"); } + public static async Task AssertOnBlockedPage(this IPage page) + { + await page.WaitForUrlPathAsync("/sign-in/blocked"); + } + public static async Task SignOutFromAccountPageWithoutClientContext(this IPage page) { await page.AssertOnAccountPage(); diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Register.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Register.cs index 8eae18ee5..497741917 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Register.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/Register.cs @@ -461,6 +461,21 @@ public async Task User_WithEmailAlreadyExists_SignsInExistingUser(string? additi { var existingUser = await _hostFixture.TestData.CreateUser(hasTrn: true); + ConfigureDqtApiGetTeacherByTrnRequest(existingUser.Trn!, new() + { + FirstName = existingUser.FirstName, + MiddleName = existingUser.MiddleName ?? string.Empty, + LastName = existingUser.LastName, + DateOfBirth = existingUser.DateOfBirth, + Email = existingUser.EmailAddress, + NationalInsuranceNumber = existingUser.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = existingUser.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + await using var context = await _hostFixture.CreateBrowserContext(); var page = await context.NewPageAsync(); @@ -491,6 +506,21 @@ public async Task User_WithMobileAlreadyExists_SignsInExistingUser(string? addit var email = Faker.Internet.Email(); var existingUser = await _hostFixture.TestData.CreateUser(hasTrn: true, hasMobileNumber: true); + ConfigureDqtApiGetTeacherByTrnRequest(existingUser.Trn!, new() + { + FirstName = existingUser.FirstName, + MiddleName = existingUser.MiddleName ?? string.Empty, + LastName = existingUser.LastName, + DateOfBirth = existingUser.DateOfBirth, + Email = existingUser.EmailAddress, + NationalInsuranceNumber = existingUser.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = existingUser.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + await using var context = await _hostFixture.CreateBrowserContext(); var page = await context.NewPageAsync(); @@ -529,6 +559,21 @@ public async Task User_WithMatchingNameAndDob_SignsInExistingUserFromEmail(strin var existingUser = await _hostFixture.TestData.CreateUser(hasTrn: true); + ConfigureDqtApiGetTeacherByTrnRequest(existingUser.Trn!, new() + { + FirstName = existingUser.FirstName, + MiddleName = existingUser.MiddleName ?? string.Empty, + LastName = existingUser.LastName, + DateOfBirth = existingUser.DateOfBirth, + Email = existingUser.EmailAddress, + NationalInsuranceNumber = existingUser.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = existingUser.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + await using var context = await _hostFixture.CreateBrowserContext(); var page = await context.NewPageAsync(); @@ -575,6 +620,21 @@ public async Task User_WithMatchingNameAndDob_SignsInExistingUserFromMobilePhone var existingUser = await _hostFixture.TestData.CreateUser(hasTrn: true); + ConfigureDqtApiGetTeacherByTrnRequest(existingUser.Trn!, new() + { + FirstName = existingUser.FirstName, + MiddleName = existingUser.MiddleName ?? string.Empty, + LastName = existingUser.LastName, + DateOfBirth = existingUser.DateOfBirth, + Email = existingUser.EmailAddress, + NationalInsuranceNumber = existingUser.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = existingUser.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + await using var context = await _hostFixture.CreateBrowserContext(); var page = await context.NewPageAsync(); @@ -689,6 +749,70 @@ public async Task NewUser_WithInstitutionEmail_CanRegister(bool useInstitutionEm }); } + [Fact] + public async Task UserMatchesToDqtRecord_IsShownBlockedPageForServiceThatBlocksProhitiedTeachers() + { + var email = Faker.Internet.Email(); + var mobileNumber = _hostFixture.TestData.GenerateUniqueMobileNumber(); + var firstName = Faker.Name.First(); + var lastName = Faker.Name.Last(); + var dateOfBirth = DateOnly.FromDateTime(Faker.Identification.DateOfBirth()); + var trn = _hostFixture.TestData.GenerateTrn(); + + ConfigureDqtApiFindTeachersRequest(result: new() + { + DateOfBirth = dateOfBirth, + FirstName = firstName, + MiddleName = null, + LastName = lastName, + EmailAddresses = new[] { email }, + HasActiveSanctions = false, + NationalInsuranceNumber = null, + Trn = trn, + Uid = Guid.NewGuid().ToString() + }); + + ConfigureDqtApiGetTeacherByTrnRequest(trn, new() + { + DateOfBirth = dateOfBirth, + FirstName = firstName, + MiddleName = "", + LastName = lastName, + Email = email, + NationalInsuranceNumber = null, + Trn = trn, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Alerts = new[] { new AlertInfo() { AlertType = AlertType.Prohibition, DqtSanctionCode = "G1" } }, + AllowIdSignInWithProhibitions = false + }); + + await using var context = await _hostFixture.CreateBrowserContext(); + var page = await context.NewPageAsync(); + + await page.StartOAuthJourney(CustomScopes.DqtRead, TrnRequirementType.Required, blockProhibitedTeachers: true); + + await page.RegisterFromLandingPage(); + + await page.SubmitRegisterEmailPage(email); + + await page.SubmitRegisterEmailConfirmationPage(); + + await page.SubmitRegisterPhonePage(mobileNumber); + + await page.SubmitRegisterPhoneConfirmationPage(); + + await page.SubmitRegisterNamePage(firstName, lastName); + + await page.SubmitRegisterPreferredNamePage(); + + await page.SubmitDateOfBirthPage(dateOfBirth); + + await page.SubmitCheckAnswersPage(); + + await page.AssertOnBlockedPage(); + } + private void ConfigureDqtApiFindTeachersRequest(FindTeachersResponseResult? result) { var results = result is not null ? new[] { result } : Array.Empty(); @@ -700,4 +824,11 @@ private void ConfigureDqtApiFindTeachersRequest(FindTeachersResponseResult? resu Results = results }); } + + private void ConfigureDqtApiGetTeacherByTrnRequest(string trn, TeacherInfo? result) + { + _hostFixture.DqtApiClient + .Setup(mock => mock.GetTeacherByTrn(trn, It.IsAny())) + .ReturnsAsync(result); + } } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/SignIn.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/SignIn.cs index b8da43d8a..f44098ba7 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/SignIn.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/SignIn.cs @@ -1,4 +1,7 @@ +using Moq; using TeacherIdentity.AuthServer.Models; +using TeacherIdentity.AuthServer.Oidc; +using TeacherIdentity.AuthServer.Services.DqtApi; namespace TeacherIdentity.AuthServer.EndToEndTests; @@ -68,4 +71,48 @@ public async Task FirstRequestToProtectedAreaOfSiteForUserAlreadySignedInViaOAut _hostFixture.EventObserver.AssertEventsSaved( e => _hostFixture.AssertEventIsUserSignedIn(e, user.UserId, expectOAuthProperties: false)); } + + [Fact] + public async Task ExistingUserWithTrn_IsShownBlockedPageForServiceThatBlocksProhitiedTeachers() + { + var user = await _hostFixture.TestData.CreateUser(hasTrn: true, trnVerificationLevel: TrnVerificationLevel.Medium); + + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new TeacherInfo() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = user.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = new[] + { + new AlertInfo() { AlertType = AlertType.Prohibition, DqtSanctionCode = "G1" } + }, + AllowIdSignInWithProhibitions = false + }); + + await using var context = await _hostFixture.CreateBrowserContext(); + var page = await context.NewPageAsync(); + + await page.StartOAuthJourney(additionalScope: CustomScopes.DqtRead, trnRequirement: TrnRequirementType.Required, trnMatchPolicy: TrnMatchPolicy.Strict, blockProhibitedTeachers: true); + + await page.SignInFromLandingPage(); + + await page.SubmitEmailPage(user.EmailAddress); + + await page.SubmitEmailConfirmationPage(); + + await page.AssertOnBlockedPage(); + } + + private void ConfigureDqtApiGetTeacherByTrnRequest(string trn, TeacherInfo? result) + { + _hostFixture.DqtApiClient + .Setup(mock => mock.GetTeacherByTrn(trn, It.IsAny())) + .ReturnsAsync(result); + } } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/TrnTokenSignInJourney.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/TrnTokenSignInJourney.cs index 17af47de1..e81d6d7e1 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/TrnTokenSignInJourney.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.EndToEndTests/TrnTokenSignInJourney.cs @@ -43,7 +43,8 @@ public async Task NewTeacherUser_WithTrnToken_CreatesUserAndCompletesFlow() PendingDateOfBirthChange = false, PendingNameChange = false, Email = trnToken.Email, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); await using var context = await _hostFixture.CreateBrowserContext(); @@ -94,7 +95,8 @@ public async Task NewTeacherUser_WithTrnTokenForDqtRecordWithMissingDateOfBirth_ PendingDateOfBirthChange = false, PendingNameChange = false, Email = trnToken.Email, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); await using var context = await _hostFixture.CreateBrowserContext(); @@ -146,7 +148,8 @@ public async Task NewTeacherUser_WithTrnTokenChangesEmail_CreatesUserAndComplete PendingDateOfBirthChange = false, PendingNameChange = false, Email = trnToken.Email, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); await using var context = await _hostFixture.CreateBrowserContext(); @@ -185,6 +188,21 @@ public async Task SignedInUserWithTrn_ValidTrnTokenMatchingEmailAndTrn_Invalidat var user = await _hostFixture.TestData.CreateUser(userType: UserType.Default, hasTrn: true); + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = user.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + await SignInUser(user, page, context); var trnToken = await CreateValidTrnToken(trn: user.Trn, email: user.EmailAddress, firstName: user.FirstName, middleName: user.MiddleName, lastName: user.LastName); @@ -240,6 +258,21 @@ public async Task SignedInUserWithTrn_ValidTrnTokenMatchingEmailNotMatchingTrn_I var user = await _hostFixture.TestData.CreateUser(userType: UserType.Default, hasTrn: true); var differentTrn = _hostFixture.TestData.GenerateTrn(); + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = user.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + await SignInUser(user, page, context); var trnToken = await CreateValidTrnToken(trn: differentTrn, email: user.EmailAddress); @@ -385,6 +418,21 @@ public async Task ExistingUserWithTrn_ValidTrnTokenNotMatchingTrn_StartsCoreSign var user = await _hostFixture.TestData.CreateUser(userType: UserType.Default, hasTrn: true); var differentTrn = _hostFixture.TestData.GenerateTrn(); + ConfigureDqtApiGetTeacherByTrnRequest(differentTrn, new() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = user.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + var trnToken = await CreateValidTrnToken(trn: differentTrn, email: user.EmailAddress); var email = Faker.Internet.Email(); @@ -501,6 +549,21 @@ public async Task ExistingUserSignsIn_ValidTrnTokenNotMatchingTrn_SignInAndIgnor var user = await _hostFixture.TestData.CreateUser(userType: UserType.Default, hasTrn: true); + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = user.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + var differentTrn = _hostFixture.TestData.GenerateTrn(); var differentEmail = _hostFixture.TestData.GenerateUniqueEmail(); @@ -594,6 +657,21 @@ public async Task NewUserSignsIn_ValidTrnTokenMatchingExistingAccountNameAndDoBW var user = await _hostFixture.TestData.CreateUser(userType: UserType.Default, hasTrn: true); + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = user.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + var differentTrn = _hostFixture.TestData.GenerateTrn(); var trnToken = await CreateValidTrnToken(trn: differentTrn, firstName: user.FirstName, lastName: user.LastName, dateOfBirth: user.DateOfBirth); @@ -622,6 +700,21 @@ public async Task NewUserSignsIn_ValidTrnTokenMatchingExistingAccountNameAndDoBW var user = await _hostFixture.TestData.CreateUser(userType: UserType.Default, hasTrn: true); + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = user.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + var differentTrn = _hostFixture.TestData.GenerateTrn(); var trnToken = await CreateValidTrnToken(trn: differentTrn, firstName: user.FirstName, lastName: user.LastName, dateOfBirth: user.DateOfBirth); @@ -724,6 +817,21 @@ public async Task NewUserRegisters_ValidTrnTokenPhoneVerificationMatchesExisting var user = await _hostFixture.TestData.CreateUser(userType: UserType.Default, hasTrn: true); + ConfigureDqtApiGetTeacherByTrnRequest(user.Trn!, new() + { + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + DateOfBirth = user.DateOfBirth, + Email = user.EmailAddress, + NationalInsuranceNumber = user.NationalInsuranceNumber, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Trn = user.Trn!, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + var differentTrn = _hostFixture.TestData.GenerateTrn(); var trnToken = await CreateValidTrnToken(differentTrn); @@ -773,7 +881,8 @@ public async Task NewTeacherUser_WithTrnTokenChangesToInstitutionEmail_CreatesUs PendingDateOfBirthChange = false, PendingNameChange = false, Email = trnToken.Email, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); var invalidEmailSuffix = "invalid.sch.uk"; @@ -934,7 +1043,8 @@ private async Task CreateValidTrnToken( PendingDateOfBirthChange = false, PendingNameChange = false, Email = email, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); return await _hostFixture.TestData.GenerateTrnToken(trn, email: email); @@ -951,4 +1061,11 @@ private void ConfigureDqtApiFindTeachersRequest(FindTeachersResponseResult? resu Results = results }); } + + private void ConfigureDqtApiGetTeacherByTrnRequest(string trn, TeacherInfo? result) + { + _hostFixture.DqtApiClient + .Setup(mock => mock.GetTeacherByTrn(trn, It.IsAny())) + .ReturnsAsync(result); + } } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/DateOfBirth/DateOfBirthTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/DateOfBirth/DateOfBirthTests.cs index 1f1c92949..2e1cf70d1 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/DateOfBirth/DateOfBirthTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/DateOfBirth/DateOfBirthTests.cs @@ -181,7 +181,7 @@ public async Task Get_ValidRequestWithoutNamesInQueryParam_PopulatesFieldsFromDa private void MockDqtApiResponse(User user, bool hasDobConflict, bool hasPendingDobChange) { HostFixture.DqtApiClient.Setup(mock => mock.GetTeacherByTrn(user.Trn!, It.IsAny())) - .ReturnsAsync(new AuthServer.Services.DqtApi.TeacherInfo() + .ReturnsAsync(new TeacherInfo() { DateOfBirth = hasDobConflict ? user.DateOfBirth!.Value.AddDays(1) : user.DateOfBirth!.Value, FirstName = user.FirstName, @@ -192,7 +192,8 @@ private void MockDqtApiResponse(User user, bool hasDobConflict, bool hasPendingD PendingNameChange = false, PendingDateOfBirthChange = hasPendingDobChange, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/IndexTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/IndexTests.cs index be2f63cb9..4769409a3 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/IndexTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/IndexTests.cs @@ -134,7 +134,8 @@ public async Task Get_ValidRequestForUserWithTrn_ShowsOfficialNames(bool hasPref PendingNameChange = false, PendingDateOfBirthChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); var request = new HttpRequestMessage(HttpMethod.Get, "/account"); @@ -188,7 +189,8 @@ public async Task Get_ValidRequestForUser_ShowsCorrectDobSummaryRowElements( PendingNameChange = false, PendingDateOfBirthChange = hasPendingReview, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); var request = new HttpRequestMessage(HttpMethod.Get, "/account"); @@ -221,7 +223,8 @@ public async Task Get_ValidRequestForUserWithPendingNameChange_DoesShowPendingTa PendingNameChange = true, PendingDateOfBirthChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); var request = new HttpRequestMessage(HttpMethod.Get, "/account"); diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/ConfirmTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/ConfirmTests.cs index 21d49b6a0..1d6923c12 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/ConfirmTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/ConfirmTests.cs @@ -120,7 +120,8 @@ private void MockDqtApiResponse(User user, bool hasDobConflict, bool hasPendingD PendingDateOfBirthChange = hasPendingDateOfBirthChange, PendingNameChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/DetailsTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/DetailsTests.cs index df9ed46a7..eb2ce962f 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/DetailsTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/DetailsTests.cs @@ -182,7 +182,8 @@ private void MockDqtApiResponse(User user, bool hasDobConflict, bool hasPendingD PendingDateOfBirthChange = hasPendingDateOfBirthChange, PendingNameChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/EvidenceTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/EvidenceTests.cs index 80d47a8ee..5f61186f3 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/EvidenceTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/EvidenceTests.cs @@ -181,7 +181,8 @@ private void MockDqtApiResponse(User user, bool hasDobConflict, bool hasPendingD PendingDateOfBirthChange = hasPendingDateOfBirthChange, PendingNameChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/OfficialDateOfBirthTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/OfficialDateOfBirthTests.cs index cd0337809..e561092db 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/OfficialDateOfBirthTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialDateOfBirth/OfficialDateOfBirthTests.cs @@ -63,7 +63,8 @@ private void MockDqtApiResponse(User user, bool hasDobConflict, bool hasPendingD PendingDateOfBirthChange = hasPendingDateOfBirthChange, PendingNameChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/ConfirmTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/ConfirmTests.cs index 96fc96227..2879abc76 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/ConfirmTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/ConfirmTests.cs @@ -186,7 +186,8 @@ private void MockDqtApiResponse(User user, bool hasPendingNameChange) PendingDateOfBirthChange = false, PendingNameChange = hasPendingNameChange, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/DetailsTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/DetailsTests.cs index 21818b140..4c8e56c38 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/DetailsTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/DetailsTests.cs @@ -205,7 +205,8 @@ private void MockDqtApiResponse(User user, bool hasPendingNameChange, string mid PendingDateOfBirthChange = false, PendingNameChange = hasPendingNameChange, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/EvidenceTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/EvidenceTests.cs index 3a57f793c..adcbd7de7 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/EvidenceTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/EvidenceTests.cs @@ -228,7 +228,8 @@ private void MockDqtApiResponse(User user, bool hasPendingNameChange) PendingDateOfBirthChange = false, PendingNameChange = hasPendingNameChange, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/OfficialNameTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/OfficialNameTests.cs index 1072e4b91..a5db87e06 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/OfficialNameTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Account/OfficialName/OfficialNameTests.cs @@ -64,7 +64,8 @@ private void MockDqtApiResponse(User user, bool hasPendingNameChange) PendingDateOfBirthChange = false, PendingNameChange = hasPendingNameChange, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/AssignTrn/ConfirmTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/AssignTrn/ConfirmTests.cs index dcedfa4d2..27bd0e443 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/AssignTrn/ConfirmTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/AssignTrn/ConfirmTests.cs @@ -554,7 +554,8 @@ private void ConfigureDqtApiMock( PendingNameChange = false, PendingDateOfBirthChange = false, Email = email ?? Faker.Internet.Email(), - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/AssignTrn/IndexTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/AssignTrn/IndexTests.cs index 069bd563e..4975acad7 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/AssignTrn/IndexTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/AssignTrn/IndexTests.cs @@ -300,7 +300,8 @@ private void ConfigureDqtApiMock( PendingNameChange = false, PendingDateOfBirthChange = false, Email = email ?? Faker.Internet.Email(), - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/UserTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/UserTests.cs index e1f9d3fe9..36a738244 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/UserTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Admin/UserTests.cs @@ -103,7 +103,8 @@ public async Task Get_ValidRequestForUserWithTrn_RendersExpectedContent() PendingNameChange = false, PendingDateOfBirthChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); var request = new HttpRequestMessage(HttpMethod.Get, $"/admin/users/{user.UserId}"); @@ -167,7 +168,8 @@ public async Task Get_ValidRequestForTrnVerificationLevel_RendersExpectedContent PendingNameChange = false, PendingDateOfBirthChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); // Act @@ -220,7 +222,8 @@ public async Task Get_ValidRequestForUserWithTrnAndProhibitions_RendersWarning() PendingNameChange = false, PendingDateOfBirthChange = false, Email = null, - Alerts = new[] { new AlertInfo() { AlertType = AlertType.Prohibition, DqtSanctionCode = "" } } + Alerts = new[] { new AlertInfo() { AlertType = AlertType.Prohibition, DqtSanctionCode = "" } }, + AllowIdSignInWithProhibitions = false }); var request = new HttpRequestMessage(HttpMethod.Get, $"/admin/users/{user.UserId}"); @@ -258,7 +261,8 @@ public async Task Get_ValidRequestForUserWithTrnAndNoProhibition_DoesNotRenderWa PendingNameChange = false, PendingDateOfBirthChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); var request = new HttpRequestMessage(HttpMethod.Get, $"/admin/users/{user.UserId}"); diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Oidc/AuthorizeTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Oidc/AuthorizeTests.cs index b64ec702c..c83b6107a 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Oidc/AuthorizeTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/Oidc/AuthorizeTests.cs @@ -525,7 +525,8 @@ private void MockDqtApiResponse(string? trn = null, string? firstName = null, st PendingDateOfBirthChange = false, PendingNameChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); } } diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/SignIn/CompleteTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/SignIn/CompleteTests.cs index 16ff00c1a..d6475ac40 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/SignIn/CompleteTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/SignIn/CompleteTests.cs @@ -234,7 +234,7 @@ public async Task Get_ValidRequest_RendersExpectedContent( false, new[] { - $"You cannot {TestClients.DefaultClient.DisplayName} online", + "You cannot access this service yet", "This could be because you do not have teaching qualifications, for example, qualified teacher status (QTS).", "You’ve created a DfE Identity account. When you’re eligible to use this service, you can sign in just using your email" } @@ -250,7 +250,7 @@ public async Task Get_ValidRequest_RendersExpectedContent( true, new[] { - $"You cannot {TestClients.DefaultClient.DisplayName} online", + "You cannot access this service yet", "We need to do some more checks to see if your details are in our records.", "We’ll email you when we’ve completed those checks - we may need some more information.", "You’ve created a DfE Identity account. To sign in to this service in the future, you’ll just need your email address" @@ -282,7 +282,7 @@ public async Task Get_ValidRequest_RendersExpectedContent( false, new[] { - $"You cannot {TestClients.DefaultClient.DisplayName} online", + "You cannot access this service yet", "This could be because you do not have teaching qualifications, for example, qualified teacher status (QTS).", "You’ve signed in to your DfE Identity account" } @@ -313,7 +313,7 @@ public async Task Get_ValidRequest_RendersExpectedContent( true, new[] { - $"You cannot {TestClients.DefaultClient.DisplayName} online", + "You cannot access this service yet", "We need to do some more checks to see if your details are in our records.", "We’ll email you when we’ve completed those checks - we may need some more information.", "You’ve signed in to your DfE Identity account" diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/SignIn/EmailConfirmationTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/SignIn/EmailConfirmationTests.cs index 0fd311bf6..b241011d8 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/SignIn/EmailConfirmationTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/EndpointTests/SignIn/EmailConfirmationTests.cs @@ -304,6 +304,22 @@ public async Task Post_ValidPinForKnownUserWithTrn_UpdatesAuthenticationStateSig // Arrange var user = await TestData.CreateUser(hasTrn: hasTrn); + HostFixture.DqtApiClient.Setup(mock => mock.GetTeacherByTrn(user.Trn!, It.IsAny())) + .ReturnsAsync(new TeacherInfo() + { + DateOfBirth = DateOnly.FromDateTime(Faker.Identification.DateOfBirth()), + Email = Faker.Internet.Email(), + FirstName = user.FirstName, + MiddleName = user.MiddleName ?? string.Empty, + LastName = user.LastName, + NationalInsuranceNumber = user.NationalInsuranceNumber, + Trn = user.Trn!, + PendingDateOfBirthChange = false, + PendingNameChange = false, + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false + }); + var userVerificationService = HostFixture.Services.GetRequiredService(); var pinResult = await userVerificationService.GenerateEmailPin(user.EmailAddress); @@ -486,7 +502,8 @@ public async Task Post_ValidPinForKnownUserWithTrnAndDifferentDqtName_UpdatesUse Trn = user.Trn!, PendingDateOfBirthChange = false, PendingNameChange = false, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); var authStateHelper = await CreateAuthenticationStateHelper(c => c.EmailSet(user.EmailAddress), additionalScopes: null); diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/Jobs/SyncNamesWithDqtJobTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/Jobs/SyncNamesWithDqtJobTests.cs index 00bcfed6b..30204ba1c 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/Jobs/SyncNamesWithDqtJobTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/Jobs/SyncNamesWithDqtJobTests.cs @@ -69,7 +69,8 @@ await _dbFixture.TestData.WithDbContext(async dbContext => PendingNameChange = false, PendingDateOfBirthChange = false, Email = Faker.Internet.Email(), - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }; var dqtApiClient = Mock.Of(); @@ -153,7 +154,8 @@ await _dbFixture.TestData.WithDbContext(async dbContext => PendingNameChange = false, PendingDateOfBirthChange = false, Email = Faker.Internet.Email(), - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }; var dqtApiClient = Mock.Of(); diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/Services/UserImport/UserImportProcessorTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/Services/UserImport/UserImportProcessorTests.cs index edf1d1f7e..0d1579b48 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/Services/UserImport/UserImportProcessorTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/Services/UserImport/UserImportProcessorTests.cs @@ -51,7 +51,8 @@ public static TheoryData GetProcessImportData() PendingNameChange = false, PendingDateOfBirthChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }; var getTeacherByTrnResultTest23 = new TeacherInfo() @@ -65,7 +66,8 @@ public static TheoryData GetProcessImportData() PendingNameChange = false, PendingDateOfBirthChange = false, Email = null, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }; return new TheoryData() diff --git a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/UserClaimHelperTests.cs b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/UserClaimHelperTests.cs index 85b88844e..bbfa67504 100644 --- a/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/UserClaimHelperTests.cs +++ b/dotnet-authserver/tests/TeacherIdentity.AuthServer.Tests/UserClaimHelperTests.cs @@ -192,7 +192,8 @@ public async Task GetPublicClaims_TrnMatchPolicyStrictAndUserTrnAssociationSourc PendingDateOfBirthChange = false, PendingNameChange = false, Trn = user.Trn!, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); using var dbContext = _dbFixture.GetDbContext(); @@ -234,7 +235,8 @@ public async Task GetPublicClaims_TrnMatchPolicyStrictAndUserTrnAssociationSourc PendingDateOfBirthChange = false, PendingNameChange = false, Trn = user.Trn!, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); using var dbContext = _dbFixture.GetDbContext(); @@ -276,7 +278,8 @@ public async Task GetPublicClaims_TrnMatchPolicyStrictAndUserTrnAssociationSourc PendingDateOfBirthChange = false, PendingNameChange = false, Trn = user.Trn!, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); using var dbContext = _dbFixture.GetDbContext(); @@ -320,7 +323,8 @@ public async Task GetPublicClaims_TrnMatchPolicyStrictAndUserTrnAssociationSourc PendingDateOfBirthChange = false, PendingNameChange = false, Trn = user.Trn!, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); using var dbContext = _dbFixture.GetDbContext(); @@ -364,7 +368,8 @@ public async Task GetPublicClaims_TrnMatchPolicyStrictAndUserTrnAssociationSourc PendingDateOfBirthChange = false, PendingNameChange = false, Trn = user.Trn!, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); using var dbContext = _dbFixture.GetDbContext(); @@ -408,7 +413,8 @@ public async Task GetPublicClaims_TrnMatchPolicyStrictAndUserTrnAssociationSourc PendingDateOfBirthChange = false, PendingNameChange = false, Trn = user.Trn!, - Alerts = Array.Empty() + Alerts = Array.Empty(), + AllowIdSignInWithProhibitions = false }); using var dbContext = _dbFixture.GetDbContext();