--- /dev/null
+// -----------------------------------------------------------------------
+// <copyright file="PithosAccount.cs" company="Microsoft">
+// TODO: Update copyright text.
+// </copyright>
+// -----------------------------------------------------------------------
+
+namespace Pithos.Client.WPF
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using System.Net;
+ using System.Threading.Tasks;
+ using System.Diagnostics.Contracts;
+ using System.Diagnostics;
+ using System.Net.Sockets;
+
+ /// <summary>
+ /// TODO: Update summary.
+ /// </summary>
+ /// <summary>
+ /// Retrieves an account name and token from PITHOS
+ /// </summary>
+ public static class PithosAccount
+ {
+ /// <summary>
+ /// Asynchronously retrieves PITHOS credentials
+ /// </summary>
+ /// <param name="pithosSite">URL to retrieve the account info from PITHOS. Must end with =</param>
+ /// <returns>The credentials wrapped in a Task</returns>
+ public static Task<NetworkCredential> RetrieveCredentialsAsync(string pithosSite)
+ {
+ Contract.Requires(Uri.IsWellFormedUriString(pithosSite, UriKind.Absolute));
+
+ if (!Uri.IsWellFormedUriString(pithosSite, UriKind.Absolute))
+ throw new ArgumentException("The pithosSite parameter must be a valid absolute URL", "pithosSite");
+
+ int port = GetFreePort();
+
+
+ var listenerUrl = String.Format("http://127.0.0.1:{0}/", port);
+
+ HttpListener listener = new HttpListener();
+ listener.Prefixes.Add(listenerUrl);
+
+ Trace.TraceInformation("[RETRIEVE] Listening at {0}", listenerUrl);
+
+ listener.Start();
+
+ var task = Task.Factory.FromAsync<HttpListenerContext>(listener.BeginGetContext, listener.EndGetContext, null)
+ .WithTimeout(TimeSpan.FromMinutes(1))
+ .ContinueWith(tc =>
+ {
+ try
+ {
+ if (tc.IsFaulted)
+ {
+ Trace.TraceError("[RETRIEVE][ERROR] Receive connection {0}", tc.Exception);
+ throw tc.Exception;
+ }
+ else
+ {
+
+ var context = tc.Result;
+ var request = context.Request;
+ Trace.TraceInformation("[RETRIEVE] Got Connection {0}", request.RawUrl);
+
+ var query = request.QueryString;
+ var userName = query["user"];
+ var token = query["token"];
+
+ Trace.TraceInformation("[RETRIEVE] Credentials retrieved user:{0} token:{1}", userName, token);
+ Respond(context);
+
+ return new NetworkCredential(userName, token);
+ }
+
+ }
+ finally
+ {
+ listener.Close();
+ }
+ });
+
+ var uriBuilder=new UriBuilder(pithosSite);
+ uriBuilder.Path="login";
+ uriBuilder.Query="next=" + listenerUrl;
+
+ var retrieveUri = uriBuilder.Uri;
+ Trace.TraceInformation("[RETRIEVE] Open Browser at {0}", retrieveUri);
+ Process.Start(retrieveUri.ToString());
+
+ return task;
+ }
+
+ private static void Respond(HttpListenerContext context)
+ {
+ var response = context.Response;
+ var outBuffer = Encoding.UTF8.GetBytes("<html><head><title>Authenticated</title></head><body><h1>Got It</h1></body></html>");
+ response.ContentLength64 = outBuffer.Length;
+ using (var stream = response.OutputStream)
+ {
+ stream.Write(outBuffer, 0, outBuffer.Length);
+ }
+
+ Trace.TraceInformation("[RETRIEVE] Responded");
+ }
+ /// <summary>
+ /// Locates a free local port
+ /// </summary>
+ /// <returns>A free port</returns>
+ /// <remarks>The method starts and stops a TcpListener on port 0 to locate a free port.</remarks>
+ public static int GetFreePort()
+ {
+ //The TcpListener will locate a free port
+ var listener = new TcpListener(IPAddress.Any, 0);
+ listener.Start();
+ var port = ((IPEndPoint)listener.LocalEndpoint).Port;
+ listener.Stop();
+ return port;
+ }
+ }
+}