//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenIdOfflineProvider { using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Net.Http.Headers; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.Provider; using log4net; using log4net.Appender; using log4net.Core; using Validation; /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window, IDisposable { /// /// The OpenID Provider host object. /// private HostedProvider hostedProvider = new HostedProvider(); /// /// The logger the application may use. /// private ILog logger = log4net.LogManager.GetLogger(typeof(MainWindow)); /// /// Initializes a new instance of the class. /// public MainWindow() { this.InitializeComponent(); this.hostedProvider.ProcessRequestAsync = this.ProcessRequestAsync; TextWriterAppender boxLogger = log4net.LogManager.GetRepository().GetAppenders().OfType().FirstOrDefault(a => a.Name == "TextBoxAppender"); if (boxLogger != null) { boxLogger.Writer = new TextBoxTextWriter(this.logBox); } this.startProvider(); } #region IDisposable Members /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { this.Dispose(true); } /// /// Releases unmanaged and - optionally - managed resources /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected virtual void Dispose(bool disposing) { if (disposing) { var host = this.hostedProvider as IDisposable; if (host != null) { host.Dispose(); } this.hostedProvider = null; } } #endregion /// /// Raises the event. /// /// The instance containing the event data. protected override void OnClosing(System.ComponentModel.CancelEventArgs e) { this.stopProvider(); base.OnClosing(e); } /// /// Adds a set of HTTP headers to an instance, /// taking care to set some headers to the appropriate properties of /// /// /// The headers to add. /// The instance to set the appropriate values to. private static void ApplyHeadersToResponse(HttpResponseHeaders headers, HttpListenerResponse response) { Requires.NotNull(headers, "headers"); Requires.NotNull(response, "response"); foreach (var header in headers) { switch (header.Key) { case "Content-Type": response.ContentType = header.Value.First(); break; // Add more special cases here as necessary. default: response.AddHeader(header.Key, header.Value.First()); break; } } } /// /// Processes an incoming request at the OpenID Provider endpoint. /// /// The request info. /// The response. /// /// A task that completes with the asynchronous operation. /// private async Task ProcessRequestAsync(HttpRequestBase requestInfo, HttpListenerResponse response) { IRequest request = await this.hostedProvider.Provider.GetRequestAsync(requestInfo, CancellationToken.None); if (request == null) { App.Logger.Error("A request came in that did not carry an OpenID message."); response.ContentType = "text/html"; response.StatusCode = (int)HttpStatusCode.BadRequest; using (StreamWriter sw = new StreamWriter(response.OutputStream)) { sw.WriteLine("This is an OpenID Provider endpoint."); } return; } this.Dispatcher.Invoke(async delegate { if (!request.IsResponseReady) { var authRequest = request as IAuthenticationRequest; if (authRequest != null) { switch (this.checkidRequestList.SelectedIndex) { case 0: if (authRequest.IsDirectedIdentity) { string userIdentityPageBase = this.hostedProvider.UserIdentityPageBase.AbsoluteUri; if (this.capitalizedHostName.IsChecked.Value) { userIdentityPageBase = (this.hostedProvider.UserIdentityPageBase.Scheme + Uri.SchemeDelimiter + this.hostedProvider.UserIdentityPageBase.Authority).ToUpperInvariant() + this.hostedProvider.UserIdentityPageBase.PathAndQuery; } string leafPath = "directedidentity"; if (this.directedIdentityTrailingPeriodsCheckbox.IsChecked.Value) { leafPath += "."; } authRequest.ClaimedIdentifier = Identifier.Parse(userIdentityPageBase + leafPath, true); authRequest.LocalIdentifier = authRequest.ClaimedIdentifier; } authRequest.IsAuthenticated = true; break; case 1: authRequest.IsAuthenticated = false; break; case 2: IntPtr oldForegroundWindow = NativeMethods.GetForegroundWindow(); bool stoleFocus = NativeMethods.SetForegroundWindow(this); await CheckIdWindow.ProcessAuthenticationAsync(this.hostedProvider, authRequest); if (stoleFocus) { NativeMethods.SetForegroundWindow(oldForegroundWindow); } break; } } } }); var responseMessage = await this.hostedProvider.Provider.PrepareResponseAsync(request, CancellationToken.None); ApplyHeadersToResponse(responseMessage.Headers, response); } /// /// Starts the provider. /// private void startProvider() { this.hostedProvider.StartProvider(); this.opIdentifierLabel.Content = this.hostedProvider.OPIdentifier; } /// /// Stops the provider. /// private void stopProvider() { this.hostedProvider.StopProvider(); this.opIdentifierLabel.Content = string.Empty; } /// /// Handles the MouseDown event of the opIdentifierLabel control. /// /// The source of the event. /// The instance containing the event data. private void opIdentifierLabel_MouseDown(object sender, MouseButtonEventArgs e) { try { Clipboard.SetText(this.opIdentifierLabel.Content.ToString()); } catch (COMException ex) { MessageBox.Show(this, ex.Message, "Error while copying OP Identifier to the clipboard", MessageBoxButton.OK, MessageBoxImage.Error); } } /// /// Handles the Click event of the ClearLogButton control. /// /// The source of the event. /// The instance containing the event data. private void ClearLogButton_Click(object sender, RoutedEventArgs e) { this.logBox.Clear(); } } }