Holy crap auth works (#2099)

* Holy crap auth works

* Fix some usages of UserID instead of UserName

* Refactor preferences.

They be non-async now. Also faster.

* Rename DbContext.

* Guest username assignment.

* Fix saving of profiles.

* Don't store data for guests.

* Fix generating invalid random colors.

* Don't allow dumb garbage for char preferences.

* Bans.

* Lol forgot to fill out the command description.

* Connection log.

* Rename all the tables and columns to be snake_case.

* Re-do migrations.

* Fixing tests and warnings.

* Update submodule
This commit is contained in:
Pieter-Jan Briers
2020-09-29 14:26:00 +02:00
committed by GitHub
parent 8a33e0a9bd
commit 66c8a68891
72 changed files with 4144 additions and 2642 deletions

View File

@@ -1,110 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Database;
using Content.Server.Preferences;
using Content.Shared;
using Content.Shared.Preferences;
using NUnit.Framework;
using Robust.Shared.Maths;
using Robust.UnitTesting;
namespace Content.Tests.Server.Preferences
{
[TestFixture]
public class PreferencesDatabaseTests : RobustUnitTest
{
private const int MaxCharacterSlots = 10;
private static HumanoidCharacterProfile CharlieCharlieson()
{
return new HumanoidCharacterProfile(
"Charlie Charlieson",
21,
Sex.Male,
new HumanoidCharacterAppearance(
"Afro",
Color.Aqua,
"Shaved",
Color.Aquamarine,
Color.Azure,
Color.Beige
),
new Dictionary<string, JobPriority>
{
{SharedGameTicker.OverflowJob, JobPriority.High}
},
PreferenceUnavailableMode.StayInLobby,
new List<string>{}
);
}
private static PreferencesDatabase GetDb()
{
return new PreferencesDatabase(new SqliteConfiguration(Path.GetTempFileName()), MaxCharacterSlots);
}
[Test]
public async Task TestUserDoesNotExist()
{
var db = GetDb();
Assert.Null(await db.GetPlayerPreferencesAsync("[The database should be empty so any string should do]"));
}
[Test]
public async Task TestUserDoesExist()
{
var db = GetDb();
const string username = "bobby";
await db.SaveSelectedCharacterIndexAsync(username, 0);
var prefs = await db.GetPlayerPreferencesAsync(username);
Assert.NotNull(prefs);
Assert.Zero(prefs.SelectedCharacterIndex);
Assert.That(prefs.Characters.ToList().TrueForAll(character => character is null));
}
[Test]
public async Task TestUpdateCharacter()
{
var db = GetDb();
const string username = "charlie";
const int slot = 0;
var originalProfile = CharlieCharlieson();
await db.SaveSelectedCharacterIndexAsync(username, slot);
await db.SaveCharacterSlotAsync(username, originalProfile, slot);
var prefs = await db.GetPlayerPreferencesAsync(username);
Assert.That(prefs.Characters.ElementAt(slot).MemberwiseEquals(originalProfile));
}
[Test]
public async Task TestDeleteCharacter()
{
var db = GetDb();
const string username = "charlie";
const int slot = 0;
await db.SaveSelectedCharacterIndexAsync(username, slot);
await db.SaveCharacterSlotAsync(username, CharlieCharlieson(), slot);
await db.SaveCharacterSlotAsync(username, null, slot);
var prefs = await db.GetPlayerPreferencesAsync(username);
Assert.That(prefs.Characters.ToList().TrueForAll(character => character is null));
}
[Test]
public async Task TestInvalidSlot()
{
var db = GetDb();
const string username = "charlie";
const int slot = -1;
await db.SaveSelectedCharacterIndexAsync(username, slot);
await db.SaveCharacterSlotAsync(username, CharlieCharlieson(), slot);
var prefs = await db.GetPlayerPreferencesAsync(username);
Assert.That(prefs.SelectedCharacterIndex, Is.EqualTo(0));
await db.SaveSelectedCharacterIndexAsync(username, MaxCharacterSlots);
prefs = await db.GetPlayerPreferencesAsync(username);
Assert.That(prefs.SelectedCharacterIndex, Is.EqualTo(MaxCharacterSlots - 1));
}
}
}

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Database;
using Content.Shared;
using Content.Shared.Preferences;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using NUnit.Framework;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.UnitTesting;
namespace Content.Tests.Server.Preferences
{
[TestFixture]
public class ServerDbSqliteTests : RobustUnitTest
{
private const int MaxCharacterSlots = 10;
private static HumanoidCharacterProfile CharlieCharlieson()
{
return new HumanoidCharacterProfile(
"Charlie Charlieson",
21,
Sex.Male,
new HumanoidCharacterAppearance(
"Afro",
Color.Aqua,
"Shaved",
Color.Aquamarine,
Color.Azure,
Color.Beige
),
new Dictionary<string, JobPriority>
{
{SharedGameTicker.OverflowJob, JobPriority.High}
},
PreferenceUnavailableMode.StayInLobby,
new List<string> ()
);
}
private static ServerDbSqlite GetDb()
{
var builder = new DbContextOptionsBuilder<ServerDbContext>();
var conn = new SqliteConnection("Data Source=:memory:");
conn.Open();
builder.UseSqlite(conn);
return new ServerDbSqlite(builder.Options);
}
[Test]
public async Task TestUserDoesNotExist()
{
var db = GetDb();
// Database should be empty so a new GUID should do it.
Assert.Null(await db.GetPlayerPreferencesAsync(NewUserId()));
}
[Test]
public async Task TestInitPrefs()
{
var db = GetDb();
var username = new NetUserId(new Guid("640bd619-fc8d-4fe2-bf3c-4a5fb17d6ddd"));
const int slot = 0;
var originalProfile = CharlieCharlieson();
await db.InitPrefsAsync(username, originalProfile);
var prefs = await db.GetPlayerPreferencesAsync(username);
Assert.That(prefs.Characters.ElementAt(slot).MemberwiseEquals(originalProfile));
}
[Test]
public async Task TestDeleteCharacter()
{
var db = GetDb();
var username = new NetUserId(new Guid("640bd619-fc8d-4fe2-bf3c-4a5fb17d6ddd"));
await db.InitPrefsAsync(username, HumanoidCharacterProfile.Default());
await db.SaveCharacterSlotAsync(username, CharlieCharlieson(), 1);
await db.SaveSelectedCharacterIndexAsync(username, 1);
await db.SaveCharacterSlotAsync(username, null, 1);
var prefs = await db.GetPlayerPreferencesAsync(username);
Assert.That(prefs.Characters.Skip(1).All(character => character is null));
}
private static NetUserId NewUserId()
{
return new NetUserId(Guid.NewGuid());
}
}
}

View File

@@ -0,0 +1,61 @@
using System.Net;
using Content.Server.Utility;
using NUnit.Framework;
namespace Content.Tests.Server.Utility
{
public class IPAddressExtTest
{
[Test]
[TestCase("192.168.5.85/24", "192.168.5.1")]
[TestCase("192.168.5.85/24", "192.168.5.254")]
[TestCase("10.128.240.50/30", "10.128.240.48")]
[TestCase("10.128.240.50/30", "10.128.240.49")]
[TestCase("10.128.240.50/30", "10.128.240.50")]
[TestCase("10.128.240.50/30", "10.128.240.51")]
public void IpV4SubnetMaskMatchesValidIpAddress(string netMask, string ipAddress)
{
var ipAddressObj = IPAddress.Parse(ipAddress);
Assert.That(ipAddressObj.IsInSubnet(netMask), Is.True);
}
[Test]
[TestCase("192.168.5.85/24", "192.168.4.254")]
[TestCase("192.168.5.85/24", "191.168.5.254")]
[TestCase("10.128.240.50/30", "10.128.240.47")]
[TestCase("10.128.240.50/30", "10.128.240.52")]
[TestCase("10.128.240.50/30", "10.128.239.50")]
[TestCase("10.128.240.50/30", "10.127.240.51")]
public void IpV4SubnetMaskDoesNotMatchInvalidIpAddress(string netMask, string ipAddress)
{
var ipAddressObj = IPAddress.Parse(ipAddress);
Assert.That(ipAddressObj.IsInSubnet(netMask), Is.False);
}
// ReSharper disable StringLiteralTypo
[Test]
[TestCase("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:0000:0000:0000:0000")]
[TestCase("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:FFFF:FFFF:FFFF:FFFF")]
[TestCase("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:0001:0000:0000:0000")]
[TestCase("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:FFFF:FFFF:FFFF:FFF0")]
[TestCase("2001:db8:abcd:0012::0/128", "2001:0DB8:ABCD:0012:0000:0000:0000:0000")]
public void IpV6SubnetMaskMatchesValidIpAddress(string netMask, string ipAddress)
{
var ipAddressObj = IPAddress.Parse(ipAddress);
Assert.That(ipAddressObj.IsInSubnet(netMask), Is.True);
}
[Test]
[TestCase("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0011:FFFF:FFFF:FFFF:FFFF")]
[TestCase("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0013:0000:0000:0000:0000")]
[TestCase("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0013:0001:0000:0000:0000")]
[TestCase("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0011:FFFF:FFFF:FFFF:FFF0")]
[TestCase("2001:db8:abcd:0012::0/128", "2001:0DB8:ABCD:0012:0000:0000:0000:0001")]
// ReSharper restore StringLiteralTypo
public void IpV6SubnetMaskDoesNotMatchInvalidIpAddress(string netMask, string ipAddress)
{
var ipAddressObj = IPAddress.Parse(ipAddress);
Assert.That(ipAddressObj.IsInSubnet(netMask), Is.False);
}
}
}