예제 #1
0
        /// <inheritdoc/>
        public override async Task Run()
        {
            SerializeableCloudStorageCredentials credentials = StoryBoard.LoadFromSession <SerializeableCloudStorageCredentials>(SynchronizationStorySessionKey.CloudStorageCredentials.ToInt());
            ICloudStorageClient cloudStorageClient           = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId);

            try
            {
                bool stopBecauseNewOAuthLoginIsRequired = false;
                if ((cloudStorageClient is OAuth2CloudStorageClient oauthStorageClient) &&
                    credentials.Token.NeedsRefresh())
                {
                    try
                    {
                        // Get a new access token by using the refresh token
                        credentials.Token = await oauthStorageClient.RefreshTokenAsync(credentials.Token);

                        SaveCredentialsToSettings(credentials);
                    }
                    catch (RefreshTokenExpiredException)
                    {
                        // Refresh-token cannot be used to get new access-tokens anymore, a new
                        // authorization by the user is required.
                        stopBecauseNewOAuthLoginIsRequired = true;
                        switch (StoryBoard.Mode)
                        {
                        case StoryBoardMode.GuiAndToasts:
                            await StoryBoard.ContinueWith(SynchronizationStoryStepId.ShowCloudStorageAccount.ToInt());

                            break;

                        case StoryBoardMode.ToastsOnly:
                            _feedbackService.ShowToast(_languageService["sync_error_generic"]);
                            break;
                        }
                    }
                }

                if (!stopBecauseNewOAuthLoginIsRequired)
                {
                    bool repositoryExists = await cloudStorageClient.ExistsFileAsync(Config.RepositoryFileName, credentials);

                    // If no error occured the credentials are ok and we can safe them
                    SaveCredentialsToSettings(credentials);

                    if (repositoryExists)
                    {
                        await StoryBoard.ContinueWith(SynchronizationStoryStepId.DownloadCloudRepository.ToInt());
                    }
                    else
                    {
                        await StoryBoard.ContinueWith(SynchronizationStoryStepId.StoreLocalRepositoryToCloudAndQuit.ToInt());
                    }
                }
            }
            catch (Exception ex)
            {
                // Keep the current page open and show the error message
                ShowExceptionMessage(ex, _feedbackService, _languageService);
            }
        }
        /// <inheritdoc/>
        public override Task Run()
        {
            if (StoryBoard.Mode.ShouldUseGui())
            {
                SerializeableCloudStorageCredentials credentials = StoryBoard.LoadFromSession <SerializeableCloudStorageCredentials>(SynchronizationStorySessionKey.CloudStorageCredentials.ToInt());
                ICloudStorageClient cloudStorageClient           = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId);
                if (cloudStorageClient is IOAuth2CloudStorageClient oauthStorageClient)
                {
                    // Show waiting page
                    _navigationService.Navigate(ControllerNames.CloudStorageOauthWaiting);

                    // Open OAuth2 login page in external browser
                    string oauthState        = CryptoUtils.GenerateRandomBase62String(16, _randomSource);
                    string oauthCodeVerifier = CryptoUtils.GenerateRandomBase62String(64, _randomSource);
                    StoryBoard.StoreToSession(SynchronizationStorySessionKey.OauthState.ToInt(), oauthState);
                    StoryBoard.StoreToSession(SynchronizationStorySessionKey.OauthCodeVerifier.ToInt(), oauthCodeVerifier);

                    string url = oauthStorageClient.BuildAuthorizationRequestUrl(oauthState, oauthCodeVerifier);
                    _nativeBrowserService.OpenWebsiteInApp(url);
                }
                else
                {
                    _navigationService.Navigate(ControllerNames.CloudStorageAccount);
                }
            }
            return(Task.CompletedTask);
        }
        /// <inheritdoc/>
        public override async Task Run()
        {
            _repositoryStorageService.LoadRepositoryOrDefault(out NoteRepositoryModel localRepository);
            NoteRepositoryModel cloudRepository = StoryBoard.LoadFromSession <NoteRepositoryModel>(PullPushStorySessionKey.CloudRepository);

            if (localRepository.Id == cloudRepository.Id)
            {
                await StoryBoard.ContinueWith(PullPushStoryStepId.StoreMergedRepositoryAndQuit);
            }
            else
            {
                _feedbackService.ShowToast(_languageService["pushpull_error_need_sync_first"]);
            }
        }
