Skip to content

Commit

Permalink
Store the user from claim details during authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisJWoodcock committed Jun 29, 2022
1 parent c8de2e5 commit d9a4fff
Show file tree
Hide file tree
Showing 9 changed files with 342 additions and 210 deletions.
251 changes: 125 additions & 126 deletions src/SFA.DAS.EmployerFinance.AcceptanceTests/Steps/Hooks.cs
Original file line number Diff line number Diff line change
@@ -1,129 +1,128 @@
using System;
using System.Data.Common;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;
using BoDi;
using Moq;
using NServiceBus;
using SFA.DAS.EmployerFinance.AcceptanceTests.DependencyResolution;
using SFA.DAS.EmployerFinance.AcceptanceTests.Extensions;
using SFA.DAS.EmployerFinance.Configuration;
using SFA.DAS.EmployerFinance.Interfaces;
using SFA.DAS.NLog.Logger;
using SFA.DAS.NServiceBus.Configuration;
using SFA.DAS.NServiceBus.Configuration.NLog;
using SFA.DAS.NServiceBus.Configuration.StructureMap;
using SFA.DAS.NServiceBus.Configuration.NewtonsoftJsonSerializer;
using SFA.DAS.NServiceBus.SqlServer.Configuration;
using SFA.DAS.Testing.AzureStorageEmulator;
using SFA.DAS.UnitOfWork.NServiceBus;
using StructureMap;
using TechTalk.SpecFlow;
using BoDi;
using Moq;
using NServiceBus;
using SFA.DAS.EmployerFinance.AcceptanceTests.DependencyResolution;
using SFA.DAS.EmployerFinance.AcceptanceTests.Extensions;
using SFA.DAS.EmployerFinance.Configuration;
using SFA.DAS.EmployerFinance.Interfaces;
using SFA.DAS.NLog.Logger;
using SFA.DAS.NServiceBus.Configuration;
using SFA.DAS.NServiceBus.Configuration.NewtonsoftJsonSerializer;
using SFA.DAS.NServiceBus.Configuration.NLog;
using SFA.DAS.NServiceBus.Configuration.StructureMap;
using SFA.DAS.NServiceBus.SqlServer.Configuration;
using SFA.DAS.Testing.AzureStorageEmulator;
using SFA.DAS.UnitOfWork.NServiceBus.Configuration;
using StructureMap;
using System;
using System.Data.Common;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;
using TechTalk.SpecFlow;

