예제 #1
0
파일: App.cs 프로젝트: Arushacked/keepass2
        public IFileStorage GetFileStorage(IOConnectionInfo iocInfo, bool allowCache)
        {
            IFileStorage fileStorage;

            if (iocInfo.IsLocalFile())
            {
                fileStorage = new LocalFileStorage(this);
            }
            else
            {
                IFileStorage innerFileStorage = GetCloudFileStorage(iocInfo);

                if (DatabaseCacheEnabled && allowCache)
                {
                    fileStorage = new CachingFileStorage(innerFileStorage, Application.Context, this);
                }
                else
                {
                    fileStorage = innerFileStorage;
                }
            }
            if (fileStorage is IOfflineSwitchable)
            {
                ((IOfflineSwitchable)fileStorage).IsOffline = App.Kp2a.OfflineMode;
            }
            return(fileStorage);
        }
 private void SetupFileStorage()
 {
     _testFileStorage     = new TestFileStorage(new TestKp2aApp());
     _testCacheSupervisor = new TestCacheSupervisor();
     //_fileStorage = new CachingFileStorage(_testFileStorage, Application.Context.CacheDir.Path, _testCacheSupervisor);
     _fileStorage = new CachingFileStorage(_testFileStorage, "/mnt/sdcard/kp2atest_cache", _testCacheSupervisor);
     _fileStorage.ClearCache();
     File.WriteAllText(CachingTestFile, _defaultCacheFileContents);
 }
예제 #3
0
        private Stream GetStreamForBaseFile(IFileStorage fileStorage, IOConnectionInfo ioc)
        {
            //if we have the original file already available: use it
            if (_streamForOrigFile != null)
            {
                return(_streamForOrigFile);
            }

            //if the file storage caches, it might return the local data in case of a conflict. This would result in data loss
            // so we need to ensure we get the data from remote (only if the remote file is available. if not, we won't overwrite anything)
            CachingFileStorage cachingFileStorage = fileStorage as CachingFileStorage;

            if (cachingFileStorage != null)
            {
                return(cachingFileStorage.OpenRemoteForReadIfAvailable(ioc));
            }
            return(fileStorage.OpenFileForRead(ioc));
        }
예제 #4
0
        public byte[] HashOriginalFile(IOConnectionInfo iocFile)
        {
            if (iocFile == null)
            {
                Debug.Assert(false); return(null);
            }                                                                      // Assert only

            Stream sIn;

            try
            {
                IFileStorage       fileStorage        = _app.GetFileStorage(iocFile);
                CachingFileStorage cachingFileStorage = fileStorage as CachingFileStorage;
                if (cachingFileStorage != null)
                {
                    string hash;
                    cachingFileStorage.GetRemoteDataAndHash(iocFile, out hash);
                    return(MemUtil.HexStringToByteArray(hash));
                }
                else
                {
                    sIn = fileStorage.OpenFileForRead(iocFile);
                }

                if (sIn == null)
                {
                    throw new FileNotFoundException();
                }
            }
            catch (Exception) { return(null); }

            byte[] pbHash;
            try
            {
                SHA256Managed sha256 = new SHA256Managed();
                pbHash = sha256.ComputeHash(sIn);
            }
            catch (Exception) { Debug.Assert(false); sIn.Close(); return(null); }

            sIn.Close();
            return(pbHash);
        }
        public override void Run()
        {
            try
            {
                IOConnectionInfo ioc         = _app.GetDb().Ioc;
                IFileStorage     fileStorage = _app.GetFileStorage(ioc);
                if (!(fileStorage is CachingFileStorage))
                {
                    throw new Exception("Cannot sync a non-cached database!");
                }
                StatusLogger.UpdateMessage(UiStringKey.SynchronizingCachedDatabase);
                CachingFileStorage cachingFileStorage = (CachingFileStorage)fileStorage;

                //download file from remote location and calculate hash:
                StatusLogger.UpdateSubMessage(_app.GetResourceString(UiStringKey.DownloadingRemoteFile));
                string hash;

                MemoryStream remoteData;
                try
                {
                    remoteData = cachingFileStorage.GetRemoteDataAndHash(ioc, out hash);
                }
                catch (FileNotFoundException)
                {
                    StatusLogger.UpdateSubMessage(_app.GetResourceString(UiStringKey.RestoringRemoteFile));
                    cachingFileStorage.UpdateRemoteFile(ioc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions));
                    Finish(true, _app.GetResourceString(UiStringKey.SynchronizedDatabaseSuccessfully));
                    return;
                }

                //check if remote file was modified:
                if (cachingFileStorage.GetBaseVersionHash(ioc) != hash)
                {
                    //remote file is modified
                    if (cachingFileStorage.HasLocalChanges(ioc))
                    {
                        //conflict! need to merge
                        _saveDb = new SaveDb(_context, _app, new ActionOnFinish((success, result) =>
                        {
                            if (!success)
                            {
                                Finish(false, result);
                            }
                            else
                            {
                                Finish(true, _app.GetResourceString(UiStringKey.SynchronizedDatabaseSuccessfully));
                            }
                            _saveDb = null;
                        }), false, remoteData);
                        _saveDb.Run();

                        _app.GetDb().MarkAllGroupsAsDirty();
                    }
                    else
                    {
                        //only the remote file was modified -> reload database.
                        //note: it's best to lock the database and do a complete reload here (also better for UI consistency in case something goes wrong etc.)
                        _app.TriggerReload(_context);
                        Finish(true);
                    }
                }
                else
                {
                    //remote file is unmodified
                    if (cachingFileStorage.HasLocalChanges(ioc))
                    {
                        //but we have local changes -> upload:
                        StatusLogger.UpdateSubMessage(_app.GetResourceString(UiStringKey.UploadingFile));
                        cachingFileStorage.UpdateRemoteFile(ioc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions));
                        StatusLogger.UpdateSubMessage("");
                        Finish(true, _app.GetResourceString(UiStringKey.SynchronizedDatabaseSuccessfully));
                    }
                    else
                    {
                        //files are in sync: just set the result
                        Finish(true, _app.GetResourceString(UiStringKey.FilesInSync));
                    }
                }
            }
            catch (Exception e)
            {
                Finish(false, e.Message);
            }
        }