/// <inheritdoc/>
        public override void ShowInView(IHtmlView htmlView, KeyValueList <string, string> variables, Navigation redirectedFrom)
        {
            base.ShowInView(htmlView, variables, redirectedFrom);
            IStoryBoardService storyBoardService             = Ioc.GetOrCreate <IStoryBoardService>();
            SerializeableCloudStorageCredentials credentials = storyBoardService.ActiveStory.LoadFromSession <SerializeableCloudStorageCredentials>(SynchronizationStorySessionKey.CloudStorageCredentials);

            _viewModel = new CloudStorageAccountViewModel(
                Ioc.GetOrCreate <INavigationService>(),
                Ioc.GetOrCreate <ILanguageService>(),
                Ioc.GetOrCreate <ISvgIconService>(),
                Ioc.GetOrCreate <IThemeService>(),
                Ioc.GetOrCreate <IBaseUrlService>(),
                storyBoardService,
                Ioc.GetOrCreate <IFeedbackService>(),
                Ioc.GetOrCreate <ICloudStorageClientFactory>(),
                credentials);

            VueBindingShortcut[] shortcuts = new[]
            {
                new VueBindingShortcut(VueBindingShortcut.KeyEscape, nameof(CloudStorageAccountViewModel.CancelCommand)),
                new VueBindingShortcut(VueBindingShortcut.KeyEnter, nameof(CloudStorageAccountViewModel.OkCommand)),
            };
            VueBindings = new VueDataBinding(_viewModel, View, shortcuts);
            _viewModel.VueDataBindingScript = VueBindings.BuildVueScript();
            VueBindings.StartListening();

            string html = _viewService.GenerateHtml(_viewModel);

            View.LoadHtml(html);
        }
Exemple #2
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 void ShowInView(IHtmlView htmlView, KeyValueList <string, string> variables, Navigation redirectedFrom)
        {
            base.ShowInView(htmlView, variables, redirectedFrom);
            IStoryBoardService storyBoardService             = Ioc.GetOrCreate <IStoryBoardService>();
            SerializeableCloudStorageCredentials credentials = storyBoardService.ActiveStory.LoadFromSession <SerializeableCloudStorageCredentials>(SynchronizationStorySessionKey.CloudStorageCredentials);

            _viewModel = new CloudStorageAccountViewModel(
                Ioc.GetOrCreate <INavigationService>(),
                Ioc.GetOrCreate <ILanguageService>(),
                Ioc.GetOrCreate <ISvgIconService>(),
                Ioc.GetOrCreate <IThemeService>(),
                Ioc.GetOrCreate <IBaseUrlService>(),
                storyBoardService,
                Ioc.GetOrCreate <IFeedbackService>(),
                Ioc.GetOrCreate <ICloudStorageClientFactory>(),
                credentials);

            Bindings.BindCommand("GoBack", _viewModel.GoBackCommand);
            Bindings.BindCommand("OkCommand", _viewModel.OkCommand);
            Bindings.BindCommand("CancelCommand", _viewModel.CancelCommand);
            Bindings.BindText("Url", null, (v) => _viewModel.Url           = v, null, null, HtmlViewBindingMode.OneWayToViewmodel);
            Bindings.BindText("Username", null, (v) => _viewModel.Username = v, null, null, HtmlViewBindingMode.OneWayToViewmodel);
            Bindings.BindText("Password", () => SecureStringExtensions.SecureStringToString(_viewModel.Password), (v) => _viewModel.Password = SecureStringExtensions.StringToSecureString(v), _viewModel, nameof(_viewModel.Password), HtmlViewBindingMode.TwoWayPlusOneTimeToView);
            Bindings.BindCheckbox("Secure", null, (v) => _viewModel.Secure = v, null, null, HtmlViewBindingMode.OneWayToViewmodel);

            string html = _viewService.GenerateHtml(_viewModel);

            View.LoadHtml(html);
        }
        /// <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);
            }
        }
