//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenIdOfflineProvider { using System; using System.ComponentModel; using System.Globalization; using System.Linq; using System.Net; using System.Net.Http.Headers; using System.Runtime.InteropServices; using System.ServiceModel; using System.Threading.Tasks; using System.Web; using System.Windows; using System.Windows.Input; using DotNetOpenAuth.Logging; using Microsoft.Owin.Hosting; using Validation; /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window, IDisposable { /// /// The main window for the app. /// internal static MainWindow Instance; /// /// The logger the application may use. /// private ILog _logger; private IDisposable hostServer; /// /// Initializes a new instance of the class. /// public MainWindow() { this.InitializeComponent(); LogProvider.SetCurrentLogProvider(new TextWriterLogProvider(new TextBoxTextWriter(this.logBox))); this._logger = LogProvider.GetLogger(typeof(MainWindow)); Instance = this; this.StartProviderAsync(); } #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) { if (this.hostServer != null) { this.hostServer.Dispose(); } this.hostServer = null; } } #endregion /// /// Raises the event. /// /// The instance containing the event data. protected override void OnClosing(CancelEventArgs e) { this.StopProviderAsync(); 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; } } } /// /// 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(); } /// /// Starts the provider. /// /// A task that completes when the asynchronous operation is finished. private async Task StartProviderAsync() { Exception exception = null; try { Verify.Operation(this.hostServer == null, "Server already started."); int port = 45235; try { this.hostServer = WebApp.Start(url: string.Format("http://localhost:{0}", port)); this._logger.Info("Server Started"); } catch (AddressAccessDeniedException ex) { // If this throws an exception, use an elevated command prompt and execute: // netsh http add urlacl url=http://+:45235/ user=YOUR_USERNAME_HERE string message = string.Format( CultureInfo.CurrentCulture, "Use an elevated command prompt and execute: \nnetsh http add urlacl url=http://+:{0}/ user={1}\\{2}", port, Environment.UserDomainName, Environment.UserName); throw new InvalidOperationException(message, ex); } this.opIdentifierLabel.Content = string.Format("http://localhost:{0}", port); } catch (InvalidOperationException ex) { exception = ex; } if (exception != null) { if (MessageBox.Show(exception.Message, "Configuration error", MessageBoxButton.OKCancel, MessageBoxImage.Error) == MessageBoxResult.OK) { await this.StartProviderAsync(); return; } else { this.Close(); } } } /// /// Stops the provider. /// /// A task that completes when the asynchronous operation is finished. private async Task StopProviderAsync() { if (this.hostServer != null) { this.hostServer.Dispose(); this.hostServer = null; } this.opIdentifierLabel.Content = string.Empty; } } }