Skip to content

Commit

Permalink
Adding ICryptographicCenter and ISerializationCenter interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
YassinLokhat committed Jan 9, 2025
1 parent 9a812f0 commit 29af6eb
Show file tree
Hide file tree
Showing 14 changed files with 414 additions and 167 deletions.
40 changes: 26 additions & 14 deletions Core/ClassDiagram.cd
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,6 @@
<Members>
<Field Name="_service" Hidden="true" />
</Members>
<AssociationLine Name="Options" Type="Upsilon.Apps.PassKey.Core.Enums.AccountOption" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
<Path>
<Point X="13" Y="15.562" />
<Point X="12.422" Y="15.562" />
<Point X="12.422" Y="16.42" />
<Point X="3.125" Y="16.42" />
<Point X="3.125" Y="15.989" />
</Path>
</AssociationLine>
<TypeIdentifier>
<HashCode>AAAgAAAAEBADAABQgIAAAQAAAAAAQAACgAAQAABAAAA=</HashCode>
<FileName>Models\Account.cs</FileName>
Expand Down Expand Up @@ -156,15 +147,22 @@
<FileName>Interfaces\IAccount.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Property Name="Options" />
<Property Name="Service" />
<Property Name="Options" />
</ShowAsAssociation>
</Interface>
<Interface Name="Upsilon.Apps.Passkey.Core.Interfaces.IDatabase">
<Position X="5.75" Y="1" Width="1.5" />
<AssociationLine Name="User" Type="Upsilon.Apps.Passkey.Core.Interfaces.IUser">
<Position X="2.5" Y="1.25" Width="1.5" />
<AssociationLine Name="User" Type="Upsilon.Apps.Passkey.Core.Interfaces.IUser" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
<Path>
<Point X="3.906" Y="4.281" />
<Point X="3.906" Y="5.015" />
<Point X="4.802" Y="5.015" />
<Point X="4.802" Y="5.938" />
<Point X="5.5" Y="5.938" />
</Path>
<MemberNameLabel ManuallyPlaced="true" ManuallySized="true">
<Position X="0.112" Y="0.098" Height="0.162" Width="0.5" />
<Position X="0.098" Y="0.112" Height="0.162" Width="0.5" />
</MemberNameLabel>
</AssociationLine>
<TypeIdentifier>
Expand All @@ -182,10 +180,24 @@
<FileName>Interfaces\IChangable.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Upsilon.Apps.PassKey.Core.Interfaces.ISerializationCenter">
<Position X="6" Y="1" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAACBAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Interfaces\ISerializationCenter.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Upsilon.Apps.PassKey.Core.Interfaces.ICryptographicCenter">
<Position X="6" Y="2.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AQACAAAAAAAAABAQAIAAAAAAAAAAAAACAAAAAABAAAA=</HashCode>
<FileName>Interfaces\ICryptographicCenter.cs</FileName>
</TypeIdentifier>
</Interface>
<Enum Name="Upsilon.Apps.PassKey.Core.Enums.AccountOption">
<Position X="2.25" Y="14.75" Width="1.75" />
<TypeIdentifier>
<HashCode>AIAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAEAAAA=</HashCode>
<HashCode>AIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA=</HashCode>
<FileName>Enums\AccountOption.cs</FileName>
</TypeIdentifier>
</Enum>
Expand Down
56 changes: 56 additions & 0 deletions Core/Interfaces/ICryptographicCenter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
namespace Upsilon.Apps.PassKey.Core.Interfaces
{
/// <summary>
/// Represent a cryptographic center.
/// </summary>
public interface ICryptographicCenter
{
/// <summary>
/// Returs a fast string hash of the given string.
/// </summary>
/// <param name="source">The string to hash.</param>
/// <returns>The hash.</returns>
public string GetHash(string source);

/// <summary>
/// Returs a slow string hash of the given string.
/// </summary>
/// <param name="source">The string to hash.</param>
/// <returns>The hash.</returns>
string GetSlowHash(string source);

/// <summary>
/// The fixed length of the hash.
/// </summary>
int HashLength { get; }

/// <summary>
/// Sign a string.
/// </summary>
/// <param name="source">The string to sign. The method will modify the string to add the signature.</param>
void Sign(ref string source);

/// <summary>
/// check the signature of a given string.
/// </summary>
/// <param name="source">The string to sign. The method will modify the string to remove the signature.</param>
/// <returns>True if the signature is good, False else.</returns>
bool CheckSign(ref string source);

/// <summary>
/// Encrypt a string with a set of passekeys in an onion structure.
/// </summary>
/// <param name="source">The string to encrypt.</param>
/// <param name="passwords">The set of passkeys.</param>
/// <returns>The encrypted string.</returns>
string Encrypt(string source, string[] passwords);

/// <summary>
/// Decrypt a string with a set of passekeys in an onion structure.
/// </summary>
/// <param name="source">The string to decrypt.</param>
/// <param name="passwords">The set of passkeys.</param>
/// <returns>The decrypted string.</returns>
string Decrypt(string source, string[] passwords);
}
}
37 changes: 33 additions & 4 deletions Core/Interfaces/IDatabase.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Upsilon.Apps.Passkey.Core.Models;
using Upsilon.Apps.PassKey.Core.Events;
using Upsilon.Apps.PassKey.Core.Interfaces;

