Removed ModernKeePassLib dependency

Code cleanup
WIP on service replacement and VM use
This commit is contained in:
Geoffroy BONNEVILLE
2020-03-27 18:45:13 +01:00
parent e3638c2f5c
commit 45fcf7e8ab
31 changed files with 383 additions and 277 deletions

View File

@@ -1,5 +1,4 @@
using System;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
@@ -7,12 +6,11 @@ using Windows.Storage.AccessCache;
using MediatR;
using ModernKeePass.Application.Database.Commands.UpdateCredentials;
using ModernKeePass.Application.Database.Queries.OpenDatabase;
using ModernKeePass.Application.Security.Commands.GenerateKeyFile;
using ModernKeePass.Application.Security.Queries.EstimatePasswordComplexity;
using ModernKeePass.Common;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using ModernKeePassLib.Cryptography;
using ModernKeePassLib.Keys;
namespace ModernKeePass.ViewModels
{
@@ -101,8 +99,8 @@ namespace ModernKeePass.ViewModels
public Application.Group.Models.GroupVm RootGroup { get; set; }
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
public double PasswordComplexityIndicator => _mediator.Send(new EstimatePasswordComplexityQuery { Password = Password }).GetAwaiter().GetResult();
private bool _hasPassword;
private bool _hasKeyFile;
private bool _hasUserAccount;
@@ -129,15 +127,13 @@ namespace ModernKeePass.ViewModels
try
{
_isOpening = true;
OnPropertyChanged("IsValid");
var fileInfo = new FileInfo
{
Name = databaseFile.DisplayName,
Path = StorageApplicationPermissions.FutureAccessList.Add(databaseFile)
};
OnPropertyChanged(nameof(IsValid));
var database = await _mediator.Send(new OpenDatabaseQuery { FileInfo = fileInfo, Credentials = CreateCredentials()});
await Task.Run(() => RootGroup = database.RootGroup);
RootGroup = await _mediator.Send(new OpenDatabaseQuery {
FilePath = StorageApplicationPermissions.FutureAccessList.Add(databaseFile),
KeyFilePath = HasKeyFile && KeyFile != null ? StorageApplicationPermissions.FutureAccessList.Add(KeyFile) : null,
Password = Password = HasPassword ? Password : null,
});
return true;
}
catch (ArgumentException)
@@ -163,16 +159,19 @@ namespace ModernKeePass.ViewModels
public async Task UpdateKey()
{
//Database.UpdateCompositeKey(await CreateCompositeKey());
await _mediator.Send(new UpdateCredentialsCommand {Credentials = CreateCredentials()});
await _mediator.Send(new UpdateCredentialsCommand
{
KeyFilePath = HasKeyFile && KeyFile != null ? StorageApplicationPermissions.FutureAccessList.Add(KeyFile) : null,
Password = Password = HasPassword ? Password : null,
});
UpdateStatus(_resource.GetResourceValue("CompositeKeyUpdated"), StatusTypes.Success);
}
public async Task CreateKeyFile(StorageFile file)
{
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
// TODO: implement entropy generator
var fileContents = await FileIO.ReadBufferAsync(file);
KcpKeyFile.Create(fileContents.ToArray());
await _mediator.Send(new GenerateKeyFileCommand {KeyFilePath = token});
KeyFile = file;
}
@@ -181,15 +180,5 @@ namespace ModernKeePass.ViewModels
Status = text;
StatusType = (int)type;
}
private Credentials CreateCredentials()
{
var credentials = new Credentials
{
Password = HasPassword ? Password: null,
KeyFilePath = HasKeyFile && KeyFile != null ? StorageApplicationPermissions.FutureAccessList.Add(KeyFile) : null
};
return credentials;
}
}
}

View File

