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