namespace Upsilon.Apps.Passkey.Core.Interfaces
{
Expand Down Expand Up @@ -56,26 +57,54 @@ public interface IDatabase : IDisposable
/// Create a new user database and returns the database.
/// After creating, the User should be loaded with the Login method.
/// </summary>
/// <param name="cryptographicCenter">An implementation of the cryptographic center.</param>
/// <param name="serializationCenter">An implementation of the serialization center.</param>
/// <param name="databaseFile">The path to the database file.</param>
/// <param name="autoSaveFile">The path to the autosave file.</param>
/// <param name="logFile">The path to the log file.</param>
/// <param name="username">The username.</param>
/// <param name="passkeys">The passkeys.</param>
/// <returns>The database created.</returns>
static IDatabase Create(string databaseFile, string autoSaveFile, string logFile, string username, string[] passkeys)
=> Database.Create(databaseFile, autoSaveFile, logFile, username, passkeys);
static IDatabase Create(ICryptographicCenter cryptographicCenter,
ISerializationCenter serializationCenter,
string databaseFile,
string autoSaveFile,
string logFile,
string username,
string[] passkeys)
=> Database.Create(cryptographicCenter,
serializationCenter,
databaseFile,
autoSaveFile,
logFile,
username,
passkeys);

/// <summary>
/// Open an user and returns the database.
/// After opening, the User should be loaded with the Login method.
/// </summary>
/// <param name="cryptographicCenter">An implementation of the cryptographic center.</param>
/// <param name="serializationCenter">An implementation of the serialization center.</param>
/// <param name="databaseFile">The path to the database file.</param>
/// <param name="autoSaveFile">The path to the autosave file.</param>
/// <param name="logFile">The path to the log file.</param>
/// <param name="username">The username.</param>
/// <param name="autoSaveHandler">The event handler for Auto-save merge behavior.</param>
/// <returns>The database opened.</returns>
static IDatabase Open(string databaseFile, string autoSaveFile, string logFile, string username, EventHandler<AutoSaveDetectedEventArgs>? autoSaveHandler = null)
=> Database.Open(databaseFile, autoSaveFile, logFile, username, autoSaveHandler);
static IDatabase Open(ICryptographicCenter cryptographicCenter,
ISerializationCenter serializationCenter,
string databaseFile,
string autoSaveFile,
string logFile,
string username,
EventHandler<AutoSaveDetectedEventArgs>? autoSaveHandler = null)
=> Database.Open(cryptographicCenter,
serializationCenter,
databaseFile,
autoSaveFile,
logFile,
username,
autoSaveHandler);
}
}
24 changes: 24 additions & 0 deletions Core/Interfaces/ISerializationCenter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Upsilon.Apps.PassKey.Core.Interfaces
{
/// <summary>
/// Represent a serialization center.
/// </summary>
public interface ISerializationCenter
{
/// <summary>
/// Serialize the given object to a string.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="toSerialize">The object to serialize.</param>
/// <returns>The serialised string.</returns>
string Serialize<T>(T toSerialize) where T : notnull;

/// <summary>
/// Deserialize the given string to the given type object.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="toDeserialize">The serialised string.</param>
/// <returns>The deserialized object.</returns>
T Deserialize<T>(string toDeserialize) where T : notnull;
}
}
27 changes: 14 additions & 13 deletions Core/Models/Account.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.ComponentModel;
using Upsilon.Apps.Passkey.Core.Interfaces;
using Upsilon.Apps.PassKey.Core.Enums;
using Upsilon.Apps.PassKey.Core.Utils;

namespace Upsilon.Apps.Passkey.Core.Models
{
Expand All @@ -15,13 +14,13 @@ internal sealed class Account : IAccount, IChangable
string IAccount.Label
{
get => Label;
set => Label = Service.User.Database.AutoSave.UpdateValue(ItemId, nameof(Label), value);
set => Label = Database.AutoSave.UpdateValue(ItemId, nameof(Label), value);
}

string[] IAccount.Identifiants
{
get => Identifiants;
set => Identifiants = Service.User.Database.AutoSave.UpdateValue(ItemId, nameof(Identifiants), value);
set => Identifiants = Database.AutoSave.UpdateValue(ItemId, nameof(Identifiants), value);
}

public string Password
Expand All @@ -30,7 +29,7 @@ public string Password
set
{
Passwords[DateTime.Now.Ticks] = value;
_ = Service.User.Database.AutoSave.UpdateValue(ItemId, nameof(Passwords), Passwords);
_ = Database.AutoSave.UpdateValue(ItemId, nameof(Passwords), Passwords);
}
}

