/// <summary> /// Creates a ViewModel wrapping a brand new KdbxGroup as a child of the specified parent group. /// </summary> /// <param name="resourceProvider">IResourceProvider for localizing strings.</param> /// <param name="navigationViewModel">A ViewModel used for tracking navigation history.</param> /// <param name="persistenceService">A service used for persisting the document.</param> /// <param name="clipboardService">A service used for accessing the clipboard.</param> /// <param name="settingsService">A service used for accessing app settings.</param> /// <param name="document">A KdbxDocument representing the database we are working on.</param> /// <param name="parentGroup">The IKeePassGroup to use as a parent for the new group.</param> /// <param name="rng">A random number generator used to protect strings in memory.</param> public EntryDetailsViewModel( IResourceProvider resourceProvider, IDatabaseNavigationViewModel navigationViewModel, IDatabasePersistenceService persistenceService, ISensitiveClipboardService clipboardService, IAppSettingsService settingsService, KdbxDocument document, IKeePassGroup parentGroup, IRandomNumberGenerator rng ) : this( resourceProvider, navigationViewModel, persistenceService, clipboardService, settingsService, document, new KdbxEntry(parentGroup, rng, document.Metadata), true, false, rng ) { if (parentGroup == null) { throw new ArgumentNullException(nameof(parentGroup)); } if (rng == null) { throw new ArgumentNullException(nameof(rng)); } }
/// <summary> /// Creates a ViewModel wrapping a brand new KdbxGroup as a child of the specified parent group. /// </summary> /// <param name="navigationViewModel">A ViewModel used for tracking navigation history.</param> /// <param name="persistenceService">A service used for persisting the document.</param> /// <param name="document">A KdbxDocument representing the database we are working on.</param> /// <param name="parentGroup">The IKeePassGroup to use as a parent for the new group.</param> public GroupDetailsViewModel( IDatabaseNavigationViewModel navigationViewModel, IDatabasePersistenceService persistenceService, KdbxDocument document, IKeePassGroup parentGroup ) : base(navigationViewModel, persistenceService, document, new KdbxGroup(parentGroup), true, false) { if (parentGroup == null) { throw new ArgumentNullException("parentGroup"); } }
/// <summary> /// Creates a ViewModel wrapping an existing KdbxGroup. /// <param name="navigationViewModel">A ViewModel used for tracking navigation history.</param> /// <param name="persistenceService">A service used for persisting the document.</param> /// <param name="document">A KdbxDocument representing the database we are working on.</param> /// <param name="groupToEdit">The group being viewed.</param> /// <param name="isReadOnly">Whether to open the group in read-only mode.</param> public GroupDetailsViewModel( IDatabaseNavigationViewModel navigationViewModel, IDatabasePersistenceService persistenceService, KdbxDocument document, IKeePassGroup groupToEdit, bool isReadOnly ) : base(navigationViewModel, persistenceService, document, groupToEdit, false, isReadOnly) { if (groupToEdit == null) { throw new ArgumentNullException("groupToEdit"); } }
/// <summary> /// Creates a ViewModel wrapping an existing KdbxGroup. /// </summary> /// <param name="resourceProvider">IResourceProvider for localizing strings.</param> /// <param name="navigationViewModel">A ViewModel used for tracking navigation history.</param> /// <param name="persistenceService">A service used for persisting the document.</param> /// <param name="clipboardService">A service used for accessing the clipboard.</param> /// <param name="settingsService">A service used to access app settings.</param> /// <param name="document">A KdbxDocument representing the database we are working on.</param> /// <param name="entryToEdit">The entry being viewed.</param> /// <param name="isReadOnly">Whether to open the group in read-only mode.</param> /// <param name="rng">A random number generator used to protect strings in memory.</param> public EntryDetailsViewModel( IResourceProvider resourceProvider, IDatabaseNavigationViewModel navigationViewModel, IDatabasePersistenceService persistenceService, ISensitiveClipboardService clipboardService, IAppSettingsService settingsService, KdbxDocument document, IKeePassEntry entryToEdit, bool isReadOnly, IRandomNumberGenerator rng ) : this(resourceProvider, navigationViewModel, persistenceService, clipboardService, settingsService, document, entryToEdit, false, isReadOnly, rng) { if (entryToEdit == null) { throw new ArgumentNullException(nameof(entryToEdit)); } }
/// <summary> /// Initializes the instance. /// </summary> /// <param name="syncContext">Context to use for marshalling to the UI thread.</param> /// <param name="timerFactory">Used to create a timer.</param> /// <param name="file">The file on disk represented by this database.</param> /// <param name="fileIsSample">Whether this file is a sample file.</param> /// <param name="document">The decrypted database.</param> /// <param name="resourceProvider">A IResourceProvider for the View.</param> /// <param name="rng">A random number generator used to protect strings.</param> /// <param name="navigationViewModel">A ViewModel representing the navigation of the database.</param> /// <param name="masterKeyViewModel">A ViewModel that allows configuring the database's master key.</param> /// <param name="persistenceService">A service used to save the database.</param> /// <param name="identityService">A service used to authenticate the user.</param> /// <param name="credentialStorage">A service used to update saved credentials.</param> /// <param name="settingsService">A service used to access app settings.</param> /// <param name="clipboardService">A service used to access the clipboard for credentials.</param> public DatabaseParentViewModel( ISyncContext syncContext, ITimerFactory timerFactory, ITestableFile file, bool fileIsSample, KdbxDocument document, IResourceProvider resourceProvider, IRandomNumberGenerator rng, IDatabaseNavigationViewModel navigationViewModel, IMasterKeyViewModel masterKeyViewModel, IDatabasePersistenceService persistenceService, IIdentityVerificationService identityService, ICredentialStorageProvider credentialStorage, IAppSettingsService settingsService, ISensitiveClipboardService clipboardService ) : base(document, persistenceService) { if (timerFactory == null) { throw new ArgumentNullException(nameof(timerFactory)); } this.syncContext = syncContext ?? throw new ArgumentNullException(nameof(syncContext)); this.idleTimer = timerFactory.Assemble(TimeSpan.FromSeconds(1)); this.file = file ?? throw new ArgumentNullException(nameof(file)); this.fileIsSample = fileIsSample; this.document = document ?? throw new ArgumentNullException(nameof(document)); this.resourceProvider = resourceProvider ?? throw new ArgumentNullException(nameof(resourceProvider)); this.rng = rng ?? throw new ArgumentNullException(nameof(rng)); this.navigationViewModel = navigationViewModel ?? throw new ArgumentNullException(nameof(navigationViewModel)); this.settingsViewModel = new DatabaseSettingsViewModel(PersistenceService.SettingsProvider); this.masterKeyViewModel = masterKeyViewModel ?? throw new ArgumentNullException(nameof(masterKeyViewModel)); this.identityService = identityService ?? throw new ArgumentNullException(nameof(identityService)); this.credentialProvider = credentialStorage ?? throw new ArgumentNullException(nameof(credentialStorage)); this.settingsService = settingsService ?? throw new ArgumentNullException(nameof(settingsService)); this.clipboardService = clipboardService ?? throw new ArgumentNullException(nameof(clipboardService)); }
public async Task Initialize() { try { CancellationTokenSource cts = new CancellationTokenSource(); Utils.DatabaseInfo databaseInfo = await Utils.GetDatabaseInfoForTest(TestContext); KdbxReader reader = new KdbxReader(); using (IRandomAccessStream stream = await databaseInfo.Database.AsIStorageFile.OpenReadAsync()) { Assert.IsFalse((await reader.ReadHeaderAsync(stream, cts.Token)).IsError); KdbxDecryptionResult decryption = await reader.DecryptFileAsync(stream, databaseInfo.Password, databaseInfo.Keyfile, cts.Token); Assert.IsFalse(decryption.Result.IsError); this.document = decryption.GetDocument(); } } catch (InvalidOperationException) { } this.viewModel = new DatabaseNavigationViewModel(); }
/// <summary> /// Initializes the base class from a subclass. /// </summary> /// <param name="navigationViewModel">A ViewModel used for tracking navigation history.</param> /// <param name="persistenceService">A service used for persisting the document.</param> /// <param name="document">A KdbxDocument representing the database we are working on.</param> /// <param name="item">The item this ViewModel wraps.</param> /// <param name="isNew">Whether the child is being created for the first time.</param> /// <param name="isReadOnly">Whether the child is being accessed as read-only.</param> protected NodeDetailsViewModel( IDatabaseNavigationViewModel navigationViewModel, IDatabasePersistenceService persistenceService, KdbxDocument document, T item, bool isNew, bool isReadOnly ) : base(document, persistenceService) { if (isNew && item.Parent == null) { throw new ArgumentException("Cannot create a new node with no parent!"); } if (navigationViewModel.ActiveGroup != item.Parent) { throw new ArgumentException("The database's active group must be the node's parent!"); } NavigationViewModel = navigationViewModel ?? throw new ArgumentNullException(nameof(navigationViewModel)); Document = document ?? throw new ArgumentNullException(nameof(document)); IsNew = isNew; if (!isNew) { this.masterCopy = GetClone(item); WorkingCopy = GetClone(this.masterCopy); } else { this.masterCopy = null; WorkingCopy = GetClone(item); } IsReadOnly = isReadOnly; }
/// <summary> /// Provides a means of the parent page requesting a navigate from a clicked breadcrumb to the specified group. /// </summary> /// <remarks> /// This allows the page to preempt the navigate or do necessary cleanup. /// </remarks> /// <param name="dbViewModel">The DatabaseViewModel to use for the navigation.</param> /// <param name="navViewModel">The NavigationViewModel to update.</param> /// <param name="clickedGroup">The group to navigate to.</param> public override Task RequestBreadcrumbNavigation(IDatabaseViewModel dbViewModel, IDatabaseNavigationViewModel navViewModel, IKeePassGroup clickedGroup) { Action navCallback = () => { navViewModel.SetGroup(clickedGroup); }; Frame.Navigate(typeof(DatabaseView), new CancellableNavigationParameter(navCallback, dbViewModel)); return(Task.FromResult <object>(null)); }
/// <summary> /// Passes provided parameters to the base constructor and initializes commands. /// </summary> /// <param name="resourceProvider">IResourceProvider for localizing strings.</param> /// <param name="navigationViewModel"></param> /// <param name="persistenceService"></param> /// <param name="clipboardService"></param> /// <param name="settingsService"></param> /// <param name="document"></param> /// <param name="entry"></param> /// <param name="isNew"></param> /// <param name="isReadOnly"></param> /// <param name="rng"></param> private EntryDetailsViewModel( IResourceProvider resourceProvider, IDatabaseNavigationViewModel navigationViewModel, IDatabasePersistenceService persistenceService, ISensitiveClipboardService clipboardService, IAppSettingsService settingsService, KdbxDocument document, IKeePassEntry entry, bool isNew, bool isReadOnly, IRandomNumberGenerator rng ) : base(navigationViewModel, persistenceService, document, entry, isNew, isReadOnly) { this.resourceProvider = resourceProvider; this.clipboardService = clipboardService; this.settingsService = settingsService; this.rng = rng; this.copyFieldValueCommand = new TypedCommand <IProtectedString>( str => { clipboardService.CopyCredential(str.ClearValue, ClipboardOperationType.Other); } ); this.deleteFieldCommand = new TypedCommand <IProtectedString>( str => !IsReadOnly && PersistenceService.CanSave, str => { DebugHelper.Assert(!IsReadOnly); WorkingCopy.Fields.Remove(str); } ); this.editFieldCommand = new AsyncTypedCommand <IProtectedString>( str => PersistenceService.CanSave, async str => { IsReadOnly = false; await UpdateFieldEditorViewModel(new FieldEditorViewModel(str, this.resourceProvider)); } ); this.newFieldCommand = new AsyncActionCommand( () => PersistenceService.CanSave, async() => { IsReadOnly = false; await UpdateFieldEditorViewModel(new FieldEditorViewModel(this.rng, this.resourceProvider)); } ); this.commitFieldCommand = new AsyncActionCommand( () => FieldEditorViewModel?.CommitCommand.CanExecute(WorkingCopy) ?? false, async() => { FieldEditorViewModel.CommitCommand.Execute(WorkingCopy); await UpdateFieldEditorViewModel(null); } ); PropertyChanged += (s, e) => { if (e.PropertyName == nameof(IsReadOnly)) { ((TypedCommand <IProtectedString>)DeleteFieldCommand).RaiseCanExecuteChanged(); } else if (e.PropertyName == nameof(WorkingCopy)) { OnPropertyChanged(nameof(WorkingCopyViewModel)); } }; }
/// <summary> /// Provides a means of the parent page requesting a navigate from a clicked breadcrumb to the specified group. /// </summary> /// <remarks> /// This doesn't actually navigate, just updates the navViewModel. /// </remarks> /// <param name="dbViewModel">The DatabaseViewModel to use for the navigation.</param> /// <param name="navViewModel">The NavigationViewModel to update.</param> /// <param name="clickedGroup">The group to navigate to.</param> public override Task RequestBreadcrumbNavigation(IDatabaseViewModel dbViewModel, IDatabaseNavigationViewModel navViewModel, IKeePassGroup clickedGroup) { navViewModel.SetGroup(clickedGroup); // Task.CompletedTask is better here but not available presently. return(Task.FromResult(0)); }
/// <summary> /// Generats a ViewModel representing an existing child in the DOM. /// </summary> /// <param name="navigationViewModel"></param> /// <param name="persistenceService"></param> /// <param name="document"></param> /// <param name="openForReadOnly"></param> /// <returns>A ViewModel representing an existing child in the DOM.</returns> protected abstract TViewModel GetExistingViewModel( IDatabaseNavigationViewModel navigationViewModel, IDatabasePersistenceService persistenceService, KdbxDocument document, bool openForReadOnly );
/// <summary> /// Generates a ViewModel representing a new child. /// </summary> /// <param name="navigationViewModel"></param> /// <param name="persistenceService"></param> /// <param name="document"></param> /// <param name="parent"></param> /// <returns>A ViewModel representing a new child not already in the tree.</returns> protected abstract TViewModel GetNewViewModel( IDatabaseNavigationViewModel navigationViewModel, IDatabasePersistenceService persistenceService, KdbxDocument document, IKeePassGroup parent );
/// <summary> /// Provides a means of the parent page requesting a navigate from a clicked breadcrumb to the specified group. /// </summary> /// <remarks> /// This allows the page to preempt the navigate or do necessary cleanup. /// </remarks> /// <param name="dbViewModel">The DatabaseViewModel to use for the navigation.</param> /// <param name="navViewModel">The NavigationViewModel to update.</param> /// <param name="clickedGroup">The group to navigate to.</param> /// <returns>A Task representing the request.</returns> public abstract Task RequestBreadcrumbNavigation(IDatabaseViewModel dbViewModel, IDatabaseNavigationViewModel navViewModel, IKeePassGroup clickedGroup);