using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using Google.Apis.Auth.OAuth2; using Google.Apis.Auth.OAuth2.Requests; using Google.Apis.Auth.OAuth2.Responses; namespace Mesen.GUI.GoogleDriveIntegration { public class MesenCodeReceiver : LocalServerCodeReceiver, ICodeReceiver { private const string baseResponse = @" Mesen - Authentication Successful "; private const string successResponse = baseResponse + @"
Mesen - Authentication Successful
Mesen will now save battery files and save states in your Google Drive account.

Please close this window.
"; private const string failureResponse = baseResponse + @"
Mesen - Authentication Failed
Mesen was unable to integrate with your Google Drive account - please close this window and try again.
"; async Task ICodeReceiver.ReceiveCodeAsync(AuthorizationCodeRequestUrl url, CancellationToken taskCancellationToken) { var authorizationUrl = url.Build().ToString(); using(var listener = new HttpListener()) { listener.Prefixes.Add(RedirectUri); try { listener.Start(); Process.Start(authorizationUrl); // Wait to get the authorization code response. var context = await listener.GetContextAsync().ConfigureAwait(false); NameValueCollection coll = context.Request.QueryString; // Write a "close" response. Thread.Sleep(200); // Create a new response URL with a dictionary that contains all the response query parameters. var codeResponse = new AuthorizationCodeResponseUrl(coll.AllKeys.ToDictionary(k => k, k => coll[k])); using(var writer = new System.IO.StreamWriter(context.Response.OutputStream)) { writer.WriteLine(string.IsNullOrWhiteSpace(codeResponse.Error) ? successResponse : failureResponse); writer.Flush(); } context.Response.OutputStream.Close(); return codeResponse; } finally { listener.Close(); } } } } }