From a17d6b05aebb0d6b23d68b6f28ee147b4f8df8cb Mon Sep 17 00:00:00 2001 From: Geoffroy BONNEVILLE Date: Thu, 26 Mar 2020 12:25:22 +0100 Subject: [PATCH] Added lots of commands Simplified KeePass client --- ModernKeePass.Application/Application.csproj | 24 ++- .../Common/Interfaces/IDatabaseProxy.cs | 36 ++-- .../Common/Mappings/MappingProfiles.cs | 1 - .../CreateDatabase/CreateDatabaseCommand.cs | 17 +- .../Database/Models/DatabaseVm.cs | 19 +- .../Queries/GetDatabase/GetDatabaseQuery.cs | 16 +- .../Queries/OpenDatabase/OpenDatabaseQuery.cs | 20 +- .../ReOpenDatabase/ReOpenDatabaseQuery.cs | 36 ++++ .../Entry/Models/EntryVm.cs | 22 ++- .../Commands/AddEntry/AddEntryCommand.cs | 54 +++++ .../Commands/AddGroup/AddGroupCommand.cs | 36 ++++ .../CreateEntry/CreateEntryCommand.cs | 41 ++++ .../CreateGroup/CreateGroupCommand.cs | 42 ++++ .../DeleteEntry/DeleteEntryCommand.cs | 35 ++++ .../DeleteGroup/DeleteGroupCommand.cs | 35 ++++ .../RemoveEntry/RemoveEntryCommand.cs | 37 ++++ .../RemoveGroup/RemoveGroupCommand.cs | 36 ++++ .../SortEntries/SortEntriesCommand.cs | 34 ++++ .../Commands/SortGroups/SortGroupsCommand.cs | 34 ++++ .../Group/Models/GroupVm.cs | 8 +- ModernKeePass.Domain/Domain.csproj | 3 +- ModernKeePass.Domain/Entities/BaseEntity.cs | 3 - .../Entities/DatabaseEntity.cs | 9 - ModernKeePass.Domain/Entities/EntryEntity.cs | 5 +- ModernKeePass.Domain/Interfaces/IDateTime.cs | 9 + .../Common/MachineDateTime.cs | 10 + .../Infrastructure.csproj | 3 + .../KeePass/GroupMappingProfile.cs | 31 +++ .../KeePass/KeePassDatabaseClient.cs | 184 +++++++++--------- .../AutomapperProfilesTest.cs | 95 +++++++++ .../Data/TestDatabase.kdbx | Bin 0 -> 1854 bytes .../KeePassDatabaseClientTests.cs | 155 +++++++++++++++ .../ModernKeePass.KeePassDatabaseTests.csproj | 38 ++++ ModernKeePass.sln | 23 ++- ModernKeePass/Actions/DeleteEntityAction.cs | 6 +- ModernKeePass/App.xaml.cs | 10 +- .../Common/ToastNotificationHelper.cs | 2 +- ModernKeePass/Events/PasswordEventArgs.cs | 2 +- .../Interfaces/{IPwEntity.cs => IVmEntity.cs} | 9 +- ModernKeePass/ViewModels/CompositeKeyVm.cs | 6 +- ModernKeePass/ViewModels/EntryVm.cs | 6 +- ModernKeePass/ViewModels/GroupVm.cs | 87 +++++---- ModernKeePass/Views/GroupDetailPage.xaml.cs | 6 +- .../BreadCrumbUserControl.xaml.cs | 8 +- .../HamburgerMenuUserControl.xaml.cs | 8 +- ModernKeePass/Win81App.csproj | 2 +- 46 files changed, 1057 insertions(+), 246 deletions(-) create mode 100644 ModernKeePass.Application/Database/Queries/ReOpenDatabase/ReOpenDatabaseQuery.cs create mode 100644 ModernKeePass.Application/Group/Commands/AddEntry/AddEntryCommand.cs create mode 100644 ModernKeePass.Application/Group/Commands/AddGroup/AddGroupCommand.cs create mode 100644 ModernKeePass.Application/Group/Commands/CreateEntry/CreateEntryCommand.cs create mode 100644 ModernKeePass.Application/Group/Commands/CreateGroup/CreateGroupCommand.cs create mode 100644 ModernKeePass.Application/Group/Commands/DeleteEntry/DeleteEntryCommand.cs create mode 100644 ModernKeePass.Application/Group/Commands/DeleteGroup/DeleteGroupCommand.cs create mode 100644 ModernKeePass.Application/Group/Commands/RemoveEntry/RemoveEntryCommand.cs create mode 100644 ModernKeePass.Application/Group/Commands/RemoveGroup/RemoveGroupCommand.cs create mode 100644 ModernKeePass.Application/Group/Commands/SortEntries/SortEntriesCommand.cs create mode 100644 ModernKeePass.Application/Group/Commands/SortGroups/SortGroupsCommand.cs delete mode 100644 ModernKeePass.Domain/Entities/DatabaseEntity.cs create mode 100644 ModernKeePass.Domain/Interfaces/IDateTime.cs create mode 100644 ModernKeePass.Infrastructure/Common/MachineDateTime.cs create mode 100644 ModernKeePass.Infrastructure/KeePass/GroupMappingProfile.cs create mode 100644 ModernKeePass.KeePassDatabaseTests/AutomapperProfilesTest.cs create mode 100644 ModernKeePass.KeePassDatabaseTests/Data/TestDatabase.kdbx create mode 100644 ModernKeePass.KeePassDatabaseTests/KeePassDatabaseClientTests.cs create mode 100644 ModernKeePass.KeePassDatabaseTests/ModernKeePass.KeePassDatabaseTests.csproj rename ModernKeePass/Interfaces/{IPwEntity.cs => IVmEntity.cs} (83%) diff --git a/ModernKeePass.Application/Application.csproj b/ModernKeePass.Application/Application.csproj index 1ba72ee..309be71 100644 --- a/ModernKeePass.Application/Application.csproj +++ b/ModernKeePass.Application/Application.csproj @@ -65,8 +65,19 @@ + + + + + + + + + + + @@ -79,14 +90,13 @@ - - - - - - + + - + + + + diff --git a/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs b/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs index 53c5252..d1cc6ba 100644 --- a/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs +++ b/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs @@ -8,22 +8,34 @@ namespace ModernKeePass.Application.Common.Interfaces { bool IsOpen { get; } string Name { get; } - GroupEntity RecycleBin { get; set; } - BaseEntity Cipher { get; set; } - BaseEntity KeyDerivation { get; set; } - string Compression { get; set; } + GroupEntity RootGroup { get; } - Task Open(FileInfo fileInfo, Credentials credentials); - Task Create(FileInfo fileInfo, Credentials credentials); + string RecycleBinId { get; set; } + string CipherId { get; set; } + string KeyDerivationId { get; set; } + string Compression { get; set; } + bool IsRecycleBinEnabled { get; } + + Task Open(FileInfo fileInfo, Credentials credentials); + Task ReOpen(); + Task Create(FileInfo fileInfo, Credentials credentials); Task SaveDatabase(); Task SaveDatabase(FileInfo FileInfo); Task UpdateCredentials(Credentials credentials); void CloseDatabase(); - Task AddEntry(GroupEntity parentGroup, EntryEntity entity); - Task AddGroup(GroupEntity parentGroup, GroupEntity entity); - Task UpdateEntry(EntryEntity entity); - Task UpdateGroup(GroupEntity entity); - Task DeleteEntry(EntryEntity entity); - Task DeleteGroup(GroupEntity entity); + + Task AddEntry(string parentGroupId, string entryId); + Task AddGroup(string parentGroupId, string groupId); + Task UpdateEntry(string entryId); + Task UpdateGroup(string groupId); + Task RemoveEntry(string parentGroupId, string entryId); + Task RemoveGroup(string parentGroupId, string groupId); + EntryEntity CreateEntry(string parentGroupId); + GroupEntity CreateGroup(string parentGroupId, string nameId, bool isRecycleBin = false); + Task DeleteEntry(string entryId); + Task DeleteGroup(string groupId); + + void SortEntries(string groupId); + void SortSubGroups(string groupId); } } \ No newline at end of file diff --git a/ModernKeePass.Application/Common/Mappings/MappingProfiles.cs b/ModernKeePass.Application/Common/Mappings/MappingProfiles.cs index dbd055d..4467ddf 100644 --- a/ModernKeePass.Application/Common/Mappings/MappingProfiles.cs +++ b/ModernKeePass.Application/Common/Mappings/MappingProfiles.cs @@ -9,7 +9,6 @@ namespace ModernKeePass.Application.Common.Mappings { public void ApplyMappings() { - new DatabaseVm().Mapping(this); new EntryVm().Mapping(this); new GroupVm().Mapping(this); } diff --git a/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs b/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs index c61eb9f..f8fb901 100644 --- a/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs +++ b/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using AutoMapper; using ModernKeePass.Application.Common.Interfaces; -using ModernKeePass.Application.Database.Models; using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; using ModernKeePass.Application.Group.Models; using ModernKeePass.Domain.Dtos; @@ -10,12 +9,12 @@ using ModernKeePass.Domain.Exceptions; namespace ModernKeePass.Application.Database.Commands.CreateDatabase { - public class CreateDatabaseCommand : IRequest + public class CreateDatabaseCommand : IRequest { public FileInfo FileInfo { get; set; } public Credentials Credentials { get; set; } - public class CreateDatabaseCommandHandler : IAsyncRequestHandler + public class CreateDatabaseCommandHandler : IAsyncRequestHandler { private readonly IDatabaseProxy _database; private readonly IMediator _mediator; @@ -28,19 +27,13 @@ namespace ModernKeePass.Application.Database.Commands.CreateDatabase _mapper = mapper; } - public async Task Handle(CreateDatabaseCommand message) + public async Task Handle(CreateDatabaseCommand message) { var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); if (isDatabaseOpen) throw new DatabaseOpenException(); - var database = await _database.Create(message.FileInfo, message.Credentials); - var databaseVm = new DatabaseVm - { - IsOpen = true, - Name = database.Name, - RootGroup = _mapper.Map(database.RootGroupEntity) - }; - return databaseVm; + var rootGroup = await _database.Create(message.FileInfo, message.Credentials); + return _mapper.Map(rootGroup); } } diff --git a/ModernKeePass.Application/Database/Models/DatabaseVm.cs b/ModernKeePass.Application/Database/Models/DatabaseVm.cs index bc7cbde..b3efd5d 100644 --- a/ModernKeePass.Application/Database/Models/DatabaseVm.cs +++ b/ModernKeePass.Application/Database/Models/DatabaseVm.cs @@ -1,21 +1,16 @@ -using AutoMapper; -using ModernKeePass.Application.Common.Mappings; -using ModernKeePass.Application.Group.Models; -using ModernKeePass.Domain.Entities; +using ModernKeePass.Application.Group.Models; namespace ModernKeePass.Application.Database.Models { - public class DatabaseVm: IMapFrom + public class DatabaseVm { public bool IsOpen { get; set; } public string Name { get; set; } public GroupVm RootGroup { get; set; } - - public void Mapping(Profile profile) - { - profile.CreateMap() - .ForMember(d => d.Name, opts => opts.MapFrom(s => s.Name)) - .ForMember(d => d.RootGroup, opts => opts.MapFrom(s => s.RootGroupEntity)); - } + public string RecycleBinId { get; set; } + public bool IsRecycleBinEnabled { get; set; } + public string Compression { get; set; } + public string CipherId { get; set; } + public string KeyDerivationId { get; set; } } } \ No newline at end of file diff --git a/ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs b/ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs index 259b73d..26d0c08 100644 --- a/ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs +++ b/ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs @@ -1,6 +1,8 @@ -using MediatR; +using AutoMapper; +using MediatR; using ModernKeePass.Application.Common.Interfaces; using ModernKeePass.Application.Database.Models; +using ModernKeePass.Application.Group.Models; namespace ModernKeePass.Application.Database.Queries.GetDatabase { @@ -9,10 +11,12 @@ namespace ModernKeePass.Application.Database.Queries.GetDatabase public class GetDatabaseQueryHandler : IRequestHandler { private readonly IDatabaseProxy _databaseProxy; + private readonly IMapper _mapper; - public GetDatabaseQueryHandler(IDatabaseProxy databaseProxy) + public GetDatabaseQueryHandler(IDatabaseProxy databaseProxy, IMapper mapper) { _databaseProxy = databaseProxy; + _mapper = mapper; } public DatabaseVm Handle(GetDatabaseQuery request) @@ -20,7 +24,13 @@ namespace ModernKeePass.Application.Database.Queries.GetDatabase var database = new DatabaseVm { IsOpen = _databaseProxy.IsOpen, - Name = _databaseProxy.Name + Name = _databaseProxy.Name, + RootGroup = _mapper.Map(_databaseProxy.RootGroup), + IsRecycleBinEnabled = _databaseProxy.IsRecycleBinEnabled, + RecycleBinId = _databaseProxy.RecycleBinId, + Compression = _databaseProxy.Compression, + CipherId = _databaseProxy.CipherId, + KeyDerivationId = _databaseProxy.CipherId }; return database; } diff --git a/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs b/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs index 4febd77..2dfcd66 100644 --- a/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs +++ b/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs @@ -1,9 +1,7 @@ -using System.Threading; -using System.Threading.Tasks; +using System.Threading.Tasks; using AutoMapper; using MediatR; using ModernKeePass.Application.Common.Interfaces; -using ModernKeePass.Application.Database.Models; using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; using ModernKeePass.Application.Group.Models; using ModernKeePass.Domain.Dtos; @@ -11,12 +9,12 @@ using ModernKeePass.Domain.Exceptions; namespace ModernKeePass.Application.Database.Queries.OpenDatabase { - public class OpenDatabaseQuery: IRequest + public class OpenDatabaseQuery: IRequest { public FileInfo FileInfo { get; set; } public Credentials Credentials { get; set; } - public class OpenDatabaseQueryHandler : IAsyncRequestHandler + public class OpenDatabaseQueryHandler : IAsyncRequestHandler { private readonly IMapper _mapper; private readonly IMediator _mediator; @@ -29,19 +27,13 @@ namespace ModernKeePass.Application.Database.Queries.OpenDatabase _databaseProxy = databaseProxy; } - public async Task Handle(OpenDatabaseQuery request) + public async Task Handle(OpenDatabaseQuery request) { var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); if (isDatabaseOpen) throw new DatabaseOpenException(); - var database = await _databaseProxy.Open(request.FileInfo, request.Credentials); - var databaseVm = new DatabaseVm - { - IsOpen = true, - Name = database.Name, - RootGroup = _mapper.Map(database.RootGroupEntity) - }; - return databaseVm; + var rootGroup = await _databaseProxy.Open(request.FileInfo, request.Credentials); + return _mapper.Map(rootGroup); } } } diff --git a/ModernKeePass.Application/Database/Queries/ReOpenDatabase/ReOpenDatabaseQuery.cs b/ModernKeePass.Application/Database/Queries/ReOpenDatabase/ReOpenDatabaseQuery.cs new file mode 100644 index 0000000..3625f9b --- /dev/null +++ b/ModernKeePass.Application/Database/Queries/ReOpenDatabase/ReOpenDatabaseQuery.cs @@ -0,0 +1,36 @@ +using System.Threading.Tasks; +using AutoMapper; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Database.Queries.ReOpenDatabase +{ + public class ReOpenDatabaseQuery: IRequest + { + public class ReOpenDatabaseQueryHandler : IAsyncRequestHandler + { + private readonly IMapper _mapper; + private readonly IMediator _mediator; + private readonly IDatabaseProxy _databaseProxy; + + public ReOpenDatabaseQueryHandler(IMapper mapper, IMediator mediator, IDatabaseProxy databaseProxy) + { + _mapper = mapper; + _mediator = mediator; + _databaseProxy = databaseProxy; + } + + public async Task Handle(ReOpenDatabaseQuery request) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (!isDatabaseOpen) throw new DatabaseClosedException(); + + var rootGroup = await _databaseProxy.ReOpen(); + return _mapper.Map(rootGroup); + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Entry/Models/EntryVm.cs b/ModernKeePass.Application/Entry/Models/EntryVm.cs index 44f6bcd..ea13b79 100644 --- a/ModernKeePass.Application/Entry/Models/EntryVm.cs +++ b/ModernKeePass.Application/Entry/Models/EntryVm.cs @@ -1,4 +1,6 @@ -using System.Drawing; +using System; +using System.Collections.Generic; +using System.Drawing; using AutoMapper; using ModernKeePass.Application.Common.Mappings; using ModernKeePass.Domain.Entities; @@ -10,15 +12,33 @@ namespace ModernKeePass.Application.Entry.Models { public string Id { get; set; } public string Title { get; set; } + public string Username { get; set; } + public string Password { get; set; } + public string Notes { get; set; } + public Uri Url { get; set; } + public Dictionary AdditionalFields { get; set; } + public IEnumerable History { get; set; } public Icon Icon { get; set; } public Color ForegroundColor { get; set; } public Color BackgroundColor { get; set; } + public bool HasExpirationDate { get; internal set; } + public DateTimeOffset ExpirationDate { get; internal set; } + public DateTimeOffset ModificationDate { get; internal set; } public void Mapping(Profile profile) { profile.CreateMap() .ForMember(d => d.Id, opts => opts.MapFrom(s => s.Id)) .ForMember(d => d.Title, opts => opts.MapFrom(s => s.Name)) + .ForMember(d => d.Username, opts => opts.MapFrom(s => s.UserName)) + .ForMember(d => d.Password, opts => opts.MapFrom(s => s.Password)) + .ForMember(d => d.Url, opts => opts.MapFrom(s => s.Url)) + .ForMember(d => d.Notes, opts => opts.MapFrom(s => s.Notes)) + .ForMember(d => d.AdditionalFields, opts => opts.MapFrom(s => s.AdditionalFields)) + .ForMember(d => d.History, opts => opts.MapFrom(s => s.History)) + .ForMember(d => d.HasExpirationDate, opts => opts.MapFrom(s => s.HasExpirationDate)) + .ForMember(d => d.ExpirationDate, opts => opts.MapFrom(s => s.ExpirationDate)) + .ForMember(d => d.ModificationDate, opts => opts.MapFrom(s => s.LastModificationDate)) .ForMember(d => d.Icon, opts => opts.MapFrom(s => s.Icon)) .ForMember(d => d.ForegroundColor, opts => opts.MapFrom(s => s.ForegroundColor)) .ForMember(d => d.BackgroundColor, opts => opts.MapFrom(s => s.BackgroundColor)); diff --git a/ModernKeePass.Application/Group/Commands/AddEntry/AddEntryCommand.cs b/ModernKeePass.Application/Group/Commands/AddEntry/AddEntryCommand.cs new file mode 100644 index 0000000..a1a1f27 --- /dev/null +++ b/ModernKeePass.Application/Group/Commands/AddEntry/AddEntryCommand.cs @@ -0,0 +1,54 @@ +using System.Threading.Tasks; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Application.Entry.Models; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Commands.AddEntry +{ + public class AddEntryCommand : IRequest + { + public GroupVm ParentGroup { get; set; } + public EntryVm Entry { get; set; } + + public class AddEntryCommandHandler : IAsyncRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMediator _mediator; + + public AddEntryCommandHandler(IDatabaseProxy database, IMediator mediator) + { + _database = database; + _mediator = mediator; + } + + public async Task Handle(AddEntryCommand message) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (!isDatabaseOpen) throw new DatabaseClosedException(); + /*var entryEntity = new EntryEntity + { + Id = message.Entry.Id, + Name = message.Entry.Title, + UserName = message.Entry.Username, + Password = message.Entry.Password, + Url = message.Entry.Url, + Notes = message.Entry.Notes, + HasExpirationDate = message.Entry.HasExpirationDate, + ExpirationDate = message.Entry.ExpirationDate, + LastModificationDate = message.Entry.ModificationDate, + BackgroundColor = message.Entry.BackgroundColor, + ForegroundColor = message.Entry.ForegroundColor, + Icon = message.Entry.Icon, + AdditionalFields = message.Entry.AdditionalFields, + History = message.Entry.History + };*/ + + await _database.AddEntry(message.ParentGroup.Id, message.Entry.Id); + message.ParentGroup.Entries.Add(message.Entry); + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Commands/AddGroup/AddGroupCommand.cs b/ModernKeePass.Application/Group/Commands/AddGroup/AddGroupCommand.cs new file mode 100644 index 0000000..d947041 --- /dev/null +++ b/ModernKeePass.Application/Group/Commands/AddGroup/AddGroupCommand.cs @@ -0,0 +1,36 @@ +using System.Threading.Tasks; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Commands.AddGroup +{ + public class AddGroupCommand : IRequest + { + public GroupVm ParentGroup { get; set; } + public GroupVm Group { get; set; } + + public class AddGroupCommandHandler : IAsyncRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMediator _mediator; + + public AddGroupCommandHandler(IDatabaseProxy database, IMediator mediator) + { + _database = database; + _mediator = mediator; + } + + public async Task Handle(AddGroupCommand message) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (!isDatabaseOpen) throw new DatabaseClosedException(); + + await _database.AddGroup(message.ParentGroup.Id, message.Group.Id); + message.ParentGroup.SubGroups.Add(message.Group); + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Commands/CreateEntry/CreateEntryCommand.cs b/ModernKeePass.Application/Group/Commands/CreateEntry/CreateEntryCommand.cs new file mode 100644 index 0000000..09c5040 --- /dev/null +++ b/ModernKeePass.Application/Group/Commands/CreateEntry/CreateEntryCommand.cs @@ -0,0 +1,41 @@ +using System.Threading.Tasks; +using AutoMapper; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Application.Entry.Models; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Commands.CreateEntry +{ + public class CreateEntryCommand : IRequest + { + public GroupVm ParentGroup { get; set; } + + public class CreateEntryCommandHandler : IAsyncRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMediator _mediator; + private readonly IMapper _mapper; + + public CreateEntryCommandHandler(IDatabaseProxy database, IMediator mediator, IMapper mapper) + { + _database = database; + _mediator = mediator; + _mapper = mapper; + } + + public async Task Handle(CreateEntryCommand message) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (!isDatabaseOpen) throw new DatabaseClosedException(); + + var entry = _database.CreateEntry(message.ParentGroup.Id); + var entryVm = _mapper.Map(entry); + message.ParentGroup.Entries.Add(entryVm); + return entryVm; + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Commands/CreateGroup/CreateGroupCommand.cs b/ModernKeePass.Application/Group/Commands/CreateGroup/CreateGroupCommand.cs new file mode 100644 index 0000000..727185b --- /dev/null +++ b/ModernKeePass.Application/Group/Commands/CreateGroup/CreateGroupCommand.cs @@ -0,0 +1,42 @@ +using System.Threading.Tasks; +using AutoMapper; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Commands.CreateGroup +{ + public class CreateGroupCommand : IRequest + { + public GroupVm ParentGroup { get; set; } + public string Name { get; set; } + public bool IsRecycleBin { get; set; } + + public class CreateGroupCommandHandler : IAsyncRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMediator _mediator; + private readonly IMapper _mapper; + + public CreateGroupCommandHandler(IDatabaseProxy database, IMediator mediator, IMapper mapper) + { + _database = database; + _mediator = mediator; + _mapper = mapper; + } + + public async Task Handle(CreateGroupCommand message) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (!isDatabaseOpen) throw new DatabaseClosedException(); + + var group = _database.CreateGroup(message.ParentGroup.Id, message.Name, message.IsRecycleBin); + var groupVm = _mapper.Map(group); + message.ParentGroup.SubGroups.Add(groupVm); + return groupVm; + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Commands/DeleteEntry/DeleteEntryCommand.cs b/ModernKeePass.Application/Group/Commands/DeleteEntry/DeleteEntryCommand.cs new file mode 100644 index 0000000..5365f11 --- /dev/null +++ b/ModernKeePass.Application/Group/Commands/DeleteEntry/DeleteEntryCommand.cs @@ -0,0 +1,35 @@ +using System.Threading.Tasks; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Application.Entry.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Commands.DeleteEntry +{ + public class DeleteEntryCommand : IRequest + { + public EntryVm Entry { get; set; } + + public class DeleteEntryCommandHandler : IAsyncRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMediator _mediator; + + public DeleteEntryCommandHandler(IDatabaseProxy database, IMediator mediator) + { + _database = database; + _mediator = mediator; + } + + public async Task Handle(DeleteEntryCommand message) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (!isDatabaseOpen) throw new DatabaseClosedException(); + + await _database.DeleteEntry(message.Entry.Id); + message.Entry = null; + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Commands/DeleteGroup/DeleteGroupCommand.cs b/ModernKeePass.Application/Group/Commands/DeleteGroup/DeleteGroupCommand.cs new file mode 100644 index 0000000..7106748 --- /dev/null +++ b/ModernKeePass.Application/Group/Commands/DeleteGroup/DeleteGroupCommand.cs @@ -0,0 +1,35 @@ +using System.Threading.Tasks; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Commands.DeleteGroup +{ + public class DeleteGroupCommand : IRequest + { + public GroupVm Group { get; set; } + + public class DeleteGroupCommandHandler : IAsyncRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMediator _mediator; + + public DeleteGroupCommandHandler(IDatabaseProxy database, IMediator mediator) + { + _database = database; + _mediator = mediator; + } + + public async Task Handle(DeleteGroupCommand message) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (!isDatabaseOpen) throw new DatabaseClosedException(); + + await _database.DeleteGroup(message.Group.Id); + message.Group = null; + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Commands/RemoveEntry/RemoveEntryCommand.cs b/ModernKeePass.Application/Group/Commands/RemoveEntry/RemoveEntryCommand.cs new file mode 100644 index 0000000..ac20cdd --- /dev/null +++ b/ModernKeePass.Application/Group/Commands/RemoveEntry/RemoveEntryCommand.cs @@ -0,0 +1,37 @@ +using System.Threading.Tasks; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Application.Entry.Models; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Commands.RemoveEntry +{ + public class RemoveEntryCommand : IRequest + { + public GroupVm ParentGroup { get; set; } + public EntryVm Entry { get; set; } + + public class RemoveEntryCommandHandler : IAsyncRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMediator _mediator; + + public RemoveEntryCommandHandler(IDatabaseProxy database, IMediator mediator) + { + _database = database; + _mediator = mediator; + } + + public async Task Handle(RemoveEntryCommand message) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (!isDatabaseOpen) throw new DatabaseClosedException(); + + await _database.RemoveEntry(message.ParentGroup.Id, message.Entry.Id); + message.ParentGroup.Entries.Remove(message.Entry); + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Commands/RemoveGroup/RemoveGroupCommand.cs b/ModernKeePass.Application/Group/Commands/RemoveGroup/RemoveGroupCommand.cs new file mode 100644 index 0000000..4c02df6 --- /dev/null +++ b/ModernKeePass.Application/Group/Commands/RemoveGroup/RemoveGroupCommand.cs @@ -0,0 +1,36 @@ +using System.Threading.Tasks; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Commands.RemoveGroup +{ + public class RemoveGroupCommand : IRequest + { + public GroupVm ParentGroup { get; set; } + public GroupVm Group { get; set; } + + public class RemoveGroupCommandHandler : IAsyncRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMediator _mediator; + + public RemoveGroupCommandHandler(IDatabaseProxy database, IMediator mediator) + { + _database = database; + _mediator = mediator; + } + + public async Task Handle(RemoveGroupCommand message) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (!isDatabaseOpen) throw new DatabaseClosedException(); + + await _database.RemoveGroup(message.ParentGroup.Id, message.Group.Id); + message.ParentGroup.SubGroups.Remove(message.Group); + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Commands/SortEntries/SortEntriesCommand.cs b/ModernKeePass.Application/Group/Commands/SortEntries/SortEntriesCommand.cs new file mode 100644 index 0000000..77d31e6 --- /dev/null +++ b/ModernKeePass.Application/Group/Commands/SortEntries/SortEntriesCommand.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Commands.SortEntries +{ + public class SortEntriesCommand : IRequest + { + public GroupVm Group { get; set; } + + public class SortEntriesCommandHandler : IAsyncRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMediator _mediator; + + public SortEntriesCommandHandler(IDatabaseProxy database, IMediator mediator) + { + _database = database; + _mediator = mediator; + } + + public async Task Handle(SortEntriesCommand message) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (!isDatabaseOpen) throw new DatabaseClosedException(); + + _database.SortEntries(message.Group.Id); + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Commands/SortGroups/SortGroupsCommand.cs b/ModernKeePass.Application/Group/Commands/SortGroups/SortGroupsCommand.cs new file mode 100644 index 0000000..c194135 --- /dev/null +++ b/ModernKeePass.Application/Group/Commands/SortGroups/SortGroupsCommand.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Database.Queries.IsDatabaseOpen; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Commands.SortGroups +{ + public class SortGroupsCommand : IRequest + { + public GroupVm Group { get; set; } + + public class SortGroupsCommandHandler : IAsyncRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMediator _mediator; + + public SortGroupsCommandHandler(IDatabaseProxy database, IMediator mediator) + { + _database = database; + _mediator = mediator; + } + + public async Task Handle(SortGroupsCommand message) + { + var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery()); + if (!isDatabaseOpen) throw new DatabaseClosedException(); + + _database.SortSubGroups(message.Group.Id); + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Models/GroupVm.cs b/ModernKeePass.Application/Group/Models/GroupVm.cs index 3ba48f7..359fbb0 100644 --- a/ModernKeePass.Application/Group/Models/GroupVm.cs +++ b/ModernKeePass.Application/Group/Models/GroupVm.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using System.Drawing; +using System.Linq; using AutoMapper; using ModernKeePass.Application.Common.Mappings; using ModernKeePass.Application.Entry.Models; @@ -13,8 +13,6 @@ namespace ModernKeePass.Application.Group.Models public string Id { get; set; } public string Title { get; set; } public Icon Icon { get; set; } - public Color ForegroundColor { get; set; } - public Color BackgroundColor { get; set; } public List SubGroups { get; set; } = new List(); public List Entries { get; set; } = new List(); @@ -24,9 +22,7 @@ namespace ModernKeePass.Application.Group.Models .ForMember(d => d.Id, opts => opts.MapFrom(s => s.Id)) .ForMember(d => d.Title, opts => opts.MapFrom(s => s.Name)) .ForMember(d => d.Icon, opts => opts.MapFrom(s => s.Icon)) - .ForMember(d => d.ForegroundColor, opts => opts.MapFrom(s => s.ForegroundColor)) - .ForMember(d => d.BackgroundColor, opts => opts.MapFrom(s => s.BackgroundColor)) - .ForMember(d => d.Entries, opts => opts.MapFrom(s => s.Entries)) + .ForMember(d => d.Entries, opts => opts.MapFrom(s => s.Entries.OrderBy(e => e.Name))) .ForMember(d => d.SubGroups, opts => opts.MapFrom(s => s.SubGroups)); } } diff --git a/ModernKeePass.Domain/Domain.csproj b/ModernKeePass.Domain/Domain.csproj index 90f30a6..13f6177 100644 --- a/ModernKeePass.Domain/Domain.csproj +++ b/ModernKeePass.Domain/Domain.csproj @@ -44,7 +44,6 @@ - @@ -54,8 +53,10 @@ + +