public async Task DbUnlockViewModelReadOnly()
        {
            Utils.DatabaseInfo databaseInfo = await Utils.GetDatabaseInfoForTest(TestContext);

            Assert.IsTrue(databaseInfo.Database.AsIStorageItem.Attributes.HasFlag(FileAttributes.ReadOnly), "Database file should be read-only");

            IFileProxyProvider proxyProvider            = new MockFileProxyProvider();
            StorageFileDatabaseCandidateFactory factory = new StorageFileDatabaseCandidateFactory(proxyProvider);

            TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>();
            ICredentialStorageProvider  credentialStorage = new MockCredentialProvider();
            IDatabaseUnlockViewModel    viewModel         = new DatabaseUnlockViewModel(
                new MockSyncContext(),
                await factory.AssembleAsync(databaseInfo.Database),
                false,
                new MockStorageItemAccessList(),
                new KdbxReader(),
                proxyProvider,
                factory,
                new MasterKeyChangeViewModelFactory(new DatabaseCredentialProviderFactory(credentialStorage), new MockFileService()),
                new TaskNotificationService(),
                new MockIdentityVerifier(),
                credentialStorage,
                new MockCredentialStorageViewModelFactory()
                );

            await viewModel.ActivateAsync();

            Assert.IsTrue(viewModel.IsReadOnly, "DatabaseUnlockViewModel should be read-only for a read-only file");

            await viewModel.UpdateCandidateFileAsync(await factory.AssembleAsync(await Utils.GetDatabaseByName("StructureTesting.kdbx")));

            Assert.IsFalse(viewModel.IsReadOnly, "DatabaseUnlockViewModel should not be read-only for a writable file");
        }
        public async Task DatabaseUnlockViewModel_ChangeFiles()
        {
            DatabaseUnlockViewModel_GoodHeader();

            StorageFileDatabaseCandidateFactory factory = new StorageFileDatabaseCandidateFactory(new MockFileProxyProvider {
                ScopeValue = true
            });

            await this.viewModel.UpdateCandidateFileAsync(await factory.AssembleAsync(await Utils.GetDatabaseByName(KnownBadDatabase)));
            await ViewModelHeaderValidated();
            await DatabaseUnlockViewModel_BadHeader();

            await this.viewModel.UpdateCandidateFileAsync(await factory.AssembleAsync(await Utils.GetDatabaseByName(KnownGoodDatabase)));
            await ViewModelHeaderValidated();

            DatabaseUnlockViewModel_GoodHeader();
        }
        public async Task Initialize()
        {
            TestDataAttribute dataAttr = GetTestAttribute <TestDataAttribute>();

            if (dataAttr != null && dataAttr.SkipInitialization)
            {
                return;
            }

            this.testDatabaseInfo = null;
            IDatabaseCandidate databaseValue = null;
            bool sampleValue = false;

            try
            {
                this.testDatabaseInfo = await Utils.GetDatabaseInfoForTest(TestContext);
            }
            catch (InvalidOperationException) { }

            if (dataAttr?.UseRealProxyProvider != true)
            {
                this.proxyProvider = new MockFileProxyProvider
                {
                    ScopeValue = (dataAttr?.InAppScope == true)
                };
            }
            else
            {
                StorageFolder proxyFolder = ApplicationData.Current.TemporaryFolder;
                proxyFolder = await proxyFolder.CreateFolderAsync("Proxies", CreationCollisionOption.OpenIfExists);

                this.proxyProvider = new FileProxyProvider(proxyFolder);
            }

            IDatabaseCandidateFactory candidateFactory = new StorageFileDatabaseCandidateFactory(this.proxyProvider);

            if (this.testDatabaseInfo != null)
            {
                databaseValue = await candidateFactory.AssembleAsync(this.testDatabaseInfo.Database);

                sampleValue = (dataAttr != null && dataAttr.InitSample);
            }

            if (dataAttr != null && !dataAttr.InitDatabase)
            {
                databaseValue = null;
            }

            this.accessList = new MockStorageItemAccessList();

            this.identityService = new MockIdentityVerifier()
            {
                CanVerify = dataAttr?.IdentityVerifierAvailable ?? UserConsentVerifierAvailability.NotConfiguredForUser,
                Verified  = dataAttr?.IdentityVerified ?? false
            };
            this.credentialProvider = new MockCredentialProvider();

            if (dataAttr?.StoredCredentials == true && databaseValue != null && this.testDatabaseInfo != null)
            {
                Assert.IsTrue(
                    await this.credentialProvider.TryStoreRawKeyAsync(
                        databaseValue.File,
                        this.testDatabaseInfo.RawKey
                        )
                    );
            }

            Utils.DatabaseInfo backupDatabase = await Utils.DatabaseMap["StructureTesting"];
            this.alwaysStoredCandidate = await candidateFactory.AssembleAsync(
                backupDatabase.Database
                );

            Assert.IsTrue(
                await this.credentialProvider.TryStoreRawKeyAsync(
                    this.alwaysStoredCandidate.File,
                    backupDatabase.RawKey
                    )
                );

            this.viewModel = new DatabaseUnlockViewModel(
                new MockSyncContext(),
                databaseValue,
                sampleValue,
                this.accessList,
                new KdbxReader(),
                this.proxyProvider,
                candidateFactory,
                new MasterKeyChangeViewModelFactory(new DatabaseCredentialProviderFactory(this.credentialProvider), new MockFileService()),
                new TaskNotificationService(),
                this.identityService,
                this.credentialProvider,
                new MockCredentialStorageViewModelFactory()
                );

            await this.viewModel.ActivateAsync();

            // Set various ViewModel properties if desired
            if (this.testDatabaseInfo != null && dataAttr != null)
            {
                if (dataAttr.SetPassword)
                {
                    this.viewModel.Password = this.testDatabaseInfo.Password;
                }

                if (dataAttr.SetKeyFile)
                {
                    this.viewModel.KeyFile = this.testDatabaseInfo.Keyfile;
                }
            }

            if (databaseValue != null)
            {
                await ViewModelHeaderValidated();
            }
        }
