Skip to content

Commit

Permalink
Account Key Support (#250)
Browse files Browse the repository at this point in the history
* Adding user Key Verification to MAJORBBS Lock & Key Ordinals

* Implement hasmkey

* Handle Account Keys for RLOGIN & New Accounts

- Return Default Keys for RLOGIN Users
- Assign new users default keys on signup

* Fix Test Build Issue

* Refactor MBBSEmu Database to be Testable

- Impement haskey test
- Add `Reset()` methods to Accounts and AccounKeys Repositories
- Add Database Resets to ExportedModuleTestBase

* Fixing Failing Tests & Added Test for HASMKEY
  • Loading branch information
enusbaum authored Nov 6, 2020
1 parent 728210c commit 9b7fc6c
Show file tree
Hide file tree
Showing 15 changed files with 272 additions and 50 deletions.
11 changes: 9 additions & 2 deletions MBBSEmu.Tests/ExportedModules/ExportedModuleTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.IO;
using System.Linq;
using MBBSEmu.CPU;
using MBBSEmu.Database.Repositories.Account;
using MBBSEmu.Database.Repositories.AccountKey;
using MBBSEmu.DependencyInjection;
using MBBSEmu.Disassembler.Artifacts;
using MBBSEmu.IO;
Expand Down Expand Up @@ -46,7 +48,9 @@ protected ExportedModuleTestBase(string modulePath)
_serviceResolver.GetService<IFileUtility>(),
_serviceResolver.GetService<IGlobalCache>(),
mbbsModule,
testSessions);
testSessions,
_serviceResolver.GetService<IAccountKeyRepository>(),
_serviceResolver.GetService<IAccountRepository>());

galgsbl = new HostProcess.ExportedModules.Galgsbl(
_serviceResolver.GetService<ILogger>(),
Expand Down Expand Up @@ -97,7 +101,9 @@ protected virtual void Reset()
_serviceResolver.GetService<IFileUtility>(),
_serviceResolver.GetService<IGlobalCache>(),
mbbsModule,
testSessions);
testSessions,
_serviceResolver.GetService<IAccountKeyRepository>(),
_serviceResolver.GetService<IAccountRepository>());

galgsbl = new HostProcess.ExportedModules.Galgsbl(
_serviceResolver.GetService<ILogger>(),
Expand All @@ -106,6 +112,7 @@ protected virtual void Reset()
_serviceResolver.GetService<IGlobalCache>(),
mbbsModule,
testSessions);

}

/// <summary>
Expand Down
68 changes: 68 additions & 0 deletions MBBSEmu.Tests/ExportedModules/Majorbbs/key_Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using MBBSEmu.Memory;
using System.Collections.Generic;
using System.Text;
using MBBSEmu.Database.Repositories.Account;
using MBBSEmu.Database.Repositories.AccountKey;
using MBBSEmu.Module;
using Xunit;

namespace MBBSEmu.Tests.ExportedModules.Majorbbs
{
public class key_Tests :ExportedModuleTestBase
{

private const ushort HASKEY_ORDINAL = 334;
private const ushort HASMKEY_ORDINAL = 335;

[Fact]
public void haskey_Test()
{
//Reset State
Reset();

//Set the test Username
testSessions[0].Username = "sysop";
var key = "SYSOP";

//Set Argument Values to be Passed In
var stringPointer = mbbsEmuMemoryCore.AllocateVariable("INPUT_STRING", (ushort)(key.Length + 1));
mbbsEmuMemoryCore.SetArray("INPUT_STRING", Encoding.ASCII.GetBytes("SYSOP"));

//Execute Test
ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, HASKEY_ORDINAL, new List<IntPtr16> { stringPointer });

Assert.Equal(1, mbbsEmuCpuRegisters.AX);

}

[Fact]
public void hasmkey_Test()
{
//Reset State
Reset();

//Set the test Username
testSessions[0].Username = "sysop";
var key = "NORMAL";

var mcvPointer = (ushort)majorbbs.McvPointerDictionary.Allocate(new McvFile("TEST.MCV",
new Dictionary<int, byte[]> { { 0, Encoding.ASCII.GetBytes(key) } }));

mbbsEmuMemoryCore.SetPointer("CURRENT-MCV", new IntPtr16(0xFFFF, mcvPointer));

//Execute Test
ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, HASMKEY_ORDINAL, new List<ushort> { 0 });

Assert.Equal(1, mbbsEmuCpuRegisters.AX);

}

protected override void Reset()
{
base.Reset();

_serviceResolver.GetService<IAccountRepository>().Reset("sysop");
_serviceResolver.GetService<IAccountKeyRepository>().Reset();
}
}
}
18 changes: 17 additions & 1 deletion MBBSEmu/Configuration.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
using System;
using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;

