public void ReloadPasswordUpdatesActualGuidColor( )
        {
            // Setup
            var original = AddPassword( "abde", PasswordGenerators.LegacyAlphaNumeric, 1, "123".ToSecureString( ), "yadda yadda" );
            ViewModel = ViewModelFactory.PasswordEditorFor( PasswordRepository.LoadPassword( "abde" ) );
            ViewModel.UpdateMasterPassword( "123".ToSecureString( ) );

            bool guidColorUpdated = false;
            ViewModel.PropertyChanged += ( s, e ) => { guidColorUpdated |= e.PropertyName == "ActualGuidColor"; };

            PasswordDigestDocument updated = new PasswordDigestDocumentBuilder
                                                 {
                                                     Digest = original.Digest,
                                                     Note = original.Note,
                                                     CreatedOn = original.CreatedOn,
                                                     ModifiedOn = original.ModifiedOn.AddDays( 1 ),
                                                     MasterPasswordId = Guid.NewGuid( )
                                                 };

            PasswordRepository.UpdatePassword( original, updated );
            // Exercise
            ViewModel.Reload( );
            // Verify
            Assert.That( ViewModel.ActualGuidColor,
                         Is.EqualTo( GuidToColorConverter.Convert( updated.MasterPasswordId ) ) );
            Assert.That( guidColorUpdated, Is.True );
        }
 public void LoadReadsPasswordKeyFromElement( )
 {
     // Setup
     XElement element = new PasswordDigestDocumentBuilder { Key = "aKey" };
     SaveXml( new XElement( PasswordSerializer.PasswordStoreElement,
                            element ) );
     // Exercise
     IEnumerable<PasswordDigestDocument> passwords = _serializer.Load( _textResource );
     // Verify
     PasswordDigestDocument passwordDigest = passwords.First( );
     Assert.That( passwordDigest.Key, Is.EqualTo( "aKey" ) );
 }
 public void LoadMultiplePasswords( )
 {
     // Setup
     XElement element1 = new PasswordDigestDocumentBuilder { Key = "aKey" };
     XElement element2 = new PasswordDigestDocumentBuilder { Key = "anotherKey" };
     SaveXml( new XElement( PasswordSerializer.PasswordStoreElement,
                            element1,
                            element2 ) );
     // Exercise
     IEnumerable<PasswordDigestDocument> passwords = _serializer.Load( _textResource );
     // Verify
     Assert.That( passwords.Count( ), Is.EqualTo( 2 ) );
 }
 public void LoadReadsMasterPasswordGuidFromElement( )
 {
     // Setup
     Guid guid = Guid.Parse( "34579b9f-8ac1-464a-805a-abe564da8848" );
     XElement element = new PasswordDigestDocumentBuilder { Key = "aKey", MasterPasswordId = guid };
     SaveXml( new XElement( PasswordSerializer.PasswordStoreElement,
                            element ) );
     // Exercise
     IEnumerable<PasswordDigestDocument> passwords = _serializer.Load( _textResource );
     // Verify
     PasswordDigestDocument passwordDigest = passwords.First( );
     Assert.That( passwordDigest.Key, Is.EqualTo( "aKey" ) );
     Assert.That( passwordDigest.MasterPasswordId, Is.EqualTo( guid ) );
 }
 public void SaveNewPasswordAddsItToData( )
 {
     // Set up
     PasswordDigestDocument password = new PasswordDigestDocumentBuilder
                                           {
                                               Key = "azer",
                                               Hash = new byte[ ] { 0x12, 0x34 }
                                           };
     // Exercise
     var saved = _passwordRepository.SavePassword( password );
     // Verify
     Assert.That( saved, Is.True );
     Assert.That( _inMemoryPasswordData.LoadPasswords( ),
                  Is.EquivalentTo( new[ ] { TestPasswords.Abcd, TestPasswords.Efgh, TestPasswords.Ijkl, password } ) );
 }
        public void ViewModelPresentsDatesFormattedByFuzzyDateFormatter( )
        {
            // Set up
            TimeProvider.Now = new DateTime( 2011, 11, 14, 8, 0, 0 );

            PasswordDigestDocument password = new PasswordDigestDocumentBuilder
                                                  {
                                                      Key = "ABCD",
                                                      Iteration = 2,
                                                      PasswordGenerator = PasswordGenerators.LegacyFull,
                                                      CreatedOn = new DateTime( 2011, 11, 11 ),
                                                      ModifiedOn = new DateTime( 2011, 11, 14 ),
                                                      Note = "Need this for EFGH"
                                                  };


            // Exercise
            var viewModel = new PasswordListEntryViewModel( password, GuidToColor, FuzzyDateFormatter );

            // Verify
            Assert.That( viewModel.CreationDate, Is.EqualTo( FuzzyDateFormatter.Format( new DateTime( 2011, 11, 11 ) ) ) );
            Assert.That( viewModel.ModificationDate, Is.EqualTo( FuzzyDateFormatter.Format( new DateTime( 2011, 11, 14 ) ) ) );
        }
        public void EntryPresentsTextFromDocument( )
        {
            // Set up

            PasswordDigestDocument password = new PasswordDigestDocumentBuilder
                                                  {
                                                      Key = "ABCD",
                                                      Iteration = 2,
                                                      PasswordGenerator = PasswordGenerators.LegacyFull,
                                                      CreatedOn = new DateTime( 2011, 11, 11 ),
                                                      ModifiedOn = new DateTime( 2011, 11, 14 ),
                                                      Note = "Need this for EFGH"
                                                  };


            // Exercise
            var viewModel = new PasswordListEntryViewModel( password, GuidToColor, FuzzyDateFormatter );

            // Verify

            Assert.That( viewModel.Name, Is.EqualTo( "ABCD" ) );
            Assert.That( viewModel.Note, Is.EqualTo( "Need this for EFGH" ) );
        }
        public void ViewModelPresentsGeneratorUsingResources( )
        {
            // Set up
            PasswordDigestDocument password = new PasswordDigestDocumentBuilder
                                                  {
                                                      Key = "ABCD",
                                                      Iteration = 2,
                                                      PasswordGenerator = PasswordGenerators.LegacyFull,
                                                      CreatedOn = new DateTime( 2011, 11, 11 ),
                                                      ModifiedOn = new DateTime( 2011, 11, 14 ),
                                                      Note = "Need this for EFGH"
                                                  };


            // Exercise
            var viewModel = new PasswordListEntryViewModel( password, GuidToColor, FuzzyDateFormatter );

            // Verify
            Assert.That( viewModel.GeneratorNameAndIteration, Is.EqualTo( Resources.PasswordGeneratorccf1451c4b3045a499b0d54ec3c3a7ee + " (2)" ) );
        }
        public void NoteIsNotVisibleWhenEmpty( )
        {
            // Set up
            PasswordDigestDocument password = new PasswordDigestDocumentBuilder
                                                  {
                                                      Key = "ABCD",
                                                      Iteration = 2,
                                                      PasswordGenerator = PasswordGenerators.LegacyFull,
                                                      CreatedOn = new DateTime( 2011, 11, 11 ),
                                                      ModifiedOn = new DateTime( 2011, 11, 14 ),
                                                      Note = ""
                                                  };


            // Exercise
            var viewModel = new PasswordListEntryViewModel( password, GuidToColor, FuzzyDateFormatter );

            // Verify
            Assert.That( viewModel.NoteVisible, Is.False );
        }
        public void ReloadPasswordDoesNotUpdateWhenDirty( )
        {
            // Set up
            var original = AddPassword( "abde", PasswordGenerators.LegacyAlphaNumeric, 1, "123".ToSecureString( ), "yadda yadda" );
            ViewModel = ViewModelFactory.PasswordEditorFor( PasswordRepository.LoadPassword( "abde" ) );

            var updatedDigest =
                Engine.Derive( new PasswordRequest( original.Key, "123".ToSecureString( ), 1, PasswordGenerators.LegacyFull ) ).Digest;

            PasswordDigestDocument updated = new PasswordDigestDocumentBuilder
                                                 {
                                                     Digest = updatedDigest,
                                                     Note = original.Note,
                                                     CreatedOn = original.CreatedOn,
                                                     ModifiedOn = original.ModifiedOn.AddDays( 1 ),
                                                     MasterPasswordId = Guid.NewGuid( )
                                                 };
            PasswordRepository.UpdatePassword( original, updated );

            ViewModel.Iteration = 3;
            // Exercise
            ViewModel.Reload( );
            // Verify
            Assert.That( ViewModel.Iteration, Is.EqualTo( 3 ) );
            Assert.That( ViewModel.DerivedPasswords.First( p => p.IsSelected ).Model.Generator, Is.EqualTo( PasswordGenerators.LegacyAlphaNumeric ) );
        }
        public void SaveOverMoreRecentDeletedPasswordFails( )
        {
            // Set up
            PasswordDigestDocument password = new PasswordDigestDocumentBuilder
                                                  {
                                                      Key = "ijkl",
                                                      Hash = new byte[ ] { 0x12, 0x34 },
                                                      ModifiedOn = new DateTime( 2011, 11, 3 )
                                                  };

            // Exercise
            var saved = _passwordRepository.SavePassword( password );

            // Verify
            Assert.That( saved, Is.False );
            Assert.That( _inMemoryPasswordData.LoadPasswords( ), Is.EquivalentTo( _allPasswords ) );
        }
 public void UpdateMissingPasswordFails( )
 {
     // Set up
     PasswordDigestDocument password = new PasswordDigestDocumentBuilder
                                           {
                                               Key = "azer",
                                               Hash = new byte[ ] { 0x12, 0x34 },
                                               ModifiedOn = new DateTime( 2011, 11, 3 )
                                           };
     PasswordDigestDocument updatedPassword = Update( password, new DateTime( 2011, 11, 5 ) );
     // Exercise
     var updated = _passwordRepository.UpdatePassword( password, updatedPassword );
     // Verify
     Assert.That( updated, Is.False );
     Assert.That( _inMemoryPasswordData.LoadPasswords( ), Is.EquivalentTo( _allPasswords ) );
 }
        public void ReloadWithBackEndChangeWhileNotDirtyUpdatesContent( )
        {
            // Set up
            _model.MasterPassword = "******".ToSecureString( );
            _model.UpdateDerivedPasswords( );

            var digest = _engine.Derive( new PasswordRequest( "abij", "1234".ToSecureString( ), 5, PasswordGenerators.LegacyAlphaNumeric ) );

            var updated = new PasswordDigestDocumentBuilder
                              {
                                  Digest = digest.Digest,
                                  CreatedOn = new DateTime( 2011, 11, 2 ),
                                  ModifiedOn = new DateTime( 2011, 11, 5 ),
                                  MasterPasswordId = Guid.NewGuid( ),
                                  Note = "AB IJ K"
                              };


            Assert.That( _passwordRepository.SavePassword( updated ), Is.True );


            // Exercise
            _model.Reload( );
            // Verify
            Assert.That( _model.Key, Is.EqualTo( "abij" ) );
            Assert.That( _model.MasterPassword.ConsumeBytes( Encoding.UTF8, b => Encoding.UTF8.GetString( b ) ),
                         Is.EqualTo( "4321" ) );
            Assert.That( _model.SelectedPassword,
                         Is.EqualTo( _model.DerivedPasswords.First( p => p.Generator == PasswordGenerators.LegacyAlphaNumeric ) ) );
            Assert.That( _model.Iteration, Is.EqualTo( 5 ) );
            Assert.That( _model.Note, Is.EqualTo( "AB IJ K" ) );

            Assert.That( _model.IsDirty, Is.False );
            Assert.That( _model.CanSave, Is.True );
            Assert.That( _model.CanDelete, Is.True );
        }
        public void ReloadPasswordUpdateIteration( )
        {
            // Set up
            var original = AddPassword( "abde", PasswordGenerators.LegacyAlphaNumeric, 1, "123".ToSecureString( ), "yadda yadda" );
            ViewModel = ViewModelFactory.PasswordEditorFor( PasswordRepository.LoadPassword( "abde" ) );

            bool iterationUpdated = false;
            ViewModel.PropertyChanged += ( s, e ) => { iterationUpdated |= e.PropertyName == "Iteration"; };

            PasswordDigestDocument updated = new PasswordDigestDocumentBuilder
                                                 {
                                                     Digest = new PasswordDigest( original.Key, original.Hash, 2, original.PasswordGenerator ),
                                                     Note = original.Note,
                                                     CreatedOn = original.CreatedOn,
                                                     ModifiedOn = original.ModifiedOn.AddDays( 1 ),
                                                     MasterPasswordId = original.MasterPasswordId
                                                 };
            PasswordRepository.UpdatePassword( original, updated );

            // Exercise
            ViewModel.Reload( );

            // Verify
            Assert.That( ViewModel.Iteration, Is.EqualTo( 2 ) );
            Assert.That( iterationUpdated, Is.True );
        }
        public void LoadFixesInconsistentModificationTimeInVersion1File( )
        {
            // Set up
            XElement element = new PasswordDigestDocumentBuilder
                                   {
                                       Key = "aKey",
                                       CreatedOn = new DateTime( 123456789123L ),
                                       ModifiedOn = new DateTime( 111111111111L ),
                                   };
            SaveXml( new XElement( PasswordSerializer.PasswordStoreElement,
                                   new XAttribute( PasswordSerializer.VersionAttribute, "1" ),
                                   element ) );

            // Exercise
            IEnumerable<PasswordDigestDocument> passwords = _serializer.Load( _textResource );
            // Verify
            PasswordDigestDocument passwordDigest = passwords.First( );
            Assert.That( passwordDigest.ModifiedOn, Is.EqualTo( passwordDigest.CreatedOn ) );
        }
        public void LoadDropsPasswordWithoutModificationTimeInVersion1File( )
        {
            // Set up
            XElement element = new PasswordDigestDocumentBuilder { Key = "aKey", CreatedOn = new DateTime( 123456789123L ) };

            element.Elements( PasswordSerializer.ModifiedElement ).Remove( );

            SaveXml( new XElement( PasswordSerializer.PasswordStoreElement,
                                   new XAttribute( PasswordSerializer.VersionAttribute, "1" ),
                                   element ) );

            // Exercise
            IEnumerable<PasswordDigestDocument> passwords = _serializer.Load( _textResource );
            // Verify
            Assert.That( passwords, Is.Empty );
        }
 public void LoadReadsModificationDateFromElement( )
 {
     // Setup
     DateTime modificationTime = new DateTime( 634122874455500442 );
     XElement element = new PasswordDigestDocumentBuilder { Key = "aKey", ModifiedOn = modificationTime };
     SaveXml( new XElement( PasswordSerializer.PasswordStoreElement,
                            element ) );
     // Exercise
     IEnumerable<PasswordDigestDocument> passwords = _serializer.Load( _textResource );
     // Verify
     PasswordDigestDocument passwordDigest = passwords.First( );
     Assert.That( passwordDigest.Key, Is.EqualTo( "aKey" ) );
     Assert.That( passwordDigest.ModifiedOn, Is.EqualTo( modificationTime ) );
 }
        public void SaveOverEarlierDeletedPasswordOverwritesIt( )
        {
            // Set up
            PasswordDigestDocument password = new PasswordDigestDocumentBuilder
                                                  {
                                                      Key = "ijkl",
                                                      Hash = new byte[ ] { 0x12, 0x34 },
                                                      ModifiedOn = new DateTime( 2011, 11, 6 )
                                                  };

            // Exercise
            var saved = _passwordRepository.SavePassword( password );

            // Verify
            Assert.That( saved, Is.True );
            Assert.That( _inMemoryPasswordData.LoadPasswords( ),
                         Is.EquivalentTo( new[ ] { TestPasswords.Abcd, TestPasswords.Efgh, password } ) );
        }
        public void ChangeFromInternalToExternalSavesFurtherPasswordsToExternal( )
        {
            // Set up
            var passwordsFile = new FileInfo( TempFile );
            PasswordDigestDocument password = new PasswordDigestDocumentBuilder { Key = "abc " };

            _settings.PasswordsAreExternal = false;
            _storageConfiguration = new StorageConfiguration( _settings, _storage );
            _storageConfiguration.SelectExternalStorage( passwordsFile );
            // Exercise
            _storage.PasswordRepository.SavePassword( password );
            // Verify
            var passwords = XmlPasswordData
                .From( new FileTextResource( passwordsFile ) )
                .LoadPasswords( );

            Assert.That( passwords,
                         Is.EquivalentTo( new[ ] { password } ) );
        }
        public void SaveDeletedPasswordFailsWithException( )
        {
            // Set up
            PasswordDigestDocument password = new PasswordDigestDocumentBuilder
                                                  {
                                                      Key = "erty",
                                                      Hash = new byte[ ] { 0x12, 0x34 },
                                                      ModifiedOn = new DateTime( 2011, 11, 3 )
                                                  };

            // Exercise
            _passwordRepository.SavePassword( password.Delete( new DateTime( 2011, 11, 4 ) ) );

            // Verify
        }
        public void DeletePasswordModifiedLaterLeavesIt( )
        {
            // Set up
            _timeProvider.Now = new DateTime( 2011, 11, 5 );
            PasswordDigestDocument updated = new PasswordDigestDocumentBuilder
                                                 {
                                                     Digest = _original.Digest,
                                                     CreatedOn = _original.CreatedOn,
                                                     ModifiedOn = new DateTime( 2011, 11, 6 ),
                                                     Note = "I changed the note.",
                                                     MasterPasswordId = _original.MasterPasswordId
                                                 };
            _passwordRepository.UpdatePassword( _original, updated );

            // Exercise
            var deleted = _model.Delete( );
            // Verify
            Assert.That( deleted, Is.False );
            Assert.That( _passwordRepository.LoadPasswords( ), Is.EquivalentTo( new[ ] { updated } ) );
            Assert.That( _passwordData.LoadPasswords( ), Has.Count.EqualTo( 1 ) );
            Assert.That( _passwordData.LoadPasswords( ).ElementAt( 0 ).IsDeleted, Is.False );
        }
        public void UpdatePreviouslyDeletedPasswordOverwritesIt( )
        {
            // Set up
            var passwordToDelete = _passwordRepository.LoadPassword( "abcd" );
            _passwordRepository.DeletePassword( passwordToDelete, new DateTime( 2011, 11, 11 ) );

            PasswordDigestDocument newVersion = new PasswordDigestDocumentBuilder
                                                    {
                                                        Key = "abcd",
                                                        Hash = new byte[ ] { 0x65 },
                                                        PasswordGenerator = PasswordGenerators.LegacyAlphaNumeric,
                                                        Iteration = 2,
                                                        MasterPasswordId = Guid.NewGuid( ),
                                                        CreatedOn = new DateTime( 2011, 11, 12 ),
                                                        ModifiedOn = new DateTime( 2011, 11, 13 ),
                                                        Note = ""
                                                    };

            PasswordDigestDocument deleted = _inMemoryPasswordData.LoadPasswords( ).First( p => p.Key == "abcd" );
            // Exercise
            var updated = _passwordRepository.UpdatePassword( deleted, newVersion );
            // Verify
            Assert.That( updated, Is.True );
            Assert.That( _passwordRepository.LoadPassword( "abcd" ), Is.EqualTo( newVersion ) );
            Assert.That( _inMemoryPasswordData.LoadPasswords( ).Where( p => p.Key == "abcd" ).Count( ), Is.EqualTo( 1 ) );
        }
        public void ViewModelPresentsMasterPasswordId( )
        {
            // Set up

            Guid guid = Guid.Parse( "ADB07A84-ED76-420F-9570-D0684DD044FE" );
            PasswordDigestDocument password = new PasswordDigestDocumentBuilder
                                                  {
                                                      Key = "ABCD",
                                                      Iteration = 2,
                                                      PasswordGenerator = PasswordGenerators.LegacyFull,
                                                      CreatedOn = new DateTime( 2011, 11, 11 ),
                                                      ModifiedOn = new DateTime( 2011, 11, 14 ),
                                                      Note = "Need this for EFGH",
                                                      MasterPasswordId = guid
                                                  };


            // Exercise
            var viewModel = new PasswordListEntryViewModel( password, GuidToColor, FuzzyDateFormatter );

            // Verify
            Assert.That( viewModel.MasterPasswordGuid, Is.EqualTo( guid ) );
            Assert.That( viewModel.MasterPasswordColor, Is.EqualTo( GuidToColor.Convert( guid ) ) );
        }
        public void SaveOverEarlierExistingPasswordOverwritesIt( )
        {
            // Set up
            PasswordDigestDocument passwordV1 = new PasswordDigestDocumentBuilder
                                                    {
                                                        Key = "azer",
                                                        Hash = new byte[ ] { 0x12, 0x34 },
                                                        ModifiedOn = new DateTime( 2011, 11, 1 )
                                                    };
            _passwordRepository.SavePassword( passwordV1 );

            PasswordDigestDocument passwordV2 = new PasswordDigestDocumentBuilder
                                                    {
                                                        Key = "azer",
                                                        Hash = new byte[ ] { 0x56, 0x78 },
                                                        ModifiedOn = new DateTime( 2011, 11, 2 )
                                                    };

            // Exercise
            var saved = _passwordRepository.SavePassword( passwordV2 );

            // Verify
            Assert.That( saved, Is.True );
            Assert.That( _inMemoryPasswordData.LoadPasswords( ),
                         Is.EquivalentTo( new[ ] { TestPasswords.Abcd, TestPasswords.Efgh, TestPasswords.Ijkl, passwordV2 } ) );
        }
        public void ReloadPasswordUpdatesSelectedDerivedPassword( )
        {
            // Set up
            var original = AddPassword( "abde", PasswordGenerators.LegacyAlphaNumeric, 1, "123".ToSecureString( ), "yadda yadda" );
            ViewModel = ViewModelFactory.PasswordEditorFor( PasswordRepository.LoadPassword( "abde" ) );

            bool derivedPasswordUpdated = false;
            foreach ( var derivedPassword in ViewModel.DerivedPasswords )
            {
                derivedPassword.PropertyChanged += ( s, e ) => { if ( e.PropertyName == "IsSelected" ) derivedPasswordUpdated = true; };
            }

            PasswordDigestDocument updated = new PasswordDigestDocumentBuilder
                                                 {
                                                     Digest = new PasswordDigest( original.Key, original.Hash, 1, PasswordGenerators.LegacyFull ),
                                                     Note = original.Note,
                                                     CreatedOn = original.CreatedOn,
                                                     ModifiedOn = original.ModifiedOn.AddDays( 1 ),
                                                     MasterPasswordId = original.MasterPasswordId
                                                 };
            PasswordRepository.UpdatePassword( original, updated );

            // Exercise
            ViewModel.Reload( );
            // Verify
            Assert.That( ViewModel.DerivedPasswords.First( p => p.IsSelected ).Model.Generator,
                         Is.EqualTo( PasswordGenerators.LegacyFull ) );
            Assert.That( derivedPasswordUpdated, Is.True );
        }