namespace SFA.DAS.EmployerFinance.AcceptanceTests.Steps
{
[Binding]
public class Hooks
{
private static IContainer _container;
private static IEndpointInstance _endpoint;
private readonly IObjectContainer _objectContainer;

public Hooks(IObjectContainer objectContainer)
{
_objectContainer = objectContainer;
}

[BeforeTestRun]
public static async Task BeforeTestRun()
{
AzureStorageEmulatorManager.StartStorageEmulator();

_container = IoC.Initialize();

await StartNServiceBusEndpoint();
}

[BeforeScenario]
public void BeforeScenario()
{
_container.GetInstance<ILog>().Info("Starting Scenario.");

ResetCurrentDateTime(_container);
ResetFundsExpiryPeriod(_container);

_objectContainer.RegisterInstances(_container);
_objectContainer.RegisterMocks(_container);
}

[AfterScenario]
public void AfterScenario()
{
_objectContainer.Dispose();
}

[AfterTestRun]
public static async Task AfterTestRun()
{
using (_container)
{
await StopNServiceBusEndpoint();
}
}

private static void ResetCurrentDateTime(IContainer container)
{
var currentDateTime = container.GetInstance<Mock<ICurrentDateTime>>();
currentDateTime.Setup(x => x.Now).Returns(DateTime.Now);
}

private static void ResetFundsExpiryPeriod(IContainer container)
{
var config = container.GetInstance<EmployerFinanceConfiguration>();
config.FundsExpiryPeriod = 24;
}

private static async Task StartNServiceBusEndpoint()
{
try
{
_container.GetInstance<ILog>().Info("Starting endpoint.");

var endpointConfiguration = new EndpointConfiguration("SFA.DAS.EmployerFinance.AcceptanceTests")
.UseAzureServiceBusTransport()
.UseErrorQueue("SFA.DAS.EmployerFinance.AcceptanceTests-errors")
.UseInstallers()
.UseLicense(WebUtility.HtmlDecode(_container.GetInstance<EmployerFinanceConfiguration>().NServiceBusLicense))
.UseSqlServerPersistence(() => _container.GetInstance<DbConnection>())
.UseNewtonsoftJsonSerializer()
.UseNLogFactory()
.UseOutbox()
.UseStructureMapBuilder(_container)
.UseUnitOfWork();

if (Debugger.IsAttached)
{
endpointConfiguration.PurgeOnStartup(true);
}

_endpoint = await Endpoint.Start(endpointConfiguration).ConfigureAwait(false);

_container.Configure(c => c.For<IMessageSession>().Use(_endpoint));

_container.GetInstance<ILog>().Info("Endpoint Started.");
}
catch (Exception e)
{
_container.GetInstance<ILog>().Error(e, "Error starting endpoint.");
throw;
}
}

private static Task StopNServiceBusEndpoint()
{
return _endpoint.Stop();
}
}
namespace SFA.DAS.EmployerFinance.AcceptanceTests.Steps
{
[Binding]
public class Hooks
{
private static IContainer _container;
private static IEndpointInstance _endpoint;
private readonly IObjectContainer _objectContainer;

public Hooks(IObjectContainer objectContainer)
{
_objectContainer = objectContainer;
}

[BeforeTestRun]
public static async Task BeforeTestRun()
{
AzureStorageEmulatorManager.StartStorageEmulator();

_container = IoC.Initialize();

await StartNServiceBusEndpoint();
}

[BeforeScenario]
public void BeforeScenario()
{
_container.GetInstance<ILog>().Info("Starting Scenario.");

ResetCurrentDateTime(_container);
ResetFundsExpiryPeriod(_container);

_objectContainer.RegisterInstances(_container);
_objectContainer.RegisterMocks(_container);
}

[AfterScenario]
public void AfterScenario()
{
_objectContainer.Dispose();
}

[AfterTestRun]
public static async Task AfterTestRun()
{
using (_container)
{
await StopNServiceBusEndpoint();
}
}

private static void ResetCurrentDateTime(IContainer container)
{
var currentDateTime = container.GetInstance<Mock<ICurrentDateTime>>();
currentDateTime.Setup(x => x.Now).Returns(DateTime.Now);
}

private static void ResetFundsExpiryPeriod(IContainer container)
{
var config = container.GetInstance<EmployerFinanceConfiguration>();
config.FundsExpiryPeriod = 24;
}

private static async Task StartNServiceBusEndpoint()
{
try
{
_container.GetInstance<ILog>().Info("Starting endpoint.");

var endpointConfiguration = new EndpointConfiguration("SFA.DAS.EmployerFinance.AcceptanceTests")
.UseAzureServiceBusTransport()
.UseErrorQueue("SFA.DAS.EmployerFinance.AcceptanceTests-errors")
.UseInstallers()
.UseLicense(WebUtility.HtmlDecode(_container.GetInstance<EmployerFinanceConfiguration>().NServiceBusLicense))
.UseSqlServerPersistence(() => _container.GetInstance<DbConnection>())
.UseNewtonsoftJsonSerializer()
.UseNLogFactory()
.UseOutbox()
.UseStructureMapBuilder(_container)
.UseUnitOfWork();

if (Debugger.IsAttached)
{
endpointConfiguration.PurgeOnStartup(true);
}

_endpoint = await Endpoint.Start(endpointConfiguration).ConfigureAwait(false);

_container.Configure(c => c.For<IMessageSession>().Use(_endpoint));

_container.GetInstance<ILog>().Info("Endpoint Started.");
}
catch (Exception e)
{
_container.GetInstance<ILog>().Error(e, "Error starting endpoint.");
throw;
}
}

private static Task StopNServiceBusEndpoint()
{
return _endpoint.Stop();
}
}
}
48 changes: 33 additions & 15 deletions src/SFA.DAS.EmployerFinance.Web/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Web.Mvc;
using MediatR;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using NLog;
using Owin;
using SFA.DAS.Authentication;
using SFA.DAS.EmployerFinance.Commands.UpsertRegisteredUser;
using SFA.DAS.EmployerFinance.Configuration;
using SFA.DAS.EmployerFinance.Web;
using SFA.DAS.EmployerFinance.Web.App_Start;
using SFA.DAS.EmployerFinance.Web.Authentication;
using SFA.DAS.EmployerFinance.Web.ViewModels;
using SFA.DAS.EmployerUsers.WebClientComponents;
using SFA.DAS.OidcMiddleware;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using System.Web.Mvc;

[assembly: OwinStartup(typeof(Startup))]

Expand Down Expand Up @@ -60,7 +62,7 @@ public void Configuration(IAppBuilder app)
TokenValidationMethod = config.Identity.UseCertificate ? TokenValidationMethod.SigningKey : TokenValidationMethod.BinarySecret,
AuthenticatedCallback = identity =>
{
PostAuthentiationAction(identity, constants);
PostAuthentiationAction(identity, constants).GetAwaiter().GetResult();
}
});