예제 #4
0
        /// <inheritdoc/>
        public override async Task Run()
        {
            _repositoryStorageService.LoadRepositoryOrDefault(out NoteRepositoryModel localRepository);
            NoteRepositoryModel cloudRepository = StoryBoard.LoadFromSession <NoteRepositoryModel>(SynchronizationStorySessionKey.CloudRepository);

            if (localRepository.Id == cloudRepository.Id)
            {
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.StoreMergedRepositoryAndQuit);
            }
            else
            {
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.ShowMergeChoice);
            }
        }
        /// <inheritdoc/>
        public override async Task Run()
        {
            try
            {
                SettingsModel settings = _settingsService.LoadSettingsOrDefault();
                byte[]        binaryCloudRepository = StoryBoard.LoadFromSession <byte[]>(SynchronizationStorySessionKey.BinaryCloudRepository);

                // Try to decode with all possible transfer codes
                bool successfullyDecryptedRepository = TryDecryptWithAllTransferCodes(
                    settings, binaryCloudRepository, out byte[] decryptedRepository);

                if (successfullyDecryptedRepository)
                {
                    // Deserialize and update repository
                    XDocument cloudRepositoryXml = XmlUtils.LoadFromXmlBytes(decryptedRepository);
                    if (_noteRepositoryUpdater.IsTooNewForThisApp(cloudRepositoryXml))
                    {
                        throw new SynchronizationStoryBoard.UnsuportedRepositoryRevisionException();
                    }

                    _noteRepositoryUpdater.Update(cloudRepositoryXml);
                    NoteRepositoryModel cloudRepository = XmlUtils.DeserializeFromXmlDocument <NoteRepositoryModel>(cloudRepositoryXml);

                    // Continue with next step
                    StoryBoard.StoreToSession(SynchronizationStorySessionKey.CloudRepository, cloudRepository);
                    await StoryBoard.ContinueWith(SynchronizationStoryStepId.IsSameRepository);
                }
                else
                {
                    bool existsUserEnteredTransferCode = StoryBoard.TryLoadFromSession <string>(SynchronizationStorySessionKey.UserEnteredTransferCode, out _);
                    if (existsUserEnteredTransferCode)
                    {
                        // Keep transfercode page open and show message
                        _feedbackService.ShowToast(_languageService["sync_error_transfercode"]);
                    }
                    else
                    {
                        // Open transfercode page
                        await StoryBoard.ContinueWith(SynchronizationStoryStepId.ShowTransferCode);
                    }
                }
            }
            catch (Exception ex)
            {
                // Keep the current page open and show the error message
                ShowExceptionMessage(ex, _feedbackService, _languageService);
            }
        }
        /// <inheritdoc/>
        public override async Task Run()
        {
            try
            {
                NoteRepositoryModel cloudRepository = StoryBoard.LoadFromSession <NoteRepositoryModel>(SynchronizationStorySessionKey.CloudRepository);
                _repositoryStorageService.TrySaveRepository(cloudRepository);
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.StopAndShowRepository);

                _feedbackService.ShowToast(_languageService["sync_success"]);
            }
            catch (Exception ex)
            {
                // Keep the current page open and show the error message
                ShowExceptionMessage(ex, _feedbackService, _languageService);
            }
        }
        /// <inheritdoc/>
        public override async Task Run()
        {
            try
            {
                SerializeableCloudStorageCredentials credentials = StoryBoard.LoadFromSession <SerializeableCloudStorageCredentials>(SynchronizationStorySessionKey.CloudStorageCredentials);
                _repositoryStorageService.LoadRepositoryOrDefault(out NoteRepositoryModel localRepository);
                SettingsModel settings     = _settingsService.LoadSettingsOrDefault();
                string        transferCode = settings.TransferCode;

                bool needsNewTransferCode = !TransferCode.IsCodeSet(transferCode);
                if (needsNewTransferCode)
                {
                    transferCode = TransferCode.GenerateCode(_cryptoRandomService);
                }

                byte[] encryptedRepository = EncryptRepository(
                    localRepository, transferCode, _cryptoRandomService, settings.SelectedEncryptionAlgorithm);

                ICloudStorageClient cloudStorageClient = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId);
                await cloudStorageClient.UploadFileAsync(Config.RepositoryFileName, encryptedRepository, credentials);

                // All went well, time to save the transfer code, if a new one was created
                if (needsNewTransferCode)
                {
                    settings.TransferCode = transferCode;
                    _settingsService.TrySaveSettingsToLocalDevice(settings);

                    string formattedTransferCode = TransferCode.FormatTransferCodeForDisplay(transferCode).Replace(' ', '-');
                    string messageNewCreated     = _languageService.LoadTextFmt("transfer_code_created", formattedTransferCode);
                    string messageWriteDown      = _languageService.LoadText("transfer_code_writedown");
                    if (StoryBoard.Mode.ShouldUseGui())
                    {
                        await _feedbackService.ShowMessageAsync(messageNewCreated + Environment.NewLine + messageWriteDown, null, MessageBoxButtons.Ok, false);
                    }
                }

                await StoryBoard.ContinueWith(SynchronizationStoryStepId.StopAndShowRepository);

                _feedbackService.ShowToast(_languageService["sync_success"]);
            }
            catch (Exception ex)
            {
                // Keep the current page open and show the error message
                ShowExceptionMessage(ex, _feedbackService, _languageService);
            }
        }