Expand All @@ -39,23 +38,25 @@ public string Password
string IAccount.Notes
{
get => Notes;
set => Notes = Service.User.Database.AutoSave.UpdateValue(ItemId, nameof(Notes), value);
set => Notes = Database.AutoSave.UpdateValue(ItemId, nameof(Notes), value);
}

int IAccount.PasswordUpdateReminderDelay
{
get => PasswordUpdateReminderDelay;
set => PasswordUpdateReminderDelay = Service.User.Database.AutoSave.UpdateValue(ItemId, nameof(PasswordUpdateReminderDelay), value);
set => PasswordUpdateReminderDelay = Database.AutoSave.UpdateValue(ItemId, nameof(PasswordUpdateReminderDelay), value);
}

AccountOption IAccount.Options
{
get => Options;
set => Options = Service.User.Database.AutoSave.UpdateValue(ItemId, nameof(Options), value);
set => Options = Database.AutoSave.UpdateValue(ItemId, nameof(Options), value);
}

#endregion

internal Database Database => Service.User.Database;

public string ItemId { get; set; } = string.Empty;

private Service? _service;
Expand All @@ -80,22 +81,22 @@ public void Apply(Change change)
switch (change.FieldName)
{
case nameof(Label):
Label = change.Value.Deserialize<string>();
Label = Database.SerializationCenter.Deserialize<string>(change.Value);
break;
case nameof(Identifiants):
Identifiants = change.Value.Deserialize<string[]>();
Identifiants = Database.SerializationCenter.Deserialize<string[]>(change.Value);
break;
case nameof(Notes):
Notes = change.Value.Deserialize<string>();
Notes = Database.SerializationCenter.Deserialize<string>(change.Value);
break;
case nameof(Passwords):
Passwords = change.Value.Deserialize<Dictionary<long, string>>();
Passwords = Database.SerializationCenter.Deserialize<Dictionary<long, string>>(change.Value);
break;
case nameof(PasswordUpdateReminderDelay):
PasswordUpdateReminderDelay = change.Value.Deserialize<int>();
PasswordUpdateReminderDelay = Database.SerializationCenter.Deserialize<int>(change.Value);
break;
case nameof(Options):
Options = change.Value.Deserialize<AccountOption>();
Options = Database.SerializationCenter.Deserialize<AccountOption>(change.Value);
break;
default:
throw new InvalidDataException("FieldName not valid");
Expand Down
13 changes: 6 additions & 7 deletions Core/Models/AutoSave.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Upsilon.Apps.PassKey.Core.Enums;
using Upsilon.Apps.PassKey.Core.Utils;

namespace Upsilon.Apps.Passkey.Core.Models
{
Expand All @@ -16,21 +15,21 @@ internal Database Database

internal T UpdateValue<T>(string itemId, string fieldName, T value) where T : notnull
{
_addChange(itemId, fieldName, value.Serialize(), ChangeType.Update);
_addChange(itemId, fieldName, Database.SerializationCenter.Serialize(value), ChangeType.Update);

return value;
}

internal T AddValue<T>(string itemId, T value) where T : notnull
{
_addChange(itemId, string.Empty, value.Serialize(), ChangeType.Add);
_addChange(itemId, string.Empty, Database.SerializationCenter.Serialize(value), ChangeType.Add);

return value;
}

internal T DeleteValue<T>(string itemId, T value) where T : notnull
{
_addChange(itemId, string.Empty, value.Serialize(), ChangeType.Delete);
_addChange(itemId, string.Empty, Database.SerializationCenter.Serialize(value), ChangeType.Delete);

return value;
}
Expand All @@ -47,15 +46,15 @@ private void _addChange(string itemId, string fieldName, string value, ChangeTyp

if (Database.AutoSaveFileLocker == null)
{
Database.AutoSaveFileLocker = new(Database.AutoSaveFile, FileMode.OpenOrCreate);
Database.AutoSaveFileLocker = new(Database.CryptographicCenter, Database.SerializationCenter, Database.AutoSaveFile, FileMode.OpenOrCreate);
}

Database.AutoSaveFileLocker.WriteAllText(this.Serialize(), Database.Passkeys);
Database.AutoSaveFileLocker.WriteAllText(Database.SerializationCenter.Serialize(this), Database.Passkeys);
}

internal void MergeChange()
{
while (Changes.Any())
while (Changes.Count != 0)
{
Database.User?.Apply(Changes.Dequeue());
}
Expand Down
Loading

0 comments on commit 29af6eb

Please sign in to comment.