コード例 #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);
            }
        }
コード例 #2
0
        /// <inheritdoc/>
        public override async Task Run()
        {
            SettingsModel settings = _settingsService.LoadSettingsOrDefault();
            SerializeableCloudStorageCredentials credentials = settings.Credentials;

            if (!settings.HasCloudStorageClient || !settings.HasTransferCode)
            {
                _feedbackService.ShowToast(_languageService["pushpull_error_need_sync_first"]);
                return;
            }

            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;
                    }
                }

                if (stopBecauseNewOAuthLoginIsRequired)
                {
                    _feedbackService.ShowToast(_languageService["sync_error_oauth_refresh"]);
                }
                else
                {
                    bool repositoryExists = await cloudStorageClient.ExistsFileAsync(Config.RepositoryFileName, credentials);

                    if (repositoryExists)
                    {
                        await StoryBoard.ContinueWith(PullPushStoryStepId.DownloadCloudRepository);
                    }
                    else
                    {
                        _feedbackService.ShowToast(_languageService["pushpull_error_need_sync_first"]);
                    }
                }
            }
            catch (Exception ex)
            {
                // Keep the current page open and show the error message
                ShowExceptionMessage(ex, _feedbackService, _languageService);
            }
        }
コード例 #3
0
        /// <inheritdoc/>
        public override async Task Run()
        {
            SettingsModel settings = _settingsService.LoadSettingsOrDefault();

            if (settings.HasCloudStorageClient)
            {
                StoryBoard.StoreToSession(SynchronizationStorySessionKey.CloudStorageCredentials, settings.Credentials);
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.ExistsCloudRepository);
            }
            else
            {
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.ShowFirstTimeDialog);
            }
        }
コード例 #4
0
        public override async Task Run()
        {
            try
            {
                if (!StoryBoard.TryLoadFromSession(SynchronizationStorySessionKey.CloudStorageCredentials, out SerializeableCloudStorageCredentials credentials))
                {
                    throw new ArgumentNullException(nameof(credentials));
                }
                if (!StoryBoard.TryLoadFromSession(SynchronizationStorySessionKey.OauthState, out string oauthState))
                {
                    throw new ArgumentNullException(nameof(oauthState));
                }
                if (!StoryBoard.TryLoadFromSession(SynchronizationStorySessionKey.OauthCodeVerifier, out string oauthCodeVerifier))
                {
                    throw new ArgumentNullException(nameof(oauthState));
                }
                if (!StoryBoard.TryLoadFromSession(SynchronizationStorySessionKey.OauthRedirectUrl, out string redirectUrl))
                {
                    throw new ArgumentNullException(nameof(redirectUrl));
                }

                StoryBoard.RemoveFromSession(SynchronizationStorySessionKey.OauthState);
                StoryBoard.RemoveFromSession(SynchronizationStorySessionKey.OauthCodeVerifier);
                StoryBoard.RemoveFromSession(SynchronizationStorySessionKey.OauthRedirectUrl);

                ICloudStorageClient cloudStorageClient = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId);
                if (cloudStorageClient is IOAuth2CloudStorageClient oauthStorageClient)
                {
                    CloudStorageToken token = await oauthStorageClient.FetchTokenAsync(redirectUrl, oauthState, oauthCodeVerifier);

                    if (token != null)
                    {
                        // User has granted access.
                        credentials.Token = token;
                        await StoryBoard.ContinueWith(SynchronizationStoryStepId.ExistsCloudRepository);
                    }
                    else
                    {
                        // User has rejected access.
                        _feedbackService.ShowToast(_languageService.LoadText("sync_reject"));
                        await StoryBoard.ContinueWith(SynchronizationStoryStepId.StopAndShowRepository);
                    }
                }
            }
            catch (Exception ex)
            {
                // Keep the current page open and show the error message
                ShowExceptionMessage(ex, _feedbackService, _languageService);
            }
        }
コード例 #5
0
        /// <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"]);
            }
        }
コード例 #6
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);
            }
        }
コード例 #7
0
        /// <inheritdoc/>
        public override async Task Run()
        {
            SettingsModel settings = _settingsService.LoadSettingsOrDefault();

            // Execute step
            if (settings.HasTransferCode)
            {
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.DecryptCloudRepository);
            }
            else
            {
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.ShowTransferCode);
            }
        }
コード例 #8
0
        /// <inheritdoc/>
        public override async Task Run()
        {
            SettingsModel settings = _settingsService.LoadSettingsOrDefault();

            // Execute step
            if (!string.IsNullOrWhiteSpace(settings.TransferCode))
            {
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.DecryptCloudRepository.ToInt());
            }
            else
            {
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.ShowTransferCode.ToInt());
            }
        }
コード例 #9
0
        /// <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);
            }
        }
コード例 #10
0
        /// <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);
            }
        }
コード例 #11
0
        /// <inheritdoc/>
        public override async Task Run()
        {
            SettingsModel settings = _settingsService.LoadSettingsOrDefault();

            bool clientIsSet = (settings.Credentials?.CloudStorageId != null);

            if (clientIsSet)
            {
                StoryBoard.StoreToSession(SynchronizationStorySessionKey.CloudStorageCredentials.ToInt(), settings.Credentials);
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.ExistsCloudRepository.ToInt());
            }
            else
            {
                await StoryBoard.ContinueWith(SynchronizationStoryStepId.ShowFirstTimeDialog.ToInt());
            }
        }
コード例 #12
0
        /// <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);
            }
        }
コード例 #13
0
        /// <inheritdoc/>
        public override async Task Run()
        {
            SerializeableCloudStorageCredentials credentials = _settingsService.LoadSettingsOrDefault().Credentials;
            ICloudStorageClient cloudStorageClient           = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId);

            try
            {
                // The repository can be cached for this story, download the repository only once.
                byte[] binaryCloudRepository = await cloudStorageClient.DownloadFileAsync(Config.RepositoryFileName, credentials);

                StoryBoard.StoreToSession(PullPushStorySessionKey.BinaryCloudRepository, binaryCloudRepository);
                await StoryBoard.ContinueWith(PullPushStoryStepId.DecryptCloudRepository);
            }
            catch (Exception ex)
            {
                // Keep the current page open and show the error message
                ShowExceptionMessage(ex, _feedbackService, _languageService);
            }
        }
コード例 #14
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);
            }
        }
コード例 #15
0
        /// <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);
            }
        }
コード例 #16
0
        /// <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);
            }
        }