Exemple #6
0
        protected void SaveCredentialsToSettings(SerializeableCloudStorageCredentials credentials)
        {
            SettingsModel settings = _settingsService.LoadSettingsOrDefault();

            if (!credentials.AreEqualOrNull(settings.Credentials))
            {
                settings.Credentials = credentials;
                _settingsService.TrySaveSettingsToLocalDevice(settings);
            }
        }
        private async void Choose(string cloudStorageId)
        {
            SerializeableCloudStorageCredentials credentials = new SerializeableCloudStorageCredentials {
                CloudStorageId = cloudStorageId
            };

            _storyBoardService.ActiveStory?.StoreToSession(SynchronizationStorySessionKey.CloudStorageCredentials, credentials);
            await(_storyBoardService.ActiveStory?.ContinueWith(SynchronizationStoryStepId.ShowCloudStorageAccount)
                  ?? Task.CompletedTask);
        }
        public void StoreMergedRepositoryWhenDifferent()
        {
            const string transferCode = "abcdefgh";
            SerializeableCloudStorageCredentials credentialsFromSession = new SerializeableCloudStorageCredentials();
            var settingsModel = CreateSettingsModel(transferCode);
            NoteRepositoryModel repositoryModelLocal = new NoteRepositoryModel();

            repositoryModelLocal.Notes.Add(new NoteModel());
            NoteRepositoryModel repositoryModelCloud = new NoteRepositoryModel();

            repositoryModelCloud.Notes.Add(new NoteModel());

            Mock <IStoryBoard> storyBoard = new Mock <IStoryBoard>();

            storyBoard.
            Setup(m => m.LoadFromSession <SerializeableCloudStorageCredentials>(It.Is <int>(p => p == SynchronizationStorySessionKey.CloudStorageCredentials.ToInt()))).
            Returns(credentialsFromSession);
            storyBoard.
            Setup(m => m.LoadFromSession <NoteRepositoryModel>(It.Is <int>(p => p == SynchronizationStorySessionKey.CloudRepository.ToInt()))).
            Returns(repositoryModelCloud);     // same as from repositoryStorageService
            Mock <ISettingsService> settingsService = new Mock <ISettingsService>();

            settingsService.
            Setup(m => m.LoadSettingsOrDefault()).Returns(settingsModel);
            Mock <IRepositoryStorageService> repositoryStorageService = new Mock <IRepositoryStorageService>();

            repositoryStorageService.
            Setup(m => m.LoadRepositoryOrDefault(out repositoryModelLocal));     // same as from storyBoard
            Mock <ICloudStorageClient> cloudStorageClient = new Mock <ICloudStorageClient>();

            // Run step
            var step = new StoreMergedRepositoryAndQuitStep(
                SynchronizationStoryStepId.StoreLocalRepositoryToCloudAndQuit.ToInt(),
                storyBoard.Object,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                settingsService.Object,
                CommonMocksAndStubs.CryptoRandomService(),
                repositoryStorageService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory(cloudStorageClient.Object));

            Assert.DoesNotThrowAsync(step.Run);

            // repository is stored to the local device
            repositoryStorageService.Verify(m => m.TrySaveRepository(It.IsAny <NoteRepositoryModel>()), Times.Once);

            // repository is stored to the cloud
            cloudStorageClient.Verify(m => m.UploadFileAsync(It.IsAny <string>(), It.IsAny <byte[]>(), It.IsAny <CloudStorageCredentials>()), Times.Once);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <int>(x => x == SynchronizationStoryStepId.StopAndShowRepository.ToInt())), Times.Once);
        }
Exemple #9
0
        public void SerializedXmlDoesNotContainPlaintextData()
        {
            SerializeableCloudStorageCredentials credentials = CreateExampleCredentials();

            credentials.EncryptBeforeSerialization(PseudoEncrypt);

            string xml = SerializeWithXmlSerializer(credentials);

            Assert.IsFalse(xml.Contains("atk"));
            Assert.IsFalse(xml.Contains("rtk"));
            Assert.IsFalse(xml.Contains("usr"));
            Assert.IsFalse(xml.Contains("pwd"));
        }
Exemple #10
0
        public void SerializedJsonDoesNotContainPlaintextData()
        {
            SerializeableCloudStorageCredentials credentials = CreateExampleCredentials();

            credentials.EncryptBeforeSerialization(PseudoEncrypt);

            string json = JsonConvert.SerializeObject(credentials);

            Assert.IsFalse(json.Contains("atk"));
            Assert.IsFalse(json.Contains("rtk"));
            Assert.IsFalse(json.Contains("usr"));
            Assert.IsFalse(json.Contains("pwd"));
        }
