/// <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); }
/// <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); } }
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); }
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")); }
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")); }
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)); }
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); }
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); }
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")); }
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); } }
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); }
/// <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); } }
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); }
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); }
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); }
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); }
/// <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); } }
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); }
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); } }
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); }
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); }