Beispiel #4
0
        public async Task MultiEdit_Degenerate()
        {
            StorageFileDatabaseCandidateFactory factory = new StorageFileDatabaseCandidateFactory(new MockFileProxyProvider {
                ScopeValue = true
            });
            StorageFolder work = await Utils.GetWorkFolder();

            IDatabaseCandidate workDb = await factory.AssembleAsync(
                (await this.thisTestInfo.Database.AsIStorageFile.CopyAsync(work, "Work.kdbx", NameCollisionOption.ReplaceExisting))
                .AsWrapper()
                );

            IKdbxWriter  writer;
            KdbxDocument doc;

            var reader = new KdbxReader();

            using (IRandomAccessStream stream = await workDb.GetRandomReadAccessStreamAsync())
            {
                ReaderResult headerResult = await reader.ReadHeaderAsync(stream, CancellationToken.None);

                Assert.AreEqual(headerResult, ReaderResult.Success);
            }

            KdbxDecryptionResult bodyResult = null;

            using (IRandomAccessStream stream = await workDb.GetRandomReadAccessStreamAsync())
            {
                bodyResult = await reader.DecryptFileAsync(stream, this.thisTestInfo.Password, this.thisTestInfo.Keyfile, CancellationToken.None);

                Assert.AreEqual(bodyResult.Result, ReaderResult.Success);
            }

            writer = reader.GetWriter();
            doc    = bodyResult.GetDocument();

            IDatabasePersistenceService persistor = new DefaultFilePersistenceService(writer, writer, workDb, new MockSyncContext(), await workDb.File.CheckWritableAsync());

            Assert.IsTrue(persistor.CanSave);
            Assert.IsTrue(await persistor.Save(doc));

            // Remove the last group
            doc.Root.DatabaseGroup.Children.RemoveAt(
                doc.Root.DatabaseGroup.Children.IndexOf(
                    doc.Root.DatabaseGroup.Children.Last(node => node is IKeePassGroup)
                    )
                );
            Assert.IsTrue(await persistor.Save(doc));

            reader = new KdbxReader();
            using (IRandomAccessStream stream = await workDb.GetRandomReadAccessStreamAsync())
            {
                ReaderResult headerResult = await reader.ReadHeaderAsync(stream, CancellationToken.None);

                Assert.AreEqual(headerResult, ReaderResult.Success);
            }
            using (IRandomAccessStream stream = await workDb.GetRandomReadAccessStreamAsync())
            {
                bodyResult = await reader.DecryptFileAsync(stream, this.thisTestInfo.Password, this.thisTestInfo.Keyfile, CancellationToken.None);

                Assert.AreEqual(bodyResult.Result, ReaderResult.Success);
            }

            writer = reader.GetWriter();
            doc    = bodyResult.GetDocument();

            doc.Root.DatabaseGroup.Children.RemoveAt(
                doc.Root.DatabaseGroup.Children.IndexOf(
                    doc.Root.DatabaseGroup.Children.Last(node => node is IKeePassGroup)
                    )
                );
            Assert.IsTrue(await persistor.Save(doc));

            reader = new KdbxReader();
            using (IRandomAccessStream stream = await workDb.GetRandomReadAccessStreamAsync())
            {
                ReaderResult headerResult = await reader.ReadHeaderAsync(stream, CancellationToken.None);

                Assert.AreEqual(headerResult, ReaderResult.Success);
            }
            using (IRandomAccessStream stream = await workDb.GetRandomReadAccessStreamAsync())
            {
                bodyResult = await reader.DecryptFileAsync(stream, this.thisTestInfo.Password, this.thisTestInfo.Keyfile, CancellationToken.None);

                Assert.AreEqual(bodyResult.Result, ReaderResult.Success);
            }

            writer = reader.GetWriter();
            doc    = bodyResult.GetDocument();
        }