Exemple #11
0
        public void SerializedDatacontractCanBeReadBack()
        {
            SerializeableCloudStorageCredentials credentials = CreateExampleCredentials();

            credentials.EncryptBeforeSerialization(PseudoEncrypt);
            string xml = SerializeWithDatacontract(credentials);

            var credentials2 = DeserializeWithDatacontract <SerializeableCloudStorageCredentials>(xml);

            credentials2.DecryptAfterDeserialization(PseudoDecrypt);

            Assert.IsTrue(credentials.AreEqualOrNull(credentials2));
        }
Exemple #12
0
        public void DecryptAfterDesrializationRespectsNullProperties()
        {
            var credentials = new SerializeableCloudStorageCredentials();

            credentials.DecryptAfterDeserialization(PseudoDecrypt);

            // The Serialization* are set and are not plaintext
            Assert.IsNull(credentials.Token);
            Assert.IsNull(credentials.Username);
            Assert.IsNull(credentials.Password);
            Assert.IsNull(credentials.Url);
            Assert.IsFalse(credentials.Secure);
        }
Exemple #13
0
        public void EncryptBeforeSerializationRespectsNullProperties()
        {
            var credentials = new SerializeableCloudStorageCredentials();

            credentials.EncryptBeforeSerialization(PseudoEncrypt);

            // The Serialization* are set and are not plaintext
            Assert.IsNull(credentials.SerializeableAccessToken);
            Assert.IsNull(credentials.SerializeableExpiryDate);
            Assert.IsNull(credentials.SerializeableRefreshToken);
            Assert.IsNull(credentials.SerializeableUsername);
            Assert.IsNull(credentials.SerializeablePassword);
            Assert.IsNull(credentials.SerializeableUrl);
        }
Exemple #14
0
        public void SerializedJsonDoesNotContainNullProperties()
        {
            var credentials = new SerializeableCloudStorageCredentials();

            credentials.EncryptBeforeSerialization(PseudoEncrypt);

            string json = JsonConvert.SerializeObject(credentials);

            Assert.IsFalse(json.Contains("access_token"));
            Assert.IsFalse(json.Contains("refresh_token"));
            Assert.IsFalse(json.Contains("username"));
            Assert.IsFalse(json.Contains("password"));
            Assert.IsFalse(json.Contains("url"));
            Assert.IsFalse(json.Contains("secure"));
        }
Exemple #15
0
        public void SerializedDatacontractDoesNotContainNullProperties()
        {
            var credentials = new SerializeableCloudStorageCredentials();

            credentials.EncryptBeforeSerialization(PseudoEncrypt);

            string xml = SerializeWithDatacontract(credentials);

            Assert.IsFalse(xml.Contains("<access_token>"));
            Assert.IsFalse(xml.Contains("<refresh_token>"));
            Assert.IsFalse(xml.Contains("<username>"));
            Assert.IsFalse(xml.Contains("<password>"));
            Assert.IsFalse(xml.Contains("<url>"));
            Assert.IsFalse(xml.Contains("<secure>"));
        }
        /// <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);
            }
        }
Exemple #17
0
        public void EncryptBeforeSerializationProtectsAllNecessaryProperties()
        {
            SerializeableCloudStorageCredentials credentials = CreateExampleCredentials();

            credentials.EncryptBeforeSerialization(PseudoEncrypt);

            // The Serialization* are set and are not plaintext
            Assert.IsNotNull(credentials.SerializeableAccessToken);
            Assert.IsNotNull(credentials.SerializeableExpiryDate);
            Assert.IsNotNull(credentials.SerializeableRefreshToken);
            Assert.IsNotNull(credentials.SerializeableUsername);
            Assert.IsNotNull(credentials.SerializeablePassword);
            Assert.IsNotNull(credentials.SerializeableUrl);
            Assert.IsNotNull(credentials.SerializeableSecure);
            Assert.AreNotEqual(credentials.Token.AccessToken, credentials.SerializeableAccessToken);
            Assert.AreNotEqual(credentials.Token.RefreshToken, credentials.SerializeableRefreshToken);
            Assert.AreNotEqual(credentials.Username, credentials.SerializeableUsername);
            Assert.AreNotEqual(credentials.UnprotectedPassword, credentials.SerializeablePassword);
        }
