mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
Added lots of commands
Simplified KeePass client
This commit is contained in:
@@ -65,8 +65,19 @@
|
|||||||
<Compile Include="Database\Queries\IsDatabaseOpen\IsDatabaseOpenQuery.cs" />
|
<Compile Include="Database\Queries\IsDatabaseOpen\IsDatabaseOpenQuery.cs" />
|
||||||
<Compile Include="Database\Queries\OpenDatabase\OpenDatabaseQuery.cs" />
|
<Compile Include="Database\Queries\OpenDatabase\OpenDatabaseQuery.cs" />
|
||||||
<Compile Include="Database\Queries\OpenDatabase\OpenDatabaseQueryValidator.cs" />
|
<Compile Include="Database\Queries\OpenDatabase\OpenDatabaseQueryValidator.cs" />
|
||||||
|
<Compile Include="Database\Queries\ReOpenDatabase\ReOpenDatabaseQuery.cs" />
|
||||||
<Compile Include="DependencyInjection.cs" />
|
<Compile Include="DependencyInjection.cs" />
|
||||||
<Compile Include="Entry\Models\EntryVm.cs" />
|
<Compile Include="Entry\Models\EntryVm.cs" />
|
||||||
|
<Compile Include="Group\Commands\AddEntry\AddEntryCommand.cs" />
|
||||||
|
<Compile Include="Group\Commands\AddGroup\AddGroupCommand.cs" />
|
||||||
|
<Compile Include="Group\Commands\CreateEntry\CreateEntryCommand.cs" />
|
||||||
|
<Compile Include="Group\Commands\CreateGroup\CreateGroupCommand.cs" />
|
||||||
|
<Compile Include="Group\Commands\DeleteEntry\DeleteEntryCommand.cs" />
|
||||||
|
<Compile Include="Group\Commands\DeleteGroup\DeleteGroupCommand.cs" />
|
||||||
|
<Compile Include="Group\Commands\RemoveEntry\RemoveEntryCommand.cs" />
|
||||||
|
<Compile Include="Group\Commands\RemoveGroup\RemoveGroupCommand.cs" />
|
||||||
|
<Compile Include="Group\Commands\SortEntries\SortEntriesCommand.cs" />
|
||||||
|
<Compile Include="Group\Commands\SortGroups\SortGroupsCommand.cs" />
|
||||||
<Compile Include="Group\Models\GroupVm.cs" />
|
<Compile Include="Group\Models\GroupVm.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Content Include="Services\CryptographyService.cs" />
|
<Content Include="Services\CryptographyService.cs" />
|
||||||
@@ -79,14 +90,13 @@
|
|||||||
<Content Include="Services\SettingsService.cs" />
|
<Content Include="Services\SettingsService.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Entry\Commands\UpdateEntry\" />
|
<Folder Include="Entry\Commands\SetFieldValue\" />
|
||||||
<Folder Include="Entry\Queries\" />
|
<Folder Include="Entry\Queries\GetEntry\" />
|
||||||
<Folder Include="Group\Commands\CreateEntry\" />
|
|
||||||
<Folder Include="Group\Commands\CreateGroup\" />
|
|
||||||
<Folder Include="Group\Commands\DeleteEntry\" />
|
|
||||||
<Folder Include="Group\Commands\DeleteGroup\" />
|
|
||||||
<Folder Include="Group\Commands\UpdateGroup\" />
|
<Folder Include="Group\Commands\UpdateGroup\" />
|
||||||
<Folder Include="Group\Queries\" />
|
<Folder Include="Group\Queries\GetGroup\" />
|
||||||
|
<Folder Include="Parameters\Commands\SetCipher\" />
|
||||||
|
<Folder Include="Parameters\Commands\SetCompression\" />
|
||||||
|
<Folder Include="Parameters\Commands\SetKeyDerivation\" />
|
||||||
<Folder Include="Resources\Commands\" />
|
<Folder Include="Resources\Commands\" />
|
||||||
<Folder Include="Resources\Queries\" />
|
<Folder Include="Resources\Queries\" />
|
||||||
<Folder Include="Settings\" />
|
<Folder Include="Settings\" />
|
||||||
|
@@ -8,22 +8,34 @@ namespace ModernKeePass.Application.Common.Interfaces
|
|||||||
{
|
{
|
||||||
bool IsOpen { get; }
|
bool IsOpen { get; }
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
GroupEntity RecycleBin { get; set; }
|
GroupEntity RootGroup { get; }
|
||||||
BaseEntity Cipher { get; set; }
|
|
||||||
BaseEntity KeyDerivation { get; set; }
|
|
||||||
string Compression { get; set; }
|
|
||||||
|
|
||||||
Task<DatabaseEntity> Open(FileInfo fileInfo, Credentials credentials);
|
string RecycleBinId { get; set; }
|
||||||
Task<DatabaseEntity> Create(FileInfo fileInfo, Credentials credentials);
|
string CipherId { get; set; }
|
||||||
|
string KeyDerivationId { get; set; }
|
||||||
|
string Compression { get; set; }
|
||||||
|
bool IsRecycleBinEnabled { get; }
|
||||||
|
|
||||||
|
Task<GroupEntity> Open(FileInfo fileInfo, Credentials credentials);
|
||||||
|
Task<GroupEntity> ReOpen();
|
||||||
|
Task<GroupEntity> Create(FileInfo fileInfo, Credentials credentials);
|
||||||
Task SaveDatabase();
|
Task SaveDatabase();
|
||||||
Task SaveDatabase(FileInfo FileInfo);
|
Task SaveDatabase(FileInfo FileInfo);
|
||||||
Task UpdateCredentials(Credentials credentials);
|
Task UpdateCredentials(Credentials credentials);
|
||||||
void CloseDatabase();
|
void CloseDatabase();
|
||||||
Task AddEntry(GroupEntity parentGroup, EntryEntity entity);
|
|
||||||
Task AddGroup(GroupEntity parentGroup, GroupEntity entity);
|
Task AddEntry(string parentGroupId, string entryId);
|
||||||
Task UpdateEntry(EntryEntity entity);
|
Task AddGroup(string parentGroupId, string groupId);
|
||||||
Task UpdateGroup(GroupEntity entity);
|
Task UpdateEntry(string entryId);
|
||||||
Task DeleteEntry(EntryEntity entity);
|
Task UpdateGroup(string groupId);
|
||||||
Task DeleteGroup(GroupEntity entity);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -9,7 +9,6 @@ namespace ModernKeePass.Application.Common.Mappings
|
|||||||
{
|
{
|
||||||
public void ApplyMappings()
|
public void ApplyMappings()
|
||||||
{
|
{
|
||||||
new DatabaseVm().Mapping(this);
|
|
||||||
new EntryVm().Mapping(this);
|
new EntryVm().Mapping(this);
|
||||||
new GroupVm().Mapping(this);
|
new GroupVm().Mapping(this);
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using ModernKeePass.Application.Common.Interfaces;
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
using ModernKeePass.Application.Database.Models;
|
|
||||||
using ModernKeePass.Application.Database.Queries.IsDatabaseOpen;
|
using ModernKeePass.Application.Database.Queries.IsDatabaseOpen;
|
||||||
using ModernKeePass.Application.Group.Models;
|
using ModernKeePass.Application.Group.Models;
|
||||||
using ModernKeePass.Domain.Dtos;
|
using ModernKeePass.Domain.Dtos;
|
||||||
@@ -10,12 +9,12 @@ using ModernKeePass.Domain.Exceptions;
|
|||||||
|
|
||||||
namespace ModernKeePass.Application.Database.Commands.CreateDatabase
|
namespace ModernKeePass.Application.Database.Commands.CreateDatabase
|
||||||
{
|
{
|
||||||
public class CreateDatabaseCommand : IRequest<DatabaseVm>
|
public class CreateDatabaseCommand : IRequest<GroupVm>
|
||||||
{
|
{
|
||||||
public FileInfo FileInfo { get; set; }
|
public FileInfo FileInfo { get; set; }
|
||||||
public Credentials Credentials { get; set; }
|
public Credentials Credentials { get; set; }
|
||||||
|
|
||||||
public class CreateDatabaseCommandHandler : IAsyncRequestHandler<CreateDatabaseCommand, DatabaseVm>
|
public class CreateDatabaseCommandHandler : IAsyncRequestHandler<CreateDatabaseCommand, GroupVm>
|
||||||
{
|
{
|
||||||
private readonly IDatabaseProxy _database;
|
private readonly IDatabaseProxy _database;
|
||||||
private readonly IMediator _mediator;
|
private readonly IMediator _mediator;
|
||||||
@@ -28,19 +27,13 @@ namespace ModernKeePass.Application.Database.Commands.CreateDatabase
|
|||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DatabaseVm> Handle(CreateDatabaseCommand message)
|
public async Task<GroupVm> Handle(CreateDatabaseCommand message)
|
||||||
{
|
{
|
||||||
var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery());
|
var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery());
|
||||||
if (isDatabaseOpen) throw new DatabaseOpenException();
|
if (isDatabaseOpen) throw new DatabaseOpenException();
|
||||||
|
|
||||||
var database = await _database.Create(message.FileInfo, message.Credentials);
|
var rootGroup = await _database.Create(message.FileInfo, message.Credentials);
|
||||||
var databaseVm = new DatabaseVm
|
return _mapper.Map<GroupVm>(rootGroup);
|
||||||
{
|
|
||||||
IsOpen = true,
|
|
||||||
Name = database.Name,
|
|
||||||
RootGroup = _mapper.Map<GroupVm>(database.RootGroupEntity)
|
|
||||||
};
|
|
||||||
return databaseVm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,21 +1,16 @@
|
|||||||
using AutoMapper;
|
using ModernKeePass.Application.Group.Models;
|
||||||
using ModernKeePass.Application.Common.Mappings;
|
|
||||||
using ModernKeePass.Application.Group.Models;
|
|
||||||
using ModernKeePass.Domain.Entities;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Application.Database.Models
|
namespace ModernKeePass.Application.Database.Models
|
||||||
{
|
{
|
||||||
public class DatabaseVm: IMapFrom<DatabaseEntity>
|
public class DatabaseVm
|
||||||
{
|
{
|
||||||
public bool IsOpen { get; set; }
|
public bool IsOpen { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public GroupVm RootGroup { get; set; }
|
public GroupVm RootGroup { get; set; }
|
||||||
|
public string RecycleBinId { get; set; }
|
||||||
public void Mapping(Profile profile)
|
public bool IsRecycleBinEnabled { get; set; }
|
||||||
{
|
public string Compression { get; set; }
|
||||||
profile.CreateMap<DatabaseEntity, DatabaseVm>()
|
public string CipherId { get; set; }
|
||||||
.ForMember(d => d.Name, opts => opts.MapFrom(s => s.Name))
|
public string KeyDerivationId { get; set; }
|
||||||
.ForMember(d => d.RootGroup, opts => opts.MapFrom(s => s.RootGroupEntity));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,6 +1,8 @@
|
|||||||
using MediatR;
|
using AutoMapper;
|
||||||
|
using MediatR;
|
||||||
using ModernKeePass.Application.Common.Interfaces;
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
using ModernKeePass.Application.Database.Models;
|
using ModernKeePass.Application.Database.Models;
|
||||||
|
using ModernKeePass.Application.Group.Models;
|
||||||
|
|
||||||
namespace ModernKeePass.Application.Database.Queries.GetDatabase
|
namespace ModernKeePass.Application.Database.Queries.GetDatabase
|
||||||
{
|
{
|
||||||
@@ -9,10 +11,12 @@ namespace ModernKeePass.Application.Database.Queries.GetDatabase
|
|||||||
public class GetDatabaseQueryHandler : IRequestHandler<GetDatabaseQuery, DatabaseVm>
|
public class GetDatabaseQueryHandler : IRequestHandler<GetDatabaseQuery, DatabaseVm>
|
||||||
{
|
{
|
||||||
private readonly IDatabaseProxy _databaseProxy;
|
private readonly IDatabaseProxy _databaseProxy;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
public GetDatabaseQueryHandler(IDatabaseProxy databaseProxy)
|
public GetDatabaseQueryHandler(IDatabaseProxy databaseProxy, IMapper mapper)
|
||||||
{
|
{
|
||||||
_databaseProxy = databaseProxy;
|
_databaseProxy = databaseProxy;
|
||||||
|
_mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DatabaseVm Handle(GetDatabaseQuery request)
|
public DatabaseVm Handle(GetDatabaseQuery request)
|
||||||
@@ -20,7 +24,13 @@ namespace ModernKeePass.Application.Database.Queries.GetDatabase
|
|||||||
var database = new DatabaseVm
|
var database = new DatabaseVm
|
||||||
{
|
{
|
||||||
IsOpen = _databaseProxy.IsOpen,
|
IsOpen = _databaseProxy.IsOpen,
|
||||||
Name = _databaseProxy.Name
|
Name = _databaseProxy.Name,
|
||||||
|
RootGroup = _mapper.Map<GroupVm>(_databaseProxy.RootGroup),
|
||||||
|
IsRecycleBinEnabled = _databaseProxy.IsRecycleBinEnabled,
|
||||||
|
RecycleBinId = _databaseProxy.RecycleBinId,
|
||||||
|
Compression = _databaseProxy.Compression,
|
||||||
|
CipherId = _databaseProxy.CipherId,
|
||||||
|
KeyDerivationId = _databaseProxy.CipherId
|
||||||
};
|
};
|
||||||
return database;
|
return database;
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
using System.Threading;
|
using System.Threading.Tasks;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using ModernKeePass.Application.Common.Interfaces;
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
using ModernKeePass.Application.Database.Models;
|
|
||||||
using ModernKeePass.Application.Database.Queries.IsDatabaseOpen;
|
using ModernKeePass.Application.Database.Queries.IsDatabaseOpen;
|
||||||
using ModernKeePass.Application.Group.Models;
|
using ModernKeePass.Application.Group.Models;
|
||||||
using ModernKeePass.Domain.Dtos;
|
using ModernKeePass.Domain.Dtos;
|
||||||
@@ -11,12 +9,12 @@ using ModernKeePass.Domain.Exceptions;
|
|||||||
|
|
||||||
namespace ModernKeePass.Application.Database.Queries.OpenDatabase
|
namespace ModernKeePass.Application.Database.Queries.OpenDatabase
|
||||||
{
|
{
|
||||||
public class OpenDatabaseQuery: IRequest<DatabaseVm>
|
public class OpenDatabaseQuery: IRequest<GroupVm>
|
||||||
{
|
{
|
||||||
public FileInfo FileInfo { get; set; }
|
public FileInfo FileInfo { get; set; }
|
||||||
public Credentials Credentials { get; set; }
|
public Credentials Credentials { get; set; }
|
||||||
|
|
||||||
public class OpenDatabaseQueryHandler : IAsyncRequestHandler<OpenDatabaseQuery, DatabaseVm>
|
public class OpenDatabaseQueryHandler : IAsyncRequestHandler<OpenDatabaseQuery, GroupVm>
|
||||||
{
|
{
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
private readonly IMediator _mediator;
|
private readonly IMediator _mediator;
|
||||||
@@ -29,19 +27,13 @@ namespace ModernKeePass.Application.Database.Queries.OpenDatabase
|
|||||||
_databaseProxy = databaseProxy;
|
_databaseProxy = databaseProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DatabaseVm> Handle(OpenDatabaseQuery request)
|
public async Task<GroupVm> Handle(OpenDatabaseQuery request)
|
||||||
{
|
{
|
||||||
var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery());
|
var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery());
|
||||||
if (isDatabaseOpen) throw new DatabaseOpenException();
|
if (isDatabaseOpen) throw new DatabaseOpenException();
|
||||||
|
|
||||||
var database = await _databaseProxy.Open(request.FileInfo, request.Credentials);
|
var rootGroup = await _databaseProxy.Open(request.FileInfo, request.Credentials);
|
||||||
var databaseVm = new DatabaseVm
|
return _mapper.Map<GroupVm>(rootGroup);
|
||||||
{
|
|
||||||
IsOpen = true,
|
|
||||||
Name = database.Name,
|
|
||||||
RootGroup = _mapper.Map<GroupVm>(database.RootGroupEntity)
|
|
||||||
};
|
|
||||||
return databaseVm;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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<GroupVm>
|
||||||
|
{
|
||||||
|
public class ReOpenDatabaseQueryHandler : IAsyncRequestHandler<ReOpenDatabaseQuery, GroupVm>
|
||||||
|
{
|
||||||
|
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<GroupVm> Handle(ReOpenDatabaseQuery request)
|
||||||
|
{
|
||||||
|
var isDatabaseOpen = await _mediator.Send(new IsDatabaseOpenQuery());
|
||||||
|
if (!isDatabaseOpen) throw new DatabaseClosedException();
|
||||||
|
|
||||||
|
var rootGroup = await _databaseProxy.ReOpen();
|
||||||
|
return _mapper.Map<GroupVm>(rootGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,6 @@
|
|||||||
using System.Drawing;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using ModernKeePass.Application.Common.Mappings;
|
using ModernKeePass.Application.Common.Mappings;
|
||||||
using ModernKeePass.Domain.Entities;
|
using ModernKeePass.Domain.Entities;
|
||||||
@@ -10,15 +12,33 @@ namespace ModernKeePass.Application.Entry.Models
|
|||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string Title { 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<string, string> AdditionalFields { get; set; }
|
||||||
|
public IEnumerable<EntryEntity> History { get; set; }
|
||||||
public Icon Icon { get; set; }
|
public Icon Icon { get; set; }
|
||||||
public Color ForegroundColor { get; set; }
|
public Color ForegroundColor { get; set; }
|
||||||
public Color BackgroundColor { 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)
|
public void Mapping(Profile profile)
|
||||||
{
|
{
|
||||||
profile.CreateMap<EntryEntity, EntryVm>()
|
profile.CreateMap<EntryEntity, EntryVm>()
|
||||||
.ForMember(d => d.Id, opts => opts.MapFrom(s => s.Id))
|
.ForMember(d => d.Id, opts => opts.MapFrom(s => s.Id))
|
||||||
.ForMember(d => d.Title, opts => opts.MapFrom(s => s.Name))
|
.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.Icon, opts => opts.MapFrom(s => s.Icon))
|
||||||
.ForMember(d => d.ForegroundColor, opts => opts.MapFrom(s => s.ForegroundColor))
|
.ForMember(d => d.ForegroundColor, opts => opts.MapFrom(s => s.ForegroundColor))
|
||||||
.ForMember(d => d.BackgroundColor, opts => opts.MapFrom(s => s.BackgroundColor));
|
.ForMember(d => d.BackgroundColor, opts => opts.MapFrom(s => s.BackgroundColor));
|
||||||
|
@@ -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<AddEntryCommand>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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<AddGroupCommand>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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<EntryVm>
|
||||||
|
{
|
||||||
|
public GroupVm ParentGroup { get; set; }
|
||||||
|
|
||||||
|
public class CreateEntryCommandHandler : IAsyncRequestHandler<CreateEntryCommand, EntryVm>
|
||||||
|
{
|
||||||
|
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<EntryVm> 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<EntryVm>(entry);
|
||||||
|
message.ParentGroup.Entries.Add(entryVm);
|
||||||
|
return entryVm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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<GroupVm>
|
||||||
|
{
|
||||||
|
public GroupVm ParentGroup { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public bool IsRecycleBin { get; set; }
|
||||||
|
|
||||||
|
public class CreateGroupCommandHandler : IAsyncRequestHandler<CreateGroupCommand, GroupVm>
|
||||||
|
{
|
||||||
|
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<GroupVm> 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<GroupVm>(group);
|
||||||
|
message.ParentGroup.SubGroups.Add(groupVm);
|
||||||
|
return groupVm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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<DeleteEntryCommand>
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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<DeleteGroupCommand>
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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<RemoveEntryCommand>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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<RemoveGroupCommand>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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<SortEntriesCommand>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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<SortGroupsCommand>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Linq;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using ModernKeePass.Application.Common.Mappings;
|
using ModernKeePass.Application.Common.Mappings;
|
||||||
using ModernKeePass.Application.Entry.Models;
|
using ModernKeePass.Application.Entry.Models;
|
||||||
@@ -13,8 +13,6 @@ namespace ModernKeePass.Application.Group.Models
|
|||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public Icon Icon { get; set; }
|
public Icon Icon { get; set; }
|
||||||
public Color ForegroundColor { get; set; }
|
|
||||||
public Color BackgroundColor { get; set; }
|
|
||||||
public List<GroupVm> SubGroups { get; set; } = new List<GroupVm>();
|
public List<GroupVm> SubGroups { get; set; } = new List<GroupVm>();
|
||||||
public List<EntryVm> Entries { get; set; } = new List<EntryVm>();
|
public List<EntryVm> Entries { get; set; } = new List<EntryVm>();
|
||||||
|
|
||||||
@@ -24,9 +22,7 @@ namespace ModernKeePass.Application.Group.Models
|
|||||||
.ForMember(d => d.Id, opts => opts.MapFrom(s => s.Id))
|
.ForMember(d => d.Id, opts => opts.MapFrom(s => s.Id))
|
||||||
.ForMember(d => d.Title, opts => opts.MapFrom(s => s.Name))
|
.ForMember(d => d.Title, opts => opts.MapFrom(s => s.Name))
|
||||||
.ForMember(d => d.Icon, opts => opts.MapFrom(s => s.Icon))
|
.ForMember(d => d.Icon, opts => opts.MapFrom(s => s.Icon))
|
||||||
.ForMember(d => d.ForegroundColor, opts => opts.MapFrom(s => s.ForegroundColor))
|
.ForMember(d => d.Entries, opts => opts.MapFrom(s => s.Entries.OrderBy(e => e.Name)))
|
||||||
.ForMember(d => d.BackgroundColor, opts => opts.MapFrom(s => s.BackgroundColor))
|
|
||||||
.ForMember(d => d.Entries, opts => opts.MapFrom(s => s.Entries))
|
|
||||||
.ForMember(d => d.SubGroups, opts => opts.MapFrom(s => s.SubGroups));
|
.ForMember(d => d.SubGroups, opts => opts.MapFrom(s => s.SubGroups));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -44,7 +44,6 @@
|
|||||||
<Compile Include="Dtos\FileInfo.cs" />
|
<Compile Include="Dtos\FileInfo.cs" />
|
||||||
<Compile Include="Dtos\PasswordGenerationOptions.cs" />
|
<Compile Include="Dtos\PasswordGenerationOptions.cs" />
|
||||||
<Compile Include="Entities\BaseEntity.cs" />
|
<Compile Include="Entities\BaseEntity.cs" />
|
||||||
<Compile Include="Entities\DatabaseEntity.cs" />
|
|
||||||
<Compile Include="Entities\EntryEntity.cs" />
|
<Compile Include="Entities\EntryEntity.cs" />
|
||||||
<Compile Include="Entities\GroupEntity.cs" />
|
<Compile Include="Entities\GroupEntity.cs" />
|
||||||
<Compile Include="Enums\CredentialStatusTypes.cs" />
|
<Compile Include="Enums\CredentialStatusTypes.cs" />
|
||||||
@@ -54,8 +53,10 @@
|
|||||||
<Compile Include="Exceptions\DatabaseOpenException.cs" />
|
<Compile Include="Exceptions\DatabaseOpenException.cs" />
|
||||||
<Compile Include="Exceptions\NavigationException.cs" />
|
<Compile Include="Exceptions\NavigationException.cs" />
|
||||||
<Compile Include="Exceptions\SaveException.cs" />
|
<Compile Include="Exceptions\SaveException.cs" />
|
||||||
|
<Compile Include="Interfaces\IDateTime.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Domain.Entities
|
namespace ModernKeePass.Domain.Entities
|
||||||
{
|
{
|
||||||
@@ -7,8 +6,6 @@ namespace ModernKeePass.Domain.Entities
|
|||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public Color ForegroundColor { get; set; }
|
|
||||||
public Color BackgroundColor { get; set; }
|
|
||||||
public DateTimeOffset LastModificationDate { get; set; }
|
public DateTimeOffset LastModificationDate { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,9 +0,0 @@
|
|||||||
namespace ModernKeePass.Domain.Entities
|
|
||||||
{
|
|
||||||
public class DatabaseEntity
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public GroupEntity RootGroupEntity { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
using ModernKeePass.Domain.Enums;
|
using ModernKeePass.Domain.Enums;
|
||||||
|
|
||||||
namespace ModernKeePass.Domain.Entities
|
namespace ModernKeePass.Domain.Entities
|
||||||
@@ -12,8 +13,10 @@ namespace ModernKeePass.Domain.Entities
|
|||||||
public string Notes { get; set; }
|
public string Notes { get; set; }
|
||||||
public DateTimeOffset ExpirationDate { get; set; }
|
public DateTimeOffset ExpirationDate { get; set; }
|
||||||
public Dictionary<string, string> AdditionalFields { get; set; } = new Dictionary<string, string>();
|
public Dictionary<string, string> AdditionalFields { get; set; } = new Dictionary<string, string>();
|
||||||
public IEnumerable<EntryEntity> History { get; set; }
|
public IEnumerable<EntryEntity> History { get; set; } = new List<EntryEntity>();
|
||||||
public Icon Icon { get; set; }
|
public Icon Icon { get; set; }
|
||||||
|
public Color ForegroundColor { get; set; }
|
||||||
|
public Color BackgroundColor { get; set; }
|
||||||
public bool HasExpirationDate { get; set; }
|
public bool HasExpirationDate { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
9
ModernKeePass.Domain/Interfaces/IDateTime.cs
Normal file
9
ModernKeePass.Domain/Interfaces/IDateTime.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ModernKeePass.Domain.Interfaces
|
||||||
|
{
|
||||||
|
public interface IDateTime
|
||||||
|
{
|
||||||
|
DateTime Now { get; }
|
||||||
|
}
|
||||||
|
}
|
10
ModernKeePass.Infrastructure/Common/MachineDateTime.cs
Normal file
10
ModernKeePass.Infrastructure/Common/MachineDateTime.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
using ModernKeePass.Domain.Interfaces;
|
||||||
|
|
||||||
|
namespace ModernKeePass.Infrastructure.Common
|
||||||
|
{
|
||||||
|
public class MachineDateTime: IDateTime
|
||||||
|
{
|
||||||
|
public DateTime Now => DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
@@ -40,10 +40,12 @@
|
|||||||
<None Include="project.json" />
|
<None Include="project.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Common\MachineDateTime.cs" />
|
||||||
<Compile Include="DependencyInjection.cs" />
|
<Compile Include="DependencyInjection.cs" />
|
||||||
<Compile Include="InfrastructureModule.cs" />
|
<Compile Include="InfrastructureModule.cs" />
|
||||||
<Compile Include="File\CsvImportFormat.cs" />
|
<Compile Include="File\CsvImportFormat.cs" />
|
||||||
<Compile Include="KeePass\EntryMappingProfile.cs" />
|
<Compile Include="KeePass\EntryMappingProfile.cs" />
|
||||||
|
<Compile Include="KeePass\GroupMappingProfile.cs" />
|
||||||
<Compile Include="KeePass\IconMapper.cs" />
|
<Compile Include="KeePass\IconMapper.cs" />
|
||||||
<Compile Include="KeePass\KeePassCryptographyClient.cs" />
|
<Compile Include="KeePass\KeePassCryptographyClient.cs" />
|
||||||
<Compile Include="KeePass\KeePassDatabaseClient.cs" />
|
<Compile Include="KeePass\KeePassDatabaseClient.cs" />
|
||||||
@@ -71,6 +73,7 @@
|
|||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
31
ModernKeePass.Infrastructure/KeePass/GroupMappingProfile.cs
Normal file
31
ModernKeePass.Infrastructure/KeePass/GroupMappingProfile.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using ModernKeePass.Domain.Entities;
|
||||||
|
using ModernKeePassLib;
|
||||||
|
|
||||||
|
namespace ModernKeePass.Infrastructure.KeePass
|
||||||
|
{
|
||||||
|
public class GroupMappingProfile : Profile
|
||||||
|
{
|
||||||
|
public GroupMappingProfile()
|
||||||
|
{
|
||||||
|
FromModelToDto();
|
||||||
|
FromDtoToModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FromDtoToModel()
|
||||||
|
{
|
||||||
|
CreateMap<PwGroup, GroupEntity>()
|
||||||
|
.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.MapFrom(s => s.Entries))
|
||||||
|
.ForMember(d => d.SubGroups, opts => opts.MapFrom(s => s.Groups));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FromModelToDto()
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -7,7 +7,6 @@ using ModernKeePass.Domain.Dtos;
|
|||||||
using ModernKeePass.Domain.Entities;
|
using ModernKeePass.Domain.Entities;
|
||||||
using ModernKeePass.Domain.Exceptions;
|
using ModernKeePass.Domain.Exceptions;
|
||||||
using ModernKeePassLib;
|
using ModernKeePassLib;
|
||||||
using ModernKeePassLib.Cryptography.Cipher;
|
|
||||||
using ModernKeePassLib.Cryptography.KeyDerivation;
|
using ModernKeePassLib.Cryptography.KeyDerivation;
|
||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
using ModernKeePassLib.Keys;
|
using ModernKeePassLib.Keys;
|
||||||
@@ -23,68 +22,41 @@ namespace ModernKeePass.Infrastructure.KeePass
|
|||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
private readonly PwDatabase _pwDatabase = new PwDatabase();
|
private readonly PwDatabase _pwDatabase = new PwDatabase();
|
||||||
private string _fileAccessToken;
|
private string _fileAccessToken;
|
||||||
private CompositeKey _compositeKey;
|
private Credentials _credentials;
|
||||||
|
|
||||||
// Main information
|
// Main information
|
||||||
public bool IsOpen => (_pwDatabase?.IsOpen).GetValueOrDefault();
|
public bool IsOpen => (_pwDatabase?.IsOpen).GetValueOrDefault();
|
||||||
public string Name => _pwDatabase?.Name;
|
public string Name => _pwDatabase?.Name;
|
||||||
public GroupEntity RootGroup { get; set; }
|
public GroupEntity RootGroup { get; private set; }
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
public GroupEntity RecycleBin
|
public string RecycleBinId
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_pwDatabase.RecycleBinEnabled)
|
if (_pwDatabase.RecycleBinEnabled)
|
||||||
{
|
{
|
||||||
var pwGroup = _pwDatabase.RootGroup.FindGroup(_pwDatabase.RecycleBinUuid, true);
|
var pwGroup = _pwDatabase.RootGroup.FindGroup(_pwDatabase.RecycleBinUuid, true);
|
||||||
var group = new GroupEntity
|
return pwGroup.Uuid.ToHexString();
|
||||||
{
|
|
||||||
Id = pwGroup.Uuid.ToHexString(),
|
|
||||||
Name = pwGroup.Name,
|
|
||||||
Icon = IconMapper.MapPwIconToIcon(pwGroup.IconId),
|
|
||||||
Entries = pwGroup.Entries.Select(e => _mapper.Map<EntryEntity>(e)).ToList(),
|
|
||||||
SubGroups = pwGroup.Groups.Select(BuildHierarchy).ToList()
|
|
||||||
};
|
|
||||||
return group;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
set
|
set { _pwDatabase.RecycleBinUuid = BuildIdFromString(value); }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public BaseEntity Cipher
|
public string CipherId
|
||||||
{
|
{
|
||||||
get
|
get { return _pwDatabase.DataCipherUuid.ToHexString(); }
|
||||||
{
|
set { _pwDatabase.DataCipherUuid = BuildIdFromString(value); }
|
||||||
var cipher = CipherPool.GlobalPool.GetCipher(_pwDatabase.DataCipherUuid);
|
|
||||||
return new BaseEntity
|
|
||||||
{
|
|
||||||
Id = cipher.CipherUuid.ToHexString(),
|
|
||||||
Name = cipher.DisplayName
|
|
||||||
};
|
|
||||||
}
|
|
||||||
set { _pwDatabase.DataCipherUuid = BuildIdFromString(value.Id); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseEntity KeyDerivation
|
public string KeyDerivationId
|
||||||
{
|
{
|
||||||
get
|
get { return _pwDatabase.KdfParameters.KdfUuid.ToHexString(); }
|
||||||
{
|
|
||||||
var keyDerivation = KdfPool.Engines.First(e => e.Uuid.Equals(_pwDatabase.KdfParameters.KdfUuid));
|
|
||||||
return new BaseEntity
|
|
||||||
{
|
|
||||||
Id = keyDerivation.Uuid.ToHexString(),
|
|
||||||
Name = keyDerivation.Name
|
|
||||||
};
|
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_pwDatabase.KdfParameters = KdfPool.Engines
|
_pwDatabase.KdfParameters = KdfPool.Engines
|
||||||
.FirstOrDefault(e => e.Uuid.Equals(BuildIdFromString(value.Name)))?.GetDefaultParameters();
|
.FirstOrDefault(e => e.Uuid.Equals(BuildIdFromString(value)))?.GetDefaultParameters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +66,8 @@ namespace ModernKeePass.Infrastructure.KeePass
|
|||||||
set { _pwDatabase.Compression = (PwCompressionAlgorithm) Enum.Parse(typeof(PwCompressionAlgorithm), value); }
|
set { _pwDatabase.Compression = (PwCompressionAlgorithm) Enum.Parse(typeof(PwCompressionAlgorithm), value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsRecycleBinEnabled => _pwDatabase.RecycleBinEnabled;
|
||||||
|
|
||||||
public KeePassDatabaseClient(ISettingsProxy settings, IFileProxy fileService, IMapper mapper)
|
public KeePassDatabaseClient(ISettingsProxy settings, IFileProxy fileService, IMapper mapper)
|
||||||
{
|
{
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
@@ -101,22 +75,19 @@ namespace ModernKeePass.Infrastructure.KeePass
|
|||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DatabaseEntity> Open(FileInfo fileInfo, Credentials credentials)
|
public async Task<GroupEntity> Open(FileInfo fileInfo, Credentials credentials)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_compositeKey = await CreateCompositeKey(credentials);
|
var compositeKey = await CreateCompositeKey(credentials);
|
||||||
var ioConnection = await BuildConnectionInfo(fileInfo);
|
var ioConnection = await BuildConnectionInfo(fileInfo);
|
||||||
|
|
||||||
_pwDatabase.Open(ioConnection, _compositeKey, new NullStatusLogger());
|
_pwDatabase.Open(ioConnection, compositeKey, new NullStatusLogger());
|
||||||
|
|
||||||
|
_credentials = credentials;
|
||||||
_fileAccessToken = fileInfo.Path;
|
_fileAccessToken = fileInfo.Path;
|
||||||
|
|
||||||
return new DatabaseEntity
|
return _mapper.Map<GroupEntity>(_pwDatabase.RootGroup);
|
||||||
{
|
|
||||||
Name = _pwDatabase.Name,
|
|
||||||
RootGroupEntity = BuildHierarchy(_pwDatabase.RootGroup)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
catch (InvalidCompositeKeyException ex)
|
catch (InvalidCompositeKeyException ex)
|
||||||
{
|
{
|
||||||
@@ -124,12 +95,17 @@ namespace ModernKeePass.Infrastructure.KeePass
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DatabaseEntity> Create(FileInfo fileInfo, Credentials credentials)
|
public async Task<GroupEntity> ReOpen()
|
||||||
{
|
{
|
||||||
_compositeKey = await CreateCompositeKey(credentials);
|
return await Open(new FileInfo {Path = _fileAccessToken}, _credentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<GroupEntity> Create(FileInfo fileInfo, Credentials credentials)
|
||||||
|
{
|
||||||
|
var compositeKey = await CreateCompositeKey(credentials);
|
||||||
var ioConnection = await BuildConnectionInfo(fileInfo);
|
var ioConnection = await BuildConnectionInfo(fileInfo);
|
||||||
|
|
||||||
_pwDatabase.New(ioConnection, _compositeKey);
|
_pwDatabase.New(ioConnection, compositeKey);
|
||||||
|
|
||||||
var fileFormat = _settings.GetSetting<string>("DefaultFileFormat");
|
var fileFormat = _settings.GetSetting<string>("DefaultFileFormat");
|
||||||
switch (fileFormat)
|
switch (fileFormat)
|
||||||
@@ -142,10 +118,7 @@ namespace ModernKeePass.Infrastructure.KeePass
|
|||||||
_fileAccessToken = fileInfo.Path;
|
_fileAccessToken = fileInfo.Path;
|
||||||
|
|
||||||
// TODO: create sample data depending on settings
|
// TODO: create sample data depending on settings
|
||||||
return new DatabaseEntity
|
return _mapper.Map<GroupEntity>(_pwDatabase.RootGroup);
|
||||||
{
|
|
||||||
RootGroupEntity = BuildHierarchy(_pwDatabase.RootGroup)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SaveDatabase()
|
public async Task SaveDatabase()
|
||||||
@@ -185,49 +158,78 @@ namespace ModernKeePass.Infrastructure.KeePass
|
|||||||
_fileService.ReleaseFile(_fileAccessToken);
|
_fileService.ReleaseFile(_fileAccessToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddEntry(GroupEntity parentGroupEntity, EntryEntity entry)
|
public async Task AddEntry(string parentGroupId, string entryId)
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
var parentPwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(parentGroupEntity.Id), true);
|
var parentPwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(parentGroupId), true);
|
||||||
|
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
|
||||||
var pwEntry = new PwEntry(true, true);
|
|
||||||
_mapper.Map(entry, pwEntry);
|
|
||||||
parentPwGroup.AddEntry(pwEntry, true);
|
parentPwGroup.AddEntry(pwEntry, true);
|
||||||
entry.Id = pwEntry.Uuid.ToHexString();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public async Task AddGroup(GroupEntity parentGroupEntity, GroupEntity group)
|
public async Task AddGroup(string parentGroupId, string groupId)
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
var parentPwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(parentGroupEntity.Id), true);
|
var parentPwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(parentGroupId), true);
|
||||||
|
var pwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(groupId), true);
|
||||||
var pwGroup = new PwGroup(true, true)
|
parentPwGroup.Groups.Add(pwGroup);
|
||||||
{
|
});
|
||||||
Name = group.Name
|
}
|
||||||
};
|
public async Task RemoveEntry(string parentGroupId, string entryId)
|
||||||
parentPwGroup.AddGroup(pwGroup, true);
|
{
|
||||||
group.Id = pwGroup.Uuid.ToHexString();
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
var parentPwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(parentGroupId), true);
|
||||||
|
var pwEntry = parentPwGroup.FindEntry(BuildIdFromString(entryId), false);
|
||||||
|
parentPwGroup.Entries.Remove(pwEntry);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task UpdateEntry(EntryEntity entry)
|
public async Task RemoveGroup(string parentGroupId, string groupId)
|
||||||
|
{
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
var parentPwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(parentGroupId), true);
|
||||||
|
var pwGroup = parentPwGroup.FindGroup(BuildIdFromString(groupId), false);
|
||||||
|
parentPwGroup.Groups.Remove(pwGroup);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task UpdateEntry(string entry)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task UpdateGroup(GroupEntity group)
|
public Task UpdateGroup(string group)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntryEntity CreateEntry(string parentGroupId)
|
||||||
|
{
|
||||||
|
var pwEntry = new PwEntry(true, true);
|
||||||
|
var parentPwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(parentGroupId), true);
|
||||||
|
parentPwGroup.Entries.Add(pwEntry);
|
||||||
|
|
||||||
public async Task DeleteEntry(EntryEntity entry)
|
return _mapper.Map<EntryEntity>(pwEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupEntity CreateGroup(string parentGroupId, string name, bool isRecycleBin = false)
|
||||||
|
{
|
||||||
|
var pwGroup = new PwGroup(true, true, name, isRecycleBin? PwIcon.TrashBin : PwIcon.Folder);
|
||||||
|
var parentPwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(parentGroupId), true);
|
||||||
|
parentPwGroup.Groups.Add(pwGroup);
|
||||||
|
if (isRecycleBin) _pwDatabase.RecycleBinUuid = pwGroup.Uuid;
|
||||||
|
|
||||||
|
return _mapper.Map<GroupEntity>(pwGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteEntry(string entryId)
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entry.Id), true);
|
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
|
||||||
var id = pwEntry.Uuid;
|
var id = pwEntry.Uuid;
|
||||||
pwEntry.ParentGroup.Entries.Remove(pwEntry);
|
pwEntry.ParentGroup.Entries.Remove(pwEntry);
|
||||||
|
|
||||||
@@ -237,11 +239,12 @@ namespace ModernKeePass.Infrastructure.KeePass
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public async Task DeleteGroup(GroupEntity group)
|
|
||||||
|
public async Task DeleteGroup(string groupId)
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
var pwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(group.Id), true);
|
var pwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(groupId), true);
|
||||||
var id = pwGroup.Uuid;
|
var id = pwGroup.Uuid;
|
||||||
pwGroup.ParentGroup.Groups.Remove(pwGroup);
|
pwGroup.ParentGroup.Groups.Remove(pwGroup);
|
||||||
|
|
||||||
@@ -252,6 +255,19 @@ namespace ModernKeePass.Infrastructure.KeePass
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SortEntries(string groupId)
|
||||||
|
{
|
||||||
|
var pwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(groupId), true);
|
||||||
|
var comparer = new PwEntryComparer(PwDefs.TitleField, true, false);
|
||||||
|
pwGroup.Entries.Sort(comparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SortSubGroups(string groupId)
|
||||||
|
{
|
||||||
|
var pwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(groupId), true);
|
||||||
|
pwGroup.SortSubGroups(false);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task UpdateCredentials(Credentials credentials)
|
public async Task UpdateCredentials(Credentials credentials)
|
||||||
{
|
{
|
||||||
_pwDatabase.MasterKey = await CreateCompositeKey(credentials);
|
_pwDatabase.MasterKey = await CreateCompositeKey(credentials);
|
||||||
@@ -274,21 +290,7 @@ namespace ModernKeePass.Infrastructure.KeePass
|
|||||||
var fileContents = await _fileService.OpenBinaryFile(fileInfo.Path);
|
var fileContents = await _fileService.OpenBinaryFile(fileInfo.Path);
|
||||||
return IOConnectionInfo.FromByteArray(fileContents);
|
return IOConnectionInfo.FromByteArray(fileContents);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GroupEntity BuildHierarchy(PwGroup pwGroup)
|
|
||||||
{
|
|
||||||
// TODO: build entity hierarchy in an iterative way or implement lazy loading
|
|
||||||
var group = new GroupEntity
|
|
||||||
{
|
|
||||||
Id = pwGroup.Uuid.ToHexString(),
|
|
||||||
Name = pwGroup.Name,
|
|
||||||
Icon = IconMapper.MapPwIconToIcon(pwGroup.IconId),
|
|
||||||
Entries = pwGroup.Entries.Select(e => _mapper.Map<EntryEntity>(e)).ToList(),
|
|
||||||
SubGroups = pwGroup.Groups.Select(BuildHierarchy).ToList()
|
|
||||||
};
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PwUuid BuildIdFromString(string id)
|
private PwUuid BuildIdFromString(string id)
|
||||||
{
|
{
|
||||||
return new PwUuid(MemUtil.HexStringToByteArray(id));
|
return new PwUuid(MemUtil.HexStringToByteArray(id));
|
||||||
|
95
ModernKeePass.KeePassDatabaseTests/AutomapperProfilesTest.cs
Normal file
95
ModernKeePass.KeePassDatabaseTests/AutomapperProfilesTest.cs
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using AutoMapper;
|
||||||
|
using ModernKeePass.Domain.Entities;
|
||||||
|
using ModernKeePass.Infrastructure.KeePass;
|
||||||
|
using ModernKeePassLib;
|
||||||
|
using ModernKeePassLib.Security;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace ModernKeePass.KeePassDatabaseTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class AutomapperProfilesTest
|
||||||
|
{
|
||||||
|
private IMapper _mapper;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
_mapper = new Mapper(new MapperConfiguration(conf => conf.AddProfile(new EntryMappingProfile())));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Assert_Mapping_Configuration_Is_Valid()
|
||||||
|
{
|
||||||
|
_mapper.ConfigurationProvider.AssertConfigurationIsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void FromDtoToModel_Should_Map_PwEntry_To_Entry()
|
||||||
|
{
|
||||||
|
var pwEntry = new PwEntry(true, true)
|
||||||
|
{
|
||||||
|
ExpiryTime = DateTime.Now,
|
||||||
|
BackgroundColor = Color.White,
|
||||||
|
ForegroundColor = Color.Black
|
||||||
|
};
|
||||||
|
pwEntry.Strings.Set(PwDefs.TitleField, new ProtectedString(true, "Test"));
|
||||||
|
pwEntry.Strings.Set(PwDefs.UserNameField, new ProtectedString(true, "toto"));
|
||||||
|
pwEntry.Strings.Set(PwDefs.PasswordField, new ProtectedString(true, "password"));
|
||||||
|
pwEntry.Strings.Set(PwDefs.UrlField, new ProtectedString(true, "http://google.com"));
|
||||||
|
pwEntry.Strings.Set(PwDefs.NotesField, new ProtectedString(true, "blabla"));
|
||||||
|
pwEntry.Strings.Set("additional", new ProtectedString(true, "custom"));
|
||||||
|
|
||||||
|
var entry = _mapper.Map<PwEntry, EntryEntity>(pwEntry);
|
||||||
|
|
||||||
|
Assert.That(entry.ExpirationDate, Is.Not.EqualTo(default(DateTimeOffset)));
|
||||||
|
Assert.That(entry.BackgroundColor, Is.EqualTo(Color.White));
|
||||||
|
Assert.That(entry.ForegroundColor, Is.EqualTo(Color.Black));
|
||||||
|
Assert.That(entry.Name, Is.EqualTo("Test"));
|
||||||
|
Assert.That(entry.UserName, Is.EqualTo("toto"));
|
||||||
|
Assert.That(entry.Password, Is.EqualTo("password"));
|
||||||
|
Assert.That(entry.Url, Is.EqualTo(new Uri("http://google.com")));
|
||||||
|
Assert.That(entry.Notes, Is.EqualTo("blabla"));
|
||||||
|
Assert.That(entry.AdditionalFields, Is.Not.Empty);
|
||||||
|
Assert.That(entry.AdditionalFields["additional"], Is.EqualTo("custom"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void FromModelToDto_Should_Map_Entry_To_PwEntry()
|
||||||
|
{
|
||||||
|
var entry = new EntryEntity
|
||||||
|
{
|
||||||
|
Id = "VGhlIHF1aWNrIGJyb3duIA==",
|
||||||
|
Name = "Test",
|
||||||
|
UserName = "toto",
|
||||||
|
Password = "password",
|
||||||
|
Url = new Uri("http://google.com"),
|
||||||
|
Notes = "blabla",
|
||||||
|
ExpirationDate = DateTimeOffset.Now,
|
||||||
|
BackgroundColor = Color.White,
|
||||||
|
ForegroundColor = Color.Black,
|
||||||
|
AdditionalFields = new Dictionary<string, string> {
|
||||||
|
{
|
||||||
|
"additional", "custom"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var pwEntry = new PwEntry(false, false);
|
||||||
|
|
||||||
|
_mapper.Map(entry, pwEntry);
|
||||||
|
|
||||||
|
Assert.That(pwEntry.ExpiryTime, Is.Not.EqualTo(default(DateTime)));
|
||||||
|
Assert.That(pwEntry.BackgroundColor, Is.EqualTo(Color.White));
|
||||||
|
Assert.That(pwEntry.ForegroundColor, Is.EqualTo(Color.Black));
|
||||||
|
Assert.That(pwEntry.Strings.GetSafe(PwDefs.TitleField).ReadString(), Is.EqualTo("Test"));
|
||||||
|
Assert.That(pwEntry.Strings.GetSafe(PwDefs.UserNameField).ReadString(), Is.EqualTo("toto"));
|
||||||
|
Assert.That(pwEntry.Strings.GetSafe(PwDefs.PasswordField).ReadString(), Is.EqualTo("password"));
|
||||||
|
Assert.That(pwEntry.Strings.GetSafe(PwDefs.UrlField).ReadString(), Is.EqualTo(new Uri("http://google.com")));
|
||||||
|
Assert.That(pwEntry.Strings.GetSafe(PwDefs.NotesField).ReadString(), Is.EqualTo("blabla"));
|
||||||
|
Assert.That(pwEntry.Strings.GetSafe("additional").ReadString(), Is.EqualTo("custom"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
ModernKeePass.KeePassDatabaseTests/Data/TestDatabase.kdbx
Normal file
BIN
ModernKeePass.KeePassDatabaseTests/Data/TestDatabase.kdbx
Normal file
Binary file not shown.
155
ModernKeePass.KeePassDatabaseTests/KeePassDatabaseClientTests.cs
Normal file
155
ModernKeePass.KeePassDatabaseTests/KeePassDatabaseClientTests.cs
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AutoMapper;
|
||||||
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
|
using ModernKeePass.Application.Services;
|
||||||
|
using ModernKeePass.Domain.Dtos;
|
||||||
|
using ModernKeePass.Domain.Entities;
|
||||||
|
using ModernKeePass.Domain.Interfaces;
|
||||||
|
using ModernKeePass.Infrastructure.KeePass;
|
||||||
|
using NSubstitute;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using FileInfo = ModernKeePass.Domain.Dtos.FileInfo;
|
||||||
|
|
||||||
|
namespace ModernKeePass.KeePassDatabaseTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class DatabaseTests
|
||||||
|
{
|
||||||
|
private IDatabaseProxy _database;
|
||||||
|
private FileInfo _fileInfo;
|
||||||
|
private readonly Credentials _credentials = new Credentials
|
||||||
|
{
|
||||||
|
Password = "test"
|
||||||
|
};
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
var settingsService = Substitute.For<ISettingsService>();
|
||||||
|
var fileProxy = Substitute.For<IFileProxy>();
|
||||||
|
fileProxy.OpenBinaryFile(Arg.Any<string>()).Returns(async parameters =>
|
||||||
|
{
|
||||||
|
await using var stream = File.Open((string) parameters[0], FileMode.OpenOrCreate);
|
||||||
|
var contents = new byte[stream.Length];
|
||||||
|
await stream.ReadAsync(contents, 0, (int) stream.Length);
|
||||||
|
return contents;
|
||||||
|
});
|
||||||
|
fileProxy.WriteBinaryContentsToFile(Arg.Any<string>(), Arg.Any<byte[]>()).Returns(async parameters =>
|
||||||
|
{
|
||||||
|
await using var stream = File.Open((string)parameters[0], FileMode.OpenOrCreate);
|
||||||
|
var contents = (byte[]) parameters[1];
|
||||||
|
await stream.WriteAsync(contents, 0, contents.Length);
|
||||||
|
});
|
||||||
|
var fileService = new FileService(fileProxy);
|
||||||
|
var mapper = new Mapper(new MapperConfiguration(cfg => { cfg.AddProfile(typeof(EntryMappingProfile)); }));
|
||||||
|
_database = new KeePassDatabaseClient(settingsService, fileService, mapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown()
|
||||||
|
{
|
||||||
|
_database.CloseDatabase();
|
||||||
|
if (!string.IsNullOrEmpty(_fileInfo?.Path)) File.Delete(_fileInfo.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task TestOpen()
|
||||||
|
{
|
||||||
|
var FileInfo = new FileInfo
|
||||||
|
{
|
||||||
|
Path = Path.Combine(Directory.GetCurrentDirectory(), "Data", "TestDatabase.kdbx")
|
||||||
|
};
|
||||||
|
|
||||||
|
var rootGroup = await _database.Open(FileInfo, _credentials);
|
||||||
|
Assert.That(rootGroup.Name, Is.EqualTo("TestDatabase"));
|
||||||
|
Assert.That(rootGroup.Entries.Count(), Is.EqualTo(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task TestCreateAndSave()
|
||||||
|
{
|
||||||
|
_fileInfo = new FileInfo
|
||||||
|
{
|
||||||
|
Path = Path.Combine(Path.GetTempPath(), "NewDatabase.kdbx")
|
||||||
|
};
|
||||||
|
|
||||||
|
await _database.Create(_fileInfo, _credentials);
|
||||||
|
await _database.SaveDatabase();
|
||||||
|
_database.CloseDatabase();
|
||||||
|
|
||||||
|
Assert.DoesNotThrowAsync(async () => { await _database.Open(_fileInfo, _credentials); });
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task TestSaveAs()
|
||||||
|
{
|
||||||
|
var originalFileInfo = new FileInfo
|
||||||
|
{
|
||||||
|
Path = Path.Combine(Directory.GetCurrentDirectory(), "Data", "TestDatabase.kdbx")
|
||||||
|
};
|
||||||
|
_fileInfo = new FileInfo
|
||||||
|
{
|
||||||
|
Path = Path.Combine(Path.GetTempPath(), "SavedDatabase.kdbx")
|
||||||
|
};
|
||||||
|
|
||||||
|
await _database.Open(originalFileInfo, _credentials);
|
||||||
|
await _database.SaveDatabase(_fileInfo);
|
||||||
|
_database.CloseDatabase();
|
||||||
|
|
||||||
|
Assert.DoesNotThrowAsync(async () => { await _database.Open(_fileInfo, _credentials); });
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task TestAddGroup()
|
||||||
|
{
|
||||||
|
var originalFileInfo = new FileInfo
|
||||||
|
{
|
||||||
|
Path = Path.Combine(Directory.GetCurrentDirectory(), "Data", "TestDatabase.kdbx")
|
||||||
|
};
|
||||||
|
_fileInfo = new FileInfo
|
||||||
|
{
|
||||||
|
Path = Path.Combine(Path.GetTempPath(), "SavedDatabase.kdbx")
|
||||||
|
};
|
||||||
|
var newGroup = new GroupEntity {Name = "New Group Test"};
|
||||||
|
|
||||||
|
var rootGroup = await _database.Open(originalFileInfo, _credentials);
|
||||||
|
await _database.AddEntity(rootGroup, newGroup);
|
||||||
|
await _database.SaveDatabase(_fileInfo);
|
||||||
|
_database.CloseDatabase();
|
||||||
|
rootGroup = await _database.Open(_fileInfo, _credentials);
|
||||||
|
|
||||||
|
Assert.That(newGroup.Id, Is.Not.Empty);
|
||||||
|
Assert.That(rootGroup.SubGroups.Count, Is.EqualTo(7));
|
||||||
|
Assert.That(rootGroup.SubGroups.Last().Name, Is.EqualTo("New Group Test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task TestAddEntry()
|
||||||
|
{
|
||||||
|
var originalFileInfo = new FileInfo
|
||||||
|
{
|
||||||
|
Path = Path.Combine(Directory.GetCurrentDirectory(), "Data", "TestDatabase.kdbx")
|
||||||
|
};
|
||||||
|
_fileInfo = new FileInfo
|
||||||
|
{
|
||||||
|
Path = Path.Combine(Path.GetTempPath(), "SavedDatabase.kdbx")
|
||||||
|
};
|
||||||
|
var newEntry = new EntryEntity
|
||||||
|
{
|
||||||
|
Name = "New Entry Test"
|
||||||
|
};
|
||||||
|
|
||||||
|
var rootGroup = await _database.Open(originalFileInfo, _credentials);
|
||||||
|
await _database.AddEntity(rootGroup, newEntry);
|
||||||
|
await _database.SaveDatabase(_fileInfo);
|
||||||
|
_database.CloseDatabase();
|
||||||
|
rootGroup = await _database.Open(_fileInfo, _credentials);
|
||||||
|
|
||||||
|
Assert.That(newEntry.Id, Is.Not.Empty);
|
||||||
|
Assert.That(rootGroup.Entries.Count, Is.EqualTo(3));
|
||||||
|
Assert.That(rootGroup.Entries.Last().Name, Is.EqualTo("New Entry Test"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Data\TestDatabase.kdbx" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Data\TestDatabase.kdbx">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AutoMapper" Version="9.0.0" />
|
||||||
|
<PackageReference Include="ModernKeePassLib" Version="2.44.1" />
|
||||||
|
<PackageReference Include="NSubstitute" Version="4.2.1" />
|
||||||
|
<PackageReference Include="nunit" Version="3.12.0" />
|
||||||
|
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||||
|
<PackageReference Include="Splat" Version="3.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ModernKeePass.Application\Application.csproj" />
|
||||||
|
<ProjectReference Include="..\ModernKeePass.Domain\Domain.csproj" />
|
||||||
|
<ProjectReference Include="..\ModernKeePass.Infrastructure\Infrastructure.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 14
|
# Visual Studio Version 16
|
||||||
VisualStudioVersion = 14.0.25420.1
|
VisualStudioVersion = 16.0.29911.84
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Win81App", "ModernKeePass\Win81App.csproj", "{A0CFC681-769B-405A-8482-0CDEE595A91F}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Win81App", "ModernKeePass\Win81App.csproj", "{A0CFC681-769B-405A-8482-0CDEE595A91F}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -26,6 +26,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Domain", "ModernKeePass.Dom
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Infrastructure", "ModernKeePass.Infrastructure\Infrastructure.csproj", "{09577E4C-4899-45B9-BF80-1803D617CCAE}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Infrastructure", "ModernKeePass.Infrastructure\Infrastructure.csproj", "{09577E4C-4899-45B9-BF80-1803D617CCAE}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModernKeePass.KeePassDatabaseTests", "ModernKeePass.KeePassDatabaseTests\ModernKeePass.KeePassDatabaseTests.csproj", "{52FEA1EE-2FA7-4862-85FE-CB05893D439E}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -134,6 +136,22 @@ Global
|
|||||||
{09577E4C-4899-45B9-BF80-1803D617CCAE}.Release|x64.Build.0 = Release|Any CPU
|
{09577E4C-4899-45B9-BF80-1803D617CCAE}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{09577E4C-4899-45B9-BF80-1803D617CCAE}.Release|x86.ActiveCfg = Release|Any CPU
|
{09577E4C-4899-45B9-BF80-1803D617CCAE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{09577E4C-4899-45B9-BF80-1803D617CCAE}.Release|x86.Build.0 = Release|Any CPU
|
{09577E4C-4899-45B9-BF80-1803D617CCAE}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -145,6 +163,7 @@ Global
|
|||||||
{42353562-5E43-459C-8E3E-2F21E575261D} = {0B30588B-07B8-4A88-A268-F58D06EA1627}
|
{42353562-5E43-459C-8E3E-2F21E575261D} = {0B30588B-07B8-4A88-A268-F58D06EA1627}
|
||||||
{9A0759F1-9069-4841-99E3-3BEC44E17356} = {0B30588B-07B8-4A88-A268-F58D06EA1627}
|
{9A0759F1-9069-4841-99E3-3BEC44E17356} = {0B30588B-07B8-4A88-A268-F58D06EA1627}
|
||||||
{09577E4C-4899-45B9-BF80-1803D617CCAE} = {0B30588B-07B8-4A88-A268-F58D06EA1627}
|
{09577E4C-4899-45B9-BF80-1803D617CCAE} = {0B30588B-07B8-4A88-A268-F58D06EA1627}
|
||||||
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E} = {107C7C00-56F4-41B0-A8CC-0156C46A3650}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {0ADC1BC6-B1CA-427D-A97C-3CA40AAB0428}
|
SolutionGuid = {0ADC1BC6-B1CA-427D-A97C-3CA40AAB0428}
|
||||||
|
@@ -10,14 +10,14 @@ namespace ModernKeePass.Actions
|
|||||||
{
|
{
|
||||||
public class DeleteEntityAction : DependencyObject, IAction
|
public class DeleteEntityAction : DependencyObject, IAction
|
||||||
{
|
{
|
||||||
public IPwEntity Entity
|
public IVmEntity Entity
|
||||||
{
|
{
|
||||||
get { return (IPwEntity)GetValue(EntityProperty); }
|
get { return (IVmEntity)GetValue(EntityProperty); }
|
||||||
set { SetValue(EntityProperty, value); }
|
set { SetValue(EntityProperty, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty EntityProperty =
|
public static readonly DependencyProperty EntityProperty =
|
||||||
DependencyProperty.Register("Entity", typeof(IPwEntity), typeof(DeleteEntityAction),
|
DependencyProperty.Register("Entity", typeof(IVmEntity), typeof(DeleteEntityAction),
|
||||||
new PropertyMetadata(null));
|
new PropertyMetadata(null));
|
||||||
|
|
||||||
public ICommand Command
|
public ICommand Command
|
||||||
|
@@ -17,6 +17,7 @@ using ModernKeePass.Application;
|
|||||||
using ModernKeePass.Application.Database.Commands.CloseDatabase;
|
using ModernKeePass.Application.Database.Commands.CloseDatabase;
|
||||||
using ModernKeePass.Application.Database.Commands.SaveDatabase;
|
using ModernKeePass.Application.Database.Commands.SaveDatabase;
|
||||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||||
|
using ModernKeePass.Application.Database.Queries.ReOpenDatabase;
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using ModernKeePass.Domain.Dtos;
|
using ModernKeePass.Domain.Dtos;
|
||||||
using ModernKeePass.Domain.Exceptions;
|
using ModernKeePass.Domain.Exceptions;
|
||||||
@@ -157,9 +158,9 @@ namespace ModernKeePass
|
|||||||
Window.Current.Content = rootFrame;
|
Window.Current.Content = rootFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lauchActivatedEventArgs = e as LaunchActivatedEventArgs;
|
var launchActivatedEventArgs = e as LaunchActivatedEventArgs;
|
||||||
if (lauchActivatedEventArgs != null && rootFrame.Content == null)
|
if (launchActivatedEventArgs != null && rootFrame.Content == null)
|
||||||
rootFrame.Navigate(typeof(MainPage), lauchActivatedEventArgs.Arguments);
|
rootFrame.Navigate(typeof(MainPage), launchActivatedEventArgs.Arguments);
|
||||||
|
|
||||||
// Ensure the current window is active
|
// Ensure the current window is active
|
||||||
Window.Current.Activate();
|
Window.Current.Activate();
|
||||||
@@ -171,7 +172,7 @@ namespace ModernKeePass
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var database = await Mediator.Send(new GetDatabaseQuery());
|
var database = await Mediator.Send(new ReOpenDatabaseQuery());
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
ToastNotificationHelper.ShowGenericToast(database.Name, "Database reopened (changes were saved)");
|
ToastNotificationHelper.ShowGenericToast(database.Name, "Database reopened (changes were saved)");
|
||||||
#endif
|
#endif
|
||||||
@@ -207,7 +208,6 @@ namespace ModernKeePass
|
|||||||
var deferral = e.SuspendingOperation.GetDeferral();
|
var deferral = e.SuspendingOperation.GetDeferral();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var database = await Mediator.Send(new GetDatabaseQuery());
|
|
||||||
if (SettingsService.Instance.GetSetting("SaveSuspend", true))
|
if (SettingsService.Instance.GetSetting("SaveSuspend", true))
|
||||||
{
|
{
|
||||||
await Mediator.Send(new SaveDatabaseCommand());
|
await Mediator.Send(new SaveDatabaseCommand());
|
||||||
|
@@ -9,7 +9,7 @@ namespace ModernKeePass.Common
|
|||||||
{
|
{
|
||||||
public static class ToastNotificationHelper
|
public static class ToastNotificationHelper
|
||||||
{
|
{
|
||||||
public static void ShowMovedToast(IPwEntity entity, string action, string text)
|
public static void ShowMovedToast(IVmEntity entity, string action, string text)
|
||||||
{
|
{
|
||||||
var notificationXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
|
var notificationXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
|
||||||
var toastElements = notificationXml.GetElementsByTagName("text");
|
var toastElements = notificationXml.GetElementsByTagName("text");
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using ModernKeePass.ViewModels;
|
using ModernKeePass.Application.Group.Models;
|
||||||
|
|
||||||
namespace ModernKeePass.Events
|
namespace ModernKeePass.Events
|
||||||
{
|
{
|
||||||
|
@@ -1,17 +1,18 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using ModernKeePass.ViewModels;
|
using ModernKeePass.ViewModels;
|
||||||
|
|
||||||
namespace ModernKeePass.Interfaces
|
namespace ModernKeePass.Interfaces
|
||||||
{
|
{
|
||||||
public interface IPwEntity
|
public interface IVmEntity
|
||||||
{
|
{
|
||||||
GroupVm ParentGroup { get; }
|
GroupVm ParentGroup { get; }
|
||||||
GroupVm PreviousGroup { get; }
|
GroupVm PreviousGroup { get; }
|
||||||
int IconId { get; }
|
int IconId { get; }
|
||||||
string Id { get; }
|
string Id { get; }
|
||||||
string Name { get; set; }
|
string Name { get; set; }
|
||||||
IEnumerable<IPwEntity> BreadCrumb { get; }
|
IEnumerable<IVmEntity> BreadCrumb { get; }
|
||||||
bool IsEditMode { get; }
|
bool IsEditMode { get; }
|
||||||
bool IsRecycleOnDelete { get; }
|
bool IsRecycleOnDelete { get; }
|
||||||
|
|
||||||
@@ -31,10 +32,10 @@ namespace ModernKeePass.Interfaces
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete from Model
|
/// Delete from Model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void CommitDelete();
|
Task CommitDelete();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete from ViewModel
|
/// Delete from ViewModel
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void MarkForDelete(string recycleBinTitle);
|
Task MarkForDelete(string recycleBinTitle);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -99,7 +99,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
set { SetProperty(ref _keyFileText, value); }
|
set { SetProperty(ref _keyFileText, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupVm RootGroup { get; set; }
|
public Application.Group.Models.GroupVm RootGroup { get; set; }
|
||||||
|
|
||||||
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
|
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
_isOpening = true;
|
_isOpening = true;
|
||||||
OnPropertyChanged("IsValid");;
|
OnPropertyChanged("IsValid");
|
||||||
var fileInfo = new FileInfo
|
var fileInfo = new FileInfo
|
||||||
{
|
{
|
||||||
Name = databaseFile.DisplayName,
|
Name = databaseFile.DisplayName,
|
||||||
@@ -137,7 +137,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
};
|
};
|
||||||
|
|
||||||
var database = await _mediator.Send(new OpenDatabaseQuery { FileInfo = fileInfo, Credentials = CreateCredentials()});
|
var database = await _mediator.Send(new OpenDatabaseQuery { FileInfo = fileInfo, Credentials = CreateCredentials()});
|
||||||
await Task.Run(() => RootGroup = new GroupVm(database.RootGroup));
|
await Task.Run(() => RootGroup = database.RootGroup);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
|
@@ -13,7 +13,7 @@ using ModernKeePassLib.Cryptography;
|
|||||||
|
|
||||||
namespace ModernKeePass.ViewModels
|
namespace ModernKeePass.ViewModels
|
||||||
{
|
{
|
||||||
public class EntryVm : INotifyPropertyChanged, IPwEntity, ISelectableModel
|
public class EntryVm : INotifyPropertyChanged, IVmEntity, ISelectableModel
|
||||||
{
|
{
|
||||||
public GroupVm ParentGroup { get; private set; }
|
public GroupVm ParentGroup { get; private set; }
|
||||||
public GroupVm PreviousGroup { get; private set; }
|
public GroupVm PreviousGroup { get; private set; }
|
||||||
@@ -32,7 +32,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
public PwUuid IdUuid => _pwEntry?.Uuid;
|
public PwUuid IdUuid => _pwEntry?.Uuid;
|
||||||
public string Id => _pwEntry?.Uuid.ToHexString();
|
public string Id => _pwEntry?.Uuid.ToHexString();
|
||||||
public bool IsRecycleOnDelete => _database.RecycleBinEnabled && !ParentGroup.IsSelected;
|
public bool IsRecycleOnDelete => _database.RecycleBinEnabled && !ParentGroup.IsSelected;
|
||||||
public IEnumerable<IPwEntity> BreadCrumb => new List<IPwEntity>(ParentGroup.BreadCrumb) {ParentGroup};
|
public IEnumerable<IVmEntity> BreadCrumb => new List<IVmEntity>(ParentGroup.BreadCrumb) {ParentGroup};
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if the Entry is current or from history
|
/// Determines if the Entry is current or from history
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -160,7 +160,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IPwEntity> History
|
public IEnumerable<IVmEntity> History
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@@ -5,14 +5,17 @@ using System.Collections.Specialized;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using MediatR;
|
||||||
|
using ModernKeePass.Application.Database.Commands.SaveDatabase;
|
||||||
|
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
|
using ModernKeePass.Domain.Enums;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
using ModernKeePass.Services;
|
|
||||||
using ModernKeePassLib;
|
using ModernKeePassLib;
|
||||||
|
|
||||||
namespace ModernKeePass.ViewModels
|
namespace ModernKeePass.ViewModels
|
||||||
{
|
{
|
||||||
public class GroupVm : NotifyPropertyChangedBase, IPwEntity, ISelectableModel
|
public class GroupVm : NotifyPropertyChangedBase, IVmEntity, ISelectableModel
|
||||||
{
|
{
|
||||||
public GroupVm ParentGroup { get; private set; }
|
public GroupVm ParentGroup { get; private set; }
|
||||||
public GroupVm PreviousGroup { get; private set; }
|
public GroupVm PreviousGroup { get; private set; }
|
||||||
@@ -40,23 +43,22 @@ namespace ModernKeePass.ViewModels
|
|||||||
|
|
||||||
public ObservableCollection<GroupVm> Groups { get; set; } = new ObservableCollection<GroupVm>();
|
public ObservableCollection<GroupVm> Groups { get; set; } = new ObservableCollection<GroupVm>();
|
||||||
|
|
||||||
public PwUuid IdUuid => _pwGroup?.Uuid;
|
public string Id => _group.Id;
|
||||||
public string Id => IdUuid?.ToHexString();
|
|
||||||
public bool IsNotRoot => ParentGroup != null;
|
public bool IsNotRoot => ParentGroup != null;
|
||||||
|
|
||||||
public bool ShowRestore => IsNotRoot && ParentGroup.IsSelected;
|
public bool ShowRestore => IsNotRoot && ParentGroup.IsSelected;
|
||||||
|
|
||||||
public bool IsRecycleOnDelete => _database.RecycleBinEnabled && !IsSelected && !ParentGroup.IsSelected;
|
public bool IsRecycleOnDelete => IsRecycleBinEnabled().GetAwaiter().GetResult() && !IsSelected && !ParentGroup.IsSelected;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is the Group the database Recycle Bin?
|
/// Is the Group the database Recycle Bin?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsSelected
|
public bool IsSelected
|
||||||
{
|
{
|
||||||
get { return _database != null && _database.RecycleBinEnabled && _database.RecycleBin?.Id == Id; }
|
get { return IsRecycleBinEnabled().GetAwaiter().GetResult() && _database.RecycleBin?.Id == Id; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value && _pwGroup != null) _database.RecycleBin = this;
|
if (value && _group != null) _database.RecycleBin = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,18 +69,18 @@ namespace ModernKeePass.ViewModels
|
|||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get { return _pwGroup == null ? string.Empty : _pwGroup.Name; }
|
get { return _group == null ? string.Empty : _group.Title; }
|
||||||
set { _pwGroup.Name = value; }
|
set { _group.Title = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public int IconId
|
public int IconId
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_pwGroup?.IconId != null) return (int) _pwGroup?.IconId;
|
if (_group?.Icon != null) return (int) _group?.Icon;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
set { _pwGroup.IconId = (PwIcon)value; }
|
set { _group.Icon = (Icon)value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsEditMode
|
public bool IsEditMode
|
||||||
@@ -98,7 +100,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
set { SetProperty(ref _isMenuClosed, value); }
|
set { SetProperty(ref _isMenuClosed, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IPwEntity> BreadCrumb
|
public IEnumerable<IVmEntity> BreadCrumb
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -119,36 +121,35 @@ namespace ModernKeePass.ViewModels
|
|||||||
public ICommand SortGroupsCommand { get; }
|
public ICommand SortGroupsCommand { get; }
|
||||||
public ICommand UndoDeleteCommand { get; }
|
public ICommand UndoDeleteCommand { get; }
|
||||||
|
|
||||||
private readonly PwGroup _pwGroup;
|
private readonly Application.Group.Models.GroupVm _group;
|
||||||
private readonly IDatabaseService _database;
|
private readonly IMediator _mediator;
|
||||||
private bool _isEditMode;
|
private bool _isEditMode;
|
||||||
private PwEntry _reorderedEntry;
|
private Application.Entry.Models.EntryVm _reorderedEntry;
|
||||||
private ObservableCollection<EntryVm> _entries = new ObservableCollection<EntryVm>();
|
private ObservableCollection<EntryVm> _entries = new ObservableCollection<EntryVm>();
|
||||||
private bool _isMenuClosed = true;
|
private bool _isMenuClosed = true;
|
||||||
|
|
||||||
public GroupVm() {}
|
public GroupVm() {}
|
||||||
|
|
||||||
internal GroupVm(PwGroup pwGroup, GroupVm parent, PwUuid recycleBinId = null) : this(pwGroup, parent,
|
internal GroupVm(Application.Group.Models.GroupVm group, GroupVm parent, string recycleBinId = null) : this(group, parent, App.Mediator, recycleBinId)
|
||||||
DatabaseService.Instance, recycleBinId)
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public GroupVm(PwGroup pwGroup, GroupVm parent, IDatabaseService database, PwUuid recycleBinId = null)
|
public GroupVm(Application.Group.Models.GroupVm group, GroupVm parent, IMediator mediator, string recycleBinId = null)
|
||||||
{
|
{
|
||||||
_pwGroup = pwGroup;
|
_group = group;
|
||||||
_database = database;
|
_mediator = mediator;
|
||||||
ParentGroup = parent;
|
ParentGroup = parent;
|
||||||
|
|
||||||
SaveCommand = new RelayCommand(() => _database.Save());
|
SaveCommand = new RelayCommand(async () => await _mediator.Send(new SaveDatabaseCommand()));
|
||||||
SortEntriesCommand = new RelayCommand(async () =>
|
SortEntriesCommand = new RelayCommand(async () =>
|
||||||
await SortEntriesAsync().ConfigureAwait(false), () => IsEditMode);
|
await SortEntriesAsync().ConfigureAwait(false), () => IsEditMode);
|
||||||
SortGroupsCommand = new RelayCommand(async () =>
|
SortGroupsCommand = new RelayCommand(async () =>
|
||||||
await SortGroupsAsync().ConfigureAwait(false), () => IsEditMode);
|
await SortGroupsAsync().ConfigureAwait(false), () => IsEditMode);
|
||||||
UndoDeleteCommand = new RelayCommand(() => Move(PreviousGroup), () => PreviousGroup != null);
|
UndoDeleteCommand = new RelayCommand(() => Move(PreviousGroup), () => PreviousGroup != null);
|
||||||
|
|
||||||
if (recycleBinId != null && _pwGroup.Uuid.Equals(recycleBinId)) _database.RecycleBin = this;
|
if (recycleBinId != null && _group.Id.Equals(recycleBinId)) _database.RecycleBin = this;
|
||||||
Entries = new ObservableCollection<EntryVm>(pwGroup.Entries.Select(e => new EntryVm(e, this)));
|
Entries = new ObservableCollection<EntryVm>(group.Entries.Select(e => new EntryVm(e, this)));
|
||||||
Entries.CollectionChanged += Entries_CollectionChanged;
|
Entries.CollectionChanged += Entries_CollectionChanged;
|
||||||
Groups = new ObservableCollection<GroupVm>(pwGroup.Groups.Select(g => new GroupVm(g, this, recycleBinId)));
|
Groups = new ObservableCollection<GroupVm>(group.SubGroups.Select(g => new GroupVm(g, this, recycleBinId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
private void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||||
@@ -157,12 +158,12 @@ namespace ModernKeePass.ViewModels
|
|||||||
{
|
{
|
||||||
case NotifyCollectionChangedAction.Remove:
|
case NotifyCollectionChangedAction.Remove:
|
||||||
var oldIndex = (uint) e.OldStartingIndex;
|
var oldIndex = (uint) e.OldStartingIndex;
|
||||||
_reorderedEntry = _pwGroup.Entries.GetAt(oldIndex);
|
_reorderedEntry = _group.Entries.GetAt(oldIndex);
|
||||||
_pwGroup.Entries.RemoveAt(oldIndex);
|
_group.Entries.RemoveAt(oldIndex);
|
||||||
break;
|
break;
|
||||||
case NotifyCollectionChangedAction.Add:
|
case NotifyCollectionChangedAction.Add:
|
||||||
if (_reorderedEntry == null) _pwGroup.AddEntry(((EntryVm) e.NewItems[0]).GetPwEntry(), true);
|
if (_reorderedEntry == null) _group.AddEntry(((EntryVm) e.NewItems[0]).GetPwEntry(), true);
|
||||||
else _pwGroup.Entries.Insert((uint)e.NewStartingIndex, _reorderedEntry);
|
else _group.Entries.Insert((uint)e.NewStartingIndex, _reorderedEntry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,7 +171,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
public GroupVm AddNewGroup(string name = "")
|
public GroupVm AddNewGroup(string name = "")
|
||||||
{
|
{
|
||||||
var pwGroup = new PwGroup(true, true, name, PwIcon.Folder);
|
var pwGroup = new PwGroup(true, true, name, PwIcon.Folder);
|
||||||
_pwGroup.AddGroup(pwGroup, true);
|
_group.AddGroup(pwGroup, true);
|
||||||
var newGroup = new GroupVm(pwGroup, this) {Name = name, IsEditMode = string.IsNullOrEmpty(name)};
|
var newGroup = new GroupVm(pwGroup, this) {Name = name, IsEditMode = string.IsNullOrEmpty(name)};
|
||||||
Groups.Add(newGroup);
|
Groups.Add(newGroup);
|
||||||
return newGroup;
|
return newGroup;
|
||||||
@@ -185,11 +186,12 @@ namespace ModernKeePass.ViewModels
|
|||||||
return newEntry;
|
return newEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MarkForDelete(string recycleBinTitle)
|
public async Task MarkForDelete(string recycleBinTitle)
|
||||||
{
|
{
|
||||||
if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
var isRecycleBinEnabled = await IsRecycleBinEnabled();
|
||||||
|
if (isRecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
||||||
_database.CreateRecycleBin(recycleBinTitle);
|
_database.CreateRecycleBin(recycleBinTitle);
|
||||||
Move(_database.RecycleBinEnabled && !IsSelected ? _database.RecycleBin : null);
|
Move(isRecycleBinEnabled && !IsSelected ? _database.RecycleBin : null);
|
||||||
((RelayCommand)UndoDeleteCommand).RaiseCanExecuteChanged();
|
((RelayCommand)UndoDeleteCommand).RaiseCanExecuteChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +204,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
{
|
{
|
||||||
PreviousGroup = ParentGroup;
|
PreviousGroup = ParentGroup;
|
||||||
PreviousGroup.Groups.Remove(this);
|
PreviousGroup.Groups.Remove(this);
|
||||||
PreviousGroup._pwGroup.Groups.Remove(_pwGroup);
|
PreviousGroup._group.SubGroups.Remove(_group);
|
||||||
if (destination == null)
|
if (destination == null)
|
||||||
{
|
{
|
||||||
_database.AddDeletedItem(IdUuid);
|
_database.AddDeletedItem(IdUuid);
|
||||||
@@ -210,13 +212,13 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
ParentGroup = destination;
|
ParentGroup = destination;
|
||||||
ParentGroup.Groups.Add(this);
|
ParentGroup.Groups.Add(this);
|
||||||
ParentGroup._pwGroup.AddGroup(_pwGroup, true);
|
ParentGroup._group.AddGroup(_group, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CommitDelete()
|
public async Task CommitDelete()
|
||||||
{
|
{
|
||||||
_pwGroup.ParentGroup.Groups.Remove(_pwGroup);
|
_group.ParentGroup.Groups.Remove(_group);
|
||||||
if (_database.RecycleBinEnabled && !PreviousGroup.IsSelected) _database.RecycleBin._pwGroup.AddGroup(_pwGroup, true);
|
if (await IsRecycleBinEnabled() && !PreviousGroup.IsSelected) _database.RecycleBin._group.AddGroup(_group, true);
|
||||||
else _database.AddDeletedItem(IdUuid);
|
else _database.AddDeletedItem(IdUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +232,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
var comparer = new PwEntryComparer(PwDefs.TitleField, true, false);
|
var comparer = new PwEntryComparer(PwDefs.TitleField, true, false);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_pwGroup.Entries.Sort(comparer);
|
_group.Entries.Sort(comparer);
|
||||||
Entries = new ObservableCollection<EntryVm>(Entries.OrderBy(e => e.Name));
|
Entries = new ObservableCollection<EntryVm>(Entries.OrderBy(e => e.Name));
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -243,8 +245,8 @@ namespace ModernKeePass.ViewModels
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_pwGroup.SortSubGroups(false);
|
_group.SortSubGroups(false);
|
||||||
Groups = new ObservableCollection<GroupVm>(Groups.OrderBy(g => g.Name).ThenBy(g => g._pwGroup == null));
|
Groups = new ObservableCollection<GroupVm>(Groups.OrderBy(g => g.Name).ThenBy(g => g._group == null));
|
||||||
OnPropertyChanged("Groups");
|
OnPropertyChanged("Groups");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -253,5 +255,10 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<bool> IsRecycleBinEnabled()
|
||||||
|
{
|
||||||
|
var database = await _mediator.Send(new GetDatabaseQuery());
|
||||||
|
return database.IsRecycleBinEnabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -47,7 +47,7 @@ namespace ModernKeePass.Views
|
|||||||
{
|
{
|
||||||
NavigationHelper.OnNavigatedTo(e);
|
NavigationHelper.OnNavigatedTo(e);
|
||||||
|
|
||||||
var args = e.Parameter as PasswordEventArgs;
|
/*var args = e.Parameter as PasswordEventArgs;
|
||||||
if (args != null)
|
if (args != null)
|
||||||
DataContext = args.RootGroup;
|
DataContext = args.RootGroup;
|
||||||
else
|
else
|
||||||
@@ -55,7 +55,9 @@ namespace ModernKeePass.Views
|
|||||||
var vm = e.Parameter as GroupVm;
|
var vm = e.Parameter as GroupVm;
|
||||||
if (vm != null)
|
if (vm != null)
|
||||||
DataContext = vm;
|
DataContext = vm;
|
||||||
}
|
}*/
|
||||||
|
var args = e.Parameter as Application.Group.Models.GroupVm;
|
||||||
|
if (args != null) DataContext = new GroupVm(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||||
|
@@ -13,17 +13,17 @@ namespace ModernKeePass.Views.UserControls
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IPwEntity> ItemsSource
|
public IEnumerable<IVmEntity> ItemsSource
|
||||||
{
|
{
|
||||||
get { return (IEnumerable<IPwEntity>)GetValue(ItemsSourceProperty); }
|
get { return (IEnumerable<IVmEntity>)GetValue(ItemsSourceProperty); }
|
||||||
set { SetValue(ItemsSourceProperty, value); }
|
set { SetValue(ItemsSourceProperty, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty ItemsSourceProperty =
|
public static readonly DependencyProperty ItemsSourceProperty =
|
||||||
DependencyProperty.Register(
|
DependencyProperty.Register(
|
||||||
"ItemsSource",
|
"ItemsSource",
|
||||||
typeof(IEnumerable<IPwEntity>),
|
typeof(IEnumerable<IVmEntity>),
|
||||||
typeof(BreadCrumbUserControl),
|
typeof(BreadCrumbUserControl),
|
||||||
new PropertyMetadata(new Stack<IPwEntity>(), (o, args) => { }));
|
new PropertyMetadata(new Stack<IVmEntity>(), (o, args) => { }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,18 +75,18 @@ namespace ModernKeePass.Views.UserControls
|
|||||||
typeof(HamburgerMenuUserControl),
|
typeof(HamburgerMenuUserControl),
|
||||||
new PropertyMetadata(Visibility.Collapsed, (o, args) => { }));
|
new PropertyMetadata(Visibility.Collapsed, (o, args) => { }));
|
||||||
|
|
||||||
public IEnumerable<IPwEntity> ItemsSource
|
public IEnumerable<IVmEntity> ItemsSource
|
||||||
{
|
{
|
||||||
get { return (IEnumerable<IPwEntity>)GetValue(ItemsSourceProperty); }
|
get { return (IEnumerable<IVmEntity>)GetValue(ItemsSourceProperty); }
|
||||||
set { SetValue(ItemsSourceProperty, value); }
|
set { SetValue(ItemsSourceProperty, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty ItemsSourceProperty =
|
public static readonly DependencyProperty ItemsSourceProperty =
|
||||||
DependencyProperty.Register(
|
DependencyProperty.Register(
|
||||||
"ItemsSource",
|
"ItemsSource",
|
||||||
typeof(IEnumerable<IPwEntity>),
|
typeof(IEnumerable<IVmEntity>),
|
||||||
typeof(HamburgerMenuUserControl),
|
typeof(HamburgerMenuUserControl),
|
||||||
new PropertyMetadata(new List<IPwEntity>(), (o, args) => { }));
|
new PropertyMetadata(new List<IVmEntity>(), (o, args) => { }));
|
||||||
|
|
||||||
public object SelectedItem
|
public object SelectedItem
|
||||||
{
|
{
|
||||||
|
@@ -192,7 +192,7 @@
|
|||||||
<Compile Include="Converters\TextToWidthConverter.cs" />
|
<Compile Include="Converters\TextToWidthConverter.cs" />
|
||||||
<Compile Include="Events\PasswordEventArgs.cs" />
|
<Compile Include="Events\PasswordEventArgs.cs" />
|
||||||
<Compile Include="Interfaces\IIsEnabled.cs" />
|
<Compile Include="Interfaces\IIsEnabled.cs" />
|
||||||
<Compile Include="Interfaces\IPwEntity.cs" />
|
<Compile Include="Interfaces\IVmEntity.cs" />
|
||||||
<Compile Include="Views\MainPage.xaml.cs">
|
<Compile Include="Views\MainPage.xaml.cs">
|
||||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
Reference in New Issue
Block a user