@@ -5,7 +5,10 @@ using System.Threading.Tasks;
using System.Windows.Input;
using MediatR;
using ModernKeePass.Application.Database.Commands.SaveDatabase;
using ModernKeePass.Application.Database.Models;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Application.Entry.Commands.SetFieldValue;
using ModernKeePass.Application.Group.Commands.CreateGroup;
using ModernKeePass.Application.Group.Commands.DeleteEntry;
using ModernKeePass.Application.Resources.Queries;
using ModernKeePass.Application.Security.Commands.GeneratePassword;
@@ -32,7 +35,7 @@ namespace ModernKeePass.ViewModels
public bool BracketsPatternSelected { get; set; }
public string CustomChars { get; set; } = string.Empty;
public string Id => _entry.Id;
public bool IsRecycleOnDelete => _database.RecycleBinEnabled && !ParentGroup.IsSelected;
public bool IsRecycleOnDelete => GetDatabase().IsRecycleBinEnabled && !ParentGroup.IsSelected;
public IEnumerable<IVmEntity> BreadCrumb => new List<IVmEntity>(ParentGroup.BreadCrumb) {ParentGroup};
/// <summary>
/// Determines if the Entry is current or from history
@@ -211,7 +214,7 @@ namespace ModernKeePass.ViewModels
SaveCommand = new RelayCommand(() => _mediator.Send(new SaveDatabaseCommand()));
GeneratePasswordCommand = new RelayCommand(async () => await GeneratePassword());
UndoDeleteCommand = new RelayCommand(() => Move(PreviousGroup), () => PreviousGroup != null);
UndoDeleteCommand = new RelayCommand(async () => await Move(PreviousGroup), () => PreviousGroup != null);
}
public async Task GeneratePassword()
@@ -233,20 +236,21 @@ namespace ModernKeePass.ViewModels
}
public Task MarkForDelete(string recycleBinTitle)
public async Task MarkForDelete(string recycleBinTitle)
{
if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
_database.CreateRecycleBin(recycleBinTitle);
Move(_database.RecycleBinEnabled && !ParentGroup.IsSelected ? _database.RecycleBin : null);
var database = GetDatabase();
if (database.IsRecycleBinEnabled && database.RecycleBinId == null)
await _mediator.Send(new CreateGroupCommand { ParentGroup = database.RootGroup, IsRecycleBin = true, Name = recycleBinTitle});
await Move(database.IsRecycleBinEnabled && !ParentGroup.IsSelected ? _database.RecycleBin : null);
}
public void Move(GroupVm destination)
public async Task Move(GroupVm destination)
{
PreviousGroup = ParentGroup;
PreviousGroup.Entries.Remove(this);
if (destination == null)
{
_database.AddDeletedItem(IdUuid);
await _mediator.Send(new DeleteEntryCommand { Entry = _entry });
return;
}
ParentGroup = destination;
@@ -269,5 +273,10 @@ namespace ModernKeePass.ViewModels
_mediator.Send(new GetResourceQuery{Key = "EntryCurrent"}).GetAwaiter().GetResult() :
_entry.ModificationDate.ToString("g");
}
private DatabaseVm GetDatabase()
{
return _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
}
}
}

View File