Exemple #18
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);
            }
        }
Exemple #19
0
        public void AccountIsStoredWhenDifferent()
        {
            SerializeableCloudStorageCredentials credentialsFromSession = new SerializeableCloudStorageCredentials {
                CloudStorageId = CloudStorageClientFactory.CloudStorageIdDropbox
            };
            SettingsModel settingsModel = new SettingsModel {
                Credentials = new SerializeableCloudStorageCredentials {
                    CloudStorageId = CloudStorageClientFactory.CloudStorageIdFtp
                }
            };

            Mock <IStoryBoard> storyBoard = new Mock <IStoryBoard>();

            storyBoard.
            Setup(m => m.LoadFromSession <SerializeableCloudStorageCredentials>(It.Is <SynchronizationStorySessionKey>(p => p == SynchronizationStorySessionKey.CloudStorageCredentials))).
            Returns(credentialsFromSession);
            Mock <ISettingsService> settingsService = new Mock <ISettingsService>();

            settingsService.
            Setup(m => m.LoadSettingsOrDefault()).Returns(settingsModel);
            Mock <ICloudStorageClient> cloudStorageClient = new Mock <ICloudStorageClient>();

            cloudStorageClient.
            Setup(m => m.ExistsFileAsync(It.IsAny <string>(), It.IsAny <CloudStorageCredentials>())).
            ReturnsAsync(true);

            // Run step
            var step = new ExistsCloudRepositoryStep(
                SynchronizationStoryStepId.ExistsCloudRepository,
                storyBoard.Object,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                settingsService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory(cloudStorageClient.Object));

            Assert.DoesNotThrowAsync(step.Run);

            // Settings are stored with account from session
            settingsService.Verify(m => m.TrySaveSettingsToLocalDevice(It.Is <SettingsModel>(s => s.Credentials == credentialsFromSession)), Times.Once);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <SynchronizationStoryStepId>(x => x == SynchronizationStoryStepId.DownloadCloudRepository)), Times.Once);
        }
Exemple #20
0
        public void QuitWhenMissingClientOrTransfercode()
        {
            SerializeableCloudStorageCredentials credentials = new SerializeableCloudStorageCredentials {
                CloudStorageId = CloudStorageClientFactory.CloudStorageIdDropbox
            };
            SettingsModel settingsModel = new SettingsModel {
                Credentials = credentials
            };

            Mock <IStoryBoard>      storyBoard      = new Mock <IStoryBoard>();
            Mock <ISettingsService> settingsService = new Mock <ISettingsService>();

            settingsService.
            Setup(m => m.LoadSettingsOrDefault()).Returns(settingsModel);
            Mock <ICloudStorageClient> cloudStorageClient = new Mock <ICloudStorageClient>();

            cloudStorageClient.
            Setup(m => m.ExistsFileAsync(It.IsAny <string>(), It.IsAny <CloudStorageCredentials>())).
            ReturnsAsync(true);

            // Run step with missing transfercode
            var step = new ExistsCloudRepositoryStep(
                PullPushStoryStepId.ExistsCloudRepository,
                storyBoard.Object,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                settingsService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory(cloudStorageClient.Object));

            Assert.DoesNotThrowAsync(step.Run);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <PullPushStoryStepId>(x => x == PullPushStoryStepId.DownloadCloudRepository)), Times.Never);

            // Run step with missing storage client
            settingsModel.TransferCode = "abc";
            settingsModel.Credentials.CloudStorageId = null;
            Assert.DoesNotThrowAsync(step.Run);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <PullPushStoryStepId>(x => x == PullPushStoryStepId.DownloadCloudRepository)), Times.Never);
        }
