mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-05-17 07:12:32 +00:00
Add website authentication tests
This commit is contained in:
parent
1fbabe0000
commit
281be33640
6 changed files with 177 additions and 3 deletions
|
@ -23,8 +23,6 @@ namespace ProjectLighthouse.Tests.GameApiTests
|
||||||
Assert.NotNull(userB);
|
Assert.NotNull(userB);
|
||||||
|
|
||||||
await database.RemoveUser(userA); // Only remove userA since userA and userB are the same user
|
await database.RemoveUser(userA); // Only remove userA since userA and userB are the same user
|
||||||
|
|
||||||
await database.SaveChangesAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
133
ProjectLighthouse.Tests.WebsiteTests/AuthenticationTests.cs
Normal file
133
ProjectLighthouse.Tests.WebsiteTests/AuthenticationTests.cs
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using LBPUnion.ProjectLighthouse;
|
||||||
|
using LBPUnion.ProjectLighthouse.Helpers;
|
||||||
|
using LBPUnion.ProjectLighthouse.Tests;
|
||||||
|
using LBPUnion.ProjectLighthouse.Types;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using OpenQA.Selenium;
|
||||||
|
using OpenQA.Selenium.Chrome;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace ProjectLighthouse.Tests.WebsiteTests
|
||||||
|
{
|
||||||
|
public class AuthenticationTests : IDisposable
|
||||||
|
{
|
||||||
|
public readonly IWebHost WebHost = new WebHostBuilder().UseKestrel().UseStartup<TestStartup>().UseWebRoot("StaticFiles").Build();
|
||||||
|
public readonly string BaseAddress;
|
||||||
|
|
||||||
|
public readonly IWebDriver Driver = new ChromeDriver();
|
||||||
|
|
||||||
|
public AuthenticationTests()
|
||||||
|
{
|
||||||
|
this.WebHost.Start();
|
||||||
|
|
||||||
|
IServerAddressesFeature? serverAddressesFeature = WebHost.ServerFeatures.Get<IServerAddressesFeature>();
|
||||||
|
if (serverAddressesFeature == null) throw new ArgumentNullException();
|
||||||
|
|
||||||
|
this.BaseAddress = serverAddressesFeature.Addresses.First();
|
||||||
|
}
|
||||||
|
|
||||||
|
[DatabaseFact]
|
||||||
|
public async Task ShouldLoginWithPassword()
|
||||||
|
{
|
||||||
|
await using Database database = new();
|
||||||
|
Random random = new();
|
||||||
|
|
||||||
|
string password = HashHelper.Sha256Hash(HashHelper.GenerateRandomBytes(64).ToArray());
|
||||||
|
User user = await database.CreateUser($"unitTestUser{random.Next()}", HashHelper.BCryptHash(HashHelper.Sha256Hash(password)));
|
||||||
|
|
||||||
|
this.Driver.Navigate().GoToUrl(this.BaseAddress + "/login");
|
||||||
|
|
||||||
|
this.Driver.FindElement(By.Id("text")).SendKeys(user.Username);
|
||||||
|
this.Driver.FindElement(By.Id("password")).SendKeys(password);
|
||||||
|
|
||||||
|
this.Driver.FindElement(By.Id("submit")).Click();
|
||||||
|
|
||||||
|
WebToken? webToken = await database.WebTokens.FirstOrDefaultAsync(t => t.UserId == user.UserId);
|
||||||
|
Assert.NotNull(webToken);
|
||||||
|
|
||||||
|
await database.RemoveUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DatabaseFact]
|
||||||
|
public async Task ShouldNotLoginWithNoPassword()
|
||||||
|
{
|
||||||
|
await using Database database = new();
|
||||||
|
Random random = new();
|
||||||
|
User user = await database.CreateUser($"unitTestUser{random.Next()}", HashHelper.BCryptHash("just like the hindenberg,"));
|
||||||
|
|
||||||
|
this.Driver.Navigate().GoToUrl(this.BaseAddress + "/login");
|
||||||
|
|
||||||
|
this.Driver.FindElement(By.Id("text")).SendKeys(user.Username);
|
||||||
|
|
||||||
|
this.Driver.FindElement(By.Id("submit")).Click();
|
||||||
|
|
||||||
|
WebToken? webToken = await database.WebTokens.FirstOrDefaultAsync(t => t.UserId == user.UserId);
|
||||||
|
Assert.Null(webToken);
|
||||||
|
|
||||||
|
await database.RemoveUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DatabaseFact]
|
||||||
|
public async Task ShouldNotLoginWithWrongPassword()
|
||||||
|
{
|
||||||
|
await using Database database = new();
|
||||||
|
Random random = new();
|
||||||
|
User user = await database.CreateUser($"unitTestUser{random.Next()}", HashHelper.BCryptHash("i'm an engineering failure"));
|
||||||
|
|
||||||
|
this.Driver.Navigate().GoToUrl(this.BaseAddress + "/login");
|
||||||
|
|
||||||
|
this.Driver.FindElement(By.Id("text")).SendKeys(user.Username);
|
||||||
|
this.Driver.FindElement(By.Id("password")).SendKeys("nah man");
|
||||||
|
|
||||||
|
this.Driver.FindElement(By.Id("submit")).Click();
|
||||||
|
|
||||||
|
WebToken? webToken = await database.WebTokens.FirstOrDefaultAsync(t => t.UserId == user.UserId);
|
||||||
|
Assert.Null(webToken);
|
||||||
|
|
||||||
|
await database.RemoveUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DatabaseFact]
|
||||||
|
public async Task ShouldLoginWithInjectedCookie()
|
||||||
|
{
|
||||||
|
const string loggedInAsUsernameTextXPath = "/html/body/div/div/div/p[1]/b";
|
||||||
|
|
||||||
|
await using Database database = new();
|
||||||
|
Random random = new();
|
||||||
|
User user = await database.CreateUser($"unitTestUser{random.Next()}", HashHelper.BCryptHash("i'm an engineering failure"));
|
||||||
|
|
||||||
|
WebToken webToken = new()
|
||||||
|
{
|
||||||
|
UserId = user.UserId,
|
||||||
|
UserToken = HashHelper.GenerateAuthToken(),
|
||||||
|
};
|
||||||
|
|
||||||
|
database.WebTokens.Add(webToken);
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
|
INavigation navigation = this.Driver.Navigate();
|
||||||
|
|
||||||
|
navigation.GoToUrl(this.BaseAddress + "/");
|
||||||
|
this.Driver.Manage().Cookies.AddCookie(new Cookie("LighthouseToken", webToken.UserToken));
|
||||||
|
Assert.Throws<NoSuchElementException>(() => this.Driver.FindElement(By.XPath(loggedInAsUsernameTextXPath)));
|
||||||
|
navigation.Refresh();
|
||||||
|
Assert.True(this.Driver.FindElement(By.XPath(loggedInAsUsernameTextXPath)).Text == user.Username);
|
||||||
|
|
||||||
|
await database.RemoveUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
this.Driver.Close();
|
||||||
|
this.Driver.Dispose();
|
||||||
|
this.WebHost.Dispose();
|
||||||
|
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0"/>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.0"/>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
|
||||||
|
<PackageReference Include="Selenium.WebDriver" Version="4.1.0"/>
|
||||||
|
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="96.0.4664.4500"/>
|
||||||
|
<PackageReference Include="xunit" Version="2.4.1"/>
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.1.0">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ProjectLighthouse.Tests\ProjectLighthouse.Tests.csproj"/>
|
||||||
|
<ProjectReference Include="..\ProjectLighthouse\ProjectLighthouse.csproj"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -22,7 +22,6 @@ namespace LBPUnion.ProjectLighthouse.Tests
|
||||||
public LighthouseServerTest()
|
public LighthouseServerTest()
|
||||||
{
|
{
|
||||||
this.Server = new TestServer(new WebHostBuilder().UseStartup<TestStartup>());
|
this.Server = new TestServer(new WebHostBuilder().UseStartup<TestStartup>());
|
||||||
|
|
||||||
this.Client = this.Server.CreateClient();
|
this.Client = this.Server.CreateClient();
|
||||||
}
|
}
|
||||||
public async Task<HttpResponseMessage> AuthenticateResponse(int number = -1, bool createUser = true)
|
public async Task<HttpResponseMessage> AuthenticateResponse(int number = -1, bool createUser = true)
|
||||||
|
|
|
@ -8,6 +8,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D360C08E
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectLighthouse.Tests.GameApiTests", "ProjectLighthouse.Tests.GameApiTests\ProjectLighthouse.Tests.GameApiTests.csproj", "{200EED99-FE3E-45C6-A51E-76ED9819CA2B}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectLighthouse.Tests.GameApiTests", "ProjectLighthouse.Tests.GameApiTests\ProjectLighthouse.Tests.GameApiTests.csproj", "{200EED99-FE3E-45C6-A51E-76ED9819CA2B}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectLighthouse.Tests.WebsiteTests", "ProjectLighthouse.Tests.WebsiteTests\ProjectLighthouse.Tests.WebsiteTests.csproj", "{CF65EB5B-5364-4D2A-8639-F147A67F08E7}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -26,9 +28,14 @@ Global
|
||||||
{200EED99-FE3E-45C6-A51E-76ED9819CA2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{200EED99-FE3E-45C6-A51E-76ED9819CA2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{200EED99-FE3E-45C6-A51E-76ED9819CA2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{200EED99-FE3E-45C6-A51E-76ED9819CA2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{200EED99-FE3E-45C6-A51E-76ED9819CA2B}.Release|Any CPU.Build.0 = Release|Any CPU
|
{200EED99-FE3E-45C6-A51E-76ED9819CA2B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{CF65EB5B-5364-4D2A-8639-F147A67F08E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{CF65EB5B-5364-4D2A-8639-F147A67F08E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{CF65EB5B-5364-4D2A-8639-F147A67F08E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{CF65EB5B-5364-4D2A-8639-F147A67F08E7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{AFC74569-B289-4ACC-B21C-313A3A62C017} = {D360C08E-EA47-43AC-A566-FDF413442980}
|
{AFC74569-B289-4ACC-B21C-313A3A62C017} = {D360C08E-EA47-43AC-A566-FDF413442980}
|
||||||
{200EED99-FE3E-45C6-A51E-76ED9819CA2B} = {D360C08E-EA47-43AC-A566-FDF413442980}
|
{200EED99-FE3E-45C6-A51E-76ED9819CA2B} = {D360C08E-EA47-43AC-A566-FDF413442980}
|
||||||
|
{CF65EB5B-5364-4D2A-8639-F147A67F08E7} = {D360C08E-EA47-43AC-A566-FDF413442980}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -89,6 +89,7 @@
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Affero/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Affero/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=asdf/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BCAS/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=BCAS/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BCES/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=BCES/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BCET/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=BCET/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue