/// <inheritdoc/> public override async Task Run() { SerializeableCloudStorageCredentials credentials = StoryBoard.LoadFromSession <SerializeableCloudStorageCredentials>(SynchronizationStorySessionKey.CloudStorageCredentials.ToInt()); ICloudStorageClient cloudStorageClient = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId); try { bool stopBecauseNewOAuthLoginIsRequired = false; if ((cloudStorageClient is OAuth2CloudStorageClient oauthStorageClient) && credentials.Token.NeedsRefresh()) { try { // Get a new access token by using the refresh token credentials.Token = await oauthStorageClient.RefreshTokenAsync(credentials.Token); SaveCredentialsToSettings(credentials); } catch (RefreshTokenExpiredException) { // Refresh-token cannot be used to get new access-tokens anymore, a new // authorization by the user is required. stopBecauseNewOAuthLoginIsRequired = true; switch (StoryBoard.Mode) { case StoryBoardMode.GuiAndToasts: await StoryBoard.ContinueWith(SynchronizationStoryStepId.ShowCloudStorageAccount.ToInt()); break; case StoryBoardMode.ToastsOnly: _feedbackService.ShowToast(_languageService["sync_error_generic"]); break; } } } if (!stopBecauseNewOAuthLoginIsRequired) { bool repositoryExists = await cloudStorageClient.ExistsFileAsync(Config.RepositoryFileName, credentials); // If no error occured the credentials are ok and we can safe them SaveCredentialsToSettings(credentials); if (repositoryExists) { await StoryBoard.ContinueWith(SynchronizationStoryStepId.DownloadCloudRepository.ToInt()); } else { await StoryBoard.ContinueWith(SynchronizationStoryStepId.StoreLocalRepositoryToCloudAndQuit.ToInt()); } } } catch (Exception ex) { // Keep the current page open and show the error message ShowExceptionMessage(ex, _feedbackService, _languageService); } }
/// <inheritdoc/> public override Task Run() { if (StoryBoard.Mode.ShouldUseGui()) { SerializeableCloudStorageCredentials credentials = StoryBoard.LoadFromSession <SerializeableCloudStorageCredentials>(SynchronizationStorySessionKey.CloudStorageCredentials.ToInt()); ICloudStorageClient cloudStorageClient = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId); if (cloudStorageClient is IOAuth2CloudStorageClient oauthStorageClient) { // Show waiting page _navigationService.Navigate(ControllerNames.CloudStorageOauthWaiting); // Open OAuth2 login page in external browser string oauthState = CryptoUtils.GenerateRandomBase62String(16, _randomSource); string oauthCodeVerifier = CryptoUtils.GenerateRandomBase62String(64, _randomSource); StoryBoard.StoreToSession(SynchronizationStorySessionKey.OauthState.ToInt(), oauthState); StoryBoard.StoreToSession(SynchronizationStorySessionKey.OauthCodeVerifier.ToInt(), oauthCodeVerifier); string url = oauthStorageClient.BuildAuthorizationRequestUrl(oauthState, oauthCodeVerifier); _nativeBrowserService.OpenWebsiteInApp(url); } else { _navigationService.Navigate(ControllerNames.CloudStorageAccount); } } return(Task.CompletedTask); }
/// <inheritdoc/> public override async Task Run() { 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); } }
/// <summary> /// Creates an <see cref="ICloudStorageClientFactory"/> mock from a given /// <paramref name="cloudStorageClient"/>. /// </summary> /// <param name="cloudStorageClient">Cloud storage client which should be returned.</param> /// <returns>Mock for a cloud storage client factory.</returns> public static ICloudStorageClientFactory CloudStorageClientFactory(ICloudStorageClient cloudStorageClient) { Mock <ICloudStorageClientFactory> result = new Mock <ICloudStorageClientFactory>(); result. Setup(m => m.GetOrCreate(It.IsAny <string>())). Returns(cloudStorageClient); return(result.Object); }
/// <summary> /// Initializes a new instance of the <see cref="EmailHandlerManager"/> class. /// </summary> /// <param name="configuration">An instance of <see cref="IConfiguration"/>.</param> /// <param name="mSGraphSetting">Graph settings <see cref="MSGraphSetting"/>.</param> /// <param name="cloudStorageClient">An instance of <see cref="ICloudStorageClient"/>.</param> /// <param name="logger">An instance of <see cref="ILogger"/>.</param> /// <param name="emailManager">An instance of <see cref="IEmailManager"/>.</param> public EmailHandlerManager( IConfiguration configuration, IOptions <MSGraphSetting> mSGraphSetting, ICloudStorageClient cloudStorageClient, ILogger logger, IEmailManager emailManager) { this.configuration = configuration; this.mSGraphSetting = mSGraphSetting?.Value; this.cloudStorageClient = cloudStorageClient; this.logger = logger; this.emailManager = emailManager; }
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); } }
/// <summary> /// Initializes a new instance of the <see cref="EmailHandlerManager"/> class. /// </summary> /// <param name="configuration">An instance of <see cref="IConfiguration"/>.</param> /// <param name="mSGraphSetting">Graph settings <see cref="MSGraphSetting"/>.</param> /// <param name="cloudStorageClient">An instance of <see cref="ICloudStorageClient"/>.</param> /// <param name="logger">An instance of <see cref="ILogger"/>.</param> /// <param name="emailManager">An instance of <see cref="IEmailManager"/>.</param> public EmailHandlerManager( IConfiguration configuration, IOptions <MSGraphSetting> mSGraphSetting, ICloudStorageClient cloudStorageClient, ILogger logger, IEmailManager emailManager) { this.configuration = configuration; this.mSGraphSetting = mSGraphSetting?.Value; this.cloudStorageClient = cloudStorageClient; this.logger = logger; this.emailManager = emailManager; this.notificationQueue = this.configuration?[$"{ConfigConstants.StorageAccountConfigSectionKey}:{ConfigConstants.StorageAccNotificationQueueName}"]; }
private async Task <bool> TryDeleteCloudNoteRepository() { var credentials = Model.Credentials; ICloudStorageClient cloudStorageClient = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId); try { await cloudStorageClient.DeleteFileAsync(Config.RepositoryFileName, credentials); return(true); } catch (Exception) { return(false); } }
/// <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); } }
/// <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); } }
/// <summary> /// Initializes a new instance of the <see cref="EmailServiceManager"/> class. /// </summary> /// <param name="configuration">An instance of <see cref="IConfiguration"/>.</param> /// <param name="repositoryFactory">An instance of <see cref="IRepositoryFactory"/>.</param> /// <param name="cloudStorageClient">An instance of <see cref="ICloudStorageClient"/>.</param> /// <param name="logger">Instance of Logger.</param> /// <param name="notificationProviderFactory">An instance of <see cref="INotificationProviderFactory"/>.</param> /// <param name="emailManager">An instance of <see cref="IEmailManager"/>.</param> public EmailServiceManager( IConfiguration configuration, IRepositoryFactory repositoryFactory, ICloudStorageClient cloudStorageClient, ILogger logger, INotificationProviderFactory notificationProviderFactory, IEmailManager emailManager) { this.repositoryFactory = repositoryFactory; this.configuration = configuration; this.emailNotificationRepository = repositoryFactory.GetRepository(Enum.TryParse <StorageType>(this.configuration?[Constants.StorageType], out this.repo) ? this.repo : throw new Exception()); this.cloudStorageClient = cloudStorageClient; this.logger = logger; this.notificationProvider = notificationProviderFactory.GetNotificationProvider(Enum.TryParse <NotificationProviderType>(this.configuration?[Constants.NotificationProviderType], out this.provider) ? this.provider : throw new Exception()); if (this.configuration?["MailSettings"] != null) { this.mailSettings = JsonConvert.DeserializeObject <List <MailSettings> >(this.configuration?["MailSettings"]); } this.emailManager = emailManager; }
/// <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); } }
/// <summary> /// Initializes a new instance of the <see cref="MailTemplateRepository"/> class. /// </summary> /// <param name="logger">logger.</param> /// <param name="cloudStorageClient">cloud storage client for blob storage.</param> /// <param name="tableStorageClient">cloud storage client for table storage.</param> /// <param name="storageAccountSetting">primary key of storage account.</param> public MailTemplateRepository( ILogger logger, ICloudStorageClient cloudStorageClient, ITableStorageClient tableStorageClient, IOptions <StorageAccountSetting> storageAccountSetting) { this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.cloudStorageClient = cloudStorageClient ?? throw new ArgumentNullException(nameof(cloudStorageClient)); this.tableStorageClient = tableStorageClient ?? throw new ArgumentNullException(nameof(tableStorageClient)); if (storageAccountSetting is null) { throw new ArgumentNullException(nameof(storageAccountSetting)); } if (string.IsNullOrWhiteSpace(storageAccountSetting?.Value?.MailTemplateTableName)) { this.logger.WriteException(new ArgumentException("MailTemplateTableName")); throw new ArgumentException("MailTemplateTableName"); } this.cloudTable = this.tableStorageClient.GetCloudTable(storageAccountSetting.Value.MailTemplateTableName); }
/// <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); } }
/// <summary> /// Initializes a new instance of the <see cref="MailAttachmentRepository"/> class. /// </summary> /// <param name="logger">The Logger instance.</param> /// <param name="cloudStorageClient">The Cloud Storage Client instance.</param> /// <param name="encryptionService">The IEncryptionService instance.</param> public MailAttachmentRepository(ILogger logger, ICloudStorageClient cloudStorageClient, IEncryptionService encryptionService) { this.logger = logger; this.cloudStorageClient = cloudStorageClient; this.encryptionService = encryptionService; }
protected ICloudStorageClientTests(ICloudStorageClient client, string testFolder) { this._client = client; this.TestFolder = testFolder; }
protected ICloudStorageThumbnailProviderTests(ICloudStorageClient client, string testFolder) : base(client, testFolder) { }
/// <inheritdoc/> public override async Task Run() { try { NoteRepositoryModel cloudRepository = StoryBoard.LoadFromSession <NoteRepositoryModel>(PullPushStorySessionKey.CloudRepository); _repositoryStorageService.LoadRepositoryOrDefault(out NoteRepositoryModel localRepository); SettingsModel settings = _settingsService.LoadSettingsOrDefault(); SerializeableCloudStorageCredentials credentials = settings.Credentials; NoteModel cloudNote = cloudRepository.Notes.FindById(_noteId); NoteModel localNote = localRepository.Notes.FindById(_noteId); if (localNote == null) { throw new Exception("PullPushStory is triggered on the note dialog, so the note must exist."); } if (cloudNote == null) { // Note does not yet exist in the cloud, or it was deleted permanently. Both // cases should be rejected. _feedbackService.ShowToast(_languageService["pushpull_error_no_cloud_note"]); return; } if (cloudNote.ModifiedAt == localNote.ModifiedAt) { // Notes are equal, nothing to sync _feedbackService.ShowToast(_languageService["pushpull_success"]); return; } // Merge repositories if (_direction == PullPushDirection.PullFromServer) { cloudNote.CloneTo(localNote); // this can possibly move the note to the recycling bin or reverse AddSafeToOtherRepositoryIfMissing(cloudRepository, localRepository, cloudNote.SafeId); _repositoryStorageService.TrySaveRepository(localRepository); } else { // Uploading explicitely can be seen as a confirmation that this version is the // most current one. So we make sure that the uploaded version is not overwritten // by other devices afterwards. localNote.RefreshModifiedAt(); _repositoryStorageService.TrySaveRepository(localRepository); localNote.CloneTo(cloudNote); // this can possibly move the note to the recycling bin or reverse AddSafeToOtherRepositoryIfMissing(localRepository, cloudRepository, localNote.SafeId); byte[] encryptedRepository = EncryptRepository( cloudRepository, settings.TransferCode, _cryptoRandomService, settings.SelectedEncryptionAlgorithm); ICloudStorageClient cloudStorageClient = _cloudStorageClientFactory.GetOrCreate(credentials.CloudStorageId); await cloudStorageClient.UploadFileAsync(Config.RepositoryFileName, encryptedRepository, credentials); } _feedbackService.ShowToast(_languageService["pushpull_success"]); } catch (Exception ex) { // Keep the current page open and show the error message ShowExceptionMessage(ex, _feedbackService, _languageService); } }
private static async Task Test(ICloudStorageClient client) { TokenManager tokenManager = new TokenManager(client.GetType().Name); client.SaveAccessTokenDelegate = tokenManager.SaveAccessToken; client.SaveRefreshTokenDelegate = tokenManager.SaveRefreshToken; client.LoadAccessTokenDelegate = tokenManager.LoadAccessToken; client.LoadRefreshTokenDelegate = tokenManager.LoadRefresToken; var result = await client.InitAsync(); if (result.Status != Status.Success) { Console.WriteLine("Initial failed, status=" + result.Status + ", reason=" + result.Message); } CloudStorageAccountInfo accountInfo; if (result.Status == Status.NeedAuthenticate) { (result, accountInfo) = await client.LoginAsync(); client.StopListen(); } else { (result, accountInfo) = await client.GetAccountInfoAsync(); } if (result.Status != Status.Success) { Console.WriteLine("Login failed, reason=" + result.Message); return; } Console.WriteLine("Login success, account=" + accountInfo.userEmail + ", username="******"Account space: {0:fs} / {1:fs}", accountInfo.usedSpace, accountInfo.totalSpace)); string rootId = await client.GetRootFolderIdAsync(); string folderId, folderName = "test"; (result, folderId) = await client.CreateFolderAsync(rootId, folderName); if (result.Status != Status.Success) { Console.WriteLine("Create folder failed, reason=" + result.Message); return; } Console.WriteLine($"Created folder {folderName}, id={folderId}"); string localFile = "test.txt"; File.WriteAllText(localFile, "I am a test file."); CancellationTokenSource cts = new CancellationTokenSource(); CloudStorageFile cloudFile; (result, cloudFile) = await client.UploadFileToFolderByIdAsync(localFile, folderId, cts.Token); if (result.Status != Status.Success) { Console.WriteLine("Upload file failed, reason=" + result.Message); return; } Console.WriteLine($"Uploaded file {localFile}"); File.Delete(localFile); result = await client.DownloadFileByIdAsync(cloudFile.Id, localFile, cts.Token); if (result.Status != Status.Success) { Console.WriteLine("Download file failed, reason=" + result.Message); return; } Console.WriteLine($"Downloaded file {localFile}"); result = await client.DeleteFileByIdAsync(cloudFile.Id); if (result.Status != Status.Success) { Console.WriteLine("Delete file failed, reason=" + result.Message); return; } Console.WriteLine($"Deleted file '{cloudFile.Name}'"); // test a larger file const string testPic = @"D:\Test Dir\CloudStorages\surprised pikachu.png"; (result, cloudFile) = await client.UploadFileToFolderByIdAsync(testPic, folderId, cts.Token); if (result.Status != Status.Success) { Console.WriteLine("Upload large file failed, reason=" + result.Message); return; } Console.WriteLine($"Uploaded large file '{testPic}'"); const string testPic2 = @"D:\Test Dir\CloudStorages\surprised pikachu 2.png"; result = await client.DownloadFileByIdAsync(cloudFile.Id, testPic2, cts.Token); if (result.Status != Status.Success) { Console.WriteLine("Download large file failed, reason=" + result.Message); return; } Console.WriteLine($"Downloaded large file '{testPic2}'"); result = await client.DeleteFileByIdAsync(cloudFile.Id); if (result.Status != Status.Success) { Console.WriteLine("Delete file failed, reason=" + result.Message); return; } Console.WriteLine($"Deleted file '{cloudFile.Name}'"); File.Delete(testPic2); }