Exemple #21
0
        public void CorrectNextStepWhenNoCloudRepositoryExists()
        {
            SerializeableCloudStorageCredentials credentials = new SerializeableCloudStorageCredentials {
                CloudStorageId = CloudStorageClientFactory.CloudStorageIdDropbox
            };
            SettingsModel settingsModel = new SettingsModel {
                Credentials = credentials
            };

            Mock <IStoryBoard> storyBoard = new Mock <IStoryBoard>();

            storyBoard.
            Setup(m => m.LoadFromSession <SerializeableCloudStorageCredentials>(It.Is <SynchronizationStorySessionKey>(p => p == SynchronizationStorySessionKey.CloudStorageCredentials))).
            Returns(credentials);
            Mock <ISettingsService> settingsService = new Mock <ISettingsService>();

            settingsService.
            Setup(m => m.LoadSettingsOrDefault()).Returns(settingsModel);
            Mock <ICloudStorageClient> cloudStorageClient = new Mock <ICloudStorageClient>();

            cloudStorageClient.
            Setup(m => m.ExistsFileAsync(It.IsAny <string>(), It.IsAny <CloudStorageCredentials>())).
            ReturnsAsync(false);

            // Run step
            var step = new ExistsCloudRepositoryStep(
                SynchronizationStoryStepId.ExistsCloudRepository,
                storyBoard.Object,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                settingsService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory(cloudStorageClient.Object));

            Assert.DoesNotThrowAsync(step.Run);

            // Settings are not stored because they are equal
            settingsService.Verify(m => m.TrySaveSettingsToLocalDevice(It.IsAny <SettingsModel>()), Times.Never);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <SynchronizationStoryStepId>(x => x == SynchronizationStoryStepId.StoreLocalRepositoryToCloudAndQuit)), Times.Once);
        }
Exemple #22
0
        public void DecryptAfterDesrializationCanReadAllPropertiesBack()
        {
            SerializeableCloudStorageCredentials credentials = CreateExampleCredentials();

            credentials.EncryptBeforeSerialization(PseudoEncrypt);

            credentials.Token    = null;
            credentials.Username = null;
            credentials.Password = null;
            credentials.Url      = null;
            credentials.Secure   = false;

            credentials.DecryptAfterDeserialization(PseudoDecrypt);

            Assert.AreEqual("atk", credentials.Token.AccessToken);
            Assert.AreEqual(new DateTime(1999, 12, 24, 0, 0, 0, DateTimeKind.Utc), credentials.Token.ExpiryDate);
            Assert.AreEqual("rtk", credentials.Token.RefreshToken);
            Assert.AreEqual("usr", credentials.Username);
            Assert.AreEqual("pwd", credentials.UnprotectedPassword);
            Assert.IsTrue(credentials.Secure);
        }
        public void KeepExistingTransfercode()
        {
            SerializeableCloudStorageCredentials credentialsFromSession = new SerializeableCloudStorageCredentials();
            var settingsModel = CreateSettingsModel("abcdefgh"); // Transfercode exists
            NoteRepositoryModel repositoryModel = new NoteRepositoryModel();

            Mock <IStoryBoard> storyBoard = new Mock <IStoryBoard>();

            storyBoard.
            Setup(m => m.LoadFromSession <SerializeableCloudStorageCredentials>(It.Is <SynchronizationStorySessionKey>(p => p == SynchronizationStorySessionKey.CloudStorageCredentials))).
            Returns(credentialsFromSession);
            Mock <ISettingsService> settingsService = new Mock <ISettingsService>();

            settingsService.
            Setup(m => m.LoadSettingsOrDefault()).Returns(settingsModel);
            Mock <IRepositoryStorageService> repositoryStorageService = new Mock <IRepositoryStorageService>();

            repositoryStorageService.
            Setup(m => m.LoadRepositoryOrDefault(out repositoryModel));

            // Run step
            var step = new StoreLocalRepositoryToCloudAndQuitStep(
                SynchronizationStoryStepId.StoreLocalRepositoryToCloudAndQuit,
                storyBoard.Object,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                settingsService.Object,
                CommonMocksAndStubs.CryptoRandomService(),
                repositoryStorageService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory());

            Assert.DoesNotThrowAsync(step.Run);

            // No settings are stored
            settingsService.Verify(m => m.TrySaveSettingsToLocalDevice(It.IsAny <SettingsModel>()), Times.Never);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <SynchronizationStoryStepId>(x => x == SynchronizationStoryStepId.StopAndShowRepository)), Times.Once);
        }
        public void GenerateAndStoreNewTransfercode()
        {
            SerializeableCloudStorageCredentials credentialsFromSession = new SerializeableCloudStorageCredentials();
            var settingsModel = CreateSettingsModel(null); // Transfercode does not yet exist
            NoteRepositoryModel repositoryModel = new NoteRepositoryModel();

            Mock <IStoryBoard> storyBoard = new Mock <IStoryBoard>();

            storyBoard.
            Setup(m => m.LoadFromSession <SerializeableCloudStorageCredentials>(It.Is <int>(p => p == SynchronizationStorySessionKey.CloudStorageCredentials.ToInt()))).
            Returns(credentialsFromSession);
            Mock <ISettingsService> settingsService = new Mock <ISettingsService>();

            settingsService.
            Setup(m => m.LoadSettingsOrDefault()).Returns(settingsModel);
            Mock <IRepositoryStorageService> repositoryStorageService = new Mock <IRepositoryStorageService>();

            repositoryStorageService.
            Setup(m => m.LoadRepositoryOrDefault(out repositoryModel));

            // Run step
            var step = new StoreLocalRepositoryToCloudAndQuitStep(
                SynchronizationStoryStepId.StoreLocalRepositoryToCloudAndQuit.ToInt(),
                storyBoard.Object,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                settingsService.Object,
                CommonMocksAndStubs.CryptoRandomService(),
                repositoryStorageService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory());

            Assert.DoesNotThrowAsync(step.Run);

            // Settings are stored with new transfer code
            settingsService.Verify(m => m.TrySaveSettingsToLocalDevice(It.Is <SettingsModel>(s => !string.IsNullOrEmpty(s.TransferCode))), Times.Once);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <int>(x => x == SynchronizationStoryStepId.StopAndShowRepository.ToInt())), Times.Once);
        }