@@ -6,13 +6,16 @@ using System.Threading.Tasks;
using System.Windows.Input;
using MediatR;
using ModernKeePass.Application.Database.Commands.SaveDatabase;
using ModernKeePass.Application.Database.Models;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Application.Group.Commands.AddEntry;
using ModernKeePass.Application.Group.Commands.AddGroup;
using ModernKeePass.Application.Group.Commands.CreateEntry;
using ModernKeePass.Application.Group.Commands.CreateGroup;
using ModernKeePass.Application.Group.Commands.DeleteGroup;
using ModernKeePass.Application.Group.Commands.InsertEntry;
using ModernKeePass.Application.Group.Commands.RemoveEntry;
using ModernKeePass.Application.Group.Commands.RemoveGroup;
using ModernKeePass.Application.Group.Commands.SortEntries;
using ModernKeePass.Application.Group.Commands.SortGroups;
using ModernKeePass.Common;
@@ -54,14 +57,18 @@ namespace ModernKeePass.ViewModels
public bool ShowRestore => IsNotRoot && ParentGroup.IsSelected;
public bool IsRecycleOnDelete => IsRecycleBinEnabled().GetAwaiter().GetResult() && !IsSelected && !ParentGroup.IsSelected;
public bool IsRecycleOnDelete => GetDatabase().IsRecycleBinEnabled && !IsSelected && !ParentGroup.IsSelected;
/// <summary>
/// Is the Group the database Recycle Bin?
/// </summary>
public bool IsSelected
{
get { return IsRecycleBinEnabled().GetAwaiter().GetResult() && _database.RecycleBin?.Id == Id; }
get
{
var database = GetDatabase();
return database.IsRecycleBinEnabled && database.RecycleBinId == Id;
}
set
{
if (value && _group != null) _database.RecycleBin = this;
@@ -150,7 +157,7 @@ namespace ModernKeePass.ViewModels
await SortEntriesAsync().ConfigureAwait(false), () => IsEditMode);
SortGroupsCommand = new RelayCommand(async () =>
await SortGroupsAsync().ConfigureAwait(false), () => IsEditMode);
UndoDeleteCommand = new RelayCommand(() => Move(PreviousGroup), () => PreviousGroup != null);
UndoDeleteCommand = new RelayCommand(async () => await Move(PreviousGroup), () => PreviousGroup != null);
if (recycleBinId != null && _group.Id.Equals(recycleBinId)) _database.RecycleBin = this;
Entries = new ObservableCollection<EntryVm>(group.Entries.Select(e => new EntryVm(e, this)));
@@ -200,31 +207,31 @@ namespace ModernKeePass.ViewModels
public async Task MarkForDelete(string recycleBinTitle)
{
var isRecycleBinEnabled = await IsRecycleBinEnabled();
if (isRecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
_database.CreateRecycleBin(recycleBinTitle);
Move(isRecycleBinEnabled && !IsSelected ? _database.RecycleBin : null);
var database = GetDatabase();
if (database.IsRecycleBinEnabled && database.RecycleBinId == null)
await _mediator.Send(new CreateGroupCommand {ParentGroup = database.RootGroup, IsRecycleBin = true, Name = recycleBinTitle});
await Move(database.IsRecycleBinEnabled && !IsSelected ? _database.RecycleBin : null);
((RelayCommand)UndoDeleteCommand).RaiseCanExecuteChanged();
}
public void UndoDelete()
public async Task UndoDelete()
{
Move(PreviousGroup);
await Move(PreviousGroup);
}
public void Move(GroupVm destination)
public async Task Move(GroupVm destination)
{
PreviousGroup = ParentGroup;
PreviousGroup.Groups.Remove(this);
PreviousGroup._group.SubGroups.Remove(_group);
await _mediator.Send(new RemoveGroupCommand {ParentGroup = PreviousGroup._group, Group = _group});
if (destination == null)
{
_database.AddDeletedItem(IdUuid);
await _mediator.Send(new DeleteGroupCommand { Group = _group });
return;
}
ParentGroup = destination;
ParentGroup.Groups.Add(this);
ParentGroup._group.AddGroup(_group, true);
await _mediator.Send(new AddGroupCommand {ParentGroup = ParentGroup._group, Group = _group});
}
public async Task CommitDelete()
@@ -251,10 +258,9 @@ namespace ModernKeePass.ViewModels
OnPropertyChanged(nameof(Groups));
}
private async Task<bool> IsRecycleBinEnabled()
private DatabaseVm GetDatabase()
{
var database = await _mediator.Send(new GetDatabaseQuery());
return database.IsRecycleBinEnabled;
return _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
}
}
}

View File