namespace MBBSEmu
{
Expand Down Expand Up @@ -50,6 +55,17 @@ public AppSettings()
public string ANSILogoff => ConfigurationRoot["ANSI.Logoff"];
public string ANSISignup => ConfigurationRoot["ANSI.Signup"];
public string ANSIMenu => ConfigurationRoot["ANSI.Menu"];
public IEnumerable<string> DefaultKeys
{
get
{
if (ConfigurationRoot.GetSection("Account.DefaultKeys") == null)
return new[] { "DEMO", "NORMAL" };

return ConfigurationRoot.GetSection("Account.DefaultKeys").GetChildren()
.ToArray().Select(c => c.Value).ToArray();
}
}

//Default Values not in appSettings
public string BBSCompanyName = "MBBSEmu\0";
Expand Down
11 changes: 11 additions & 0 deletions MBBSEmu/Database/Repositories/Account/AccountRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,17 @@ public void UpdateAccountById(int accountId, string userName, string plaintextPa
Query(EnumQueries.UpdateAccountById, new { accountId, userName, passwordHash, passwordSalt, email });
}

public void Reset(string sysopPassword)
{
if (TableExists())
DropTable();

CreateTable();

InsertAccount("sysop", sysopPassword, "sysop@mbbsemu.com");
InsertAccount("guest", "guest", "guest@mbbsemu.com");
}

/// <summary>
/// Generates a cryptographically strong random sequence of bytes
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ public interface IAccountRepository
AccountModel GetAccountById(int accountId);
void DeleteAccountById(int accountId);
void UpdateAccountById(int accountId, string userName, string plaintextPassword, string email);
void Reset(string sysopPassword);
}
}
29 changes: 29 additions & 0 deletions MBBSEmu/Database/Repositories/AccountKey/AccountKeyRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,34 @@ public IEnumerable<AccountKeyModel> GetAccountKeysByAccountId(int accountId)
{
return Query<AccountKeyModel>(EnumQueries.GetAccountKeysByAccountId, new { accountId });
}

public IEnumerable<AccountKeyModel> GetAccountKeysByUsername(string userName)
{
return Query<AccountKeyModel>(EnumQueries.GetAccountKeysByUsername, new {userName});
}

public bool InsertAccountKeyByUsername(string userName, string accountKey)
{
var result = Query(EnumQueries.InsertAccountKeyByUsername, new { userName, accountKey });
return result.Any();
}

public void Reset()
{
if (TableExists())
DropTable();

CreateTable();

//Keys for SYSOP
InsertAccountKeyByUsername("sysop", "DEMO");
InsertAccountKeyByUsername("sysop", "NORMAL");
InsertAccountKeyByUsername("sysop", "SUPER");
InsertAccountKeyByUsername("sysop", "SYSOP");

//Keys for GUEST
InsertAccountKeyByUsername("sysop", "DEMO");
InsertAccountKeyByUsername("sysop", "NORMAL");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ public interface IAccountKeyRepository
bool InsertAccountKey(Model.AccountKeyModel accountKey);
bool InsertAccountKey(int accountId, string accountKey);
IEnumerable<AccountKeyModel> GetAccountKeysByAccountId(int accountId);
IEnumerable<AccountKeyModel> GetAccountKeysByUsername(string username);
bool InsertAccountKeyByUsername(string userName, string accountKey);
public void Reset();
}
}
10 changes: 9 additions & 1 deletion MBBSEmu/Database/Repositories/AccountKey/Queries/EnumQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,20 @@ public enum EnumQueries
[Description("Inserts new Account Key")]
InsertAccountKey,

[SqlQuery("InsertAccountKeyByUsername.sql")]
[Description("Inserts new Account Key by Username")]
InsertAccountKeyByUsername,

[SqlQuery("DropAccountKeysTable.sql")]
[Description("Drops the Account Table")]
DropAccountKeysTable,

[SqlQuery("GetAccountKeysByAccountId.sql")]
[Description("Gets Account Keys by the specified Account ID")]
GetAccountKeysByAccountId
GetAccountKeysByAccountId,

[SqlQuery("GetAccountKeysByUsername.sql")]
[Description("Gets Account Keys by the specified Username")]
GetAccountKeysByUsername
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
SELECT
AK.*
FROM
AccountKeys AK
INNER JOIN
Accounts A ON
A.accountId = AK.accountId
WHERE
A.userName = @userName
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
INSERT INTO AccountKeys (
accountId,
accountKey,
createDate,
updateDate)
SELECT
A.accountID,
@accountKey,
datetime('now'),
datetime('now')
FROM
Accounts A
WHERE
userName = @userName;

SELECT last_insert_rowid();
Loading

0 comments on commit 9b7fc6c

Please sign in to comment.