Exemple #25
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);
            }
        }
Exemple #26
0
        public CloudStorageAccountViewModel(
            INavigationService navigationService,
            ILanguageService languageService,
            ISvgIconService svgIconService,
            IBaseUrlService webviewBaseUrl,
            IStoryBoardService storyBoardService,
            IFeedbackService feedbackService,
            ICloudStorageClientFactory cloudStorageClientFactory,
            SerializeableCloudStorageCredentials model)
            : base(navigationService, languageService, svgIconService, webviewBaseUrl)
        {
            _storyBoardService = storyBoardService ?? throw new ArgumentNullException(nameof(storyBoardService));
            _feedbackService   = feedbackService ?? throw new ArgumentNullException(nameof(feedbackService));
            Model = model;

            _credentialsRequirements = cloudStorageClientFactory.GetOrCreate(Model.CloudStorageId).CredentialsRequirements;
            CloudServiceName         = cloudStorageClientFactory.GetCloudStorageMetadata(Model.CloudStorageId).Title;

            GoBackCommand = new RelayCommand(GoBack);
            CancelCommand = new RelayCommand(Cancel);
            OkCommand     = new RelayCommand(Ok);
        }
Exemple #27
0
        public void ErrorMessageIsShownInCaseOfException()
        {
            SerializeableCloudStorageCredentials credentialsFromSession = new SerializeableCloudStorageCredentials();

            byte[] repositoryFromSession = null;
            byte[] repository            = new byte[8];

            Mock <IStoryBoard> storyBoard = new Mock <IStoryBoard>();

            storyBoard.
            Setup(m => m.LoadFromSession <SerializeableCloudStorageCredentials>(It.Is <int>(p => p == SynchronizationStorySessionKey.CloudStorageCredentials.ToInt()))).
            Returns(credentialsFromSession);
            storyBoard.
            Setup(m => m.TryLoadFromSession(It.Is <int>(p => p == SynchronizationStorySessionKey.BinaryCloudRepository.ToInt()), out repositoryFromSession)).
            Returns(false);
            Mock <IFeedbackService>    feedbackService    = new Mock <IFeedbackService>();
            Mock <ICloudStorageClient> cloudStorageClient = new Mock <ICloudStorageClient>();

            cloudStorageClient.
            Setup(m => m.DownloadFileAsync(It.IsAny <string>(), It.IsAny <CloudStorageCredentials>())).
            Throws <ConnectionFailedException>();

            // Run step
            var step = new DownloadCloudRepositoryStep(
                SynchronizationStoryStepId.DownloadCloudRepository.ToInt(),
                storyBoard.Object,
                CommonMocksAndStubs.LanguageService(),
                feedbackService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory(cloudStorageClient.Object));

            Assert.DoesNotThrowAsync(step.Run);

            // Error message was shown
            feedbackService.Verify(m => m.ShowToast(It.IsAny <string>()), Times.Once);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <int>(x => x == SynchronizationStoryStepId.ExistsTransferCode.ToInt())), Times.Never);
        }
        /// <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);
            }
        }