@@ -1,55 +1,74 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using MediatR;
using ModernKeePass.Application.Cryptography.Models;
using ModernKeePass.Application.Cryptography.Queries.GetCiphers;
using ModernKeePass.Application.Cryptography.Queries.GetCompressions;
using ModernKeePass.Application.Cryptography.Queries.GetKeyDerivations;
using ModernKeePass.Application.Database.Models;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Application.Parameters.Commands.SetCipher;
using ModernKeePass.Application.Parameters.Commands.SetCompression;
using ModernKeePass.Application.Parameters.Commands.SetHasRecycleBin;
using ModernKeePass.Application.Parameters.Commands.SetKeyDerivation;
using ModernKeePass.Application.Parameters.Commands.SetRecycleBin;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using ModernKeePassLib;
using ModernKeePassLib.Cryptography.Cipher;
using ModernKeePassLib.Cryptography.KeyDerivation;
namespace ModernKeePass.ViewModels
{
// TODO: implement Kdf settings
public class SettingsDatabaseVm: NotifyPropertyChangedBase, IHasSelectableObject
{
private readonly IDatabaseService _database;
private readonly IMediator _mediator;
private readonly DatabaseVm _database;
private GroupVm _selectedItem;
public bool HasRecycleBin
{
get { return _database.RecycleBinEnabled; }
get { return _database.IsRecycleBinEnabled; }
set
{
_database.RecycleBinEnabled = value;
OnPropertyChanged("HasRecycleBin");
_mediator.Send(new SetHasRecycleBinCommand {HasRecycleBin = value}).GetAwaiter().GetResult();
OnPropertyChanged(nameof(HasRecycleBin));
}
}
public bool IsNewRecycleBin
{
get { return _database.RecycleBin == null; }
get { return _database.RecycleBinId == null; }
set
{
if (value) _database.RecycleBin = null;
if (value) _mediator.Send(new SetRecycleBinCommand() { RecycleBinId = null }).GetAwaiter().GetResult();
}
}
public ObservableCollection<GroupVm> Groups { get; set; }
public IEnumerable<string> Ciphers
public IEnumerable<CipherVm> Ciphers => _mediator.Send(new GetCiphersQuery()).GetAwaiter().GetResult();
public IEnumerable<string> Compressions => _mediator.Send(new GetCompressionsQuery()).GetAwaiter().GetResult();
public IEnumerable<KeyDerivationVm> KeyDerivations => _mediator.Send(new GetKeyDerivationsQuery()).GetAwaiter().GetResult();
public CipherVm SelectedCipher
{
get
{
for (var inx = 0; inx < CipherPool.GlobalPool.EngineCount; inx++)
{
yield return CipherPool.GlobalPool[inx].DisplayName;
}
}
get { return Ciphers.FirstOrDefault(c => c.Id == _database.CipherId); }
set { _mediator.Send(new SetCipherCommand {CipherId = value.Id}).GetAwaiter().GetResult(); }
}
public int CipherIndex
public string SelectedCompression
{
get { return Compressions.FirstOrDefault(c => c == _database.Compression); }
set { _mediator.Send(new SetCompressionCommand {Compression = value}).GetAwaiter().GetResult(); }
}
public KeyDerivationVm SelectedKeyDerivation
{
get { return KeyDerivations.FirstOrDefault(c => c.Id == _database.KeyDerivationId); }
set { _mediator.Send(new SetKeyDerivationCommand {KeyDerivationId = value.Id}).GetAwaiter().GetResult(); }
}
/*public int CipherIndex
{
get
{
@@ -60,22 +79,19 @@ namespace ModernKeePass.ViewModels
return -1;
}
set { _database.DataCipher = CipherPool.GlobalPool[value].CipherUuid; }
}
}*/
public IEnumerable<string> Compressions => Enum.GetNames(typeof(PwCompressionAlgorithm)).Take((int)PwCompressionAlgorithm.Count);
public string CompressionName
/*public string CompressionName
{
get { return Enum.GetName(typeof(PwCompressionAlgorithm), _database.CompressionAlgorithm); }
get { return _database.}
set { _database.CompressionAlgorithm = (PwCompressionAlgorithm)Enum.Parse(typeof(PwCompressionAlgorithm), value); }
}
public IEnumerable<string> KeyDerivations => KdfPool.Engines.Select(e => e.Name);
public string KeyDerivationName
}*/
/*public string KeyDerivationName
{
get { return KdfPool.Get(_database.KeyDerivation.KdfUuid).Name; }
set { _database.KeyDerivation = KdfPool.Engines.FirstOrDefault(e => e.Name == value)?.GetDefaultParameters(); }
}
}*/
public ISelectableModel SelectedItem
{
@@ -97,12 +113,13 @@ namespace ModernKeePass.ViewModels
}
}
public SettingsDatabaseVm() : this(DatabaseService.Instance) { }
public SettingsDatabaseVm() : this(App.Mediator) { }
public SettingsDatabaseVm(IDatabaseService database)
public SettingsDatabaseVm(IMediator mediator)
{
_database = database;
Groups = _database?.RootGroup.Groups;
_mediator = mediator;
_database = _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
//Groups = _database.RootGroup.SubGroups;
}
}
}

View File

