//-----------------------------------------------------------------------
//
// 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;
}
}
}