//-----------------------------------------------------------------------
//
// Copyright (c) Outercurve Foundation. All rights reserved.
//
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Test.OpenId.RelyingParty {
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
using DotNetOpenAuth.OpenId.Messages;
using DotNetOpenAuth.OpenId.RelyingParty;
using DotNetOpenAuth.Test.Mocks;
using NUnit.Framework;
[TestFixture]
public class AuthenticationRequestTests : OpenIdTestBase {
private readonly Realm realm = new Realm("http://localhost/rp.aspx");
private readonly Identifier claimedId = "http://claimedId";
private readonly Identifier delegatedLocalId = "http://localId";
private readonly Protocol protocol = Protocol.Default;
private Uri returnTo;
[SetUp]
public override void SetUp() {
base.SetUp();
this.returnTo = new Uri("http://localhost/rp.aspx");
}
///
/// Verifies IsDirectedIdentity returns true when appropriate.
///
[TestCase]
public void IsDirectedIdentity() {
var iauthRequest = this.CreateAuthenticationRequest(this.claimedId, this.claimedId);
Assert.IsFalse(iauthRequest.IsDirectedIdentity);
iauthRequest = this.CreateAuthenticationRequest(IdentifierSelect, IdentifierSelect);
Assert.IsTrue(iauthRequest.IsDirectedIdentity);
}
///
/// Verifies ClaimedIdentifier behavior.
///
[TestCase]
public void ClaimedIdentifier() {
var iauthRequest = this.CreateAuthenticationRequest(this.claimedId, this.delegatedLocalId);
Assert.AreEqual(this.claimedId, iauthRequest.ClaimedIdentifier);
iauthRequest = this.CreateAuthenticationRequest(IdentifierSelect, IdentifierSelect);
Assert.IsNull(iauthRequest.ClaimedIdentifier, "In directed identity mode, the ClaimedIdentifier should be null.");
}
///
/// Verifies ProviderVersion behavior.
///
[TestCase]
public void ProviderVersion() {
var authRequest = this.CreateAuthenticationRequest(this.claimedId, this.claimedId);
Assert.AreEqual(this.protocol.Version, authRequest.DiscoveryResult.Version);
}
///
/// Verifies RedirectingResponse.
///
[TestCase]
public void CreateRequestMessage() {
OpenIdCoordinator coordinator = new OpenIdCoordinator(
rp => {
Identifier id = this.GetMockIdentifier(ProtocolVersion.V20);
IAuthenticationRequest authRequest = rp.CreateRequest(id, this.realm, this.returnTo);
// Add some callback arguments
authRequest.AddCallbackArguments("a", "b");
authRequest.AddCallbackArguments(new Dictionary { { "c", "d" }, { "e", "f" } });
// Assembly an extension request.
ClaimsRequest sregRequest = new ClaimsRequest();
sregRequest.Nickname = DemandLevel.Request;
authRequest.AddExtension(sregRequest);
// Construct the actual authentication request message.
var authRequestAccessor = (AuthenticationRequest)authRequest;
var req = authRequestAccessor.CreateRequestMessageTestHook();
Assert.IsNotNull(req);
// Verify that callback arguments were included.
NameValueCollection callbackArguments = HttpUtility.ParseQueryString(req.ReturnTo.Query);
Assert.AreEqual("b", callbackArguments["a"]);
Assert.AreEqual("d", callbackArguments["c"]);
Assert.AreEqual("f", callbackArguments["e"]);
// Verify that extensions were included.
Assert.AreEqual(1, req.Extensions.Count);
Assert.IsTrue(req.Extensions.Contains(sregRequest));
},
AutoProvider);
coordinator.Run();
}
///
/// Verifies that delegating authentication requests are filtered out when configured to do so.
///
[TestCase]
public void CreateFiltersDelegatingIdentifiers() {
Identifier id = GetMockIdentifier(ProtocolVersion.V20, false, true);
var rp = CreateRelyingParty();
// First verify that delegating identifiers work
Assert.IsTrue(AuthenticationRequest.Create(id, rp, this.realm, this.returnTo, false).Any(), "The delegating identifier should have not generated any results.");
// Now disable them and try again.
rp.SecuritySettings.RejectDelegatingIdentifiers = true;
Assert.IsFalse(AuthenticationRequest.Create(id, rp, this.realm, this.returnTo, false).Any(), "The delegating identifier should have not generated any results.");
}
///
/// Verifies the Provider property returns non-null.
///
[TestCase]
public void Provider() {
var authRequest = this.CreateAuthenticationRequest(this.claimedId, this.claimedId);
Assert.IsNotNull(authRequest.Provider);
Assert.AreEqual(OPUri, authRequest.Provider.Uri);
Assert.AreEqual(this.protocol.Version, authRequest.Provider.Version);
}
///
/// Verifies that AddCallbackArguments adds query arguments to the return_to URL of the message.
///
[TestCase]
public void AddCallbackArgument() {
var authRequest = this.CreateAuthenticationRequest(this.claimedId, this.claimedId);
Assert.AreEqual(this.returnTo, authRequest.ReturnToUrl);
authRequest.AddCallbackArguments("p1", "v1");
var req = (SignedResponseRequest)authRequest.RedirectingResponse.OriginalMessage;
NameValueCollection query = HttpUtility.ParseQueryString(req.ReturnTo.Query);
Assert.AreEqual("v1", query["p1"]);
}
///
/// Verifies that AddCallbackArguments replaces pre-existing parameter values
/// rather than appending them.
///
[TestCase]
public void AddCallbackArgumentClearsPreviousArgument() {
UriBuilder returnToWithArgs = new UriBuilder(this.returnTo);
returnToWithArgs.AppendQueryArgs(new Dictionary { { "p1", "v1" } });
this.returnTo = returnToWithArgs.Uri;
var authRequest = this.CreateAuthenticationRequest(this.claimedId, this.claimedId);
authRequest.AddCallbackArguments("p1", "v2");
var req = (SignedResponseRequest)authRequest.RedirectingResponse.OriginalMessage;
NameValueCollection query = HttpUtility.ParseQueryString(req.ReturnTo.Query);
Assert.AreEqual("v2", query["p1"]);
}
///
/// Verifies identity-less checkid_* request behavior.
///
[TestCase]
public void NonIdentityRequest() {
var authRequest = this.CreateAuthenticationRequest(this.claimedId, this.claimedId);
authRequest.IsExtensionOnly = true;
Assert.IsTrue(authRequest.IsExtensionOnly);
var req = (SignedResponseRequest)authRequest.RedirectingResponse.OriginalMessage;
Assert.IsNotInstanceOf(req, "An unexpected SignedResponseRequest derived type was generated.");
}
///
/// Verifies that discovery on identifiers that serve as OP identifiers and claimed identifiers
/// only generate OP Identifier auth requests.
///
[TestCase]
public void DualIdentifierUsedOnlyAsOPIdentifierForAuthRequest() {
var rp = this.CreateRelyingParty(true);
var results = AuthenticationRequest.Create(GetMockDualIdentifier(), rp, this.realm, this.returnTo, false).ToList();
Assert.AreEqual(1, results.Count);
Assert.IsTrue(results[0].IsDirectedIdentity);
// Also test when dual identiifer support is turned on.
rp.SecuritySettings.AllowDualPurposeIdentifiers = true;
results = AuthenticationRequest.Create(GetMockDualIdentifier(), rp, this.realm, this.returnTo, false).ToList();
Assert.AreEqual(1, results.Count);
Assert.IsTrue(results[0].IsDirectedIdentity);
}
///
/// Verifies that authentication requests are generated first for OPs that respond
/// to authentication requests.
///
[TestCase, Ignore("Not yet implemented")]
public void UnresponsiveProvidersComeLast() {
// TODO: code here
Assert.Inconclusive("Not yet implemented.");
}
private AuthenticationRequest CreateAuthenticationRequest(Identifier claimedIdentifier, Identifier providerLocalIdentifier) {
ProviderEndpointDescription providerEndpoint = new ProviderEndpointDescription(OPUri, this.protocol.Version);
IdentifierDiscoveryResult endpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, providerLocalIdentifier, providerEndpoint, 10, 5);
OpenIdRelyingParty rp = this.CreateRelyingParty();
return AuthenticationRequest.CreateForTest(endpoint, this.realm, this.returnTo, rp);
}
}
}