Expand Down Expand Up @@ -100,18 +102,34 @@ private static Func<X509Certificate2> GetSigningCertificate(bool useCertificate)
};
}

private static void PostAuthentiationAction(ClaimsIdentity identity, Constants constants)
private async static Task PostAuthentiationAction(ClaimsIdentity identity, Constants constants)
{
var mediator = StructuremapMvc.StructureMapDependencyScope.Container.GetInstance<IMediator>();

Logger.Info("Retrieving claims from OIDC server.");

var userRef = identity.Claims.FirstOrDefault(claim => claim.Type == constants.Id())?.Value;

Logger.Info($"Retrieved claims from OIDC server for user with external ID '{userRef}'.");

identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identity.Claims.First(c => c.Type == constants.Id()).Value));
identity.AddClaim(new Claim(ClaimTypes.Name, identity.Claims.First(c => c.Type == constants.DisplayName()).Value));
identity.AddClaim(new Claim("sub", identity.Claims.First(c => c.Type == constants.Id()).Value));
identity.AddClaim(new Claim("email", identity.Claims.First(c => c.Type == constants.Email()).Value));
var id = identity.Claims.First(c => c.Type == constants.Id()).Value;
var email = identity.Claims.First(c => c.Type == constants.Email()).Value;
var lastName = identity.Claims.First(c => c.Type == constants.FamilyName()).Value;
var firstName = identity.Claims.First(c => c.Type == constants.GivenName()).Value;
var displayName = identity.Claims.First(c => c.Type == constants.DisplayName()).Value;

identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id));
identity.AddClaim(new Claim(ClaimTypes.Name, displayName));
identity.AddClaim(new Claim("sub", id));
identity.AddClaim(new Claim("email", email));

await mediator.SendAsync(new UpsertRegisteredUserCommand
{
EmailAddress = email,
UserRef = userRef,
LastName = lastName,
FirstName = firstName
});
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using MediatR;

namespace SFA.DAS.EmployerFinance.Commands.UpsertRegisteredUser
{
public class UpsertRegisteredUserCommand : IAsyncRequest
{
public string UserRef { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string CorrelationId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using MediatR;
using SFA.DAS.EmployerFinance.Data;
using SFA.DAS.EmployerFinance.Models.UserProfile;
using SFA.DAS.Validation;
using System;
using System.Threading.Tasks;

namespace SFA.DAS.EmployerFinance.Commands.UpsertRegisteredUser
{
public class UpsertRegisteredUserCommandHandler : AsyncRequestHandler<UpsertRegisteredUserCommand>
{
private readonly IValidator<UpsertRegisteredUserCommand> _validator;
private readonly IUserAccountRepository _userRepository;

public UpsertRegisteredUserCommandHandler(
IValidator<UpsertRegisteredUserCommand> validator,
IUserAccountRepository userRepository)
{
_validator = validator;
_userRepository = userRepository;
}

protected override async Task HandleCore(UpsertRegisteredUserCommand message)
{
var validationResult = _validator.Validate(message);

if (!validationResult.IsValid()) throw new InvalidRequestException(validationResult.ValidationDictionary);

await _userRepository.Upsert(new User
{
Ref = new Guid(message.UserRef),
Email = message.EmailAddress,
FirstName = message.FirstName,
LastName = message.LastName,
CorrelationId = message.CorrelationId
});
}
}
}
Loading

0 comments on commit d9a4fff

Please sign in to comment.