WIP Import mechanism

This commit is contained in:
BONNEVILLE Geoffroy
2018-09-07 18:16:40 +02:00
parent 549006036b
commit 0da6a5fc60
14 changed files with 141 additions and 52 deletions

View File

@@ -0,0 +1,9 @@
using Windows.Storage;
namespace ModernKeePass.Interfaces
{
public interface IFormat
{
IPwEntity Import(IStorageFile source);
}
}

View File

@@ -0,0 +1,9 @@
using Windows.Storage;
namespace ModernKeePass.Interfaces
{
public interface IImportService<in T> where T: IFormat
{
void Import(T format, IStorageFile source, IDatabaseService database);
}
}

View File

@@ -117,10 +117,13 @@
</Compile> </Compile>
<Compile Include="Converters\IntToSymbolConverter.cs" /> <Compile Include="Converters\IntToSymbolConverter.cs" />
<Compile Include="Exceptions\NavigationException.cs" /> <Compile Include="Exceptions\NavigationException.cs" />
<Compile Include="Interfaces\IFormat.cs" />
<Compile Include="Interfaces\IImportService.cs" />
<Compile Include="Interfaces\IProxyInvocationHandler.cs" /> <Compile Include="Interfaces\IProxyInvocationHandler.cs" />
<Compile Include="Interfaces\IRecentService.cs" /> <Compile Include="Interfaces\IRecentService.cs" />
<Compile Include="Interfaces\IRecentItem.cs" /> <Compile Include="Interfaces\IRecentItem.cs" />
<Compile Include="Interfaces\IResourceService.cs" /> <Compile Include="Interfaces\IResourceService.cs" />
<Compile Include="Services\ImportService.cs" />
<Compile Include="Services\SingletonServiceBase.cs" /> <Compile Include="Services\SingletonServiceBase.cs" />
<Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" /> <Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" />
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" /> <Compile Include="ViewModels\Items\SettingsSaveVm.cs" />

View File

@@ -5,11 +5,9 @@ using ModernKeePass.Exceptions;
using ModernKeePass.Interfaces; using ModernKeePass.Interfaces;
using ModernKeePass.ViewModels; using ModernKeePass.ViewModels;
using ModernKeePassLib; using ModernKeePassLib;
using ModernKeePassLib.Collections;
using ModernKeePassLib.Cryptography.KeyDerivation; using ModernKeePassLib.Cryptography.KeyDerivation;
using ModernKeePassLib.Interfaces; using ModernKeePassLib.Interfaces;
using ModernKeePassLib.Keys; using ModernKeePassLib.Keys;
using ModernKeePassLib.Security;
using ModernKeePassLib.Serialization; using ModernKeePassLib.Serialization;
namespace ModernKeePass.Services namespace ModernKeePass.Services
@@ -73,7 +71,7 @@ namespace ModernKeePass.Services
{ {
_settings = settings; _settings = settings;
} }
/// <summary> /// <summary>
/// Open a KeePass database /// Open a KeePass database
@@ -100,9 +98,7 @@ namespace ModernKeePass.Services
if (createNew) if (createNew)
{ {
_pwDatabase.New(ioConnection, key); _pwDatabase.New(ioConnection, key);
//Get settings default values
if (_settings.GetSetting<bool>("Sample")) CreateSampleData();
var fileFormat = _settings.GetSetting<string>("DefaultFileFormat"); var fileFormat = _settings.GetSetting<string>("DefaultFileFormat");
switch (fileFormat) switch (fileFormat)
{ {
@@ -122,7 +118,7 @@ namespace ModernKeePass.Services
throw new ArgumentException(ex.Message, ex); throw new ArgumentException(ex.Message, ex);
} }
} }
public void ReOpen() public void ReOpen()
{ {
Open(_databaseFile, _compositeKey); Open(_databaseFile, _compositeKey);
@@ -190,37 +186,5 @@ namespace ModernKeePass.Services
_compositeKey = newCompositeKey; _compositeKey = newCompositeKey;
_pwDatabase.MasterKey = newCompositeKey; _pwDatabase.MasterKey = newCompositeKey;
} }
private void CreateSampleData()
{
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Banking", PwIcon.Count), true);
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Email", PwIcon.EMail), true);
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Internet", PwIcon.World), true);
var pe = new PwEntry(true, true);
pe.Strings.Set(PwDefs.TitleField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectTitle,
"Sample Entry"));
pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUserName,
"Username"));
pe.Strings.Set(PwDefs.UrlField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUrl,
PwDefs.HomepageUrl));
pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectPassword,
"Password"));
pe.Strings.Set(PwDefs.NotesField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectNotes,
"You may safely delete this sample"));
_pwDatabase.RootGroup.AddEntry(pe, true);
pe = new PwEntry(true, true);
pe.Strings.Set(PwDefs.TitleField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectTitle,
"Sample Entry #2"));
pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUserName,
"Michael321"));
pe.Strings.Set(PwDefs.UrlField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUrl,
PwDefs.HelpUrl + "kb/testform.html"));
pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectPassword,
"12345"));
pe.AutoType.Add(new AutoTypeAssociation("*Test Form - KeePass*", string.Empty));
_pwDatabase.RootGroup.AddEntry(pe, true);
}
} }
} }

