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

eerste opzet met Azure login 2FA base classes opzetten #844

Merged
merged 13 commits into from
Aug 5, 2024
6 changes: 6 additions & 0 deletions KISS-frontend.sln
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
CodeCoverage.runsettings = CodeCoverage.runsettings
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kiss.Bff.EndToEndTest", "Kiss.Bff.EndToEndTest\Kiss.Bff.EndToEndTest.csproj", "{D2EF3BA8-432E-42CE-AE01-04903D2F63FB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -45,6 +47,10 @@ Global
{DEB9BEF6-DC5E-42AD-B13E-7B969C619F65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DEB9BEF6-DC5E-42AD-B13E-7B969C619F65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DEB9BEF6-DC5E-42AD-B13E-7B969C619F65}.Release|Any CPU.Build.0 = Release|Any CPU
{D2EF3BA8-432E-42CE-AE01-04903D2F63FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D2EF3BA8-432E-42CE-AE01-04903D2F63FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D2EF3BA8-432E-42CE-AE01-04903D2F63FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D2EF3BA8-432E-42CE-AE01-04903D2F63FB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
75 changes: 75 additions & 0 deletions Kiss.Bff.EndToEndTest/AzureAdLoginHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using Microsoft.Playwright;
using OtpNet;
using System;
using System.Threading.Tasks;

namespace PlaywrightTests
{
public class AzureAdLoginHelper
{
private readonly IPage _page;
private readonly string _username;
private readonly string _password;
private readonly string _totpSecret;

public AzureAdLoginHelper(IPage page, string username, string password, string totpSecret)
{
_page = page;
_username = username;
_password = password;
_totpSecret = totpSecret;
}

public async Task LoginAsync()
{
await _page.GotoAsync("https://dev.kiss-demo.nl/");

await _page.FillAsync("input[name='loginfmt']", _username);
await _page.ClickAsync("input[type='submit']");

await _page.WaitForSelectorAsync("input[name='passwd']");
await _page.FillAsync("input[name='passwd']", _password);
await _page.ClickAsync("input[type='submit']");

await Handle2FAAsync();

await _page.WaitForURLAsync("https://dev.kiss-demo.nl/**");
}

private async Task Handle2FAAsync()
{
// Wait for the TOTP input field to appear
await _page.WaitForSelectorAsync("input[name='otc']", new() { Timeout = 30000 });

// Generate TOTP code
var totp = new Totp(Base32Encoding.ToBytes(_totpSecret));
string totpCode = totp.ComputeTotp();

// Check for "Enter Manually" link and click if present
var enterManuallyLink = await _page.QuerySelectorAsync("a:has-text('Ik kan mijn Microsoft Authenticator-app op dit moment niet gebruiken')");
if (enterManuallyLink != null)
{
await enterManuallyLink.ClickAsync();
}

// Fill in the TOTP code
await _page.FillAsync("input[name='otc']", totpCode);
await _page.ClickAsync("input[type='submit']");

// Wait for potential "Stay signed in?" prompt
var staySignedInPromptSelector = "input[value='Nee']";
await Task.Delay(2000);
var staySignedInButton = await _page.QuerySelectorAsync(staySignedInPromptSelector);

// Handle the prompt if present
if (staySignedInButton != null)
{
await staySignedInButton.ClickAsync();
}

// Wait for navigation or some confirmation that the login is successful
await _page.WaitForNavigationAsync(new() { Timeout = 30000 });
}

}
}
74 changes: 74 additions & 0 deletions Kiss.Bff.EndToEndTest/BaseTestInitializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Playwright;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading.Tasks;


namespace PlaywrightTests
{
[TestClass]
public class BaseTestInitializer
{
protected IPlaywright Playwright;
protected IBrowser Browser;
protected IBrowserContext Context;
protected IPage Page;
protected IPage FrontendPage;
protected AzureAdLoginHelper LoginHelper;
protected IConfiguration Configuration;

[TestInitialize]
public virtual async Task TestInitialize()
{
try
{
Configuration = new ConfigurationBuilder()
.AddUserSecrets<BaseTestInitializer>()
.AddEnvironmentVariables()
.Build();

var username = Configuration["TestSettings:TEST_USERNAME"];
felixcicatt marked this conversation as resolved.
Show resolved Hide resolved
var password = Configuration["TestSettings:TEST_PASSWORD"];
var totpSecret = Configuration["TestSettings:TEST_TOTP_SECRET"];

if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(totpSecret))
{
throw new InvalidOperationException("One or more required settings are missing from appsettings.json");
}

Playwright = await Microsoft.Playwright.Playwright.CreateAsync();
Browser = await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
{
Headless = false // Set to true
felixcicatt marked this conversation as resolved.
Show resolved Hide resolved
});
Context = await Browser.NewContextAsync();
Page = await Context.NewPageAsync();
LoginHelper = new AzureAdLoginHelper(Page,
Configuration["TestSettings:TEST_USERNAME"],
Configuration["TestSettings:TEST_PASSWORD"],
Configuration["TestSettings:TEST_TOTP_SECRET"]);
felixcicatt marked this conversation as resolved.
Show resolved Hide resolved

await LoginHelper.LoginAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
felixcicatt marked this conversation as resolved.
Show resolved Hide resolved
throw;
}

}

[TestCleanup]
public virtual async Task TestCleanup()
{
await Context.CloseAsync();
await Browser.CloseAsync();
Playwright?.Dispose();
}

protected virtual async Task<IPage> OpenNewPageAsync()
{
return await Context.NewPageAsync();
}
}
}
4 changes: 4 additions & 0 deletions Kiss.Bff.EndToEndTest/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
global using Microsoft.Playwright.MSTest;
global using Microsoft.VisualStudio.TestTools.UnitTesting;
global using System.Text.RegularExpressions;
global using System.Threading.Tasks;
31 changes: 31 additions & 0 deletions Kiss.Bff.EndToEndTest/Kiss.Bff.EndToEndTest.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<UserSecretsId>11d50565-5002-41ee-b700-0b7168235484</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.0.4" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
<PackageReference Include="Microsoft.Playwright.MSTest" Version="1.27.1" />
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Otp.NET" Version="1.4.0" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Loading