//-----------------------------------------------------------------------
//
// Copyright (c) Andrew Arnott. All rights reserved.
//
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Test.OpenId {
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using DotNetOAuth.Test.OpenId.UI;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Provider;
using DotNetOpenAuth.OpenId.RelyingParty;
using DotNetOpenAuth.Test.Mocks;
////using DotNetOpenAuth.Test.UI;
using log4net;
public class TestSupport {
public const string HostTestPage = "HostTest.aspx";
public const string ProviderPage = "ProviderEndpoint.aspx";
public const string DirectedProviderEndpoint = "DirectedProviderEndpoint.aspx";
public const string MobileConsumerPage = "RelyingPartyMobile.aspx";
public const string ConsumerPage = "RelyingParty.aspx";
public const string OPDefaultPage = "OPDefault.aspx";
public static readonly ILog Logger = LogManager.GetLogger("DotNetOpenId.Test");
public static readonly string TestWebDirectory = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), @"..\..\src\DotNetOpenId.TestWeb"));
private const string IdentityPage = "IdentityEndpoint.aspx";
private const string DirectedIdentityPage = "DirectedIdentityEndpoint.aspx";
public enum Scenarios {
// Authentication test scenarios
AutoApproval,
AutoApprovalAddFragment,
ApproveOnSetup,
AlwaysDeny,
/* Extension test scenarios */
///
/// Provides all required and requested fields.
///
ExtensionFullCooperation,
///
/// Provides only those fields marked as required.
///
ExtensionPartialCooperation,
}
public static Uri ReturnTo {
get { return TestSupport.GetFullUrl(TestSupport.ConsumerPage); }
}
public static Realm Realm {
get { return new Realm(TestSupport.GetFullUrl(TestSupport.ConsumerPage).AbsoluteUri); }
}
public static Identifier GetDelegateUrl(Scenarios scenario) {
return GetDelegateUrl(scenario, false);
}
public static Identifier GetDelegateUrl(Scenarios scenario, bool useSsl) {
return new UriIdentifier(GetFullUrl("/" + scenario, null, useSsl));
}
public static Uri GetFullUrl(string url) {
return GetFullUrl(url, null, false);
}
public static Uri GetFullUrl(string url, string key, object value) {
var dictionary = new Dictionary {
{ key, value.ToString() },
};
return GetFullUrl(url, dictionary, false);
}
public static Uri GetFullUrl(string url, IDictionary args, bool useSsl) {
Uri defaultUriBase = new Uri(useSsl ? "https://localhost/" : "http://localhost/");
Uri baseUri = UITestSupport.Host != null ? UITestSupport.Host.BaseUri : defaultUriBase;
UriBuilder builder = new UriBuilder(new Uri(baseUri, url));
MessagingUtilities.AppendQueryArgs(builder, args);
return builder.Uri;
}
///
/// Returns the content of a given embedded resource.
///
/// The path of the file as it appears within the project,
/// where the leading / marks the root directory of the project.
/// The content of the requested resource.
internal static string LoadEmbeddedFile(string path) {
if (!path.StartsWith("/")) {
path = "/" + path;
}
path = "DotNetOpenAuth.Test.OpenId" + path.Replace('/', '.');
Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(path);
if (resource == null) {
throw new ArgumentException();
}
using (StreamReader sr = new StreamReader(resource)) {
return sr.ReadToEnd();
}
}
////internal static UriIdentifier GetOPIdentityUrl(Scenarios scenario, bool useSsl) {
//// var args = new Dictionary {
//// { "user", scenario.ToString() },
////};
//// return new UriIdentifier(GetFullUrl("/" + OPDefaultPage, args, useSsl));
////}
internal static UriIdentifier GetIdentityUrl(Scenarios scenario, ProtocolVersion providerVersion) {
return GetIdentityUrl(scenario, providerVersion, false);
}
internal static UriIdentifier GetIdentityUrl(Scenarios scenario, ProtocolVersion providerVersion, bool useSsl) {
var dictionary = new Dictionary {
{ "user", scenario.ToString() },
{ "version", providerVersion.ToString() },
};
return new UriIdentifier(GetFullUrl("/" + IdentityPage, dictionary, useSsl));
}
internal static MockIdentifier GetMockIdentifier(Scenarios scenario, MockHttpRequest mockRequest, ProtocolVersion providerVersion) {
return GetMockIdentifier(scenario, mockRequest, providerVersion, false);
}
internal static MockIdentifier GetMockIdentifier(Scenarios scenario, MockHttpRequest mockRequest, ProtocolVersion providerVersion, bool useSsl) {
ServiceEndpoint se = GetServiceEndpoint(scenario, providerVersion, 10, useSsl);
return new MockIdentifier(GetIdentityUrl(scenario, providerVersion, useSsl), mockRequest, new ServiceEndpoint[] { se });
}
internal static ServiceEndpoint GetServiceEndpoint(Scenarios scenario, ProtocolVersion providerVersion, int servicePriority, bool useSsl) {
var providerEndpoint = new ProviderEndpointDescription(GetFullUrl("/" + ProviderPage, null, useSsl), new string[] { Protocol.Lookup(providerVersion).ClaimedIdentifierServiceTypeURI });
return ServiceEndpoint.CreateForClaimedIdentifier(
GetIdentityUrl(scenario, providerVersion, useSsl),
GetDelegateUrl(scenario, useSsl),
providerEndpoint,
servicePriority,
10);
}
///
/// A default implementation of a simple provider that responds to authentication requests
/// per the scenario that is being simulated.
///
/// The OpenIdProvider on which the process messages.
///
/// This is a very useful method to pass to the OpenIdCoordinator constructor for the Provider argument.
///
internal static void AutoProvider(OpenIdProvider provider) {
IRequest request;
while ((request = provider.GetRequest()) != null) {
if (!request.IsResponseReady) {
var authRequest = (DotNetOpenAuth.OpenId.Provider.IAuthenticationRequest)request;
var scenario = (Scenarios)Enum.Parse(typeof(Scenarios), new Uri(authRequest.LocalIdentifier).AbsolutePath.TrimStart('/'));
switch (scenario) {
case TestSupport.Scenarios.AutoApproval:
authRequest.IsAuthenticated = true;
break;
case Scenarios.AutoApprovalAddFragment:
authRequest.SetClaimedIdentifierFragment("frag");
authRequest.IsAuthenticated = true;
break;
case TestSupport.Scenarios.ApproveOnSetup:
authRequest.IsAuthenticated = !authRequest.Immediate;
break;
case Scenarios.AlwaysDeny:
authRequest.IsAuthenticated = false;
break;
default:
// All other scenarios are done programmatically only.
throw new InvalidOperationException("Unrecognized scenario");
}
}
request.Response.Send();
}
}
////internal static UriIdentifier GetDirectedIdentityUrl(Scenarios scenario, ProtocolVersion providerVersion) {
//// return GetDirectedIdentityUrl(scenario, providerVersion, false);
////}
////internal static UriIdentifier GetDirectedIdentityUrl(Scenarios scenario, ProtocolVersion providerVersion, bool useSsl) {
//// return new UriIdentifier(GetFullUrl("/" + DirectedIdentityPage, new Dictionary {
//// { "user", scenario.ToString() },
//// { "version", providerVersion.ToString() },
//// }, useSsl));
////}
////internal static IRelyingPartyApplicationStore RelyingPartyStore;
////internal static IProviderAssociationStore ProviderStore;
///////
/////// Generates a new, stateful whose direct messages
/////// will be automatically handled by an internal
/////// that uses the shared .
///////
////internal static OpenIdRelyingParty CreateRelyingParty(NameValueCollection fields) {
//// return CreateRelyingParty(RelyingPartyStore, null, fields);
////}
////internal static OpenIdRelyingParty CreateRelyingParty(IRelyingPartyApplicationStore store, NameValueCollection fields) {
//// return CreateRelyingParty(store, null, fields);
////}
///////
/////// Generates a new whose direct messages
/////// will be automatically handled by an internal
/////// that uses the shared .
///////
////internal static OpenIdRelyingParty CreateRelyingParty(IRelyingPartyApplicationStore store, Uri requestUrl, NameValueCollection fields) {
//// var rp = new OpenIdRelyingParty(store, requestUrl ?? GetFullUrl(ConsumerPage), fields ?? new NameValueCollection());
//// if (fields == null || fields.Count == 0) {
//// Assert.IsNull(rp.Response);
//// }
//// rp.DirectMessageChannel = new DirectMessageTestRedirector(ProviderStore);
//// return rp;
////}
////internal static DotNetOpenId.RelyingParty.IAuthenticationRequest CreateRelyingPartyRequest(bool stateless, Scenarios scenario, ProtocolVersion version, bool useSsl) {
//// // Publish RP discovery information
//// MockHttpRequest.RegisterMockRPDiscovery();
//// var rp = TestSupport.CreateRelyingParty(stateless ? null : RelyingPartyStore, null);
//// var rpReq = rp.CreateRequest(TestSupport.GetMockIdentifier(scenario, version, useSsl), Realm, ReturnTo);
//// // Sidetrack: verify URLs and other default properties
//// {
//// Assert.AreEqual(AuthenticationRequestMode.Setup, rpReq.Mode);
//// Assert.AreEqual(Realm, rpReq.Realm);
//// Assert.AreEqual(ReturnTo, rpReq.ReturnToUrl);
//// }
//// return rpReq;
////}
///////
/////// Generates a new ready to process a
/////// response from an .
///////
////internal static IAuthenticationResponse CreateRelyingPartyResponse(IRelyingPartyApplicationStore store, IResponse providerResponse) {
//// return CreateRelyingPartyResponse(store, providerResponse, false);
////}
////internal static IAuthenticationResponse CreateRelyingPartyResponse(IRelyingPartyApplicationStore store, IResponse providerResponse, bool requireSsl) {
//// if (providerResponse == null) throw new ArgumentNullException("providerResponse");
//// var opAuthWebResponse = (Response)providerResponse;
//// var opAuthResponse = (EncodableResponse)opAuthWebResponse.EncodableMessage;
//// var rp = CreateRelyingParty(store, opAuthResponse.RedirectUrl,
//// opAuthResponse.EncodedFields.ToNameValueCollection());
//// rp.Settings.RequireSsl = requireSsl;
//// // Get the response now, before trying the replay attack. The Response
//// // property is lazily-evaluated, so the replay attack can be evaluated first
//// // and pass, while this one that SUPPOSED to pass fails, if we don't force it now.
//// var response = rp.Response;
//// // Side-track to test for replay attack while we're at it.
//// // This simulates a network sniffing user who caught the
//// // authenticating query en route to either the user agent or
//// // the consumer, and tries the same query to the consumer in an
//// // attempt to spoof the identity of the authenticating user.
//// try {
//// Logger.Info("Attempting replay attack...");
//// var replayRP = CreateRelyingParty(store, opAuthResponse.RedirectUrl,
//// opAuthResponse.EncodedFields.ToNameValueCollection());
//// replayRP.Settings.RequireSsl = requireSsl;
//// Assert.AreNotEqual(AuthenticationStatus.Authenticated, replayRP.Response.Status, "Replay attack succeeded!");
//// } catch (OpenIdException) { // nonce already used
//// // another way to pass
//// }
//// // Return the result of the initial response (not the replay attack one).
//// return response;
////}
///////
/////// Generates a new that uses the shared
/////// store in .
///////
////internal static OpenIdProvider CreateProvider(NameValueCollection fields) {
//// return CreateProvider(fields, false);
////}
////internal static OpenIdProvider CreateProvider(NameValueCollection fields, bool useSsl) {
//// Protocol protocol = fields != null ? Protocol.Detect(fields.ToDictionary()) : Protocol.V20;
//// Uri opEndpoint = GetFullUrl(ProviderPage, null, useSsl);
//// var provider = new OpenIdProvider(ProviderStore, opEndpoint, opEndpoint, fields ?? new NameValueCollection());
//// return provider;
////}
////internal static OpenIdProvider CreateProviderForRequest(DotNetOpenId.RelyingParty.IAuthenticationRequest request) {
//// IResponse relyingPartyAuthenticationRequest = request.RedirectingResponse;
//// var rpWebMessageToOP = (Response)relyingPartyAuthenticationRequest;
//// var rpMessageToOP = (IndirectMessageRequest)rpWebMessageToOP.EncodableMessage;
//// var opEndpoint = (ServiceEndpoint)request.Provider;
//// var provider = new OpenIdProvider(ProviderStore, opEndpoint.ProviderEndpoint,
//// opEndpoint.ProviderEndpoint, rpMessageToOP.EncodedFields.ToNameValueCollection());
//// return provider;
////}
////internal static IResponse CreateProviderResponseToRequest(
//// DotNetOpenId.RelyingParty.IAuthenticationRequest request,
//// Action prepareProviderResponse) {
//// {
//// // Sidetrack: Verify the return_to and realm URLs
//// var consumerToProviderQuery = HttpUtility.ParseQueryString(request.RedirectingResponse.ExtractUrl().Query);
//// Protocol protocol = Protocol.Detect(consumerToProviderQuery.ToDictionary());
//// Assert.IsTrue(consumerToProviderQuery[protocol.openid.return_to].StartsWith(request.ReturnToUrl.AbsoluteUri, StringComparison.Ordinal));
//// Assert.AreEqual(request.Realm.ToString(), consumerToProviderQuery[protocol.openid.Realm]);
//// }
//// var op = TestSupport.CreateProviderForRequest(request);
//// var opReq = (DotNetOpenId.Provider.IAuthenticationRequest)op.Request;
//// prepareProviderResponse(opReq);
//// Assert.IsTrue(opReq.IsResponseReady);
//// return opReq.Response;
////}
////internal static IAuthenticationResponse CreateRelyingPartyResponseThroughProvider(
//// DotNetOpenId.RelyingParty.IAuthenticationRequest request,
//// Action providerAction) {
//// var rpReq = (AuthenticationRequest)request;
//// var opResponse = CreateProviderResponseToRequest(rpReq, providerAction);
//// // Be careful to use whatever store the original RP was using.
//// var rp = CreateRelyingPartyResponse(rpReq.RelyingParty.Store, opResponse,
//// ((AuthenticationRequest)request).RelyingParty.Settings.RequireSsl);
//// Assert.IsNotNull(rp);
//// return rp;
////}
////[SetUp]
////public void SetUp() {
//// log4net.Config.XmlConfigurator.Configure(Assembly.GetExecutingAssembly().GetManifestResourceStream("DotNetOpenId.Test.Logging.config"));
//// ResetStores();
////}
////[TearDown]
////public void TearDown() {
//// log4net.LogManager.Shutdown();
////}
////internal static void ResetStores() {
//// RelyingPartyStore = new ApplicationMemoryStore();
//// ProviderStore = new ProviderMemoryStore();
////}
////internal static void SetAuthenticationFromScenario(Scenarios scenario, DotNetOpenId.Provider.IAuthenticationRequest request) {
//// Assert.IsTrue(request.IsReturnUrlDiscoverable);
//// switch (scenario) {
//// case TestSupport.Scenarios.ExtensionFullCooperation:
//// case TestSupport.Scenarios.ExtensionPartialCooperation:
//// case TestSupport.Scenarios.AutoApproval:
//// // immediately approve
//// request.IsAuthenticated = true;
//// break;
//// case TestSupport.Scenarios.AutoApprovalAddFragment:
//// request.SetClaimedIdentifierFragment("frag");
//// request.IsAuthenticated = true;
//// break;
//// case TestSupport.Scenarios.ApproveOnSetup:
//// request.IsAuthenticated = !request.Immediate;
//// break;
//// case TestSupport.Scenarios.AlwaysDeny:
//// request.IsAuthenticated = false;
//// break;
//// default:
//// throw new InvalidOperationException("Unrecognized scenario");
//// }
////}
///////
/////// Uses an RPs stored association to resign an altered message from a Provider,
/////// to simulate a Provider that deliberately sent a bad message in an attempt
/////// to thwart RP security.
///////
////internal static void Resign(NameValueCollection nvc, IRelyingPartyApplicationStore store) {
//// Debug.Assert(nvc != null);
//// Debug.Assert(store != null);
//// var dict = Util.NameValueCollectionToDictionary(nvc);
//// Protocol protocol = Protocol.Detect(dict);
//// Uri providerEndpoint = new Uri(nvc[protocol.openid.op_endpoint]);
//// string assoc_handle = nvc[protocol.openid.assoc_handle];
//// Association assoc = store.GetAssociation(providerEndpoint, assoc_handle);
//// Debug.Assert(assoc != null, "Association not found in RP's store. Maybe you're communicating with a hosted OP instead of the TestSupport one?");
//// IList signed = nvc[protocol.openid.signed].Split(',');
//// var subsetDictionary = new Dictionary();
//// foreach (string signedKey in signed) {
//// string keyName = protocol.openid.Prefix + signedKey;
//// subsetDictionary.Add(signedKey, dict[keyName]);
//// }
//// nvc[protocol.openid.sig] = Convert.ToBase64String(assoc.Sign(subsetDictionary, signed));
////}
////public static IAssociationStore ProviderStoreContext {
//// get {
//// return DotNetOpenId.Provider.OpenIdProvider.HttpApplicationStore;
//// }
////}
////internal static MockIdentifier GetMockOPIdentifier(Scenarios scenario, UriIdentifier expectedClaimedId) {
//// return GetMockOPIdentifier(scenario, expectedClaimedId, false, false);
////}
////internal static MockIdentifier GetMockOPIdentifier(Scenarios scenario, UriIdentifier expectedClaimedId, bool useSslOpIdentifier, bool useSslProviderEndpoint) {
//// var fields = new Dictionary {
//// { "user", scenario.ToString() },
////};
//// Uri opEndpoint = GetFullUrl(DirectedProviderEndpoint, fields, useSslProviderEndpoint);
//// Uri opIdentifier = GetOPIdentityUrl(scenario, useSslOpIdentifier);
//// ServiceEndpoint se = ServiceEndpoint.CreateForProviderIdentifier(
//// opIdentifier,
//// opEndpoint,
//// new string[] { Protocol.V20.OPIdentifierServiceTypeURI },
//// 10,
//// 10);
//// // Register the Claimed Identifier that directed identity will choose so that RP
//// // discovery on that identifier can be mocked up.
//// MockHttpRequest.RegisterMockXrdsResponse(expectedClaimedId, se);
//// return new MockIdentifier(opIdentifier, new ServiceEndpoint[] { se });
////}
}
}