예제 #8
0
        /// <inheritdoc/>
        public override async Task Run()
        {
            try
            {
                NoteRepositoryModel cloudRepository = StoryBoard.LoadFromSession <NoteRepositoryModel>(SynchronizationStorySessionKey.CloudRepository.ToInt());
                SerializeableCloudStorageCredentials credentials = StoryBoard.LoadFromSession <SerializeableCloudStorageCredentials>(SynchronizationStorySessionKey.CloudStorageCredentials.ToInt());
                _repositoryStorageService.LoadRepositoryOrDefault(out NoteRepositoryModel localRepository);
                SettingsModel settings = _settingsService.LoadSettingsOrDefault();

                // Merge repositories
                NoteRepositoryMerger merger           = new NoteRepositoryMerger();
                NoteRepositoryModel  mergedRepository = merger.Merge(localRepository, cloudRepository);

                // Store merged repository locally when different
                if (!RepositoriesAreEqual(mergedRepository, localRepository))
                {
                    _repositoryStorageService.TrySaveRepository(mergedRepository);
                }

                // Store merged repository to the cloud when different, otherwise spare the slow upload
                if (!RepositoriesAreEqual(mergedRepository, cloudRepository))
                {
                    byte[] encryptedRepository = EncryptRepository(
                        mergedRepository, settings.TransferCode, _cryptoRandomService, settings.SelectedEncryptionAlgorithm);

                    ICloudStorageClient cloudStorageClient = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId);
                    await cloudStorageClient.UploadFileAsync(Config.RepositoryFileName, encryptedRepository, credentials);
                }

                await StoryBoard.ContinueWith(SynchronizationStoryStepId.StopAndShowRepository.ToInt());

                _feedbackService.ShowToast(_languageService["sync_success"]);
            }
            catch (Exception ex)
            {
                // Keep the current page open and show the error message
                ShowExceptionMessage(ex, _feedbackService, _languageService);
            }
        }
        /// <inheritdoc/>
        public override async Task Run()
        {
            SerializeableCloudStorageCredentials credentials = StoryBoard.LoadFromSession <SerializeableCloudStorageCredentials>(SynchronizationStorySessionKey.CloudStorageCredentials.ToInt());
            ICloudStorageClient cloudStorageClient           = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId);

            try
            {
                // The repository can be cached for this story, download the repository only once.
                byte[] binaryCloudRepository;
                if (!StoryBoard.TryLoadFromSession(SynchronizationStorySessionKey.BinaryCloudRepository.ToInt(), out binaryCloudRepository))
                {
                    binaryCloudRepository = await cloudStorageClient.DownloadFileAsync(Config.RepositoryFileName, credentials);

                    StoryBoard.StoreToSession(SynchronizationStorySessionKey.BinaryCloudRepository.ToInt(), binaryCloudRepository);
                }
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.ExistsTransferCode.ToInt());
            }
            catch (Exception ex)
            {
                // Keep the current page open and show the error message
                ShowExceptionMessage(ex, _feedbackService, _languageService);
            }
        }
        /// <inheritdoc/>
        public override async Task Run()
        {
            try
            {
                NoteRepositoryModel cloudRepository = StoryBoard.LoadFromSession <NoteRepositoryModel>(PullPushStorySessionKey.CloudRepository);
                _repositoryStorageService.LoadRepositoryOrDefault(out NoteRepositoryModel localRepository);
                SettingsModel settings = _settingsService.LoadSettingsOrDefault();
                SerializeableCloudStorageCredentials credentials = settings.Credentials;

                NoteModel cloudNote = cloudRepository.Notes.FindById(_noteId);
                NoteModel localNote = localRepository.Notes.FindById(_noteId);
                if (localNote == null)
                {
                    throw new Exception("PullPushStory is triggered on the note dialog, so the note must exist.");
                }

                if (cloudNote == null)
                {
                    // Note does not yet exist in the cloud, or it was deleted permanently. Both
                    // cases should be rejected.
                    _feedbackService.ShowToast(_languageService["pushpull_error_no_cloud_note"]);
                    return;
                }

                if (cloudNote.ModifiedAt == localNote.ModifiedAt)
                {
                    // Notes are equal, nothing to sync
                    _feedbackService.ShowToast(_languageService["pushpull_success"]);
                    return;
                }

                // Merge repositories
                if (_direction == PullPushDirection.PullFromServer)
                {
                    cloudNote.CloneTo(localNote); // this can possibly move the note to the recycling bin or reverse
                    AddSafeToOtherRepositoryIfMissing(cloudRepository, localRepository, cloudNote.SafeId);
                    _repositoryStorageService.TrySaveRepository(localRepository);
                }
                else
                {
                    // Uploading explicitely can be seen as a confirmation that this version is the
                    // most current one. So we make sure that the uploaded version is not overwritten
                    // by other devices afterwards.
                    localNote.RefreshModifiedAt();
                    _repositoryStorageService.TrySaveRepository(localRepository);

                    localNote.CloneTo(cloudNote); // this can possibly move the note to the recycling bin or reverse
                    AddSafeToOtherRepositoryIfMissing(localRepository, cloudRepository, localNote.SafeId);
                    byte[] encryptedRepository = EncryptRepository(
                        cloudRepository, settings.TransferCode, _cryptoRandomService, settings.SelectedEncryptionAlgorithm);

                    ICloudStorageClient cloudStorageClient = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId);
                    await cloudStorageClient.UploadFileAsync(Config.RepositoryFileName, encryptedRepository, credentials);
                }
                _feedbackService.ShowToast(_languageService["pushpull_success"]);
            }
            catch (Exception ex)
            {
                // Keep the current page open and show the error message
                ShowExceptionMessage(ex, _feedbackService, _languageService);
            }
        }
        /// <inheritdoc/>
        public override async Task Run()
        {
            try
            {
                SettingsModel settings = _settingsService.LoadSettingsOrDefault();
                byte[]        binaryCloudRepository = StoryBoard.LoadFromSession <byte[]>(SynchronizationStorySessionKey.BinaryCloudRepository.ToInt());
                List <string> transferCodesToTry    = ListTransferCodesToTry(settings);

                // Try to decode with all possible transfer codes
                EncryptorDecryptor encryptor           = new EncryptorDecryptor("SilentNotes");
                byte[]             decryptedRepository = null;
                bool successfullyDecryptedRepository   = false;
                int  index = 0;
                while (!successfullyDecryptedRepository && index < transferCodesToTry.Count)
                {
                    string transferCodeCandidate = transferCodesToTry[index];
                    successfullyDecryptedRepository = TryDecryptRepositoryWithTransfercode(encryptor, binaryCloudRepository, transferCodeCandidate, out decryptedRepository);
                    if (successfullyDecryptedRepository)
                    {
                        // Store transfercode and encryption mode if necessary
                        if (AdoptTransferCode(settings, transferCodeCandidate) ||
                            AdoptEncryptionMode(settings, encryptor, binaryCloudRepository))
                        {
                            _settingsService.TrySaveSettingsToLocalDevice(settings);
                        }
                    }
                    index++;
                }

                if (successfullyDecryptedRepository)
                {
                    // Deserialize and update repository
                    XDocument cloudRepositoryXml = XmlUtils.LoadFromXmlBytes(decryptedRepository);
                    if (_noteRepositoryUpdater.IsTooNewForThisApp(cloudRepositoryXml))
                    {
                        throw new SynchronizationStoryBoard.UnsuportedRepositoryRevisionException();
                    }

                    _noteRepositoryUpdater.Update(cloudRepositoryXml);
                    NoteRepositoryModel cloudRepository = XmlUtils.DeserializeFromXmlDocument <NoteRepositoryModel>(cloudRepositoryXml);

                    // Continue with next step
                    StoryBoard.StoreToSession(SynchronizationStorySessionKey.CloudRepository.ToInt(), cloudRepository);
                    await StoryBoard.ContinueWith(SynchronizationStoryStepId.IsSameRepository.ToInt());
                }
                else
                {
                    bool existsUserEnteredTransferCode = StoryBoard.TryLoadFromSession <string>(SynchronizationStorySessionKey.UserEnteredTransferCode.ToInt(), out _);
                    if (existsUserEnteredTransferCode)
                    {
                        // Keep transfercode page open and show message
                        _feedbackService.ShowToast(_languageService["sync_error_transfercode"]);
                    }
                    else
                    {
                        // Open transfercode page
                        await StoryBoard.ContinueWith(SynchronizationStoryStepId.ShowTransferCode.ToInt());
                    }
                }
            }
            catch (Exception ex)
            {
                // Keep the current page open and show the error message
                ShowExceptionMessage(ex, _feedbackService, _languageService);
            }
        }