From b61a9652d1d4cea49ea91e380e1084b565ba415f Mon Sep 17 00:00:00 2001 From: Geoffroy BONNEVILLE Date: Wed, 1 Apr 2020 19:37:30 +0200 Subject: [PATCH] WIP change to ids --- ModernKeePass.Application/Application.csproj | 6 +- .../Common/Interfaces/IDatabaseProxy.cs | 20 ++-- .../Common/Interfaces/IEntityVm.cs | 5 +- .../CreateDatabase/CreateDatabaseCommand.cs | 15 +-- .../Database/Models/DatabaseVm.cs | 4 +- .../Queries/GetDatabase/GetDatabaseQuery.cs | 4 +- .../Queries/OpenDatabase/OpenDatabaseQuery.cs | 20 ++-- .../ReOpenDatabase/ReOpenDatabaseQuery.cs | 15 +-- .../Entry/Models/EntryVm.cs | 7 +- .../Entry/Queries/GetEntry/GetEntryQuery.cs | 31 ++++++ .../CreateGroup/CreateGroupCommand.cs | 6 +- .../DeleteEntry/DeleteEntryCommand.cs | 31 ------ .../DeleteGroup/DeleteGroupCommand.cs | 31 ------ .../RemoveEntry/RemoveEntryCommand.cs | 3 +- .../RemoveGroup/RemoveGroupCommand.cs | 3 +- .../Group/Models/GroupVm.cs | 37 ++----- .../Group/Queries/GetGroup/GetGroupQuery.cs | 31 ++++++ ModernKeePass.Domain/Entities/BaseEntity.cs | 1 - .../KeePass/EntryMappingProfile.cs | 11 +- .../KeePass/GroupMappingProfile.cs | 6 +- .../KeePass/KeePassDatabaseClient.cs | 101 ++++++------------ ModernKeePass/Interfaces/IVmEntity.cs | 4 - ModernKeePass/ViewModels/EntryDetailVm.cs | 14 +-- ModernKeePass/ViewModels/GroupDetailVm.cs | 12 +-- 24 files changed, 156 insertions(+), 262 deletions(-) create mode 100644 ModernKeePass.Application/Entry/Queries/GetEntry/GetEntryQuery.cs delete mode 100644 ModernKeePass.Application/Group/Commands/DeleteEntry/DeleteEntryCommand.cs delete mode 100644 ModernKeePass.Application/Group/Commands/DeleteGroup/DeleteGroupCommand.cs create mode 100644 ModernKeePass.Application/Group/Queries/GetGroup/GetGroupQuery.cs diff --git a/ModernKeePass.Application/Application.csproj b/ModernKeePass.Application/Application.csproj index 1b819ed..a5bbcf3 100644 --- a/ModernKeePass.Application/Application.csproj +++ b/ModernKeePass.Application/Application.csproj @@ -51,6 +51,8 @@ + + @@ -79,8 +81,6 @@ - - @@ -94,9 +94,7 @@ - - diff --git a/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs b/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs index 99e85e7..70db0db 100644 --- a/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs +++ b/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs @@ -9,17 +9,16 @@ namespace ModernKeePass.Application.Common.Interfaces { bool IsOpen { get; } string Name { get; } - GroupEntity RootGroup { get; } - - GroupEntity RecycleBin { get; set; } + string RootGroupId { get; } + string RecycleBinId { get; set; } string CipherId { get; set; } string KeyDerivationId { get; set; } string Compression { get; set; } bool IsRecycleBinEnabled { get; set; } - Task Open(FileInfo fileInfo, Credentials credentials); - Task ReOpen(); - Task Create(FileInfo fileInfo, Credentials credentials, DatabaseVersion version = DatabaseVersion.V2); + Task Open(FileInfo fileInfo, Credentials credentials); + Task ReOpen(); + Task Create(FileInfo fileInfo, Credentials credentials, DatabaseVersion version = DatabaseVersion.V2); Task SaveDatabase(); Task SaveDatabase(string filePath); void SetRecycleBin(string id); @@ -31,14 +30,13 @@ namespace ModernKeePass.Application.Common.Interfaces Task AddGroup(string parentGroupId, string groupId); void UpdateEntry(string entryId, string fieldName, object fieldValue); void UpdateGroup(string groupId); - Task RemoveEntry(string parentGroupId, string entryId); - Task RemoveGroup(string parentGroupId, string groupId); + Task RemoveEntry(string parentGroupId, string entryId, bool isToBeDeleted); + Task RemoveGroup(string parentGroupId, string groupId, bool isToBeDeleted); 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); + EntryEntity GetEntry(string id); + GroupEntity GetGroup(string id); } } \ No newline at end of file diff --git a/ModernKeePass.Application/Common/Interfaces/IEntityVm.cs b/ModernKeePass.Application/Common/Interfaces/IEntityVm.cs index d334bd7..9a56b1b 100644 --- a/ModernKeePass.Application/Common/Interfaces/IEntityVm.cs +++ b/ModernKeePass.Application/Common/Interfaces/IEntityVm.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using ModernKeePass.Application.Group.Models; using ModernKeePass.Domain.Enums; namespace ModernKeePass.Application.Common.Interfaces @@ -9,7 +8,7 @@ namespace ModernKeePass.Application.Common.Interfaces string Id { get; set; } string Title { get; set; } Icon Icon { get; set; } - List Breadcrumb { get; } - GroupVm ParentGroup { get; set; } + List Breadcrumb { get; } + string ParentGroupId { get; set; } } } \ No newline at end of file diff --git a/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs b/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs index 7deafe1..4888c06 100644 --- a/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs +++ b/ModernKeePass.Application/Database/Commands/CreateDatabase/CreateDatabaseCommand.cs @@ -1,35 +1,31 @@ using MediatR; using System.Threading.Tasks; -using AutoMapper; using ModernKeePass.Application.Common.Interfaces; -using ModernKeePass.Application.Group.Models; using ModernKeePass.Domain.Dtos; using ModernKeePass.Domain.Exceptions; namespace ModernKeePass.Application.Database.Commands.CreateDatabase { - public class CreateDatabaseCommand : IRequest + public class CreateDatabaseCommand : IRequest { public string FilePath { get; set; } public string Password { get; set; } public string KeyFilePath { get; set; } - public class CreateDatabaseCommandHandler : IAsyncRequestHandler + public class CreateDatabaseCommandHandler : IAsyncRequestHandler { private readonly IDatabaseProxy _database; - private readonly IMapper _mapper; - public CreateDatabaseCommandHandler(IDatabaseProxy database, IMapper mapper) + public CreateDatabaseCommandHandler(IDatabaseProxy database) { _database = database; - _mapper = mapper; } - public async Task Handle(CreateDatabaseCommand message) + public async Task Handle(CreateDatabaseCommand message) { if (_database.IsOpen) throw new DatabaseOpenException(); - var rootGroup = await _database.Create( + await _database.Create( new FileInfo { Path = message.FilePath @@ -39,7 +35,6 @@ namespace ModernKeePass.Application.Database.Commands.CreateDatabase KeyFilePath = message.KeyFilePath, Password = message.Password }); - return GroupVm.BuildHierarchy(null, rootGroup, _mapper); } } diff --git a/ModernKeePass.Application/Database/Models/DatabaseVm.cs b/ModernKeePass.Application/Database/Models/DatabaseVm.cs index 2de796d..1b583d9 100644 --- a/ModernKeePass.Application/Database/Models/DatabaseVm.cs +++ b/ModernKeePass.Application/Database/Models/DatabaseVm.cs @@ -6,8 +6,8 @@ namespace ModernKeePass.Application.Database.Models { public bool IsOpen { get; set; } public string Name { get; set; } - public GroupVm RootGroup { get; set; } - public GroupVm RecycleBin { get; set; } + public string RootGroupId { get; set; } + public string RecycleBinId { get; set; } public bool IsRecycleBinEnabled { get; set; } public string Compression { get; set; } public string CipherId { get; set; } diff --git a/ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs b/ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs index a52dd86..927f929 100644 --- a/ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs +++ b/ModernKeePass.Application/Database/Queries/GetDatabase/GetDatabaseQuery.cs @@ -28,9 +28,9 @@ namespace ModernKeePass.Application.Database.Queries.GetDatabase if (database.IsOpen) { database.Name = _databaseProxy.Name; - database.RootGroup = GroupVm.BuildHierarchy(null, _databaseProxy.RootGroup, _mapper); + database.RootGroupId = _databaseProxy.RootGroupId; database.IsRecycleBinEnabled = _databaseProxy.IsRecycleBinEnabled; - database.RecycleBin = _mapper.Map(_databaseProxy.RecycleBin); + database.RecycleBinId = _databaseProxy.RecycleBinId; database.Compression = _databaseProxy.Compression; database.CipherId = _databaseProxy.CipherId; database.KeyDerivationId = _databaseProxy.CipherId; diff --git a/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs b/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs index 4d1eb0f..50fad37 100644 --- a/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs +++ b/ModernKeePass.Application/Database/Queries/OpenDatabase/OpenDatabaseQuery.cs @@ -1,38 +1,31 @@ -using System.Linq; -using System.Threading.Tasks; -using AutoMapper; +using System.Threading.Tasks; using MediatR; using ModernKeePass.Application.Common.Interfaces; -using ModernKeePass.Application.Entry.Models; -using ModernKeePass.Application.Group.Models; using ModernKeePass.Domain.Dtos; -using ModernKeePass.Domain.Entities; using ModernKeePass.Domain.Exceptions; namespace ModernKeePass.Application.Database.Queries.OpenDatabase { - public class OpenDatabaseQuery: IRequest + public class OpenDatabaseQuery: IRequest { public string FilePath { get; set; } public string Password { get; set; } public string KeyFilePath { get; set; } - public class OpenDatabaseQueryHandler : IAsyncRequestHandler + public class OpenDatabaseQueryHandler : IAsyncRequestHandler { - private readonly IMapper _mapper; private readonly IDatabaseProxy _database; - public OpenDatabaseQueryHandler(IMapper mapper, IDatabaseProxy database) + public OpenDatabaseQueryHandler(IDatabaseProxy database) { - _mapper = mapper; _database = database; } - public async Task Handle(OpenDatabaseQuery request) + public async Task Handle(OpenDatabaseQuery request) { if (_database.IsOpen) throw new DatabaseOpenException(); - var rootGroup = await _database.Open( + await _database.Open( new FileInfo { Path = request.FilePath @@ -42,7 +35,6 @@ namespace ModernKeePass.Application.Database.Queries.OpenDatabase KeyFilePath = request.KeyFilePath, Password = request.Password }); - return GroupVm.BuildHierarchy(null, rootGroup, _mapper); } } diff --git a/ModernKeePass.Application/Database/Queries/ReOpenDatabase/ReOpenDatabaseQuery.cs b/ModernKeePass.Application/Database/Queries/ReOpenDatabase/ReOpenDatabaseQuery.cs index 3e8a2e2..1911118 100644 --- a/ModernKeePass.Application/Database/Queries/ReOpenDatabase/ReOpenDatabaseQuery.cs +++ b/ModernKeePass.Application/Database/Queries/ReOpenDatabase/ReOpenDatabaseQuery.cs @@ -1,31 +1,26 @@ using System.Threading.Tasks; -using AutoMapper; using MediatR; using ModernKeePass.Application.Common.Interfaces; -using ModernKeePass.Application.Group.Models; using ModernKeePass.Domain.Exceptions; namespace ModernKeePass.Application.Database.Queries.ReOpenDatabase { - public class ReOpenDatabaseQuery: IRequest + public class ReOpenDatabaseQuery: IRequest { - public class ReOpenDatabaseQueryHandler : IAsyncRequestHandler + public class ReOpenDatabaseQueryHandler : IAsyncRequestHandler { - private readonly IMapper _mapper; private readonly IDatabaseProxy _database; - public ReOpenDatabaseQueryHandler(IMapper mapper, IDatabaseProxy database) + public ReOpenDatabaseQueryHandler(IDatabaseProxy database) { - _mapper = mapper; _database = database; } - public async Task Handle(ReOpenDatabaseQuery request) + public async Task Handle(ReOpenDatabaseQuery request) { if (!_database.IsOpen) throw new DatabaseClosedException(); - var rootGroup = await _database.ReOpen(); - return GroupVm.BuildHierarchy(null, rootGroup, _mapper); + await _database.ReOpen(); } } } diff --git a/ModernKeePass.Application/Entry/Models/EntryVm.cs b/ModernKeePass.Application/Entry/Models/EntryVm.cs index 401ead1..eb85d60 100644 --- a/ModernKeePass.Application/Entry/Models/EntryVm.cs +++ b/ModernKeePass.Application/Entry/Models/EntryVm.cs @@ -4,7 +4,6 @@ using System.Drawing; using AutoMapper; using ModernKeePass.Application.Common.Interfaces; using ModernKeePass.Application.Common.Mappings; -using ModernKeePass.Application.Group.Models; using ModernKeePass.Domain.Entities; using ModernKeePass.Domain.Enums; @@ -12,8 +11,8 @@ namespace ModernKeePass.Application.Entry.Models { public class EntryVm: IEntityVm, IMapFrom { - public GroupVm ParentGroup { get; set; } - public List Breadcrumb { get; } = new List(); + public string ParentGroupId { get; set; } + public List Breadcrumb { get; } = new List(); public string Id { get; set; } public string Title { get; set; } public string Username { get; set; } @@ -37,7 +36,7 @@ namespace ModernKeePass.Application.Entry.Models public void Mapping(Profile profile) { profile.CreateMap() - .ForMember(d => d.ParentGroup, opts => opts.Ignore()) + .ForMember(d => d.ParentGroupId, opts => opts.MapFrom(s => s.ParentId)) .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)) diff --git a/ModernKeePass.Application/Entry/Queries/GetEntry/GetEntryQuery.cs b/ModernKeePass.Application/Entry/Queries/GetEntry/GetEntryQuery.cs new file mode 100644 index 0000000..4bed9b1 --- /dev/null +++ b/ModernKeePass.Application/Entry/Queries/GetEntry/GetEntryQuery.cs @@ -0,0 +1,31 @@ +using AutoMapper; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Entry.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Entry.Queries.GetEntry +{ + public class GetEntryQuery: IRequest + { + public string Id { get; set; } + + public class GetEntryQueryHandler: IRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMapper _mapper; + + public GetEntryQueryHandler(IDatabaseProxy database, IMapper mapper) + { + _database = database; + _mapper = mapper; + } + + public EntryVm Handle(GetEntryQuery message) + { + if (!_database.IsOpen) throw new DatabaseClosedException(); + return _mapper.Map(_database.GetEntry(message.Id)); + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Commands/CreateGroup/CreateGroupCommand.cs b/ModernKeePass.Application/Group/Commands/CreateGroup/CreateGroupCommand.cs index 19efc17..2a4ba96 100644 --- a/ModernKeePass.Application/Group/Commands/CreateGroup/CreateGroupCommand.cs +++ b/ModernKeePass.Application/Group/Commands/CreateGroup/CreateGroupCommand.cs @@ -8,7 +8,7 @@ namespace ModernKeePass.Application.Group.Commands.CreateGroup { public class CreateGroupCommand : IRequest { - public GroupVm ParentGroup { get; set; } + public string ParentGroupId { get; set; } public string Name { get; set; } public bool IsRecycleBin { get; set; } @@ -27,10 +27,8 @@ namespace ModernKeePass.Application.Group.Commands.CreateGroup { if (!_database.IsOpen) throw new DatabaseClosedException(); - var group = _database.CreateGroup(message.ParentGroup.Id, message.Name, message.IsRecycleBin); + var group = _database.CreateGroup(message.ParentGroupId, message.Name, message.IsRecycleBin); var groupVm = _mapper.Map(group); - groupVm.ParentGroup = message.ParentGroup; - message.ParentGroup.SubGroups.Add(groupVm); return groupVm; } } diff --git a/ModernKeePass.Application/Group/Commands/DeleteEntry/DeleteEntryCommand.cs b/ModernKeePass.Application/Group/Commands/DeleteEntry/DeleteEntryCommand.cs deleted file mode 100644 index a344b7d..0000000 --- a/ModernKeePass.Application/Group/Commands/DeleteEntry/DeleteEntryCommand.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Threading.Tasks; -using MediatR; -using ModernKeePass.Application.Common.Interfaces; -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; - - public DeleteEntryCommandHandler(IDatabaseProxy database) - { - _database = database; - } - - public async Task Handle(DeleteEntryCommand message) - { - if (!_database.IsOpen) 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 deleted file mode 100644 index 37742b3..0000000 --- a/ModernKeePass.Application/Group/Commands/DeleteGroup/DeleteGroupCommand.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Threading.Tasks; -using MediatR; -using ModernKeePass.Application.Common.Interfaces; -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; - - public DeleteGroupCommandHandler(IDatabaseProxy database) - { - _database = database; - } - - public async Task Handle(DeleteGroupCommand message) - { - if (!_database.IsOpen) 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 index d097292..dd634b3 100644 --- a/ModernKeePass.Application/Group/Commands/RemoveEntry/RemoveEntryCommand.cs +++ b/ModernKeePass.Application/Group/Commands/RemoveEntry/RemoveEntryCommand.cs @@ -11,6 +11,7 @@ namespace ModernKeePass.Application.Group.Commands.RemoveEntry { public GroupVm ParentGroup { get; set; } public EntryVm Entry { get; set; } + public bool IsDelete { get; set; } public class RemoveEntryCommandHandler : IAsyncRequestHandler { @@ -25,7 +26,7 @@ namespace ModernKeePass.Application.Group.Commands.RemoveEntry { if (!_database.IsOpen) throw new DatabaseClosedException(); - await _database.RemoveEntry(message.ParentGroup.Id, message.Entry.Id); + await _database.RemoveEntry(message.ParentGroup.Id, message.Entry.Id, message.IsDelete); message.ParentGroup.Entries.Remove(message.Entry); } } diff --git a/ModernKeePass.Application/Group/Commands/RemoveGroup/RemoveGroupCommand.cs b/ModernKeePass.Application/Group/Commands/RemoveGroup/RemoveGroupCommand.cs index 7fe9230..0ce7509 100644 --- a/ModernKeePass.Application/Group/Commands/RemoveGroup/RemoveGroupCommand.cs +++ b/ModernKeePass.Application/Group/Commands/RemoveGroup/RemoveGroupCommand.cs @@ -10,6 +10,7 @@ namespace ModernKeePass.Application.Group.Commands.RemoveGroup { public GroupVm ParentGroup { get; set; } public GroupVm Group { get; set; } + public bool IsDelete { get; set; } public class RemoveGroupCommandHandler : IAsyncRequestHandler { @@ -24,7 +25,7 @@ namespace ModernKeePass.Application.Group.Commands.RemoveGroup { if (!_database.IsOpen) throw new DatabaseClosedException(); - await _database.RemoveGroup(message.ParentGroup.Id, message.Group.Id); + await _database.RemoveGroup(message.ParentGroup.Id, message.Group.Id, message.IsDelete); message.ParentGroup.SubGroups.Remove(message.Group); } } diff --git a/ModernKeePass.Application/Group/Models/GroupVm.cs b/ModernKeePass.Application/Group/Models/GroupVm.cs index d8eeee5..2bb8d09 100644 --- a/ModernKeePass.Application/Group/Models/GroupVm.cs +++ b/ModernKeePass.Application/Group/Models/GroupVm.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using AutoMapper; using ModernKeePass.Application.Common.Interfaces; using ModernKeePass.Application.Common.Mappings; @@ -13,11 +11,11 @@ namespace ModernKeePass.Application.Group.Models { public class GroupVm: IEntityVm, ISelectableModel, IMapFrom { - public GroupVm ParentGroup { get; set; } + public string ParentGroupId { get; set; } public string Id { get; set; } public string Title { get; set; } public Icon Icon { get; set; } - public List Breadcrumb { get; } = new List(); + public List Breadcrumb { get; } = new List(); public List SubGroups { get; set; } public List Entries { get; set; } public bool IsSelected { get; set; } @@ -30,34 +28,13 @@ namespace ModernKeePass.Application.Group.Models public void Mapping(Profile profile) { profile.CreateMap() - .ForMember(d => d.ParentGroup, opts => opts.Ignore()) + .ForMember(d => d.ParentGroupId, opts => opts.MapFrom(s => s.ParentId)) .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.Entries, opts => opts.Ignore()) - .ForMember(d => d.SubGroups, opts => opts.Ignore()); - } - - internal static GroupVm BuildHierarchy(GroupVm parentGroup, GroupEntity groupEntity, IMapper mapper) - { - var groupVm = mapper.Map(groupEntity); - groupVm.ParentGroup = parentGroup; - if (parentGroup != null) - { - groupVm.Breadcrumb.AddRange(parentGroup.Breadcrumb); - groupVm.Breadcrumb.Add(parentGroup); - } - groupVm.Entries = groupEntity.Entries.Select(e => - { - var entry = mapper.Map(e); - entry.ParentGroup = groupVm; - entry.Breadcrumb.AddRange(groupVm.Breadcrumb); - entry.Breadcrumb.Add(groupVm); - return entry; - }).OrderBy(e => e.Title).ToList(); - groupVm.SubGroups = groupEntity.SubGroups.Select(g => BuildHierarchy(groupVm, g, mapper)).ToList(); - - return groupVm; + .ForMember(d => d.Entries, opts => opts.MapFrom(s => s.Entries)) + .ForMember(d => d.SubGroups, opts => opts.MapFrom(s => s.SubGroups)) + .MaxDepth(1); } } } \ No newline at end of file diff --git a/ModernKeePass.Application/Group/Queries/GetGroup/GetGroupQuery.cs b/ModernKeePass.Application/Group/Queries/GetGroup/GetGroupQuery.cs new file mode 100644 index 0000000..89310d4 --- /dev/null +++ b/ModernKeePass.Application/Group/Queries/GetGroup/GetGroupQuery.cs @@ -0,0 +1,31 @@ +using AutoMapper; +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Queries.GetGroup +{ + public class GetGroupQuery : IRequest + { + public string Id { get; set; } + + public class GetGroupQueryHandler : IRequestHandler + { + private readonly IDatabaseProxy _database; + private readonly IMapper _mapper; + + public GetGroupQueryHandler(IDatabaseProxy database, IMapper mapper) + { + _database = database; + _mapper = mapper; + } + + public GroupVm Handle(GetGroupQuery message) + { + if (!_database.IsOpen) throw new DatabaseClosedException(); + return _mapper.Map(_database.GetGroup(message.Id)); + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Domain/Entities/BaseEntity.cs b/ModernKeePass.Domain/Entities/BaseEntity.cs index 8d12478..0c1586e 100644 --- a/ModernKeePass.Domain/Entities/BaseEntity.cs +++ b/ModernKeePass.Domain/Entities/BaseEntity.cs @@ -6,7 +6,6 @@ namespace ModernKeePass.Domain.Entities { public string Id { get; set; } public string Name { get; set; } - public GroupEntity ParentGroup { get; set; } public string ParentId { get; set; } public DateTimeOffset LastModificationDate { get; set; } } diff --git a/ModernKeePass.Infrastructure/KeePass/EntryMappingProfile.cs b/ModernKeePass.Infrastructure/KeePass/EntryMappingProfile.cs index 788e7d8..3095508 100644 --- a/ModernKeePass.Infrastructure/KeePass/EntryMappingProfile.cs +++ b/ModernKeePass.Infrastructure/KeePass/EntryMappingProfile.cs @@ -19,7 +19,6 @@ namespace ModernKeePass.Infrastructure.KeePass { Uri url; CreateMap() - .ForMember(dest => dest.ParentGroup, opt => opt.Ignore()) .ForMember(dest => dest.ParentId, opt => opt.MapFrom(src => src.ParentGroup.Uuid.ToHexString())) .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Uuid.ToHexString())) .ForMember(dest => dest.Name, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.TitleField))) @@ -27,7 +26,8 @@ namespace ModernKeePass.Infrastructure.KeePass .ForMember(dest => dest.Password, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.PasswordField))) .ForMember(dest => dest.Url, opt => { - opt.PreCondition(src => Uri.TryCreate(GetEntryValue(src, PwDefs.UrlField), UriKind.Absolute, out url)); + opt.PreCondition(src => + Uri.TryCreate(GetEntryValue(src, PwDefs.UrlField), UriKind.Absolute, out url)); opt.MapFrom(src => new Uri(GetEntryValue(src, PwDefs.UrlField))); }) .ForMember(dest => dest.Notes, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.NotesField))) @@ -37,8 +37,11 @@ namespace ModernKeePass.Infrastructure.KeePass .ForMember(dest => dest.HasExpirationDate, opt => opt.MapFrom(src => src.Expires)) .ForMember(dest => dest.Icon, opt => opt.MapFrom(src => IconMapper.MapPwIconToIcon(src.IconId))) .ForMember(dest => dest.AdditionalFields, opt => opt.MapFrom(src => - src.Strings.Where(s => !PwDefs.GetStandardFields().Contains(s.Key)).ToDictionary(s => s.Key, s => GetEntryValue(src, s.Key)))) - .ForMember(dest => dest.LastModificationDate, opt => opt.MapFrom(src => new DateTimeOffset(src.LastModificationTime))); + src.Strings.Where(s => !PwDefs.GetStandardFields().Contains(s.Key)) + .ToDictionary(s => s.Key, s => GetEntryValue(src, s.Key)))) + .ForMember(dest => dest.LastModificationDate, + opt => opt.MapFrom(src => new DateTimeOffset(src.LastModificationTime))) + .MaxDepth(1); } private void FromModelToDto() diff --git a/ModernKeePass.Infrastructure/KeePass/GroupMappingProfile.cs b/ModernKeePass.Infrastructure/KeePass/GroupMappingProfile.cs index 8831284..ffd8482 100644 --- a/ModernKeePass.Infrastructure/KeePass/GroupMappingProfile.cs +++ b/ModernKeePass.Infrastructure/KeePass/GroupMappingProfile.cs @@ -15,14 +15,14 @@ namespace ModernKeePass.Infrastructure.KeePass private void FromDtoToModel() { CreateMap() - .ForMember(dest => dest.ParentGroup, opt => opt.Ignore()) .ForMember(d => d.ParentId, opts => opts.MapFrom(s => s.ParentGroup.Uuid.ToHexString())) .ForMember(d => d.Id, opts => opts.MapFrom(s => s.Uuid.ToHexString())) .ForMember(d => d.Name, opts => opts.MapFrom(s => s.Name)) .ForMember(d => d.Icon, opts => opts.MapFrom(s => IconMapper.MapPwIconToIcon(s.IconId))) .ForMember(d => d.LastModificationDate, opts => opts.MapFrom(s => s.LastModificationTime)) - .ForMember(d => d.Entries, opts => opts.Ignore()) - .ForMember(d => d.SubGroups, opts => opts.Ignore()); + .ForMember(d => d.Entries, opts => opts.MapFrom(s => s.Entries)) + .ForMember(d => d.SubGroups, opts => opts.MapFrom(s => s.Groups)) + .MaxDepth(1); } private void FromModelToDto() diff --git a/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs b/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs index cd54b0d..e862eab 100644 --- a/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs +++ b/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs @@ -30,7 +30,7 @@ namespace ModernKeePass.Infrastructure.KeePass // Main information public bool IsOpen => (_pwDatabase?.IsOpen).GetValueOrDefault(); public string Name => _pwDatabase?.Name; - public GroupEntity RootGroup { get; private set; } + public string RootGroupId => _pwDatabase?.RootGroup.Uuid.ToHexString(); // Settings public bool IsRecycleBinEnabled @@ -39,19 +39,18 @@ namespace ModernKeePass.Infrastructure.KeePass set { _pwDatabase.RecycleBinEnabled = value; } } - public GroupEntity RecycleBin + public string RecycleBinId { get { if (_pwDatabase.RecycleBinEnabled) { - var pwGroup = _pwDatabase.RootGroup.FindGroup(_pwDatabase.RecycleBinUuid, true); - return _mapper.Map(pwGroup); + return _pwDatabase.RecycleBinUuid.ToHexString(); } return null; } - set { _pwDatabase.RecycleBinUuid = BuildIdFromString(value.Id); } + set { _pwDatabase.RecycleBinUuid = BuildIdFromString(value); } } public string CipherId @@ -83,7 +82,7 @@ namespace ModernKeePass.Infrastructure.KeePass _dateTime = dateTime; } - public async Task Open(FileInfo fileInfo, Credentials credentials) + public async Task Open(FileInfo fileInfo, Credentials credentials) { try { @@ -94,9 +93,6 @@ namespace ModernKeePass.Infrastructure.KeePass _credentials = credentials; _fileAccessToken = fileInfo.Path; - - RootGroup = BuildHierarchy(null, _pwDatabase.RootGroup); - return RootGroup; } catch (InvalidCompositeKeyException ex) { @@ -104,12 +100,12 @@ namespace ModernKeePass.Infrastructure.KeePass } } - public async Task ReOpen() + public async Task ReOpen() { - return await Open(new FileInfo {Path = _fileAccessToken}, _credentials); + await Open(new FileInfo {Path = _fileAccessToken}, _credentials); } - public async Task Create(FileInfo fileInfo, Credentials credentials, DatabaseVersion version = DatabaseVersion.V2) + public async Task Create(FileInfo fileInfo, Credentials credentials, DatabaseVersion version = DatabaseVersion.V2) { var compositeKey = await CreateCompositeKey(credentials); var ioConnection = await BuildConnectionInfo(fileInfo); @@ -124,9 +120,6 @@ namespace ModernKeePass.Infrastructure.KeePass } _fileAccessToken = fileInfo.Path; - - RootGroup = BuildHierarchy(null, _pwDatabase.RootGroup); - return RootGroup; } public async Task SaveDatabase() @@ -201,23 +194,33 @@ namespace ModernKeePass.Infrastructure.KeePass parentPwGroup.Groups.Add(pwGroup); }); } - public async Task RemoveEntry(string parentGroupId, string entryId) + public async Task RemoveEntry(string parentGroupId, string entryId, bool isToBeDeleted) { await Task.Run(() => { var parentPwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(parentGroupId), true); var pwEntry = parentPwGroup.FindEntry(BuildIdFromString(entryId), false); parentPwGroup.Entries.Remove(pwEntry); + + if (isToBeDeleted && (!_pwDatabase.RecycleBinEnabled || parentPwGroup.Uuid.Equals(_pwDatabase.RecycleBinUuid))) + { + _pwDatabase.DeletedObjects.Add(new PwDeletedObject(pwEntry.Uuid, _dateTime.Now)); + } }); } - public async Task RemoveGroup(string parentGroupId, string groupId) + public async Task RemoveGroup(string parentGroupId, string groupId, bool isToBeDeleted) { await Task.Run(() => { var parentPwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(parentGroupId), true); var pwGroup = parentPwGroup.FindGroup(BuildIdFromString(groupId), false); parentPwGroup.Groups.Remove(pwGroup); + + if (isToBeDeleted && (!_pwDatabase.RecycleBinEnabled || parentPwGroup.Uuid.Equals(_pwDatabase.RecycleBinUuid))) + { + _pwDatabase.DeletedObjects.Add(new PwDeletedObject(pwGroup.Uuid, _dateTime.Now)); + } }); } @@ -272,36 +275,6 @@ namespace ModernKeePass.Infrastructure.KeePass return _mapper.Map(pwGroup); } - public async Task DeleteEntry(string entryId) - { - await Task.Run(() => - { - var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true); - var id = pwEntry.Uuid; - pwEntry.ParentGroup.Entries.Remove(pwEntry); - - if (!_pwDatabase.RecycleBinEnabled || pwEntry.ParentGroup.Uuid.Equals(_pwDatabase.RecycleBinUuid)) - { - _pwDatabase.DeletedObjects.Add(new PwDeletedObject(id, DateTime.UtcNow)); - } - }); - } - - public async Task DeleteGroup(string groupId) - { - await Task.Run(() => - { - var pwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(groupId), true); - var id = pwGroup.Uuid; - pwGroup.ParentGroup.Groups.Remove(pwGroup); - - if (!_pwDatabase.RecycleBinEnabled || pwGroup.ParentGroup.Uuid.Equals(_pwDatabase.RecycleBinUuid)) - { - _pwDatabase.DeletedObjects.Add(new PwDeletedObject(id, DateTime.UtcNow)); - } - }); - } - public void SortEntries(string groupId) { var pwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(groupId), true); @@ -315,6 +288,18 @@ namespace ModernKeePass.Infrastructure.KeePass pwGroup.SortSubGroups(false); } + public EntryEntity GetEntry(string id) + { + var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(id), true); + return _mapper.Map(pwEntry); + } + + public GroupEntity GetGroup(string id) + { + var pwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(id), true); + return _mapper.Map(pwGroup); + } + public async Task UpdateCredentials(Credentials credentials) { _pwDatabase.MasterKey = await CreateCompositeKey(credentials); @@ -337,28 +322,6 @@ namespace ModernKeePass.Infrastructure.KeePass var fileContents = await _fileService.OpenBinaryFile(fileInfo.Path); return IOConnectionInfo.FromByteArray(fileContents); } - private GroupEntity BuildHierarchy(GroupEntity parentGroup, PwGroup pwGroup) - { - var group = _mapper.Map(pwGroup); - group.ParentGroup = parentGroup; - group.Entries = pwGroup.Entries.Select(e => - { - var entry = _mapper.Map(e); - entry.ParentGroup = group; - return entry; - }).ToList(); - group.SubGroups = pwGroup.Groups.Select(g => BuildHierarchy(group, g)).ToList(); - - /*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; - } private PwUuid BuildIdFromString(string id) { diff --git a/ModernKeePass/Interfaces/IVmEntity.cs b/ModernKeePass/Interfaces/IVmEntity.cs index 9860636..4b9a174 100644 --- a/ModernKeePass/Interfaces/IVmEntity.cs +++ b/ModernKeePass/Interfaces/IVmEntity.cs @@ -28,10 +28,6 @@ namespace ModernKeePass.Interfaces /// The destination to move the entity to Task Move(GroupVm destination); /// - /// Delete from Model - /// - Task CommitDelete(); - /// /// Delete from ViewModel /// Task MarkForDelete(string recycleBinTitle); diff --git a/ModernKeePass/ViewModels/EntryDetailVm.cs b/ModernKeePass/ViewModels/EntryDetailVm.cs index d43d15a..4af82d4 100644 --- a/ModernKeePass/ViewModels/EntryDetailVm.cs +++ b/ModernKeePass/ViewModels/EntryDetailVm.cs @@ -11,7 +11,6 @@ using ModernKeePass.Application.Database.Queries.GetDatabase; using ModernKeePass.Application.Entry.Commands.SetFieldValue; using ModernKeePass.Application.Group.Commands.AddEntry; using ModernKeePass.Application.Group.Commands.CreateGroup; -using ModernKeePass.Application.Group.Commands.DeleteEntry; using ModernKeePass.Application.Group.Commands.RemoveEntry; using ModernKeePass.Application.Security.Commands.GeneratePassword; using ModernKeePass.Application.Security.Queries.EstimatePasswordComplexity; @@ -266,18 +265,9 @@ namespace ModernKeePass.ViewModels public async Task Move(Application.Group.Models.GroupVm destination) { await _mediator.Send(new AddEntryCommand { ParentGroup = destination, Entry = _entry }); - await _mediator.Send(new RemoveEntryCommand { ParentGroup = _entry.ParentGroup, Entry = _entry }); - if (destination == null) - { - await _mediator.Send(new DeleteEntryCommand { Entry = _entry }); - } + await _mediator.Send(new RemoveEntryCommand { ParentGroup = _entry.ParentGroup, Entry = _entry, IsDelete = true }); } - - public async Task CommitDelete() - { - await _mediator.Send(new DeleteEntryCommand {Entry = _entry}); - } - + public Application.Entry.Models.EntryVm GetEntry() { return _entry; diff --git a/ModernKeePass/ViewModels/GroupDetailVm.cs b/ModernKeePass/ViewModels/GroupDetailVm.cs index 4506977..54df627 100644 --- a/ModernKeePass/ViewModels/GroupDetailVm.cs +++ b/ModernKeePass/ViewModels/GroupDetailVm.cs @@ -13,7 +13,6 @@ 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; @@ -182,16 +181,7 @@ namespace ModernKeePass.ViewModels public async Task Move(Application.Group.Models.GroupVm destination) { await _mediator.Send(new AddGroupCommand {ParentGroup = destination, Group = _group}); - await _mediator.Send(new RemoveGroupCommand {ParentGroup = _group.ParentGroup, Group = _group}); - if (destination == null) - { - await _mediator.Send(new DeleteGroupCommand { Group = _group }); - } - } - - public async Task CommitDelete() - { - await _mediator.Send(new DeleteGroupCommand { Group = _group }); + await _mediator.Send(new RemoveGroupCommand {ParentGroup = _group.ParentGroup, Group = _group, IsDelete = true }); } private async Task SortEntriesAsync()