/// <summary> /// Get a working Provider for Google Drive. /// </summary> /// <param name="savedState">Serialized TokenResponse from the Google Api (and folderId).</param> /// <param name="showForm">Show registration form, if the saved state did not work.</param> /// <returns></returns> public async Task <string> Register(string savedState = null, bool showForm = true) { var result = new TaskCompletionSource <string>(); try { state = new MemoryStore(Obscure.Base64Decode(savedState)); // Try to use the previously saved TokenResponse and if it fails, show the registration form (if the showForm parameter allows it) var secret = new ClientSecrets() { ClientId = Obscure.CaesarDecode(Constants.AppKey), ClientSecret = Obscure.CaesarDecode(Constants.AppSecret) }; var receiver = new CodeReceiver(showForm); var credentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(secret, Constants.Scopes, "token", CancellationToken.None, state, receiver); service = new DriveService(new BaseClientService.Initializer() { HttpClientInitializer = credentials, ApplicationName = "SharpCrop", }); // Try to use the saved application folder or get a new one // If the access token was expired or corrupted, it is safer to get the folder id again if (receiver.Executed || await state.GetAsync <string>("folderId") == null) { var folder = await GetFolder(); await state.DeleteAsync <string>("folderId"); await state.StoreAsync("folderId", folder?.Id); } // Export the serialized TokenResponse which gonna be saved into the config result.SetResult(Obscure.Base64Encode(state.Export())); } catch { result.SetResult(null); } return(await result.Task); }