@@ -1,14 +1,21 @@
using Windows.Storage;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.UI.Xaml.Controls;
using MediatR;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Application.Entry.Commands.SetFieldValue;
using ModernKeePass.Application.Group.Commands.CreateEntry;
using ModernKeePass.Application.Group.Commands.CreateGroup;
using ModernKeePass.Converters;
using ModernKeePass.Domain.Enums;
using ModernKeePass.ImportFormats;
using ModernKeePass.Interfaces;
using ModernKeePassLib;
namespace ModernKeePass.ViewModels
{
public class NewVm : OpenVm
{
private readonly IMediator _mediator;
private string _importFormatHelp;
public string Password { get; set; }
@@ -30,15 +37,23 @@ namespace ModernKeePass.ViewModels
}
}
public void PopulateInitialData(IDatabaseService database, ISettingsService settings, IImportService<IFormat> importService)
public NewVm(): this(App.Mediator) { }
public NewVm(IMediator mediator)
{
if (settings.GetSetting<bool>("Sample") && !IsImportChecked) CreateSampleData(database.RootGroup);
_mediator = mediator;
}
public async Task PopulateInitialData(ISettingsService settings, IImportService<IFormat> importService)
{
var database = await _mediator.Send(new GetDatabaseQuery());
if (settings.GetSetting<bool>("Sample") && !IsImportChecked) await CreateSampleData(database.RootGroup);
else if (IsImportChecked && ImportFile != null && ! (ImportFormat is NullImportFormat)) importService.Import(ImportFormat, ImportFile, database.RootGroup);
}
private void CreateSampleData(GroupVm group)
private async Task CreateSampleData(Application.Group.Models.GroupVm group)
{
var converter = new IntToSymbolConverter();
/*var converter = new IntToSymbolConverter();
var bankingGroup = group.AddNewGroup("Banking");
bankingGroup.Icon = (int)converter.ConvertBack(Symbol.Calculator, null, null, string.Empty);
@@ -60,7 +75,24 @@ namespace ModernKeePass.ViewModels
sample2.Title = "Sample Entry #2";
sample2.UserName = "Michael321";
sample2.Url = PwDefs.HelpUrl + "kb/testform.html";
sample2.Password = "12345";
sample2.Password = "12345";*/
var bankingGroup = await _mediator.Send(new CreateGroupCommand {ParentGroup = group, Name = "Banking"});
var emailGroup = await _mediator.Send(new CreateGroupCommand {ParentGroup = group, Name = "Email" });
var internetGroup = await _mediator.Send(new CreateGroupCommand {ParentGroup = group, Name = "Internet" });
var sample1 = await _mediator.Send(new CreateEntryCommand { ParentGroup = group });
await _mediator.Send(new SetFieldValueCommand {EntryId = sample1.Id, FieldName = EntryFieldName.Title, FieldValue = "Sample Entry"});
await _mediator.Send(new SetFieldValueCommand {EntryId = sample1.Id, FieldName = EntryFieldName.UserName, FieldValue = "Username" });
await _mediator.Send(new SetFieldValueCommand {EntryId = sample1.Id, FieldName = EntryFieldName.Password, FieldValue = "Password" });
await _mediator.Send(new SetFieldValueCommand {EntryId = sample1.Id, FieldName = EntryFieldName.Url, FieldValue = "https://keepass.info/" });
await _mediator.Send(new SetFieldValueCommand {EntryId = sample1.Id, FieldName = EntryFieldName.Notes, FieldValue = "You may safely delete this sample" });
var sample2 = await _mediator.Send(new CreateEntryCommand { ParentGroup = group });
await _mediator.Send(new SetFieldValueCommand {EntryId = sample2.Id, FieldName = EntryFieldName.Title, FieldValue = "Sample Entry #2"});
await _mediator.Send(new SetFieldValueCommand {EntryId = sample2.Id, FieldName = EntryFieldName.UserName, FieldValue = "Michael321" });
await _mediator.Send(new SetFieldValueCommand {EntryId = sample2.Id, FieldName = EntryFieldName.Password, FieldValue = "12345" });
await _mediator.Send(new SetFieldValueCommand {EntryId = sample2.Id, FieldName = EntryFieldName.Url, FieldValue = "https://keepass.info/help/kb/testform.html" });
}
}
}

View File

@@ -1,28 +1,32 @@
using Windows.Storage;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.AccessCache;
using MediatR;
using ModernKeePass.Application.Database.Commands.CloseDatabase;
using ModernKeePass.Application.Database.Commands.SaveDatabase;
namespace ModernKeePass.ViewModels
{
public class SaveVm
{
private readonly IDatabaseService _database;
public SaveVm() : this(DatabaseService.Instance) { }
private readonly IMediator _mediator;
public SaveVm() : this(App.Mediator) { }
public SaveVm(IDatabaseService database)
public SaveVm(IMediator mediator)
{
_database = database;
_mediator = mediator;
}
public void Save(bool close = true)
public async Task Save(bool close = true)
{
_database.Save();
if (close) _database.Close();
await _mediator.Send(new SaveDatabaseCommand());
if (close) await _mediator.Send(new CloseDatabaseCommand());
}
public void Save(StorageFile file)
public async Task Save(StorageFile file)
{
_database.Save(file);
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
await _mediator.Send(new SaveDatabaseCommand { FilePath = token });
}
}
}

View File

@@ -1,6 +1,8 @@
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI.Xaml.Controls;
using MediatR;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Common;
using ModernKeePass.Interfaces;
using ModernKeePass.Views;
@@ -40,10 +42,11 @@ namespace ModernKeePass.ViewModels
}
}
public SettingsVm() : this(DatabaseService.Instance, new ResourcesService()) { }
public SettingsVm() : this(App.Mediator, new ResourcesService()) { }
public SettingsVm(IDatabaseService database, IResourceService resource)
public SettingsVm(IMediator mediator, IResourceService resource)
{
var database = mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
var menuItems = new ObservableCollection<ListMenuItemVm>
{
new ListMenuItemVm