Exemple #29
0
        public void CorrectNextStepWhenCloudRepositoryExists()
        {
            SerializeableCloudStorageCredentials credentials = new SerializeableCloudStorageCredentials {
                CloudStorageId = CloudStorageClientFactory.CloudStorageIdDropbox
            };
            SettingsModel settingsModel = new SettingsModel {
                Credentials = credentials, TransferCode = "abc"
            };

            Mock <IStoryBoard>      storyBoard      = new Mock <IStoryBoard>();
            Mock <ISettingsService> settingsService = new Mock <ISettingsService>();

            settingsService.
            Setup(m => m.LoadSettingsOrDefault()).Returns(settingsModel);
            Mock <ICloudStorageClient> cloudStorageClient = new Mock <ICloudStorageClient>();

            cloudStorageClient.
            Setup(m => m.ExistsFileAsync(It.IsAny <string>(), It.IsAny <CloudStorageCredentials>())).
            ReturnsAsync(true);

            // Run step
            var step = new ExistsCloudRepositoryStep(
                PullPushStoryStepId.ExistsCloudRepository,
                storyBoard.Object,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                settingsService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory(cloudStorageClient.Object));

            Assert.DoesNotThrowAsync(step.Run);

            // Settings are not stored because no token needs to be refreshed
            settingsService.Verify(m => m.TrySaveSettingsToLocalDevice(It.IsAny <SettingsModel>()), Times.Never);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <PullPushStoryStepId>(x => x == PullPushStoryStepId.DownloadCloudRepository)), Times.Once);
        }
Exemple #30
0
        public void SuccessfulFlowEndsInNextStep()
        {
            SerializeableCloudStorageCredentials credentialsFromSession = new SerializeableCloudStorageCredentials();

            byte[] repositoryFromSession = null;
            byte[] repository            = new byte[8];

            Mock <IStoryBoard> storyBoard = new Mock <IStoryBoard>();

            storyBoard.
            Setup(m => m.LoadFromSession <SerializeableCloudStorageCredentials>(It.Is <int>(p => p == SynchronizationStorySessionKey.CloudStorageCredentials.ToInt()))).
            Returns(credentialsFromSession);
            storyBoard.
            Setup(m => m.TryLoadFromSession(It.Is <int>(p => p == SynchronizationStorySessionKey.BinaryCloudRepository.ToInt()), out repositoryFromSession)).
            Returns(false);
            Mock <ICloudStorageClient> cloudStorageClient = new Mock <ICloudStorageClient>();

            cloudStorageClient.
            Setup(m => m.DownloadFileAsync(It.IsAny <string>(), It.IsAny <CloudStorageCredentials>())).
            ReturnsAsync(repository);

            // Run step
            var step = new DownloadCloudRepositoryStep(
                SynchronizationStoryStepId.DownloadCloudRepository.ToInt(),
                storyBoard.Object,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                CommonMocksAndStubs.CloudStorageClientFactory(cloudStorageClient.Object));

            Assert.DoesNotThrowAsync(step.Run);

            // Repository was stored in session
            storyBoard.Verify(m => m.StoreToSession(It.Is <int>(p => p == SynchronizationStorySessionKey.BinaryCloudRepository.ToInt()), It.Is <object>(p => p == repository)), Times.Once);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <int>(x => x == SynchronizationStoryStepId.ExistsTransferCode.ToInt())), Times.Once);
        }