View File

@@ -0,0 +1,24 @@
using ModernKeePass.Interfaces;
using Windows.Storage;
using ModernKeePass.ViewModels;
namespace ModernKeePass.Services
{
public class ImportService : IImportService<IFormat>
{
public void Import(IFormat format, IStorageFile source, IDatabaseService databaseService)
{
var entities = (GroupVm)format.Import(source);
foreach (var entry in entities.Entries)
{
databaseService.RootGroup.Entries.Add(entry);
}
foreach (var subGroup in entities.Groups)
{
databaseService.RootGroup.Groups.Add(subGroup);
}
}
}
}

View File

@@ -483,4 +483,7 @@
<data name="RestoreGroupCommand.Message" xml:space="preserve"> <data name="RestoreGroupCommand.Message" xml:space="preserve">
<value>Group restored to its original position</value> <value>Group restored to its original position</value>
</data> </data>
<data name="NewImportCheckbox.Content" xml:space="preserve">
<value>Import existing data</value>
</data>
</root> </root>

View File

@@ -483,4 +483,7 @@
<data name="RestoreGroupCommand.Message" xml:space="preserve"> <data name="RestoreGroupCommand.Message" xml:space="preserve">
<value>Groupe replacée à son emplacement d'origine</value> <value>Groupe replacée à son emplacement d'origine</value>
</data> </data>
<data name="NewImportCheckbox.Content" xml:space="preserve">
<value>Importer des données existantes</value>
</data>
</root> </root>

View File

@@ -1,7 +1,49 @@
namespace ModernKeePass.ViewModels using Windows.Storage;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Interfaces;
using ModernKeePassLib;
namespace ModernKeePass.ViewModels
{ {
public class NewVm : OpenVm public class NewVm : OpenVm
{ {
public string Password { get; set; } public string Password { get; set; }
public bool IsImportChecked { get; set; }
public IStorageFile ImportFile { get; set; }
public IFormat ImportFormat { get; set; }
public void PopulateInitialData(IDatabaseService database, ISettingsService settings, IImportService<IFormat> importService)
{
if (settings.GetSetting<bool>("Sample") && !IsImportChecked) CreateSampleData(database);
else if (IsImportChecked && ImportFile != null) importService.Import(ImportFormat, ImportFile, database);
}
private void CreateSampleData(IDatabaseService database)
{
var bankingGroup = database.RootGroup.AddNewGroup("Banking");
bankingGroup.IconId = (int) Symbol.Calculator;
var emailGroup = database.RootGroup.AddNewGroup("Email");
emailGroup.IconId = (int) Symbol.Mail;
var internetGroup = database.RootGroup.AddNewGroup("Internet");
internetGroup.IconId = (int) Symbol.World;
var sample1 = database.RootGroup.AddNewEntry();
sample1.Name = "Sample Entry";
sample1.UserName = "Username";
sample1.Url = PwDefs.HomepageUrl;
sample1.Password = "Password";
sample1.Notes = "You may safely delete this sample";
var sample2 = database.RootGroup.AddNewEntry();
sample2.Name = "Sample Entry #2";
sample2.UserName = "Michael321";
sample2.Url = PwDefs.HelpUrl + "kb/testform.html";
sample2.Password = "12345";
}
} }
} }

View File

@@ -23,7 +23,9 @@
<HyperlinkButton Grid.Column="0" Grid.Row="1" Content="Select file..." Style="{StaticResource MainColorHyperlinkButton}" Click="ImportFileButton_OnClick" /> <HyperlinkButton Grid.Column="0" Grid.Row="1" Content="Select file..." Style="{StaticResource MainColorHyperlinkButton}" Click="ImportFileButton_OnClick" />
<StackPanel Grid.Column="1" Grid.Row="1" > <StackPanel Grid.Column="1" Grid.Row="1" >
<TextBlock Text="Format" Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,10" /> <TextBlock Text="Format" Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,10" />
<ComboBox Style="{StaticResource MainColorComboBox}" /> <ComboBox Style="{StaticResource MainColorComboBox}">
<ComboBoxItem>CSV</ComboBoxItem>
</ComboBox>
</StackPanel> </StackPanel>
<StackPanel Grid.Column="2" Grid.Row="1" > <StackPanel Grid.Column="2" Grid.Row="1" >
<TextBlock Text="Import into..." Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,10" /> <TextBlock Text="Import into..." Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,10" />

