From 4b1210f4141af2345d4a4da1abeb552bfa1b8540 Mon Sep 17 00:00:00 2001 From: Geoffroy BONNEVILLE Date: Tue, 24 Mar 2020 19:14:34 +0100 Subject: [PATCH] WIP --- ModernKeePass.Application/Application.csproj | 1 + .../SaveDatabase/SaveDatabaseCommand.cs | 1 - .../UpdateCredentialsCommand.cs | 33 +++++++++++++ .../KeePass/KeePassDatabaseClient.cs | 29 +++++++++++- ModernKeePass/App.xaml.cs | 16 +++---- ModernKeePass/ViewModels/CompositeKeyVm.cs | 47 +++++++++++-------- ModernKeePass/ViewModels/MainVm.cs | 18 +++---- .../CompositeKeyUserControl.xaml.cs | 19 ++++++-- ModernKeePass/Win81App.csproj | 2 +- 9 files changed, 121 insertions(+), 45 deletions(-) create mode 100644 ModernKeePass.Application/Database/Commands/UpdateCredentials/UpdateCredentialsCommand.cs diff --git a/ModernKeePass.Application/Application.csproj b/ModernKeePass.Application/Application.csproj index 89aab33..1ba72ee 100644 --- a/ModernKeePass.Application/Application.csproj +++ b/ModernKeePass.Application/Application.csproj @@ -58,6 +58,7 @@ + diff --git a/ModernKeePass.Application/Database/Commands/SaveDatabase/SaveDatabaseCommand.cs b/ModernKeePass.Application/Database/Commands/SaveDatabase/SaveDatabaseCommand.cs index e4200fa..8f8a567 100644 --- a/ModernKeePass.Application/Database/Commands/SaveDatabase/SaveDatabaseCommand.cs +++ b/ModernKeePass.Application/Database/Commands/SaveDatabase/SaveDatabaseCommand.cs @@ -1,5 +1,4 @@ using MediatR; -using System.Threading; using System.Threading.Tasks; using ModernKeePass.Application.Common.Interfaces; using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; diff --git a/ModernKeePass.Application/Database/Commands/UpdateCredentials/UpdateCredentialsCommand.cs b/ModernKeePass.Application/Database/Commands/UpdateCredentials/UpdateCredentialsCommand.cs new file mode 100644 index 0000000..9e4b07b --- /dev/null +++ b/ModernKeePass.Application/Database/Commands/UpdateCredentials/UpdateCredentialsCommand.cs @@ -0,0 +1,33 @@ +using System.Threading.Tasks; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Domain.Dtos; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Database.Commands.UpdateCredentials +{ + public class UpdateCredentialsCommand: IRequest + { + public Credentials Credentials { get; set; } + + public class UpdateCredentialsCommandHandler : IAsyncRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMediator _mediator; + + public UpdateCredentialsCommandHandler(IDatabaseProxy database, IMediator mediator) + { + _database = database; + _mediator = mediator; + } + + public async Task Handle(UpdateCredentialsCommand message) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (isDatabaseOpen) await _database.UpdateCredentials(message.Credentials); + else throw new DatabaseClosedException(); + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs b/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs index 9e7143e..47fd0c1 100644 --- a/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs +++ b/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs @@ -25,11 +25,37 @@ namespace ModernKeePass.Infrastructure.KeePass private string _fileAccessToken; private CompositeKey _compositeKey; + // Main information public bool IsOpen => (_pwDatabase?.IsOpen).GetValueOrDefault(); public string Name => _pwDatabase?.Name; + public GroupEntity RootGroup { get; set; } - public GroupEntity RecycleBin { get; set; } + // Settings + public GroupEntity RecycleBin + { + get + { + if (_pwDatabase.RecycleBinEnabled) + { + var pwGroup = _pwDatabase.RootGroup.FindGroup(_pwDatabase.RecycleBinUuid, true); + var group = new GroupEntity + { + Id = pwGroup.Uuid.ToHexString(), + Name = pwGroup.Name, + Icon = IconMapper.MapPwIconToIcon(pwGroup.IconId), + Entries = pwGroup.Entries.Select(e => _mapper.Map(e)).ToList(), + SubGroups = pwGroup.Groups.Select(BuildHierarchy).ToList() + }; + return group; + } + return null; + } + set + { + + } + } public BaseEntity Cipher { get @@ -88,6 +114,7 @@ namespace ModernKeePass.Infrastructure.KeePass return new DatabaseEntity { + Name = _pwDatabase.Name, RootGroupEntity = BuildHierarchy(_pwDatabase.RootGroup) }; } diff --git a/ModernKeePass/App.xaml.cs b/ModernKeePass/App.xaml.cs index 153616b..7e43ceb 100644 --- a/ModernKeePass/App.xaml.cs +++ b/ModernKeePass/App.xaml.cs @@ -35,7 +35,7 @@ namespace ModernKeePass { public IServiceProvider Services { get; } - private IMediator _mediator; + public static IMediator Mediator { get; private set; } /// /// Initializes the singleton application object. This is the first line of authored code @@ -58,7 +58,7 @@ namespace ModernKeePass serviceCollection.AddApplication(); serviceCollection.AddInfrastructure(); Services = serviceCollection.BuildServiceProvider(); - _mediator = Services.GetService(); + Mediator = Services.GetService(); } #region Event Handlers @@ -83,7 +83,7 @@ namespace ModernKeePass resource.GetResourceValue("MessageDialogSaveErrorButtonDiscard"), async command => { - var database = await _mediator.Send(new GetDatabaseQuery()); + var database = await Mediator.Send(new GetDatabaseQuery()); var savePicker = new FileSavePicker { SuggestedStartLocation = PickerLocationId.DocumentsLibrary, @@ -101,7 +101,7 @@ namespace ModernKeePass Name = file.DisplayName, Path = token }; - await _mediator.Send(new SaveDatabaseCommand { FileInfo = fileInfo }); + await Mediator.Send(new SaveDatabaseCommand { FileInfo = fileInfo }); } }, null); } @@ -171,7 +171,7 @@ namespace ModernKeePass try { - var database = await _mediator.Send(new GetDatabaseQuery()); + var database = await Mediator.Send(new GetDatabaseQuery()); #if DEBUG ToastNotificationHelper.ShowGenericToast(database.Name, "Database reopened (changes were saved)"); #endif @@ -207,12 +207,12 @@ namespace ModernKeePass var deferral = e.SuspendingOperation.GetDeferral(); try { - var database = await _mediator.Send(new GetDatabaseQuery()); + var database = await Mediator.Send(new GetDatabaseQuery()); if (SettingsService.Instance.GetSetting("SaveSuspend", true)) { - await _mediator.Send(new SaveDatabaseCommand()); + await Mediator.Send(new SaveDatabaseCommand()); } - await _mediator.Send(new CloseDatabaseCommand()); + await Mediator.Send(new CloseDatabaseCommand()); } catch (Exception exception) { diff --git a/ModernKeePass/ViewModels/CompositeKeyVm.cs b/ModernKeePass/ViewModels/CompositeKeyVm.cs index 6bf5ac4..3276a89 100644 --- a/ModernKeePass/ViewModels/CompositeKeyVm.cs +++ b/ModernKeePass/ViewModels/CompositeKeyVm.cs @@ -3,12 +3,16 @@ using System.Runtime.InteropServices.WindowsRuntime; using System.Text; using System.Threading.Tasks; using Windows.Storage; +using Windows.Storage.AccessCache; +using MediatR; +using ModernKeePass.Application.Database.Commands.UpdateCredentials; +using ModernKeePass.Application.Database.Queries.OpenDatabase; using ModernKeePass.Common; +using ModernKeePass.Domain.Dtos; using ModernKeePass.Interfaces; using ModernKeePass.Services; using ModernKeePassLib.Cryptography; using ModernKeePassLib.Keys; -using ModernKeePassLib.Serialization; namespace ModernKeePass.ViewModels { @@ -21,9 +25,7 @@ namespace ModernKeePass.ViewModels Warning = 3, Success = 5 } - - public IDatabaseService Database { get; set; } - + public bool HasPassword { get { return _hasPassword; } @@ -110,15 +112,16 @@ namespace ModernKeePass.ViewModels private StatusTypes _statusType; private StorageFile _keyFile; private string _keyFileText; + private readonly IMediator _mediator; private readonly IResourceService _resource; - public CompositeKeyVm() : this(DatabaseService.Instance, new ResourcesService()) { } + public CompositeKeyVm() : this(App.Mediator, new ResourcesService()) { } - public CompositeKeyVm(IDatabaseService database, IResourceService resource) + public CompositeKeyVm(IMediator mediator, IResourceService resource) { + _mediator = mediator; _resource = resource; _keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile"); - Database = database; } public async Task OpenDatabase(StorageFile databaseFile, bool createNew) @@ -126,9 +129,15 @@ namespace ModernKeePass.ViewModels try { _isOpening = true; - OnPropertyChanged("IsValid"); - await Database.Open(databaseFile, await CreateCompositeKey(), createNew); - await Task.Run(() => RootGroup = Database.RootGroup); + OnPropertyChanged("IsValid");; + var fileInfo = new FileInfo + { + Name = databaseFile.DisplayName, + Path = StorageApplicationPermissions.FutureAccessList.Add(databaseFile) + }; + + var database = await _mediator.Send(new OpenDatabaseQuery { FileInfo = fileInfo, Credentials = CreateCredentials()}); + await Task.Run(() => RootGroup = new GroupVm(database.RootGroup)); return true; } catch (ArgumentException) @@ -154,7 +163,8 @@ namespace ModernKeePass.ViewModels public async Task UpdateKey() { - Database.UpdateCompositeKey(await CreateCompositeKey()); + //Database.UpdateCompositeKey(await CreateCompositeKey()); + await _mediator.Send(new UpdateCredentialsCommand {Credentials = CreateCredentials()}); UpdateStatus(_resource.GetResourceValue("CompositeKeyUpdated"), StatusTypes.Success); } @@ -172,17 +182,14 @@ namespace ModernKeePass.ViewModels StatusType = (int)type; } - private async Task CreateCompositeKey() + private Credentials CreateCredentials() { - var compositeKey = new CompositeKey(); - if (HasPassword) compositeKey.AddUserKey(new KcpPassword(Password)); - if (HasKeyFile && KeyFile != null) + var credentials = new Credentials { - var fileContents = await FileIO.ReadBufferAsync(KeyFile); - compositeKey.AddUserKey(new KcpKeyFile(IOConnectionInfo.FromByteArray(fileContents.ToArray()))); - } - if (HasUserAccount) compositeKey.AddUserKey(new KcpUserAccount()); - return compositeKey; + Password = HasPassword ? Password: null, + KeyFilePath = HasKeyFile && KeyFile != null ? StorageApplicationPermissions.FutureAccessList.Add(KeyFile) : null + }; + return credentials; } } } diff --git a/ModernKeePass/ViewModels/MainVm.cs b/ModernKeePass/ViewModels/MainVm.cs index 6569e83..8389e97 100644 --- a/ModernKeePass/ViewModels/MainVm.cs +++ b/ModernKeePass/ViewModels/MainVm.cs @@ -3,6 +3,8 @@ using System.Linq; using Windows.ApplicationModel; using Windows.Storage; using Windows.UI.Xaml.Controls; +using MediatR; +using ModernKeePass.Application.Database.Queries.GetDatabase; using ModernKeePass.Common; using ModernKeePass.Interfaces; using ModernKeePass.Services; @@ -46,12 +48,12 @@ namespace ModernKeePass.ViewModels public MainVm() {} internal MainVm(Frame referenceFrame, Frame destinationFrame, StorageFile databaseFile = null) : this(referenceFrame, destinationFrame, - DatabaseService.Instance, new ResourcesService(), RecentService.Instance, databaseFile) + App.Mediator, new ResourcesService(), RecentService.Instance, databaseFile) { } - public MainVm(Frame referenceFrame, Frame destinationFrame, IDatabaseService database, IResourceService resource, IRecentService recent, StorageFile databaseFile = null) + public MainVm(Frame referenceFrame, Frame destinationFrame, IMediator mediator, IResourceService resource, IRecentService recent, StorageFile databaseFile = null) { - var isDatabaseOpen = database != null && database.IsOpen; + var database = mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult(); var mainMenuItems = new ObservableCollection { @@ -79,8 +81,8 @@ namespace ModernKeePass.ViewModels Destination = destinationFrame, Parameter = referenceFrame, SymbolIcon = Symbol.Save, - IsSelected = isDatabaseOpen, - IsEnabled = isDatabaseOpen + IsSelected = database.IsOpen, + IsEnabled = database.IsOpen }, new MainMenuItemVm { @@ -89,9 +91,7 @@ namespace ModernKeePass.ViewModels Destination = destinationFrame, Parameter = referenceFrame, SymbolIcon = Symbol.Copy, - IsSelected = - (database == null || !database.IsOpen) && - recent.EntryCount > 0, + IsSelected = !database.IsOpen && recent.EntryCount > 0, IsEnabled = recent.EntryCount > 0 }, new MainMenuItemVm @@ -120,7 +120,7 @@ namespace ModernKeePass.ViewModels SelectedItem = mainMenuItems.FirstOrDefault(m => m.IsSelected); // Add currently opened database to the menu - if (database != null && database.IsOpen) + if (database.IsOpen) mainMenuItems.Add(new MainMenuItemVm { Title = database.Name, diff --git a/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs b/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs index cb06e50..6ca4515 100644 --- a/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs +++ b/ModernKeePass/Views/UserControls/CompositeKeyUserControl.xaml.cs @@ -6,6 +6,10 @@ using Windows.Storage.Pickers; using Windows.System; using Windows.UI.Xaml; using Windows.UI.Xaml.Input; +using MediatR; +using ModernKeePass.Application.Database.Commands.CloseDatabase; +using ModernKeePass.Application.Database.Commands.SaveDatabase; +using ModernKeePass.Application.Database.Queries.GetDatabase; using ModernKeePass.Common; using ModernKeePass.Events; using ModernKeePass.Extensions; @@ -19,6 +23,7 @@ namespace ModernKeePass.Views.UserControls { public sealed partial class CompositeKeyUserControl { + private readonly IMediator _mediator; public CompositeKeyVm Model => Grid.DataContext as CompositeKeyVm; public bool CreateNew @@ -71,8 +76,12 @@ namespace ModernKeePass.Views.UserControls public bool ShowComplexityIndicator => CreateNew || UpdateKey; - public CompositeKeyUserControl() + public CompositeKeyUserControl(): this(App.Mediator) + { } + + public CompositeKeyUserControl(IMediator mediator) { + _mediator = mediator; InitializeComponent(); } @@ -90,7 +99,7 @@ namespace ModernKeePass.Views.UserControls } else { - var database = DatabaseService.Instance; + var database = await _mediator.Send(new GetDatabaseQuery()); var resource = new ResourcesService(); if (database.IsOpen) { @@ -100,16 +109,16 @@ namespace ModernKeePass.Views.UserControls resource.GetResourceValue("MessageDialogDBOpenButtonDiscard"), async command => { - database.Save(); + await _mediator.Send(new SaveDatabaseCommand()); ToastNotificationHelper.ShowGenericToast( database.Name, resource.GetResourceValue("ToastSavedMessage")); - database.Close(false); + await _mediator.Send(new CloseDatabaseCommand()); await OpenDatabase(resource); }, async command => { - database.Close(false); + await _mediator.Send(new CloseDatabaseCommand()); await OpenDatabase(resource); }); } diff --git a/ModernKeePass/Win81App.csproj b/ModernKeePass/Win81App.csproj index 69f5709..f8f060e 100644 --- a/ModernKeePass/Win81App.csproj +++ b/ModernKeePass/Win81App.csproj @@ -133,7 +133,7 @@ DonatePage.xaml - +