View File

@@ -16,20 +16,26 @@
<Page.DataContext> <Page.DataContext>
<viewModels:NewVm /> <viewModels:NewVm />
</Page.DataContext> </Page.DataContext>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<HyperlinkButton x:Uid="NewCreateButton" Click="ButtonBase_OnClick" Foreground="{StaticResource MainColor}" Style="{StaticResource MainColorHyperlinkButton}" /> <HyperlinkButton x:Uid="NewCreateButton" Click="ButtonBase_OnClick" Foreground="{StaticResource MainColor}" Style="{StaticResource MainColorHyperlinkButton}" />
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="15,0,0,30" x:Uid="NewCreateDesc" /> <TextBlock Style="{StaticResource BodyTextBlockStyle}" Margin="15,0,0,30" x:Uid="NewCreateDesc" />
<Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsFileSelected, Converter={StaticResource BooleanToVisibilityConverter}}"> <Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsFileSelected, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Margin="25,0,25,0"> <StackPanel Margin="25,0,25,0">
<TextBlock Text="{Binding Name}" /> <TextBlock Text="{Binding Name}" />
<userControls:CompositeKeyUserControl x:Uid="CompositeKeyNewButton" CreateNew="True" DatabaseFile="{Binding DatabaseFile}"> <userControls:CompositeKeyUserControl x:Uid="CompositeKeyNewButton" CreateNew="True" DatabaseFile="{Binding DatabaseFile}" ValidationChecked="CompositeKeyUserControl_OnValidationChecked" />
<interactivity:Interaction.Behaviors> </StackPanel>
<core:EventTriggerBehavior EventName="ValidationChecked"> </Border>
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" /> <CheckBox x:Name="CheckBox" x:Uid="NewImportCheckbox" IsChecked="{Binding IsImportChecked}" />
</core:EventTriggerBehavior> <Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=CheckBox}">
</interactivity:Interaction.Behaviors> <StackPanel Margin="25,0,25,0">
</userControls:CompositeKeyUserControl> <HyperlinkButton Content="Select file..." Style="{StaticResource MainColorHyperlinkButton}" Click="ImportFileButton_OnClick" />
<StackPanel>
<TextBlock Text="Format" Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,10" />
<ComboBox Style="{StaticResource MainColorComboBox}" SelectedItem="{Binding ImportFormat}">
<ComboBoxItem>CSV</ComboBoxItem>
</ComboBox>
</StackPanel>
</StackPanel> </StackPanel>
</Border> </Border>
</StackPanel> </StackPanel>

View File

@@ -2,6 +2,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using Windows.Storage.Pickers; using Windows.Storage.Pickers;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using ModernKeePass.Events;
using ModernKeePass.Services;
using ModernKeePass.ViewModels; using ModernKeePass.ViewModels;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
@@ -33,5 +35,25 @@ namespace ModernKeePass.Views
if (file == null) return; if (file == null) return;
Model.OpenFile(file); Model.OpenFile(file);
} }
private async void ImportFileButton_OnClick(object sender, RoutedEventArgs e)
{
var picker =
new FileOpenPicker
{
ViewMode = PickerViewMode.List,
SuggestedStartLocation = PickerLocationId.DocumentsLibrary
};
picker.FileTypeFilter.Add(".csv");
// Application now has read/write access to the picked file
Model.ImportFile = await picker.PickSingleFileAsync();
}
private void CompositeKeyUserControl_OnValidationChecked(object sender, PasswordEventArgs e)
{
Model.PopulateInitialData(DatabaseService.Instance, new SettingsService());
Frame.Navigate(typeof(GroupDetailPage));
}
} }
} }

View File

@@ -1,4 +1,5 @@
Improved search box Improved search box
Changing entry icon creates a new history entry Changing entry icon creates a new history entry
Corrected startup crash on some versions of Windows Corrected startup crash on some versions of Windows
Entry delete button now shows up correctly Entry delete button now shows up correctly
List of icons now only displays valid values

View File

@@ -1,4 +1,5 @@
Amelioration de la recherche Amelioration de la recherche
Changer l'icone d'une entree cree un historique Changer l'icone d'une entree cree un historique
Correction de crash lors du lancement avec certaines versions de Windows Correction de crash lors du lancement avec certaines versions de Windows
Le bouton de suppression d'une entree apparait bien desormais Le bouton de suppression d'une entree apparait bien desormais
La liste des icones n'affiche desormais que des valeurs valables

View File

@@ -46,7 +46,7 @@ namespace ModernKeePassApp.Test.Mock
{ {
_compositeKey = newCompositeKey; _compositeKey = newCompositeKey;
} }
public void CreateRecycleBin(string title) public void CreateRecycleBin(string title)
{ {
throw new NotImplementedException(); throw new NotImplementedException();