diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2008-11-24 23:41:41 -0800 |
---|---|---|
committer | Andrew <andrewarnott@gmail.com> | 2008-11-24 23:41:41 -0800 |
commit | 3d69557f925cb7e05e85b0b99371faaf9c2109c6 (patch) | |
tree | c6bb15be6693a7d97ad87079393a340a2ef2024a | |
parent | 85c813a005a2494bb71066215de8db1d7ab056d2 (diff) | |
download | DotNetOpenAuth-3d69557f925cb7e05e85b0b99371faaf9c2109c6.zip DotNetOpenAuth-3d69557f925cb7e05e85b0b99371faaf9c2109c6.tar.gz DotNetOpenAuth-3d69557f925cb7e05e85b0b99371faaf9c2109c6.tar.bz2 |
Several hundred StyleCop fixes.
33 files changed, 917 insertions, 775 deletions
diff --git a/src/DotNetOpenAuth.Test/Hosting/AspNetHost.cs b/src/DotNetOpenAuth.Test/Hosting/AspNetHost.cs index 0bbca5e..015a00b 100644 --- a/src/DotNetOpenAuth.Test/Hosting/AspNetHost.cs +++ b/src/DotNetOpenAuth.Test/Hosting/AspNetHost.cs @@ -1,4 +1,10 @@ -namespace DotNetOpenAuth.Test.Hosting { +//----------------------------------------------------------------------- +// <copyright file="AspNetHost.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.Hosting { using System; using System.IO; using System.Net; @@ -12,8 +18,8 @@ /// Hosts a 'portable' version of the OpenIdProvider for testing itself and the /// RelyingParty against it. /// </summary> - class AspNetHost : MarshalByRefObject { - HttpHost httpHost; + internal class AspNetHost : MarshalByRefObject { + private HttpHost httpHost; public AspNetHost() { httpHost = HttpHost.CreateHost(this); diff --git a/src/DotNetOpenAuth.Test/Hosting/HttpHost.cs b/src/DotNetOpenAuth.Test/Hosting/HttpHost.cs index 9606cb7..06001ce 100644 --- a/src/DotNetOpenAuth.Test/Hosting/HttpHost.cs +++ b/src/DotNetOpenAuth.Test/Hosting/HttpHost.cs @@ -1,4 +1,10 @@ -namespace DotNetOpenAuth.Test.Hosting { +//----------------------------------------------------------------------- +// <copyright file="HttpHost.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.Hosting { using System; using System.Globalization; using System.IO; @@ -6,33 +12,33 @@ using System.Threading; class HttpHost : IDisposable { - HttpListener listener; - public int Port { get; private set; } - Thread listenerThread; - AspNetHost aspNetHost; + private HttpListener listener; + private Thread listenerThread; + private AspNetHost aspNetHost; - HttpHost(AspNetHost aspNetHost) { + private HttpHost(AspNetHost aspNetHost) { this.aspNetHost = aspNetHost; - Port = 59687; + this.Port = 59687; Random r = new Random(); tryAgain: try { - listener = new HttpListener(); - listener.Prefixes.Add(string.Format(CultureInfo.InvariantCulture, - "http://localhost:{0}/", Port)); - listener.Start(); + this.listener = new HttpListener(); + this.listener.Prefixes.Add(string.Format(CultureInfo.InvariantCulture, "http://localhost:{0}/", this.Port)); + this.listener.Start(); } catch (HttpListenerException ex) { if (ex.Message.Contains("conflicts")) { - Port += r.Next(1, 20); + this.Port += r.Next(1, 20); goto tryAgain; } throw; } - listenerThread = new Thread(processRequests); - listenerThread.Start(); + this.listenerThread = new Thread(ProcessRequests); + this.listenerThread.Start(); } + public int Port { get; private set; } + public static HttpHost CreateHost(AspNetHost aspNetHost) { return new HttpHost(aspNetHost); } @@ -40,23 +46,15 @@ public static HttpHost CreateHost(string webDirectory) { return new HttpHost(AspNetHost.CreateHost(webDirectory)); } - void processRequests() { - try { - while (true) { - var context = listener.GetContext(); - aspNetHost.BeginProcessRequest(context); - } - } catch (HttpListenerException) { - // the listener is probably being shut down - } - } - + public Uri BaseUri { - get { return new Uri("http://localhost:" + Port.ToString() + "/"); } + get { return new Uri("http://localhost:" + this.Port.ToString() + "/"); } } + public string ProcessRequest(string url) { return ProcessRequest(url, null); } + public string ProcessRequest(string url, string body) { WebRequest request = WebRequest.Create(new Uri(BaseUri, url)); if (body != null) { @@ -89,5 +87,16 @@ } #endregion + + private void ProcessRequests() { + try { + while (true) { + var context = this.listener.GetContext(); + this.aspNetHost.BeginProcessRequest(context); + } + } catch (HttpListenerException) { + // the listener is probably being shut down + } + } } } diff --git a/src/DotNetOpenAuth.Test/Hosting/TestingWorkerRequest.cs b/src/DotNetOpenAuth.Test/Hosting/TestingWorkerRequest.cs index 29f1c4c..6d1ee8d 100644 --- a/src/DotNetOpenAuth.Test/Hosting/TestingWorkerRequest.cs +++ b/src/DotNetOpenAuth.Test/Hosting/TestingWorkerRequest.cs @@ -1,10 +1,20 @@ -namespace DotNetOpenAuth.Test.Hosting { +//----------------------------------------------------------------------- +// <copyright file="TestingWorkerRequest.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.Hosting { using System; using System.IO; using System.Net; using System.Web.Hosting; - class TestingWorkerRequest : SimpleWorkerRequest { + internal class TestingWorkerRequest : SimpleWorkerRequest { + private Stream entityStream; + private HttpListenerContext context; + private TextWriter writer; + public TestingWorkerRequest(string page, string query, Stream entityStream, TextWriter writer) : base(page, query, writer) { this.entityStream = entityStream; @@ -17,74 +27,71 @@ this.writer = output; } - Stream entityStream; - HttpListenerContext context; - TextWriter writer; public override string GetFilePath() { - string filePath = context.Request.Url.LocalPath.Replace("/", "\\"); + string filePath = this.context.Request.Url.LocalPath.Replace("/", "\\"); if (filePath.EndsWith("\\", StringComparison.Ordinal)) filePath += "default.aspx"; return filePath; } public override int GetLocalPort() { - return context.Request.Url.Port; + return this.context.Request.Url.Port; } public override string GetServerName() { - return context.Request.Url.Host; + return this.context.Request.Url.Host; } public override string GetQueryString() { - return context.Request.Url.Query.TrimStart('?'); + return this.context.Request.Url.Query.TrimStart('?'); } public override string GetHttpVerbName() { - return context.Request.HttpMethod; + return this.context.Request.HttpMethod; } public override string GetLocalAddress() { - return context.Request.LocalEndPoint.Address.ToString(); + return this.context.Request.LocalEndPoint.Address.ToString(); } public override string GetHttpVersion() { return "HTTP/1.1"; } public override string GetProtocol() { - return context.Request.Url.Scheme; + return this.context.Request.Url.Scheme; } public override string GetRawUrl() { - return context.Request.RawUrl; + return this.context.Request.RawUrl; } public override int GetTotalEntityBodyLength() { - return (int)context.Request.ContentLength64; + return (int)this.context.Request.ContentLength64; } public override string GetKnownRequestHeader(int index) { - return context.Request.Headers[GetKnownRequestHeaderName(index)]; + return this.context.Request.Headers[GetKnownRequestHeaderName(index)]; } public override string GetUnknownRequestHeader(string name) { - return context.Request.Headers[name]; + return this.context.Request.Headers[name]; } public override bool IsEntireEntityBodyIsPreloaded() { return false; } public override int ReadEntityBody(byte[] buffer, int size) { - return entityStream.Read(buffer, 0, size); + return this.entityStream.Read(buffer, 0, size); } public override int ReadEntityBody(byte[] buffer, int offset, int size) { - return entityStream.Read(buffer, offset, size); + return this.entityStream.Read(buffer, offset, size); } public override void SendCalculatedContentLength(int contentLength) { - context.Response.ContentLength64 = contentLength; + this.context.Response.ContentLength64 = contentLength; } public override void SendStatus(int statusCode, string statusDescription) { - if (context != null) { - context.Response.StatusCode = statusCode; - context.Response.StatusDescription = statusDescription; + if (this.context != null) { + this.context.Response.StatusCode = statusCode; + this.context.Response.StatusDescription = statusDescription; } } public override void SendKnownResponseHeader(int index, string value) { - if (context != null) { - context.Response.Headers[(HttpResponseHeader)index] = value; + if (this.context != null) { + this.context.Response.Headers[(HttpResponseHeader)index] = value; } } public override void SendUnknownResponseHeader(string name, string value) { - if (context != null) { - context.Response.Headers[name] = value; + if (this.context != null) { + this.context.Response.Headers[name] = value; } } } diff --git a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs index 1473bf0..08e4473 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs @@ -26,27 +26,8 @@ return mock; } - private MockHttpRequest(IDirectSslWebRequestHandler mockHandler) { - ErrorUtilities.VerifyArgumentNotNull(mockHandler, "mockHandler"); - this.MockWebRequestHandler = mockHandler; - } - internal IDirectSslWebRequestHandler MockWebRequestHandler { get; private set; } - private DirectWebResponse GetMockResponse(HttpWebRequest request) { - DirectWebResponse response; - if (this.registeredMockResponses.TryGetValue(request.RequestUri, out response)) { - // reset response stream position so this response can be reused on a subsequent request. - response.ResponseStream.Seek(0, SeekOrigin.Begin); - return response; - } else { - ////Assert.Fail("Unexpected HTTP request: {0}", uri); - Logger.WarnFormat("Unexpected HTTP request: {0}", request.RequestUri); - return new DirectWebResponse(request.RequestUri, request.RequestUri, new WebHeaderCollection(), HttpStatusCode.NotFound, - "text/html", null, new MemoryStream()); - } - } - internal void RegisterMockResponse(DirectWebResponse response) { if (response == null) throw new ArgumentNullException("response"); if (registeredMockResponses.ContainsKey(response.RequestUri)) { @@ -134,6 +115,7 @@ RegisterMockResponse(respondingUri, ContentTypes.Xrds, xrds.ToString()); } + internal void RegisterMockXrdsResponse(UriIdentifier directedIdentityAssignedIdentifier, ServiceEndpoint providerEndpoint) { ServiceEndpoint identityEndpoint = ServiceEndpoint.CreateForClaimedIdentifier( directedIdentityAssignedIdentifier, @@ -144,11 +126,13 @@ 10); RegisterMockXrdsResponse(identityEndpoint); } + internal Identifier RegisterMockXrdsResponse(string embeddedResourcePath) { UriIdentifier id = TestSupport.GetFullUrl(embeddedResourcePath); RegisterMockResponse(id, "application/xrds+xml", TestSupport.LoadEmbeddedFile(embeddedResourcePath)); return id; } + internal void RegisterMockRPDiscovery() { Uri rpRealmUri = TestSupport.Realm.UriWithWildcardChangedToWww; @@ -179,5 +163,24 @@ redirectionHeaders, HttpStatusCode.Redirect, null, null, new MemoryStream()); RegisterMockResponse(response); } + + private MockHttpRequest(IDirectSslWebRequestHandler mockHandler) { + ErrorUtilities.VerifyArgumentNotNull(mockHandler, "mockHandler"); + this.MockWebRequestHandler = mockHandler; + } + + private DirectWebResponse GetMockResponse(HttpWebRequest request) { + DirectWebResponse response; + if (this.registeredMockResponses.TryGetValue(request.RequestUri, out response)) { + // reset response stream position so this response can be reused on a subsequent request. + response.ResponseStream.Seek(0, SeekOrigin.Begin); + return response; + } else { + ////Assert.Fail("Unexpected HTTP request: {0}", uri); + Logger.WarnFormat("Unexpected HTTP request: {0}", request.RequestUri); + return new DirectWebResponse(request.RequestUri, request.RequestUri, new WebHeaderCollection(), HttpStatusCode.NotFound, + "text/html", null, new MemoryStream()); + } + } } } diff --git a/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs b/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs index 2b7a7a9..007a1d6 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs @@ -16,10 +16,10 @@ using DotNetOpenAuth.Messaging; /// to perform discovery, it returns a preset list of sevice endpoints to avoid /// having a dependency on a hosted web site to actually perform discovery on. /// </summary> - class MockIdentifier : Identifier { - IEnumerable<ServiceEndpoint> endpoints; - MockHttpRequest mockHttpRequest; - Identifier wrappedIdentifier; + internal class MockIdentifier : Identifier { + private IEnumerable<ServiceEndpoint> endpoints; + private MockHttpRequest mockHttpRequest; + private Identifier wrappedIdentifier; public MockIdentifier(Identifier wrappedIdentifier, MockHttpRequest mockHttpRequest, IEnumerable<ServiceEndpoint> endpoints) : base(false) { @@ -37,7 +37,7 @@ using DotNetOpenAuth.Messaging; } internal override IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler) { - return endpoints; + return this.endpoints; } internal override Identifier TrimFragment() { @@ -54,15 +54,15 @@ using DotNetOpenAuth.Messaging; } public override string ToString() { - return wrappedIdentifier.ToString(); + return this.wrappedIdentifier.ToString(); } public override bool Equals(object obj) { - return wrappedIdentifier.Equals(obj); + return this.wrappedIdentifier.Equals(obj); } public override int GetHashCode() { - return wrappedIdentifier.GetHashCode(); + return this.wrappedIdentifier.GetHashCode(); } } } diff --git a/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs b/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs index 941aa70..7bc60c7 100644 --- a/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs @@ -1,21 +1,27 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using DotNetOpenAuth.OpenId; +//----------------------------------------------------------------------- +// <copyright file="IdentifierTests.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- namespace DotNetOpenAuth.Test.OpenId { + using System; + using System.Collections.Generic; + using System.Linq; + using DotNetOpenAuth.OpenId; + using Microsoft.VisualStudio.TestTools.UnitTesting; + [TestClass] public class IdentifierTests { - string uri = "http://www.yahoo.com/"; - string uriNoScheme = "www.yahoo.com"; - string uriHttps = "https://www.yahoo.com/"; - string xri = "=arnott*andrew"; + private string uri = "http://www.yahoo.com/"; + private string uriNoScheme = "www.yahoo.com"; + private string uriHttps = "https://www.yahoo.com/"; + private string xri = "=arnott*andrew"; [TestMethod] public void Parse() { - Assert.IsInstanceOfType(Identifier.Parse(uri), typeof(UriIdentifier)); - Assert.IsInstanceOfType(Identifier.Parse(xri), typeof(XriIdentifier)); + Assert.IsInstanceOfType(Identifier.Parse(this.uri), typeof(UriIdentifier)); + Assert.IsInstanceOfType(Identifier.Parse(this.xri), typeof(XriIdentifier)); } /// <summary> @@ -40,9 +46,9 @@ namespace DotNetOpenAuth.Test.OpenId { [TestMethod] public void ParseEndUserSuppliedUriIdentifier() { // verify a fully-qualified Uri - var id = Identifier.Parse(uri); + var id = Identifier.Parse(this.uri); Assert.IsInstanceOfType(id, typeof(UriIdentifier)); - Assert.AreEqual(uri, ((UriIdentifier)id).Uri.AbsoluteUri); + Assert.AreEqual(this.uri, ((UriIdentifier)id).Uri.AbsoluteUri); // verify an HTTPS Uri id = Identifier.Parse(uriHttps); Assert.IsInstanceOfType(id, typeof(UriIdentifier)); @@ -50,7 +56,7 @@ namespace DotNetOpenAuth.Test.OpenId { // verify that if the scheme is missing it is added automatically id = Identifier.Parse(uriNoScheme); Assert.IsInstanceOfType(id, typeof(UriIdentifier)); - Assert.AreEqual(uri, ((UriIdentifier)id).Uri.AbsoluteUri); + Assert.AreEqual(this.uri, ((UriIdentifier)id).Uri.AbsoluteUri); } [TestMethod, ExpectedException(typeof(ArgumentNullException))] diff --git a/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs b/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs index 82cf976..7deafef 100644 --- a/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs +++ b/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs @@ -6,11 +6,11 @@ namespace DotNetOpenAuth.Test.OpenId { using DotNetOpenAuth.Configuration; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Provider; using DotNetOpenAuth.OpenId.RelyingParty; - using Microsoft.VisualStudio.TestTools.UnitTesting; using DotNetOpenAuth.Test.Mocks; - using DotNetOpenAuth.Messaging; + using Microsoft.VisualStudio.TestTools.UnitTesting; public class OpenIdTestBase : TestBase { protected RelyingPartySecuritySettings RelyingPartySecuritySettings { get; private set; } diff --git a/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs b/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs index 4e742dc..4470b99 100644 --- a/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs +++ b/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs @@ -7,29 +7,19 @@ namespace DotNetOpenAuth.Test.OpenId { using System; using System.Collections.Generic; - using System.Collections.Specialized; - using System.Diagnostics; using System.IO; using System.Reflection; - using System.Web; - using DotNetOpenAuth; + 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; - using IProviderAssociationStore = DotNetOpenAuth.OpenId.IAssociationStore<DotNetOpenAuth.OpenId.AssociationRelyingPartyType>; - using ProviderMemoryStore = DotNetOpenAuth.OpenId.AssociationMemoryStore<DotNetOpenAuth.OpenId.AssociationRelyingPartyType>; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using DotNetOAuth.Test.OpenId.UI; - using DotNetOpenAuth.Messaging; public class TestSupport { public static readonly string TestWebDirectory = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), @"..\..\src\DotNetOpenId.TestWeb")); public const string HostTestPage = "HostTest.aspx"; - const string identityPage = "IdentityEndpoint.aspx"; - const string directedIdentityPage = "DirectedIdentityEndpoint.aspx"; public const string ProviderPage = "ProviderEndpoint.aspx"; public const string DirectedProviderEndpoint = "DirectedProviderEndpoint.aspx"; public const string MobileConsumerPage = "RelyingPartyMobile.aspx"; @@ -42,6 +32,8 @@ namespace DotNetOpenAuth.Test.OpenId { get { return new Realm(TestSupport.GetFullUrl(TestSupport.ConsumerPage).AbsoluteUri); } } public readonly static ILog Logger = LogManager.GetLogger("DotNetOpenId.Test"); + private const string IdentityPage = "IdentityEndpoint.aspx"; + private const string DirectedIdentityPage = "DirectedIdentityEndpoint.aspx"; public enum Scenarios { // Authentication test scenarios @@ -61,82 +53,24 @@ namespace DotNetOpenAuth.Test.OpenId { ExtensionPartialCooperation, } - ////internal static UriIdentifier GetOPIdentityUrl(Scenarios scenario, bool useSsl) { - //// var args = new Dictionary<string, string> { - //// { "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) { - return new UriIdentifier(GetFullUrl("/" + identityPage, new Dictionary<string, string> { - { "user", scenario.ToString() }, - { "version", providerVersion.ToString() }, - }, useSsl)); - } - ////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<string, string> { - //// { "user", scenario.ToString() }, - //// { "version", providerVersion.ToString() }, - ////}, useSsl)); - ////} 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)); } - 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) { - return ServiceEndpoint.CreateForClaimedIdentifier( - GetIdentityUrl(scenario, providerVersion, useSsl), - GetDelegateUrl(scenario, useSsl), - GetFullUrl("/" + ProviderPage, null, useSsl), - new string[] { Protocol.Lookup(providerVersion).ClaimedIdentifierServiceTypeURI }, - servicePriority, - 10); - } - ////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<string, string> { - //// { "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 }); - ////} + public static Uri GetFullUrl(string url) { return GetFullUrl(url, null, false); } + public static Uri GetFullUrl(string url, string key, object value) { return GetFullUrl(url, new Dictionary<string, string> { { key, value.ToString() }, }, false); } + public static Uri GetFullUrl(string url, IDictionary<string, string> args, bool useSsl) { Uri defaultUriBase = new Uri(useSsl ? "https://localhost/" : "http://localhost/"); Uri baseUri = UITestSupport.Host != null ? UITestSupport.Host.BaseUri : defaultUriBase; @@ -154,12 +88,60 @@ namespace DotNetOpenAuth.Test.OpenId { if (!path.StartsWith("/")) path = "/" + path; path = "DotNetOpenAuth.Test.OpenId" + path.Replace('/', '.'); Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(path); - if (resource == null) throw new ArgumentException(); + 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<string, string> { + //// { "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) { + return new UriIdentifier(GetFullUrl("/" + IdentityPage, new Dictionary<string, string> { + { "user", scenario.ToString() }, + { "version", providerVersion.ToString() }, + }, 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) { + return ServiceEndpoint.CreateForClaimedIdentifier( + GetIdentityUrl(scenario, providerVersion, useSsl), + GetDelegateUrl(scenario, useSsl), + GetFullUrl("/" + ProviderPage, null, useSsl), + new string[] { Protocol.Lookup(providerVersion).ClaimedIdentifierServiceTypeURI }, + servicePriority, + 10); + } + + ////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<string, string> { + //// { "user", scenario.ToString() }, + //// { "version", providerVersion.ToString() }, + ////}, useSsl)); + ////} + ////internal static IRelyingPartyApplicationStore RelyingPartyStore; ////internal static IProviderAssociationStore ProviderStore; /////// <summary> @@ -360,5 +342,27 @@ namespace DotNetOpenAuth.Test.OpenId { //// 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<string, string> { + //// { "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 }); + ////} } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth.Test/OpenId/UI/UITestSupport.cs b/src/DotNetOpenAuth.Test/OpenId/UI/UITestSupport.cs index da18fa9..92008ad 100644 --- a/src/DotNetOpenAuth.Test/OpenId/UI/UITestSupport.cs +++ b/src/DotNetOpenAuth.Test/OpenId/UI/UITestSupport.cs @@ -1,4 +1,10 @@ -namespace DotNetOAuth.Test.OpenId.UI { +//----------------------------------------------------------------------- +// <copyright file="UITestSupport.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOAuth.Test.OpenId.UI { using DotNetOpenAuth.Test.Hosting; ////[SetUpFixture] diff --git a/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs b/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs index f9b54b4..1dfb173 100644 --- a/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs @@ -9,17 +9,16 @@ namespace DotNetOpenAuth.Test.OpenId { using System.Linq; using System.Net; using System.Web; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.RelyingParty; - using DotNetOpenAuth.Test.Mocks; using Microsoft.VisualStudio.TestTools.UnitTesting; - using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.Messaging; [TestClass] public class UriIdentifierTests : OpenIdTestBase { - string goodUri = "http://blog.nerdbank.net/"; - string relativeUri = "host/path"; - string badUri = "som%-)830w8vf/?.<>,ewackedURI"; + private string goodUri = "http://blog.nerdbank.net/"; + private string relativeUri = "host/path"; + private string badUri = "som%-)830w8vf/?.<>,ewackedURI"; [TestInitialize] public override void SetUp() { @@ -43,13 +42,13 @@ namespace DotNetOpenAuth.Test.OpenId { [TestMethod, ExpectedException(typeof(UriFormatException))] public void CtorBadUri() { - new UriIdentifier(badUri); + new UriIdentifier(this.badUri); } [TestMethod] public void CtorGoodUri() { - var uri = new UriIdentifier(goodUri); - Assert.AreEqual(new Uri(goodUri), uri.Uri); + var uri = new UriIdentifier(this.goodUri); + Assert.AreEqual(new Uri(this.goodUri), uri.Uri); Assert.IsFalse(uri.SchemeImplicitlyPrepended); Assert.IsFalse(uri.IsDiscoverySecureEndToEnd); } @@ -102,8 +101,8 @@ namespace DotNetOpenAuth.Test.OpenId { [TestMethod] public void IsValid() { - Assert.IsTrue(UriIdentifier.IsValidUri(goodUri)); - Assert.IsFalse(UriIdentifier.IsValidUri(badUri)); + Assert.IsTrue(UriIdentifier.IsValidUri(this.goodUri)); + Assert.IsFalse(UriIdentifier.IsValidUri(this.badUri)); Assert.IsTrue(UriIdentifier.IsValidUri(relativeUri), "URL lacking http:// prefix should have worked anyway."); } @@ -117,17 +116,17 @@ namespace DotNetOpenAuth.Test.OpenId { [TestMethod] public void ToStringTest() { - Assert.AreEqual(goodUri, new UriIdentifier(goodUri).ToString()); + Assert.AreEqual(this.goodUri, new UriIdentifier(this.goodUri).ToString()); } [TestMethod] public void EqualsTest() { - Assert.AreEqual(new UriIdentifier(goodUri), new UriIdentifier(goodUri)); + Assert.AreEqual(new UriIdentifier(this.goodUri), new UriIdentifier(this.goodUri)); // This next test is an interesting side-effect of passing off to Uri.Equals. But it's probably ok. - Assert.AreEqual(new UriIdentifier(goodUri), new UriIdentifier(goodUri + "#frag")); - Assert.AreNotEqual(new UriIdentifier(goodUri), new UriIdentifier(goodUri + "a")); - Assert.AreNotEqual(null, new UriIdentifier(goodUri)); - Assert.AreEqual(goodUri, new UriIdentifier(goodUri)); + Assert.AreEqual(new UriIdentifier(this.goodUri), new UriIdentifier(this.goodUri + "#frag")); + Assert.AreNotEqual(new UriIdentifier(this.goodUri), new UriIdentifier(this.goodUri + "a")); + Assert.AreNotEqual(null, new UriIdentifier(this.goodUri)); + Assert.AreEqual(this.goodUri, new UriIdentifier(this.goodUri)); } [TestMethod] @@ -140,113 +139,54 @@ namespace DotNetOpenAuth.Test.OpenId { Assert.AreEqual(Uri.EscapeUriString(unicodeUrl), id.ToString()); } - void discover(string url, ProtocolVersion version, Identifier expectedLocalId, bool expectSreg, bool useRedirect) { - discover(url, version, expectedLocalId, expectSreg, useRedirect, null); - } - void discover(string url, ProtocolVersion version, Identifier expectedLocalId, bool expectSreg, bool useRedirect, WebHeaderCollection headers) { - Protocol protocol = Protocol.Lookup(version); - UriIdentifier claimedId = TestSupport.GetFullUrl(url); - UriIdentifier userSuppliedIdentifier = TestSupport.GetFullUrl( - "Discovery/htmldiscovery/redirect.aspx?target=" + url); - if (expectedLocalId == null) expectedLocalId = claimedId; - Identifier idToDiscover = useRedirect ? userSuppliedIdentifier : claimedId; - - string contentType; - if (url.EndsWith("html")) { - contentType = "text/html"; - } else if (url.EndsWith("xml")) { - contentType = "application/xrds+xml"; - } else { - throw new InvalidOperationException(); - } - this.mockResponder.RegisterMockResponse(new Uri(idToDiscover), claimedId, contentType, - headers ?? new WebHeaderCollection(), TestSupport.LoadEmbeddedFile(url)); - - ServiceEndpoint se = idToDiscover.Discover(this.requestHandler).FirstOrDefault(); - Assert.IsNotNull(se, url + " failed to be discovered."); - Assert.AreSame(protocol, se.Protocol); - Assert.AreEqual(claimedId, se.ClaimedIdentifier); - Assert.AreEqual(expectedLocalId, se.ProviderLocalIdentifier); - Assert.AreEqual(expectSreg ? 2 : 1, se.ProviderSupportedServiceTypeUris.Length); - Assert.IsTrue(Array.IndexOf(se.ProviderSupportedServiceTypeUris, protocol.ClaimedIdentifierServiceTypeURI) >= 0); - - // TODO: re-enable this line once extensions support is added back in. - ////Assert.AreEqual(expectSreg, se.IsExtensionSupported(new ClaimsRequest())); - } - void discoverXrds(string page, ProtocolVersion version, Identifier expectedLocalId) { - discoverXrds(page, version, expectedLocalId, null); - } - void discoverXrds(string page, ProtocolVersion version, Identifier expectedLocalId, WebHeaderCollection headers) { - if (!page.Contains(".")) page += ".xml"; - discover("/Discovery/xrdsdiscovery/" + page, version, expectedLocalId, true, false, headers); - discover("/Discovery/xrdsdiscovery/" + page, version, expectedLocalId, true, true, headers); - } - void discoverHtml(string page, ProtocolVersion version, Identifier expectedLocalId, bool useRedirect) { - discover("/Discovery/htmldiscovery/" + page, version, expectedLocalId, false, useRedirect); - } - void discoverHtml(string scenario, ProtocolVersion version, Identifier expectedLocalId) { - string page = scenario + ".html"; - discoverHtml(page, version, expectedLocalId, false); - discoverHtml(page, version, expectedLocalId, true); - } - void failDiscover(string url) { - UriIdentifier userSuppliedId = TestSupport.GetFullUrl(url); - - this.mockResponder.RegisterMockResponse(new Uri(userSuppliedId), userSuppliedId, "text/html", - TestSupport.LoadEmbeddedFile(url)); - - Assert.AreEqual(0, userSuppliedId.Discover(this.requestHandler).Count()); // ... but that no endpoint info is discoverable - } - void failDiscoverHtml(string scenario) { - failDiscover("/Discovery/htmldiscovery/" + scenario + ".html"); - } - void failDiscoverXrds(string scenario) { - failDiscover("/Discovery/xrdsdiscovery/" + scenario + ".xml"); - } [TestMethod] public void HtmlDiscover_11() { - discoverHtml("html10prov", ProtocolVersion.V11, null); - discoverHtml("html10both", ProtocolVersion.V11, "http://c/d"); - failDiscoverHtml("html10del"); + this.DiscoverHtml("html10prov", ProtocolVersion.V11, null); + this.DiscoverHtml("html10both", ProtocolVersion.V11, "http://c/d"); + this.FailDiscoverHtml("html10del"); } + [TestMethod] public void HtmlDiscover_20() { - discoverHtml("html20prov", ProtocolVersion.V20, null); - discoverHtml("html20both", ProtocolVersion.V20, "http://c/d"); - failDiscoverHtml("html20del"); - discoverHtml("html2010", ProtocolVersion.V20, "http://c/d"); - discoverHtml("html1020", ProtocolVersion.V20, "http://c/d"); - discoverHtml("html2010combinedA", ProtocolVersion.V20, "http://c/d"); - discoverHtml("html2010combinedB", ProtocolVersion.V20, "http://c/d"); - discoverHtml("html2010combinedC", ProtocolVersion.V20, "http://c/d"); - failDiscoverHtml("html20relative"); + this.DiscoverHtml("html20prov", ProtocolVersion.V20, null); + this.DiscoverHtml("html20both", ProtocolVersion.V20, "http://c/d"); + this.FailDiscoverHtml("html20del"); + this.DiscoverHtml("html2010", ProtocolVersion.V20, "http://c/d"); + this.DiscoverHtml("html1020", ProtocolVersion.V20, "http://c/d"); + this.DiscoverHtml("html2010combinedA", ProtocolVersion.V20, "http://c/d"); + this.DiscoverHtml("html2010combinedB", ProtocolVersion.V20, "http://c/d"); + this.DiscoverHtml("html2010combinedC", ProtocolVersion.V20, "http://c/d"); + this.FailDiscoverHtml("html20relative"); } + [TestMethod] public void XrdsDiscoveryFromHead() { this.mockResponder.RegisterMockResponse(new Uri("http://localhost/xrds1020.xml"), "application/xrds+xml", TestSupport.LoadEmbeddedFile("/Discovery/xrdsdiscovery/xrds1020.xml")); - discoverXrds("XrdsReferencedInHead.html", ProtocolVersion.V10, null); + this.DiscoverXrds("XrdsReferencedInHead.html", ProtocolVersion.V10, null); } + [TestMethod] public void XrdsDiscoveryFromHttpHeader() { WebHeaderCollection headers = new WebHeaderCollection(); headers.Add("X-XRDS-Location", TestSupport.GetFullUrl("http://localhost/xrds1020.xml").AbsoluteUri); - this.mockResponder.RegisterMockResponse(new Uri("http://localhost/xrds1020.xml"), - "application/xrds+xml", TestSupport.LoadEmbeddedFile("/Discovery/xrdsdiscovery/xrds1020.xml")); - discoverXrds("XrdsReferencedInHttpHeader.html", ProtocolVersion.V10, null, headers); + this.mockResponder.RegisterMockResponse(new Uri("http://localhost/xrds1020.xml"), "application/xrds+xml", TestSupport.LoadEmbeddedFile("/Discovery/xrdsdiscovery/xrds1020.xml")); + this.DiscoverXrds("XrdsReferencedInHttpHeader.html", ProtocolVersion.V10, null, headers); } + [TestMethod] public void XrdsDirectDiscovery_10() { - failDiscoverXrds("xrds-irrelevant"); - discoverXrds("xrds10", ProtocolVersion.V10, null); - discoverXrds("xrds11", ProtocolVersion.V11, null); - discoverXrds("xrds1020", ProtocolVersion.V10, null); + this.FailDiscoverXrds("xrds-irrelevant"); + this.DiscoverXrds("xrds10", ProtocolVersion.V10, null); + this.DiscoverXrds("xrds11", ProtocolVersion.V11, null); + this.DiscoverXrds("xrds1020", ProtocolVersion.V10, null); } + [TestMethod] public void XrdsDirectDiscovery_20() { - discoverXrds("xrds20", ProtocolVersion.V20, null); - discoverXrds("xrds2010a", ProtocolVersion.V20, null); - discoverXrds("xrds2010b", ProtocolVersion.V20, null); + this.DiscoverXrds("xrds20", ProtocolVersion.V20, null); + this.DiscoverXrds("xrds2010a", ProtocolVersion.V20, null); + this.DiscoverXrds("xrds2010b", ProtocolVersion.V20, null); } [TestMethod] @@ -354,8 +294,7 @@ namespace DotNetOpenAuth.Test.OpenId { var insecureXrdsSource = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.mockResponder, ProtocolVersion.V20, false); Uri secureClaimedUri = TestSupport.GetFullUrl("/secureId", null, true); - string html = string.Format("<html><head><meta http-equiv='X-XRDS-Location' content='{0}'/></head><body></body></html>", - insecureXrdsSource); + string html = string.Format("<html><head><meta http-equiv='X-XRDS-Location' content='{0}'/></head><body></body></html>", insecureXrdsSource); this.mockResponder.RegisterMockResponse(secureClaimedUri, "text/html", html); Identifier userSuppliedIdentifier = new UriIdentifier(secureClaimedUri, true); @@ -406,5 +345,77 @@ namespace DotNetOpenAuth.Test.OpenId { this.mockResponder.RegisterMockXrdsResponse(secureClaimedId, new ServiceEndpoint[] { insecureEndpoint, secureEndpoint }); Assert.AreEqual(secureEndpoint.ProviderLocalIdentifier, secureClaimedId.Discover(this.requestHandler).Single().ProviderLocalIdentifier); } + + private void Discover(string url, ProtocolVersion version, Identifier expectedLocalId, bool expectSreg, bool useRedirect) { + this.Discover(url, version, expectedLocalId, expectSreg, useRedirect, null); + } + + private void Discover(string url, ProtocolVersion version, Identifier expectedLocalId, bool expectSreg, bool useRedirect, WebHeaderCollection headers) { + Protocol protocol = Protocol.Lookup(version); + UriIdentifier claimedId = TestSupport.GetFullUrl(url); + UriIdentifier userSuppliedIdentifier = TestSupport.GetFullUrl( + "Discovery/htmldiscovery/redirect.aspx?target=" + url); + if (expectedLocalId == null) { + expectedLocalId = claimedId; + } + Identifier idToDiscover = useRedirect ? userSuppliedIdentifier : claimedId; + + string contentType; + if (url.EndsWith("html")) { + contentType = "text/html"; + } else if (url.EndsWith("xml")) { + contentType = "application/xrds+xml"; + } else { + throw new InvalidOperationException(); + } + this.mockResponder.RegisterMockResponse(new Uri(idToDiscover), claimedId, contentType, headers ?? new WebHeaderCollection(), TestSupport.LoadEmbeddedFile(url)); + + ServiceEndpoint se = idToDiscover.Discover(this.requestHandler).FirstOrDefault(); + Assert.IsNotNull(se, url + " failed to be discovered."); + Assert.AreSame(protocol, se.Protocol); + Assert.AreEqual(claimedId, se.ClaimedIdentifier); + Assert.AreEqual(expectedLocalId, se.ProviderLocalIdentifier); + Assert.AreEqual(expectSreg ? 2 : 1, se.ProviderSupportedServiceTypeUris.Length); + Assert.IsTrue(Array.IndexOf(se.ProviderSupportedServiceTypeUris, protocol.ClaimedIdentifierServiceTypeURI) >= 0); + + // TODO: re-enable this line once extensions support is added back in. + ////Assert.AreEqual(expectSreg, se.IsExtensionSupported(new ClaimsRequest())); + } + + private void DiscoverXrds(string page, ProtocolVersion version, Identifier expectedLocalId) { + this.DiscoverXrds(page, version, expectedLocalId, null); + } + + private void DiscoverXrds(string page, ProtocolVersion version, Identifier expectedLocalId, WebHeaderCollection headers) { + if (!page.Contains(".")) page += ".xml"; + this.Discover("/Discovery/xrdsdiscovery/" + page, version, expectedLocalId, true, false, headers); + this.Discover("/Discovery/xrdsdiscovery/" + page, version, expectedLocalId, true, true, headers); + } + + private void DiscoverHtml(string page, ProtocolVersion version, Identifier expectedLocalId, bool useRedirect) { + this.Discover("/Discovery/htmldiscovery/" + page, version, expectedLocalId, false, useRedirect); + } + + private void DiscoverHtml(string scenario, ProtocolVersion version, Identifier expectedLocalId) { + string page = scenario + ".html"; + this.DiscoverHtml(page, version, expectedLocalId, false); + this.DiscoverHtml(page, version, expectedLocalId, true); + } + + private void FailDiscover(string url) { + UriIdentifier userSuppliedId = TestSupport.GetFullUrl(url); + + this.mockResponder.RegisterMockResponse(new Uri(userSuppliedId), userSuppliedId, "text/html", TestSupport.LoadEmbeddedFile(url)); + + Assert.AreEqual(0, userSuppliedId.Discover(this.requestHandler).Count()); // ... but that no endpoint info is discoverable + } + + private void FailDiscoverHtml(string scenario) { + this.FailDiscover("/Discovery/htmldiscovery/" + scenario + ".html"); + } + + private void FailDiscoverXrds(string scenario) { + this.FailDiscover("/Discovery/xrdsdiscovery/" + scenario + ".xml"); + } } } diff --git a/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs b/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs index 5f85f28..4d349ff 100644 --- a/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs @@ -1,17 +1,21 @@ -namespace DotNetOpenAuth.Test.OpenId { +//----------------------------------------------------------------------- +// <copyright file="XriIdentifierTests.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.OpenId { using System; using System.Collections.Generic; using System.Linq; + using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.RelyingParty; - using DotNetOpenAuth.Test.Mocks; using Microsoft.VisualStudio.TestTools.UnitTesting; - using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.Messaging; [TestClass] public class XriIdentifierTests : OpenIdTestBase { - string goodXri = "=Andrew*Arnott"; - string badXri = "some\\wacky%^&*()non-XRI"; + private string goodXri = "=Andrew*Arnott"; + private string badXri = "some\\wacky%^&*()non-XRI"; [TestInitialize] public override void SetUp() { @@ -30,29 +34,29 @@ [TestMethod, ExpectedException(typeof(FormatException))] public void CtorBadXri() { - new XriIdentifier(badXri); + new XriIdentifier(this.badXri); } [TestMethod] public void CtorGoodXri() { - var xri = new XriIdentifier(goodXri); - Assert.AreEqual(goodXri, xri.OriginalXri); - Assert.AreEqual(goodXri, xri.CanonicalXri); // assumes 'goodXri' is canonical already + var xri = new XriIdentifier(this.goodXri); + Assert.AreEqual(this.goodXri, xri.OriginalXri); + Assert.AreEqual(this.goodXri, xri.CanonicalXri); // assumes 'goodXri' is canonical already Assert.IsFalse(xri.IsDiscoverySecureEndToEnd); } [TestMethod] public void CtorGoodXriSecure() { - var xri = new XriIdentifier(goodXri, true); - Assert.AreEqual(goodXri, xri.OriginalXri); - Assert.AreEqual(goodXri, xri.CanonicalXri); // assumes 'goodXri' is canonical already + var xri = new XriIdentifier(this.goodXri, true); + Assert.AreEqual(this.goodXri, xri.OriginalXri); + Assert.AreEqual(this.goodXri, xri.CanonicalXri); // assumes 'goodXri' is canonical already Assert.IsTrue(xri.IsDiscoverySecureEndToEnd); } [TestMethod] public void IsValid() { - Assert.IsTrue(XriIdentifier.IsValidXri(goodXri)); - Assert.IsFalse(XriIdentifier.IsValidXri(badXri)); + Assert.IsTrue(XriIdentifier.IsValidXri(this.goodXri)); + Assert.IsFalse(XriIdentifier.IsValidXri(this.badXri)); } /// <summary> @@ -60,40 +64,28 @@ /// </summary> [TestMethod] public void StripXriScheme() { - var xri = new XriIdentifier("xri://" + goodXri); - Assert.AreEqual("xri://" + goodXri, xri.OriginalXri); - Assert.AreEqual(goodXri, xri.CanonicalXri); + var xri = new XriIdentifier("xri://" + this.goodXri); + Assert.AreEqual("xri://" + this.goodXri, xri.OriginalXri); + Assert.AreEqual(this.goodXri, xri.CanonicalXri); } [TestMethod] public void TrimFragment() { - Identifier xri = new XriIdentifier(goodXri); + Identifier xri = new XriIdentifier(this.goodXri); Assert.AreSame(xri, xri.TrimFragment()); } [TestMethod] public void ToStringTest() { - Assert.AreEqual(goodXri, new XriIdentifier(goodXri).ToString()); + Assert.AreEqual(this.goodXri, new XriIdentifier(this.goodXri).ToString()); } [TestMethod] public void EqualsTest() { - Assert.AreEqual(new XriIdentifier(goodXri), new XriIdentifier(goodXri)); - Assert.AreNotEqual(new XriIdentifier(goodXri), new XriIdentifier(goodXri + "a")); - Assert.AreNotEqual(null, new XriIdentifier(goodXri)); - Assert.AreEqual(goodXri, new XriIdentifier(goodXri)); - } - - private ServiceEndpoint verifyCanonicalId(Identifier iname, string expectedClaimedIdentifier) { - ServiceEndpoint se = iname.Discover(this.requestHandler).FirstOrDefault(); - if (expectedClaimedIdentifier != null) { - Assert.IsNotNull(se); - Assert.AreEqual(expectedClaimedIdentifier, se.ClaimedIdentifier.ToString(), "i-name {0} discovery resulted in unexpected CanonicalId", iname); - Assert.IsTrue(se.ProviderSupportedServiceTypeUris.Length > 0); - } else { - Assert.IsNull(se); - } - return se; + Assert.AreEqual(new XriIdentifier(this.goodXri), new XriIdentifier(this.goodXri)); + Assert.AreNotEqual(new XriIdentifier(this.goodXri), new XriIdentifier(this.goodXri + "a")); + Assert.AreNotEqual(null, new XriIdentifier(this.goodXri)); + Assert.AreEqual(this.goodXri, new XriIdentifier(this.goodXri)); } [TestMethod] @@ -136,7 +128,7 @@ this.mockResponder.RegisterMockXrdsResponses(mocks); string expectedCanonicalId = "=!9B72.7DD1.50A9.5CCD"; - ServiceEndpoint se = verifyCanonicalId("=Arnott", expectedCanonicalId); + ServiceEndpoint se = this.VerifyCanonicalId("=Arnott", expectedCanonicalId); Assert.AreEqual(Protocol.V10, se.Protocol); Assert.AreEqual("http://1id.com/sso", se.ProviderEndpoint.ToString()); Assert.AreEqual(se.ClaimedIdentifier, se.ProviderLocalIdentifier); @@ -366,11 +358,11 @@ uEyb50RJ7DWmXctSC0b3eymZ2lSXxAWNOsNy { "https://xri.net/@llli*area*canada.unattached*ada?_xrd_r=application/xrd%2Bxml;sep=false", llliAreaCanadaUnattachedAdaResponse }, { "https://xri.net/=Web?_xrd_r=application/xrd%2Bxml;sep=false", webResponse }, }); - verifyCanonicalId("@llli", "@!72CD.A072.157E.A9C6"); - verifyCanonicalId("@llli*area", "@!72CD.A072.157E.A9C6!0000.0000.3B9A.CA0C"); - verifyCanonicalId("@llli*area*canada.unattached", "@!72CD.A072.157E.A9C6!0000.0000.3B9A.CA0C!0000.0000.3B9A.CA41"); - verifyCanonicalId("@llli*area*canada.unattached*ada", "@!72CD.A072.157E.A9C6!0000.0000.3B9A.CA0C!0000.0000.3B9A.CA41!0000.0000.3B9A.CA01"); - verifyCanonicalId("=Web", "=!91F2.8153.F600.AE24"); + this.VerifyCanonicalId("@llli", "@!72CD.A072.157E.A9C6"); + this.VerifyCanonicalId("@llli*area", "@!72CD.A072.157E.A9C6!0000.0000.3B9A.CA0C"); + this.VerifyCanonicalId("@llli*area*canada.unattached", "@!72CD.A072.157E.A9C6!0000.0000.3B9A.CA0C!0000.0000.3B9A.CA41"); + this.VerifyCanonicalId("@llli*area*canada.unattached*ada", "@!72CD.A072.157E.A9C6!0000.0000.3B9A.CA0C!0000.0000.3B9A.CA41!0000.0000.3B9A.CA01"); + this.VerifyCanonicalId("=Web", "=!91F2.8153.F600.AE24"); } [TestMethod] @@ -456,8 +448,8 @@ uEyb50RJ7DWmXctSC0b3eymZ2lSXxAWNOsNy }); // Consistent with spec section 7.3.2.3, we do not permit // delegation on XRI discovery when there is no CanonicalID present. - verifyCanonicalId("=Web*andrew.arnott", null); - verifyCanonicalId("@id*andrewarnott", null); + this.VerifyCanonicalId("=Web*andrew.arnott", null); + this.VerifyCanonicalId("@id*andrewarnott", null); } ////[TestMethod, Ignore("XRI parsing and normalization is not implemented (yet).")] @@ -465,5 +457,17 @@ uEyb50RJ7DWmXctSC0b3eymZ2lSXxAWNOsNy Identifier id = "=!9B72.7dd1.50a9.5ccd"; Assert.AreEqual("=!9B72.7DD1.50A9.5CCD", id.ToString()); } + + private ServiceEndpoint VerifyCanonicalId(Identifier iname, string expectedClaimedIdentifier) { + ServiceEndpoint se = iname.Discover(this.requestHandler).FirstOrDefault(); + if (expectedClaimedIdentifier != null) { + Assert.IsNotNull(se); + Assert.AreEqual(expectedClaimedIdentifier, se.ClaimedIdentifier.ToString(), "i-name {0} discovery resulted in unexpected CanonicalId", iname); + Assert.IsTrue(se.ProviderSupportedServiceTypeUris.Length > 0); + } else { + Assert.IsNull(se); + } + return se; + } } } diff --git a/src/DotNetOpenAuth/Messaging/DirectWebResponse.cs b/src/DotNetOpenAuth/Messaging/DirectWebResponse.cs index 6454ba0..a0462f3 100644 --- a/src/DotNetOpenAuth/Messaging/DirectWebResponse.cs +++ b/src/DotNetOpenAuth/Messaging/DirectWebResponse.cs @@ -1,14 +1,18 @@ -namespace DotNetOpenAuth.Messaging { +//----------------------------------------------------------------------- +// <copyright file="DirectWebResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Messaging { using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; using System.Diagnostics; - using System.IO; + using System.Diagnostics.CodeAnalysis; using System.Globalization; - using System.Net.Mime; + using System.IO; using System.Net; - using System.Diagnostics.CodeAnalysis; + using System.Net.Mime; + using System.Text; /// <summary> /// Details on the response from a direct web request to a remote party. @@ -16,15 +20,36 @@ [Serializable] [DebuggerDisplay("{Status} {ContentType.MediaType}: {Body.Substring(4,50)}")] public class DirectWebResponse : IDisposable { + /// <summary> + /// The encoding to use in reading a response that does not declare its own content encoding. + /// </summary> private const string DefaultContentEncoding = "ISO-8859-1"; + + /// <summary> + /// The network response object, used to initialize this instance, that still needs + /// to be closed if applicable. + /// </summary> private HttpWebResponse httpWebResponse; + + /// <summary> + /// An object to be locked whenever the <see cref="httpWebResponse"/> or the + /// <see cref="ResponseStream"/> members are being accessed. + /// </summary> private object responseLock = new object(); + /// <summary> + /// Initializes a new instance of the <see cref="DirectWebResponse"/> class. + /// </summary> internal DirectWebResponse() { this.Status = HttpStatusCode.OK; this.Headers = new WebHeaderCollection(); } + /// <summary> + /// Initializes a new instance of the <see cref="DirectWebResponse"/> class. + /// </summary> + /// <param name="requestUri">The original request URI.</param> + /// <param name="response">The response to initialize from. The network stream is used by this class directly.</param> internal DirectWebResponse(Uri requestUri, HttpWebResponse response) { ErrorUtilities.VerifyArgumentNotNull(requestUri, "requestUri"); ErrorUtilities.VerifyArgumentNotNull(response, "response"); @@ -41,32 +66,17 @@ this.ResponseStream = response.GetResponseStream(); } - internal void CacheNetworkStreamAndClose() { - this.CacheNetworkStreamAndClose(int.MaxValue); - } - - internal void CacheNetworkStreamAndClose(int maximumBytesToRead) { - lock (responseLock) { - if (this.httpWebResponse != null) { - // Now read and cache the network stream - Stream networkStream = this.ResponseStream; - this.ResponseStream = new MemoryStream(this.httpWebResponse.ContentLength < 0 ? 4 * 1024 : Math.Min((int)this.httpWebResponse.ContentLength, maximumBytesToRead)); - // BUGBUG: strictly speaking, is the response were exactly the limit, we'd report it as truncated here. - this.IsResponseTruncated = networkStream.CopyTo(this.ResponseStream, maximumBytesToRead) == maximumBytesToRead; - this.ResponseStream.Seek(0, SeekOrigin.Begin); - - networkStream.Dispose(); - this.httpWebResponse.Close(); - this.httpWebResponse = null; - } - } - } - /// <summary> - /// Constructs a mock web response. + /// Initializes a new instance of the <see cref="DirectWebResponse"/> class. /// </summary> - internal DirectWebResponse(Uri requestUri, Uri responseUri, WebHeaderCollection headers, - HttpStatusCode statusCode, string contentType, string contentEncoding, Stream responseStream) { + /// <param name="requestUri">The request URI.</param> + /// <param name="responseUri">The final URI to respond to the request.</param> + /// <param name="headers">The headers.</param> + /// <param name="statusCode">The status code.</param> + /// <param name="contentType">Type of the content.</param> + /// <param name="contentEncoding">The content encoding.</param> + /// <param name="responseStream">The response stream.</param> + internal DirectWebResponse(Uri requestUri, Uri responseUri, WebHeaderCollection headers, HttpStatusCode statusCode, string contentType, string contentEncoding, Stream responseStream) { ErrorUtilities.VerifyArgumentNotNull(requestUri, "requestUri"); ErrorUtilities.VerifyArgumentNotNull(responseStream, "responseStream"); this.RequestUri = requestUri; @@ -81,22 +91,22 @@ } /// <summary> - /// Gets or sets the type of the content. + /// Gets the type of the content. /// </summary> public ContentType ContentType { get; private set; } /// <summary> - /// Gets or sets the content encoding. + /// Gets the content encoding. /// </summary> public string ContentEncoding { get; private set; } /// <summary> - /// Gets or sets the URI of the initial request. + /// Gets the URI of the initial request. /// </summary> public Uri RequestUri { get; private set; } /// <summary> - /// Gets or sets the URI that finally responded to the request. + /// Gets the URI that finally responded to the request. /// </summary> /// <remarks> /// This can be different from the <see cref="RequestUri"/> in cases of @@ -159,6 +169,7 @@ sb.AppendLine(this.Body); return sb.ToString(); } + /// <summary> /// Creates a text reader for the response stream. /// </summary> @@ -174,6 +185,41 @@ } } + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() { + this.Dispose(true); + GC.SuppressFinalize(true); + } + + /// <summary> + /// Caches the network stream and closes it if it is open. + /// </summary> + internal void CacheNetworkStreamAndClose() { + this.CacheNetworkStreamAndClose(int.MaxValue); + } + + /// <summary> + /// Caches the network stream and closes it if it is open. + /// </summary> + /// <param name="maximumBytesToRead">The maximum bytes to cache.</param> + internal void CacheNetworkStreamAndClose(int maximumBytesToRead) { + lock (this.responseLock) { + if (this.httpWebResponse != null) { + // Now read and cache the network stream + Stream networkStream = this.ResponseStream; + this.ResponseStream = new MemoryStream(this.httpWebResponse.ContentLength < 0 ? 4 * 1024 : Math.Min((int)this.httpWebResponse.ContentLength, maximumBytesToRead)); + // BUGBUG: strictly speaking, is the response were exactly the limit, we'd report it as truncated here. + this.IsResponseTruncated = networkStream.CopyTo(this.ResponseStream, maximumBytesToRead) == maximumBytesToRead; + this.ResponseStream.Seek(0, SeekOrigin.Begin); + + networkStream.Dispose(); + this.httpWebResponse.Close(); + this.httpWebResponse = null; + } + } + } /// <summary> /// Sets the response to some string, encoded as UTF-8. @@ -193,16 +239,6 @@ writer.Flush(); this.ResponseStream.Seek(0, SeekOrigin.Begin); } - - #region IDisposable Members - - /// <summary> - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// </summary> - public void Dispose() { - this.Dispose(true); - GC.SuppressFinalize(true); - } /// <summary> /// Releases unmanaged and - optionally - managed resources @@ -210,7 +246,7 @@ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected void Dispose(bool disposing) { if (disposing) { - lock (responseLock) { + lock (this.responseLock) { if (this.ResponseStream != null) { this.ResponseStream.Dispose(); this.ResponseStream = null; @@ -222,7 +258,5 @@ } } } - - #endregion } } diff --git a/src/DotNetOpenAuth/Messaging/IDirectSslWebRequestHandler.cs b/src/DotNetOpenAuth/Messaging/IDirectSslWebRequestHandler.cs index 084d6d2..78b48ad 100644 --- a/src/DotNetOpenAuth/Messaging/IDirectSslWebRequestHandler.cs +++ b/src/DotNetOpenAuth/Messaging/IDirectSslWebRequestHandler.cs @@ -5,10 +5,6 @@ //----------------------------------------------------------------------- namespace DotNetOpenAuth.Messaging { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; using System.IO; using System.Net; diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs index 443aab9..0964010 100644 --- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs +++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs @@ -168,16 +168,6 @@ namespace DotNetOpenAuth.Messaging { return copyTo; } - internal static Stream CreateSnapshotAndClose(this Stream copyFrom) { - ErrorUtilities.VerifyArgumentNotNull(copyFrom, "copyFrom"); - - try { - return CreateSnapshot(copyFrom); - } finally { - copyFrom.Dispose(); - } - } - /// <summary> /// Tests whether two arrays are equal in length and contents. /// </summary> diff --git a/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs b/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs index cdfc408..85a7436 100644 --- a/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs +++ b/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs @@ -38,30 +38,41 @@ namespace DotNetOpenAuth.Messaging { /// <summary> /// Gets or sets the default cache policy to use for HTTP requests. /// </summary> - internal readonly static RequestCachePolicy DefaultCachePolicy = HttpWebRequest.DefaultCachePolicy; + internal static readonly RequestCachePolicy DefaultCachePolicy = HttpWebRequest.DefaultCachePolicy; - private static DotNetOpenAuth.Configuration.UntrustedWebRequestSection Configuration { - get { return UntrustedWebRequestSection.Configuration; } - } + private ICollection<Regex> blacklistHostsRegex = new List<Regex>(Configuration.BlacklistHostsRegex.KeysAsRegexs); + + private ICollection<string> allowableSchemes = new List<string> { "http", "https" }; + + private ICollection<Regex> whitelistHostsRegex = new List<Regex>(Configuration.WhitelistHostsRegex.KeysAsRegexs); + + private ICollection<string> whitelistHosts = new List<string>(Configuration.WhitelistHosts.KeysAsStrings); + + private ICollection<string> blacklistHosts = new List<string>(Configuration.BlacklistHosts.KeysAsStrings); + + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + private int maximumRedirections = Configuration.MaximumRedirections; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private int maximumBytesToRead = Configuration.MaximumBytesToRead; /// <summary> - /// The default maximum bytes to read in any given HTTP request. - /// Default is 1MB. Cannot be less than 2KB. + /// Gets or sets the default maximum bytes to read in any given HTTP request. /// </summary> + /// <value>Default is 1MB. Cannot be less than 2KB.</value> public int MaximumBytesToRead { - get { return maximumBytesToRead; } + get { + return this.maximumBytesToRead; + } + set { - if (value < 2048) throw new ArgumentOutOfRangeException("value"); - maximumBytesToRead = value; + if (value < 2048) { + throw new ArgumentOutOfRangeException("value"); + } + this.maximumBytesToRead = value; } } - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private int maximumRedirections = Configuration.MaximumRedirections; - private IDirectWebRequestHandler chainedWebRequestHandler; /// <summary> @@ -92,10 +103,15 @@ namespace DotNetOpenAuth.Messaging { /// Default is 10. /// </summary> public int MaximumRedirections { - get { return maximumRedirections; } + get { + return this.maximumRedirections; + } + set { - if (value < 0) throw new ArgumentOutOfRangeException("value"); - maximumRedirections = value; + if (value < 0) { + throw new ArgumentOutOfRangeException("value"); + } + this.maximumRedirections = value; } } @@ -111,31 +127,33 @@ namespace DotNetOpenAuth.Messaging { /// </summary> public TimeSpan Timeout { get; set; } - private ICollection<string> allowableSchemes = new List<string> { "http", "https" }; - private ICollection<string> whitelistHosts = new List<string>(Configuration.WhitelistHosts.KeysAsStrings); /// <summary> - /// A collection of host name literals that should be allowed even if they don't + /// Gets a collection of host name literals that should be allowed even if they don't /// pass standard security checks. /// </summary> - public ICollection<string> WhitelistHosts { get { return whitelistHosts; } } - private ICollection<Regex> whitelistHostsRegex = new List<Regex>(Configuration.WhitelistHostsRegex.KeysAsRegexs); + public ICollection<string> WhitelistHosts { get { return this.whitelistHosts; } } + /// <summary> - /// A collection of host name regular expressions that indicate hosts that should + /// Gets a collection of host name regular expressions that indicate hosts that should /// be allowed even though they don't pass standard security checks. /// </summary> - public ICollection<Regex> WhitelistHostsRegex { get { return whitelistHostsRegex; } } - private ICollection<string> blacklistHosts = new List<string>(Configuration.BlacklistHosts.KeysAsStrings); + public ICollection<Regex> WhitelistHostsRegex { get { return this.whitelistHostsRegex; } } + /// <summary> - /// A collection of host name literals that should be rejected even if they + /// Gets a collection of host name literals that should be rejected even if they /// pass standard security checks. /// </summary> - public ICollection<string> BlacklistHosts { get { return blacklistHosts; } } - private ICollection<Regex> blacklistHostsRegex = new List<Regex>(Configuration.BlacklistHostsRegex.KeysAsRegexs); + public ICollection<string> BlacklistHosts { get { return this.blacklistHosts; } } + /// <summary> - /// A collection of host name regular expressions that indicate hosts that should + /// Gets a collection of host name regular expressions that indicate hosts that should /// be rjected even if they pass standard security checks. /// </summary> - public ICollection<Regex> BlacklistHostsRegex { get { return blacklistHostsRegex; } } + public ICollection<Regex> BlacklistHostsRegex { get { return this.blacklistHostsRegex; } } + + private static DotNetOpenAuth.Configuration.UntrustedWebRequestSection Configuration { + get { return UntrustedWebRequestSection.Configuration; } + } #region IDirectSslWebRequestHandler Members @@ -218,7 +236,7 @@ namespace DotNetOpenAuth.Messaging { // but our mock request infrastructure can't do redirects on its own either. Uri originalRequestUri = request.RequestUri; int i; - for (i = 0; i < MaximumRedirections; i++) { + for (i = 0; i < this.MaximumRedirections; i++) { DirectWebResponse response = this.RequestCore(request, null, originalRequestUri, requireSsl); if (response.Status == HttpStatusCode.MovedPermanently || response.Status == HttpStatusCode.Redirect || @@ -286,25 +304,27 @@ namespace DotNetOpenAuth.Messaging { return newRequest; } - private bool isHostWhitelisted(string host) { - return isHostInList(host, WhitelistHosts, WhitelistHostsRegex); + private bool IsHostWhitelisted(string host) { + return this.IsHostInList(host, this.WhitelistHosts, this.WhitelistHostsRegex); } - private bool isHostBlacklisted(string host) { - return isHostInList(host, BlacklistHosts, BlacklistHostsRegex); + private bool IsHostBlacklisted(string host) { + return IsHostInList(host, BlacklistHosts, BlacklistHostsRegex); } - private bool isHostInList(string host, ICollection<string> stringList, ICollection<Regex> regexList) { - Debug.Assert(!string.IsNullOrEmpty(host)); - Debug.Assert(stringList != null); - Debug.Assert(regexList != null); + private bool IsHostInList(string host, ICollection<string> stringList, ICollection<Regex> regexList) { + ErrorUtilities.VerifyNonZeroLength(host, "host"); + ErrorUtilities.VerifyArgumentNotNull(stringList, "stringList"); + ErrorUtilities.VerifyArgumentNotNull(regexList, "regexList"); foreach (string testHost in stringList) { - if (string.Equals(host, testHost, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(host, testHost, StringComparison.OrdinalIgnoreCase)) { return true; + } } foreach (Regex regex in regexList) { - if (regex.IsMatch(host)) + if (regex.IsMatch(host)) { return true; + } } return false; } @@ -315,21 +335,23 @@ namespace DotNetOpenAuth.Messaging { /// <param name="requestUri">The request URI.</param> /// <param name="requireSsl">If set to <c>true</c>, only web requests that can be made entirely over SSL will succeed.</param> private void EnsureAllowableRequestUri(Uri requestUri, bool requireSsl) { - ErrorUtilities.VerifyArgument(this.isUriAllowable(requestUri), MessagingStrings.UnsafeWebRequestDetected, requestUri); + ErrorUtilities.VerifyArgument(this.IsUriAllowable(requestUri), MessagingStrings.UnsafeWebRequestDetected, requestUri); ErrorUtilities.VerifyProtocol(!requireSsl || String.Equals(requestUri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase), MessagingStrings.InsecureWebRequestWithSslRequired, requestUri); } - private bool isUriAllowable(Uri uri) { + private bool IsUriAllowable(Uri uri) { Debug.Assert(uri != null); - if (!allowableSchemes.Contains(uri.Scheme)) { + if (!this.allowableSchemes.Contains(uri.Scheme)) { Logger.WarnFormat("Rejecting URL {0} because it uses a disallowed scheme.", uri); return false; } // Allow for whitelist or blacklist to override our detection. Func<string, bool> failsUnlessWhitelisted = (string reason) => { - if (isHostWhitelisted(uri.DnsSafeHost)) return true; + if (IsHostWhitelisted(uri.DnsSafeHost)) { + return true; + } Logger.WarnFormat("Rejecting URL {0} because {1}.", uri, reason); return false; }; @@ -346,12 +368,14 @@ namespace DotNetOpenAuth.Messaging { // The host is actually an IP address. switch (hostIPAddress.AddressFamily) { case System.Net.Sockets.AddressFamily.InterNetwork: - if (addressBytes[0] == 127 || addressBytes[0] == 10) + if (addressBytes[0] == 127 || addressBytes[0] == 10) { return failsUnlessWhitelisted("it is a loopback address."); + } break; case System.Net.Sockets.AddressFamily.InterNetworkV6: - if (isIPv6Loopback(hostIPAddress)) + if (this.IsIPv6Loopback(hostIPAddress)) { return failsUnlessWhitelisted("it is a loopback address."); + } break; default: return failsUnlessWhitelisted("it does not use an IPv4 or IPv6 address."); @@ -363,26 +387,31 @@ namespace DotNetOpenAuth.Messaging { return failsUnlessWhitelisted("it does not contain a period in the host name."); } } - if (isHostBlacklisted(uri.DnsSafeHost)) { + if (this.IsHostBlacklisted(uri.DnsSafeHost)) { Logger.WarnFormat("Rejected URL {0} because it is blacklisted.", uri); return false; } return true; } - private bool isIPv6Loopback(IPAddress ip) { - Debug.Assert(ip != null); + private bool IsIPv6Loopback(IPAddress ip) { + ErrorUtilities.VerifyArgumentNotNull(ip, "ip"); byte[] addressBytes = ip.GetAddressBytes(); - for (int i = 0; i < addressBytes.Length - 1; i++) - if (addressBytes[i] != 0) return false; - if (addressBytes[addressBytes.Length - 1] != 1) return false; + for (int i = 0; i < addressBytes.Length - 1; i++) { + if (addressBytes[i] != 0) { + return false; + } + } + if (addressBytes[addressBytes.Length - 1] != 1) { + return false; + } return true; } private HttpWebRequest PrepareRequest(HttpWebRequest request) { // Set/override a few properties of the request to apply our policies for untrusted requests. - request.ReadWriteTimeout = (int)ReadWriteTimeout.TotalMilliseconds; - request.Timeout = (int)Timeout.TotalMilliseconds; + request.ReadWriteTimeout = (int)this.ReadWriteTimeout.TotalMilliseconds; + request.Timeout = (int)this.Timeout.TotalMilliseconds; request.KeepAlive = false; // If SSL is required throughout, we cannot allow auto redirects because @@ -396,7 +425,7 @@ namespace DotNetOpenAuth.Messaging { private DirectWebResponse RequestCore(HttpWebRequest request, Stream postEntity, Uri originalRequestUri, bool requireSsl) { ErrorUtilities.VerifyArgumentNotNull(request, "request"); ErrorUtilities.VerifyArgumentNotNull(originalRequestUri, "originalRequestUri"); - EnsureAllowableRequestUri(request.RequestUri, requireSsl); + this.EnsureAllowableRequestUri(request.RequestUri, requireSsl); int postEntityLength = 0; try { @@ -407,7 +436,7 @@ namespace DotNetOpenAuth.Messaging { } DirectWebResponse response = this.chainedWebRequestHandler.GetResponse(request); - response.CacheNetworkStreamAndClose(MaximumBytesToRead); + response.CacheNetworkStreamAndClose(this.MaximumBytesToRead); return response; } catch (WebException e) { using (HttpWebResponse response = (HttpWebResponse)e.Response) { @@ -425,11 +454,11 @@ namespace DotNetOpenAuth.Messaging { request.ServicePoint.Expect100Continue = false; // TODO: investigate that CAS may throw here, and we can use request.Expect instead. postEntity.Seek(-postEntityLength, SeekOrigin.Current); request = CloneRequestWithNewUrl(request, request.RequestUri); - return RequestCore(request, postEntity, originalRequestUri, requireSsl); + return this.RequestCore(request, postEntity, originalRequestUri, requireSsl); } } var directResponse = new DirectWebResponse(originalRequestUri, response); - directResponse.CacheNetworkStreamAndClose(MaximumBytesToRead); + directResponse.CacheNetworkStreamAndClose(this.MaximumBytesToRead); return directResponse; } else { throw ErrorUtilities.Wrap(e, MessagingStrings.WebRequestFailed, originalRequestUri); diff --git a/src/DotNetOpenAuth/OpenId/Identifier.cs b/src/DotNetOpenAuth/OpenId/Identifier.cs index de20e6e..0fd50c6 100644 --- a/src/DotNetOpenAuth/OpenId/Identifier.cs +++ b/src/DotNetOpenAuth/OpenId/Identifier.cs @@ -125,15 +125,6 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> - /// Performs discovery on the Identifier. - /// </summary> - /// <param name="requestHandler">The web request handler to use for discovery.</param> - /// <returns> - /// An initialized structure containing the discovered provider endpoint information. - /// </returns> - internal abstract IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler); - - /// <summary> /// Tests equality between two <see cref="Identifier"/>s. /// </summary> /// <param name="id1">The first Identifier.</param> @@ -184,6 +175,15 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Performs discovery on the Identifier. + /// </summary> + /// <param name="requestHandler">The web request handler to use for discovery.</param> + /// <returns> + /// An initialized structure containing the discovered provider endpoint information. + /// </returns> + internal abstract IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler); + + /// <summary> /// Returns an <see cref="Identifier"/> that has no URI fragment. /// Quietly returns the original <see cref="Identifier"/> if it is not /// a <see cref="UriIdentifier"/> or no fragment exists. diff --git a/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs b/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs index 126a59c..d5ed2eb 100644 --- a/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs @@ -5,11 +5,10 @@ //----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenId { - using System; using System.Collections.Generic; + using System.Linq; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.RelyingParty; - using System.Linq; /// <summary> /// Wraps an existing Identifier and prevents it from performing discovery. @@ -31,10 +30,6 @@ namespace DotNetOpenAuth.OpenId { this.wrappedIdentifier = wrappedIdentifier; } - internal override IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler) { - return Enumerable.Empty<ServiceEndpoint>(); - } - /// <summary> /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. /// </summary> @@ -70,6 +65,17 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Performs discovery on the Identifier. + /// </summary> + /// <param name="requestHandler">The web request handler to use for discovery.</param> + /// <returns> + /// An initialized structure containing the discovered provider endpoint information. + /// </returns> + internal override IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler) { + return Enumerable.Empty<ServiceEndpoint>(); + } + + /// <summary> /// Returns an <see cref="Identifier"/> that has no URI fragment. /// Quietly returns the original <see cref="Identifier"/> if it is not /// a <see cref="UriIdentifier"/> or no fragment exists. diff --git a/src/DotNetOpenAuth/OpenId/ProviderDescription.cs b/src/DotNetOpenAuth/OpenId/ProviderDescription.cs index 0bc6b3d..0995d93 100644 --- a/src/DotNetOpenAuth/OpenId/ProviderDescription.cs +++ b/src/DotNetOpenAuth/OpenId/ProviderDescription.cs @@ -7,10 +7,9 @@ namespace DotNetOpenAuth.OpenId { using System; using System.Collections.Generic; + using System.Collections.ObjectModel; using System.Linq; - using System.Text; using DotNetOpenAuth.Messaging; -using System.Collections.ObjectModel; /// <summary> /// Describes some OpenID Provider endpoint and its capabilities. diff --git a/src/DotNetOpenAuth/OpenId/Realm.cs b/src/DotNetOpenAuth/OpenId/Realm.cs index 1b4b0ef..507aaec 100644 --- a/src/DotNetOpenAuth/OpenId/Realm.cs +++ b/src/DotNetOpenAuth/OpenId/Realm.cs @@ -10,13 +10,12 @@ namespace DotNetOpenAuth.OpenId { using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; + using System.Linq; using System.Text.RegularExpressions; using System.Xml; using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.Yadis; using DotNetOpenAuth.Xrds; - using System.Linq; + using DotNetOpenAuth.Yadis; /// <summary> /// A trust root to validate requests and match return URLs against. @@ -361,7 +360,7 @@ namespace DotNetOpenAuth.OpenId { /// </returns> internal IEnumerable<RelyingPartyEndpointDescription> Discover(IDirectSslWebRequestHandler requestHandler, bool allowRedirects) { // Attempt YADIS discovery - DiscoveryResult yadisResult = Yadis.Discover(requestHandler, UriWithWildcardChangedToWww, false); + DiscoveryResult yadisResult = Yadis.Discover(requestHandler, this.UriWithWildcardChangedToWww, false); if (yadisResult != null) { // Detect disallowed redirects, since realm discovery never allows them for security. ErrorUtilities.VerifyProtocol(allowRedirects || yadisResult.NormalizedUri == yadisResult.RequestUri, OpenIdStrings.RealmCausedRedirectUponDiscovery, yadisResult.RequestUri); diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs index 310bb72..7c7c5f5 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs @@ -1,7 +1,13 @@ -using System; -using System.Diagnostics.CodeAnalysis; +//----------------------------------------------------------------------- +// <copyright file="IProviderEndpoint.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenId.RelyingParty { + using System; + using System.Diagnostics.CodeAnalysis; + /// <summary> /// Information published about an OpenId Provider by the /// OpenId discovery documents found at a user's Claimed Identifier. @@ -38,12 +44,14 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /////// the extension in the request and see if a response comes back for that extension. /////// </remarks> ////bool IsExtensionSupported(Type extensionType); + /// <summary> - /// The detected version of OpenID implemented by the Provider. + /// Gets the detected version of OpenID implemented by the Provider. /// </summary> Version Version { get; } + /// <summary> - /// The URL that the OpenID Provider receives authentication requests at. + /// Gets the URL that the OpenID Provider receives authentication requests at. /// </summary> Uri Uri { get; } } diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs index f28e256..d4d0b34 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs @@ -1,4 +1,10 @@ -namespace DotNetOpenAuth.OpenId.RelyingParty { +//----------------------------------------------------------------------- +// <copyright file="IXrdsProviderEndpoint.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.RelyingParty { using System.Diagnostics.CodeAnalysis; /// <summary> @@ -8,14 +14,11 @@ [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xrds")] public interface IXrdsProviderEndpoint : IProviderEndpoint { /// <summary> - /// Checks for the presence of a given Type URI in an XRDS service. - /// </summary> - bool IsTypeUriPresent(string typeUri); - /// <summary> /// Gets the priority associated with this service that may have been given /// in the XRDS document. /// </summary> int? ServicePriority { get; } + /// <summary> /// Gets the priority associated with the service endpoint URL. /// </summary> @@ -24,5 +27,10 @@ /// <see cref="ServicePriority"/>. /// </remarks> int? UriPriority { get; } + + /// <summary> + /// Checks for the presence of a given Type URI in an XRDS service. + /// </summary> + bool IsTypeUriPresent(string typeUri); } } diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs index 2f0fb16..cf3597c 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs @@ -16,14 +16,14 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// </summary> public sealed class OpenIdRelyingParty { /// <summary> - /// Backing field for the <see cref="SecuritySettings"/> property. + /// The untrusted web request handler we use (and share) by default across all RP instances. /// </summary> - private RelyingPartySecuritySettings securitySettings; + private static IDirectSslWebRequestHandler defaultUntrustedWebRequestHandler = new UntrustedWebRequestHandler(); /// <summary> - /// The untrusted web request handler we use (and share) by default across all RP instances. + /// Backing field for the <see cref="SecuritySettings"/> property. /// </summary> - private static IDirectSslWebRequestHandler DefaultUntrustedWebRequestHandler = new UntrustedWebRequestHandler(); + private RelyingPartySecuritySettings securitySettings; /// <summary> /// Initializes a new instance of the <see cref="OpenIdRelyingParty"/> class. @@ -35,7 +35,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { this.Channel = new OpenIdChannel(); this.AssociationStore = associationStore; this.SecuritySettings = RelyingPartySection.Configuration.SecuritySettings.CreateSecuritySettings(); - this.WebRequestHandler = DefaultUntrustedWebRequestHandler; + this.WebRequestHandler = defaultUntrustedWebRequestHandler; } /// <summary> diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs index d83d26e..9d79e82 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs @@ -5,27 +5,56 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { using System.Globalization; using System.IO; using System.Text; + using DotNetOpenAuth.Messaging; /// <summary> /// Represents information discovered about a user-supplied Identifier. /// </summary> [DebuggerDisplay("ClaimedIdentifier: {ClaimedIdentifier}, ProviderEndpoint: {ProviderEndpoint}, OpenId: {Protocol.Version}")] internal class ServiceEndpoint : IXrdsProviderEndpoint { + private string friendlyIdentifierForDisplay; + private Protocol protocol; + private int? uriPriority; + private int? servicePriority; + + private ServiceEndpoint(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Uri providerEndpoint, Identifier providerLocalIdentifier, string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) { + ErrorUtilities.VerifyArgumentNotNull(claimedIdentifier, "claimedIdentifier"); + ErrorUtilities.VerifyArgumentNotNull(providerEndpoint, "providerEndpoint"); + ErrorUtilities.VerifyArgumentNotNull(providerSupportedServiceTypeUris, "providerSupportedServiceTypeUris"); + this.ClaimedIdentifier = claimedIdentifier; + this.UserSuppliedIdentifier = userSuppliedIdentifier; + this.ProviderEndpoint = providerEndpoint; + this.ProviderLocalIdentifier = providerLocalIdentifier ?? claimedIdentifier; + this.ProviderSupportedServiceTypeUris = providerSupportedServiceTypeUris; + this.servicePriority = servicePriority; + this.uriPriority = uriPriority; + } + /// <summary> - /// The URL which accepts OpenID Authentication protocol messages. + /// Used for deserializing <see cref="ServiceEndpoint"/> from authentication responses. + /// </summary> + private ServiceEndpoint(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Uri providerEndpoint, Identifier providerLocalIdentifier, Protocol protocol) { + this.ClaimedIdentifier = claimedIdentifier; + this.UserSuppliedIdentifier = userSuppliedIdentifier; + this.ProviderEndpoint = providerEndpoint; + this.ProviderLocalIdentifier = providerLocalIdentifier ?? claimedIdentifier; + this.protocol = protocol; + } + + Uri IProviderEndpoint.Uri { get { return this.ProviderEndpoint; } } + + /// <summary> + /// Gets the URL which accepts OpenID Authentication protocol messages. /// </summary> /// <remarks> /// Obtained by performing discovery on the User-Supplied Identifier. /// This value MUST be an absolute HTTP or HTTPS URL. /// </remarks> public Uri ProviderEndpoint { get; private set; } + /// <summary> /// Returns true if the <see cref="ProviderEndpoint"/> is using an encrypted channel. /// </summary> - internal bool IsSecure { - get { return string.Equals(ProviderEndpoint.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase); } - } - Uri IProviderEndpoint.Uri { get { return ProviderEndpoint; } } /* /// <summary> /// An Identifier for an OpenID Provider. @@ -33,7 +62,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { public Identifier ProviderIdentifier { get; private set; } */ /// <summary> - /// An Identifier that was presented by the end user to the Relying Party, + /// Gets the Identifier that was presented by the end user to the Relying Party, /// or selected by the user at the OpenID Provider. /// During the initiation phase of the protocol, an end user may enter /// either their own Identifier or an OP Identifier. If an OP Identifier @@ -41,33 +70,35 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// to share with the Relying Party. /// </summary> public Identifier UserSuppliedIdentifier { get; private set; } + /// <summary> - /// The Identifier that the end user claims to own. + /// Gets the Identifier that the end user claims to own. /// </summary> public Identifier ClaimedIdentifier { get; private set; } + /// <summary> - /// An alternate Identifier for an end user that is local to a + /// Gets an alternate Identifier for an end user that is local to a /// particular OP and thus not necessarily under the end user's /// control. /// </summary> public Identifier ProviderLocalIdentifier { get; private set; } - string friendlyIdentifierForDisplay; + /// <summary> - /// Supports the <see cref="IAuthenticationResponse.FriendlyIdentifierForDisplay"/> property. + /// Gets the value for the <see cref="IAuthenticationResponse.FriendlyIdentifierForDisplay"/> property. /// </summary> public string FriendlyIdentifierForDisplay { get { - if (friendlyIdentifierForDisplay == null) { - XriIdentifier xri = ClaimedIdentifier as XriIdentifier; - UriIdentifier uri = ClaimedIdentifier as UriIdentifier; + if (this.friendlyIdentifierForDisplay == null) { + XriIdentifier xri = this.ClaimedIdentifier as XriIdentifier; + UriIdentifier uri = this.ClaimedIdentifier as UriIdentifier; if (xri != null) { if (UserSuppliedIdentifier == null || String.Equals(UserSuppliedIdentifier, ClaimedIdentifier, StringComparison.OrdinalIgnoreCase)) { - friendlyIdentifierForDisplay = ClaimedIdentifier; + this.friendlyIdentifierForDisplay = this.ClaimedIdentifier; } else { - friendlyIdentifierForDisplay = UserSuppliedIdentifier; + this.friendlyIdentifierForDisplay = this.UserSuppliedIdentifier; } } else if (uri != null) { - if (uri != Protocol.ClaimedIdentifierForOPIdentifier) { + if (uri != this.Protocol.ClaimedIdentifierForOPIdentifier) { string displayUri = uri.Uri.Authority + uri.Uri.PathAndQuery; displayUri = displayUri.TrimEnd('/'); // Multi-byte unicode characters get encoded by the Uri class for transit. @@ -77,82 +108,63 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } } else { Debug.Fail("Doh! We never should have reached here."); - friendlyIdentifierForDisplay = ClaimedIdentifier; + this.friendlyIdentifierForDisplay = this.ClaimedIdentifier; } } - return friendlyIdentifierForDisplay; + return this.friendlyIdentifierForDisplay; } } + /// <summary> /// Gets the list of services available at this OP Endpoint for the /// claimed Identifier. May be null. /// </summary> public string[] ProviderSupportedServiceTypeUris { get; private set; } - ServiceEndpoint(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, - Uri providerEndpoint, Identifier providerLocalIdentifier, - string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) { - if (claimedIdentifier == null) throw new ArgumentNullException("claimedIdentifier"); - if (providerEndpoint == null) throw new ArgumentNullException("providerEndpoint"); - if (providerSupportedServiceTypeUris == null) throw new ArgumentNullException("providerSupportedServiceTypeUris"); - ClaimedIdentifier = claimedIdentifier; - UserSuppliedIdentifier = userSuppliedIdentifier; - ProviderEndpoint = providerEndpoint; - ProviderLocalIdentifier = providerLocalIdentifier ?? claimedIdentifier; - ProviderSupportedServiceTypeUris = providerSupportedServiceTypeUris; - this.servicePriority = servicePriority; - this.uriPriority = uriPriority; - } /// <summary> - /// Used for deserializing <see cref="ServiceEndpoint"/> from authentication responses. + /// Gets the OpenID protocol used by the Provider. /// </summary> - ServiceEndpoint(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, - Uri providerEndpoint, Identifier providerLocalIdentifier, Protocol protocol) { - ClaimedIdentifier = claimedIdentifier; - UserSuppliedIdentifier = userSuppliedIdentifier; - ProviderEndpoint = providerEndpoint; - ProviderLocalIdentifier = providerLocalIdentifier ?? claimedIdentifier; - this.protocol = protocol; + public Protocol Protocol { + get { + if (this.protocol == null) { + this.protocol = Protocol.Detect(ProviderSupportedServiceTypeUris); + } + if (this.protocol != null) { + return this.protocol; + } + throw new InvalidOperationException("Unable to determine the version of OpenID the Provider supports."); + } } - internal static ServiceEndpoint CreateForProviderIdentifier( - Identifier providerIdentifier, Uri providerEndpoint, - string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) { - Protocol protocol = Protocol.Detect(providerSupportedServiceTypeUris); + #region IXrdsProviderEndpoint Members - return new ServiceEndpoint(protocol.ClaimedIdentifierForOPIdentifier, providerIdentifier, - providerEndpoint, protocol.ClaimedIdentifierForOPIdentifier, - providerSupportedServiceTypeUris, servicePriority, uriPriority); + /// <summary> + /// Gets the priority associated with this service that may have been given + /// in the XRDS document. + /// </summary> + int? IXrdsProviderEndpoint.ServicePriority { + get { return this.servicePriority; } } - internal static ServiceEndpoint CreateForClaimedIdentifier( - Identifier claimedIdentifier, Identifier providerLocalIdentifier, - Uri providerEndpoint, - string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) { - return CreateForClaimedIdentifier(claimedIdentifier, null, providerLocalIdentifier, - providerEndpoint, providerSupportedServiceTypeUris, servicePriority, uriPriority); + /// <summary> + /// Gets the priority associated with the service endpoint URL. + /// </summary> + int? IXrdsProviderEndpoint.UriPriority { + get { return this.uriPriority; } } - internal static ServiceEndpoint CreateForClaimedIdentifier( - Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Identifier providerLocalIdentifier, - Uri providerEndpoint, - string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) { - return new ServiceEndpoint(claimedIdentifier, userSuppliedIdentifier, providerEndpoint, - providerLocalIdentifier, providerSupportedServiceTypeUris, servicePriority, uriPriority); + #endregion + + internal bool IsSecure { + get { return string.Equals(this.ProviderEndpoint.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase); } } - Protocol protocol; - /// <summary> - /// Gets the OpenID protocol used by the Provider. - /// </summary> - public Protocol Protocol { - get { - if (protocol == null) { - protocol = Protocol.Detect(ProviderSupportedServiceTypeUris); - } - if (protocol != null) return protocol; - throw new InvalidOperationException("Unable to determine the version of OpenID the Provider supports."); - } + public static bool operator ==(ServiceEndpoint se1, ServiceEndpoint se2) { + return se1.EqualsNullSafe(se2); + } + + public static bool operator !=(ServiceEndpoint se1, ServiceEndpoint se2) { + return !(se1 == se2); } public bool IsTypeUriPresent(string typeUri) { @@ -160,9 +172,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } public bool IsExtensionSupported(string extensionUri) { - if (ProviderSupportedServiceTypeUris == null) + if (this.ProviderSupportedServiceTypeUris == null) { throw new InvalidOperationException("Cannot lookup extension support on a rehydrated ServiceEndpoint."); - return Array.IndexOf(ProviderSupportedServiceTypeUris, extensionUri) >= 0; + } + return Array.IndexOf(this.ProviderSupportedServiceTypeUris, extensionUri) >= 0; } ////public bool IsExtensionSupported(IExtension extension) { @@ -200,50 +213,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { Version IProviderEndpoint.Version { get { return Protocol.Version; } } - /// <summary> - /// Saves the discovered information about this endpoint - /// for later comparison to validate assertions. - /// </summary> - internal void Serialize(TextWriter writer) { - writer.WriteLine(ClaimedIdentifier); - writer.WriteLine(ProviderLocalIdentifier); - writer.WriteLine(UserSuppliedIdentifier); - writer.WriteLine(ProviderEndpoint); - writer.WriteLine(Protocol.Version); - // No reason to serialize priority. We only needed priority to decide whether to use this endpoint. - } - - /// <summary> - /// Reads previously discovered information about an endpoint - /// from a solicited authentication assertion for validation. - /// </summary> - /// <returns> - /// A <see cref="ServiceEndpoint"/> object that has everything - /// except the <see cref="ProviderSupportedServiceTypeUris"/> - /// deserialized. - /// </returns> - internal static ServiceEndpoint Deserialize(TextReader reader) { - var claimedIdentifier = Identifier.Parse(reader.ReadLine()); - var providerLocalIdentifier = Identifier.Parse(reader.ReadLine()); - string userSuppliedIdentifier = reader.ReadLine(); - if (userSuppliedIdentifier.Length == 0) userSuppliedIdentifier = null; - var providerEndpoint = new Uri(reader.ReadLine()); - var protocol = Protocol.FindBestVersion(p => p.Version, new[] { new Version(reader.ReadLine()) }); - return new ServiceEndpoint(claimedIdentifier, userSuppliedIdentifier, - providerEndpoint, providerLocalIdentifier, protocol); - } - - public static bool operator ==(ServiceEndpoint se1, ServiceEndpoint se2) { - if ((object)se1 == null ^ (object)se2 == null) return false; - if ((object)se1 == null) return true; - return se1.Equals(se2); - } - public static bool operator !=(ServiceEndpoint se1, ServiceEndpoint se2) { - return !(se1 == se2); - } public override bool Equals(object obj) { ServiceEndpoint other = obj as ServiceEndpoint; - if (other == null) return false; + if (other == null) { + return false; + } // We specifically do not check our ProviderSupportedServiceTypeUris array // or the priority field // as that is not persisted in our tokens, and it is not part of the @@ -254,9 +228,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { this.ProviderLocalIdentifier == other.ProviderLocalIdentifier && this.Protocol == other.Protocol; } + public override int GetHashCode() { return ClaimedIdentifier.GetHashCode(); } + public override string ToString() { StringBuilder builder = new StringBuilder(); builder.AppendLine("ClaimedIdentifier: " + ClaimedIdentifier); @@ -282,24 +258,56 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { return builder.ToString(); } - #region IXrdsProviderEndpoint Members - - private int? servicePriority; /// <summary> - /// Gets the priority associated with this service that may have been given - /// in the XRDS document. + /// Reads previously discovered information about an endpoint + /// from a solicited authentication assertion for validation. /// </summary> - int? IXrdsProviderEndpoint.ServicePriority { - get { return servicePriority; } + /// <returns> + /// A <see cref="ServiceEndpoint"/> object that has everything + /// except the <see cref="ProviderSupportedServiceTypeUris"/> + /// deserialized. + /// </returns> + internal static ServiceEndpoint Deserialize(TextReader reader) { + var claimedIdentifier = Identifier.Parse(reader.ReadLine()); + var providerLocalIdentifier = Identifier.Parse(reader.ReadLine()); + string userSuppliedIdentifier = reader.ReadLine(); + if (userSuppliedIdentifier.Length == 0) { + userSuppliedIdentifier = null; + } + var providerEndpoint = new Uri(reader.ReadLine()); + var protocol = Protocol.FindBestVersion(p => p.Version, new[] { new Version(reader.ReadLine()) }); + return new ServiceEndpoint(claimedIdentifier, userSuppliedIdentifier, providerEndpoint, providerLocalIdentifier, protocol); } - private int? uriPriority; + + internal static ServiceEndpoint CreateForProviderIdentifier( + Identifier providerIdentifier, Uri providerEndpoint, + string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) { + Protocol protocol = Protocol.Detect(providerSupportedServiceTypeUris); + + return new ServiceEndpoint(protocol.ClaimedIdentifierForOPIdentifier, providerIdentifier, + providerEndpoint, protocol.ClaimedIdentifierForOPIdentifier, + providerSupportedServiceTypeUris, servicePriority, uriPriority); + } + + internal static ServiceEndpoint CreateForClaimedIdentifier(Identifier claimedIdentifier, Identifier providerLocalIdentifier, Uri providerEndpoint, string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) { + return CreateForClaimedIdentifier(claimedIdentifier, null, providerLocalIdentifier, providerEndpoint, providerSupportedServiceTypeUris, servicePriority, uriPriority); + } + + internal static ServiceEndpoint CreateForClaimedIdentifier(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Identifier providerLocalIdentifier, Uri providerEndpoint, string[] providerSupportedServiceTypeUris, int? servicePriority, int? uriPriority) { + return new ServiceEndpoint(claimedIdentifier, userSuppliedIdentifier, providerEndpoint, providerLocalIdentifier, providerSupportedServiceTypeUris, servicePriority, uriPriority); + } + /// <summary> - /// Gets the priority associated with the service endpoint URL. + /// Saves the discovered information about this endpoint + /// for later comparison to validate assertions. /// </summary> - int? IXrdsProviderEndpoint.UriPriority { - get { return uriPriority; } + internal void Serialize(TextWriter writer) { + writer.WriteLine(this.ClaimedIdentifier); + writer.WriteLine(this.ProviderLocalIdentifier); + writer.WriteLine(this.UserSuppliedIdentifier); + writer.WriteLine(this.ProviderEndpoint); + writer.WriteLine(this.Protocol.Version); + // No reason to serialize priority. We only needed priority to decide whether to use this endpoint. } - - #endregion } }
\ No newline at end of file diff --git a/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs b/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs index 1dd9734..56851cf 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs @@ -30,12 +30,12 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> - /// The URL to the login page on the discovered relying party web site. + /// Gets the URL to the login page on the discovered relying party web site. /// </summary> public Uri ReturnToEndpoint { get; private set; } /// <summary> - /// The OpenId protocol that the discovered relying party supports. + /// Gets the OpenId protocol that the discovered relying party supports. /// </summary> public Protocol Protocol { get; private set; } diff --git a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs index 6885fa5..b42c56d 100644 --- a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs @@ -6,15 +6,15 @@ namespace DotNetOpenAuth.OpenId { using System; - using System.Linq; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; + using System.Linq; using System.Text.RegularExpressions; using System.Web.UI.HtmlControls; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.RelyingParty; - using DotNetOpenAuth.Yadis; using DotNetOpenAuth.Xrds; + using DotNetOpenAuth.Yadis; /// <summary> /// A URI style of OpenID Identifier. @@ -196,62 +196,6 @@ namespace DotNetOpenAuth.OpenId { return true; } - /// <summary> - /// Searches HTML for the HEAD META tags that describe OpenID provider services. - /// </summary> - /// <param name="claimedIdentifier"> - /// The final URL that provided this HTML document. - /// This may not be the same as (this) userSuppliedIdentifier if the - /// userSuppliedIdentifier pointed to a 301 Redirect. - /// </param> - /// <param name="html">The HTML that was downloaded and should be searched.</param> - /// <returns> - /// An initialized ServiceEndpoint if the OpenID Provider information was - /// found. Otherwise null. - /// </returns> - /// <remarks> - /// OpenID 2.0 tags are always used if they are present, otherwise - /// OpenID 1.x tags are used if present. - /// </remarks> - private static ServiceEndpoint DiscoverFromHtml(Uri claimedIdentifier, string html) { - Uri providerEndpoint = null; - Protocol discoveredProtocol = null; - Identifier providerLocalIdentifier = null; - var linkTags = new List<HtmlLink>(HtmlParser.HeadTags<HtmlLink>(html)); - foreach (var protocol in Protocol.AllVersions) { - foreach (var linkTag in linkTags) { - // rel attributes are supposed to be interpreted with case INsensitivity, - // and is a space-delimited list of values. (http://www.htmlhelp.com/reference/html40/values.html#linktypes) - if (Regex.IsMatch(linkTag.Attributes["rel"], @"\b" + Regex.Escape(protocol.HtmlDiscoveryProviderKey) + @"\b", RegexOptions.IgnoreCase)) { - if (Uri.TryCreate(linkTag.Href, UriKind.Absolute, out providerEndpoint)) { - discoveredProtocol = protocol; - break; - } - } - } - if (providerEndpoint != null) break; - } - if (providerEndpoint == null) - return null; // html did not contain openid.server link - // See if a LocalId tag of the discovered version exists - foreach (var linkTag in linkTags) { - if (Regex.IsMatch(linkTag.Attributes["rel"], @"\b" + Regex.Escape(discoveredProtocol.HtmlDiscoveryLocalIdKey) + @"\b", RegexOptions.IgnoreCase)) { - if (Identifier.IsValid(linkTag.Href)) { - providerLocalIdentifier = linkTag.Href; - break; - } else { - Logger.WarnFormat("Skipping endpoint data because local id is badly formed ({0}).", linkTag.Href); - return null; // badly formed URL used as LocalId - } - } - } - - // Choose the TypeURI to match the OpenID version detected. - string[] typeURIs = { discoveredProtocol.ClaimedIdentifierServiceTypeURI }; - return ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, providerLocalIdentifier, - providerEndpoint, typeURIs, (int?)null, (int?)null); - } - internal override IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler) { List<ServiceEndpoint> endpoints = new List<ServiceEndpoint>(); // Attempt YADIS discovery @@ -351,6 +295,64 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Searches HTML for the HEAD META tags that describe OpenID provider services. + /// </summary> + /// <param name="claimedIdentifier"> + /// The final URL that provided this HTML document. + /// This may not be the same as (this) userSuppliedIdentifier if the + /// userSuppliedIdentifier pointed to a 301 Redirect. + /// </param> + /// <param name="html">The HTML that was downloaded and should be searched.</param> + /// <returns> + /// An initialized ServiceEndpoint if the OpenID Provider information was + /// found. Otherwise null. + /// </returns> + /// <remarks> + /// OpenID 2.0 tags are always used if they are present, otherwise + /// OpenID 1.x tags are used if present. + /// </remarks> + private static ServiceEndpoint DiscoverFromHtml(Uri claimedIdentifier, string html) { + Uri providerEndpoint = null; + Protocol discoveredProtocol = null; + Identifier providerLocalIdentifier = null; + var linkTags = new List<HtmlLink>(HtmlParser.HeadTags<HtmlLink>(html)); + foreach (var protocol in Protocol.AllVersions) { + foreach (var linkTag in linkTags) { + // rel attributes are supposed to be interpreted with case INsensitivity, + // and is a space-delimited list of values. (http://www.htmlhelp.com/reference/html40/values.html#linktypes) + if (Regex.IsMatch(linkTag.Attributes["rel"], @"\b" + Regex.Escape(protocol.HtmlDiscoveryProviderKey) + @"\b", RegexOptions.IgnoreCase)) { + if (Uri.TryCreate(linkTag.Href, UriKind.Absolute, out providerEndpoint)) { + discoveredProtocol = protocol; + break; + } + } + } + if (providerEndpoint != null) { + break; + } + } + if (providerEndpoint == null) { + return null; // html did not contain openid.server link + } + // See if a LocalId tag of the discovered version exists + foreach (var linkTag in linkTags) { + if (Regex.IsMatch(linkTag.Attributes["rel"], @"\b" + Regex.Escape(discoveredProtocol.HtmlDiscoveryLocalIdKey) + @"\b", RegexOptions.IgnoreCase)) { + if (Identifier.IsValid(linkTag.Href)) { + providerLocalIdentifier = linkTag.Href; + break; + } else { + Logger.WarnFormat("Skipping endpoint data because local id is badly formed ({0}).", linkTag.Href); + return null; // badly formed URL used as LocalId + } + } + } + + // Choose the TypeURI to match the OpenID version detected. + string[] typeURIs = { discoveredProtocol.ClaimedIdentifierServiceTypeURI }; + return ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, providerLocalIdentifier, providerEndpoint, typeURIs, (int?)null, (int?)null); + } + + /// <summary> /// Determines whether the given URI is using a scheme in the list of allowed schemes. /// </summary> /// <param name="uri">The URI whose scheme is to be checked.</param> diff --git a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs index 7bbfb9d..5a92737 100644 --- a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs @@ -149,15 +149,6 @@ namespace DotNetOpenAuth.OpenId { || xri.StartsWith(XriScheme, StringComparison.OrdinalIgnoreCase); } - private XrdsDocument downloadXrds(IDirectSslWebRequestHandler requestHandler) { - XrdsDocument doc; - using (var xrdsResponse = Yadis.Request(requestHandler, this.XrdsUrl, this.IsDiscoverySecureEndToEnd)) { - doc = new XrdsDocument(XmlReader.Create(xrdsResponse.ResponseStream)); - } - ErrorUtilities.VerifyProtocol(doc.IsXrdResolutionSuccessful, OpenIdStrings.XriResolutionFailed); - return doc; - } - internal override IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler) { return downloadXrds(requestHandler).CreateServiceEndpoints(this); } @@ -167,7 +158,7 @@ namespace DotNetOpenAuth.OpenId { /// instances that treat another given identifier as the user-supplied identifier. /// </summary> internal IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler, XriIdentifier userSuppliedIdentifier) { - return downloadXrds(requestHandler).CreateServiceEndpoints(userSuppliedIdentifier); + return this.downloadXrds(requestHandler).CreateServiceEndpoints(userSuppliedIdentifier); } /// <summary> @@ -217,5 +208,14 @@ namespace DotNetOpenAuth.OpenId { } return xri; } + + private XrdsDocument downloadXrds(IDirectSslWebRequestHandler requestHandler) { + XrdsDocument doc; + using (var xrdsResponse = Yadis.Request(requestHandler, this.XrdsUrl, this.IsDiscoverySecureEndToEnd)) { + doc = new XrdsDocument(XmlReader.Create(xrdsResponse.ResponseStream)); + } + ErrorUtilities.VerifyProtocol(doc.IsXrdResolutionSuccessful, OpenIdStrings.XriResolutionFailed); + return doc; + } } } diff --git a/src/DotNetOpenAuth/Util.cs b/src/DotNetOpenAuth/Util.cs index d35c4e8..1abbccc 100644 --- a/src/DotNetOpenAuth/Util.cs +++ b/src/DotNetOpenAuth/Util.cs @@ -7,10 +7,9 @@ namespace DotNetOpenAuth { using System; using System.Collections.Generic; using System.Globalization; - using System.Linq; + using System.Net; using System.Reflection; using System.Text; - using System.Net; /// <summary> /// A grab-bag utility class. @@ -70,9 +69,11 @@ namespace DotNetOpenAuth { return sb.ToString(); }); } + internal static object ToStringDeferred<T>(this IEnumerable<T> list) { return ToStringDeferred<T>(list, false); } + internal static object ToStringDeferred<T>(this IEnumerable<T> list, bool multiLineElements) { return new DelayedToString<IEnumerable<T>>(list, l => { StringBuilder sb = new StringBuilder(); @@ -114,24 +115,27 @@ namespace DotNetOpenAuth { }); } + internal static HttpWebRequest CreatePostRequest(Uri requestUri, string body) { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri); + request.ContentType = "application/x-www-form-urlencoded"; + request.ContentLength = body.Length; + request.Method = "POST"; + return request; + } + private class DelayedToString<T> { + private T obj; + + private Func<T, string> toString; + public DelayedToString(T obj, Func<T, string> toString) { this.obj = obj; this.toString = toString; } - T obj; - Func<T, string> toString; + public override string ToString() { - return toString(obj); + return this.toString(obj); } } - - internal static HttpWebRequest CreatePostRequest(Uri requestUri, string body) { - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri); - request.ContentType = "application/x-www-form-urlencoded"; - request.ContentLength = body.Length; - request.Method = "POST"; - return request; - } } } diff --git a/src/DotNetOpenAuth/Xrds/ServiceElement.cs b/src/DotNetOpenAuth/Xrds/ServiceElement.cs index 91c671e..d593f6c 100644 --- a/src/DotNetOpenAuth/Xrds/ServiceElement.cs +++ b/src/DotNetOpenAuth/Xrds/ServiceElement.cs @@ -69,10 +69,10 @@ namespace DotNetOpenAuth.Xrds { public int CompareTo(ServiceElement other) { if (other == null) return -1; - if (Priority.HasValue && other.Priority.HasValue) { - return Priority.Value.CompareTo(other.Priority.Value); + if (this.Priority.HasValue && other.Priority.HasValue) { + return this.Priority.Value.CompareTo(other.Priority.Value); } else { - if (Priority.HasValue) { + if (this.Priority.HasValue) { return -1; } else if (other.Priority.HasValue) { return 1; diff --git a/src/DotNetOpenAuth/Xrds/UriElement.cs b/src/DotNetOpenAuth/Xrds/UriElement.cs index c8f159f..f47e507 100644 --- a/src/DotNetOpenAuth/Xrds/UriElement.cs +++ b/src/DotNetOpenAuth/Xrds/UriElement.cs @@ -31,14 +31,18 @@ namespace DotNetOpenAuth.Xrds { #region IComparable<UriElement> Members public int CompareTo(UriElement other) { - if (other == null) return -1; + if (other == null) { + return -1; + } int compare = Service.CompareTo(other.Service); - if (compare != 0) return compare; + if (compare != 0) { + return compare; + } - if (Priority.HasValue && other.Priority.HasValue) { - return Priority.Value.CompareTo(other.Priority.Value); + if (this.Priority.HasValue && other.Priority.HasValue) { + return this.Priority.Value.CompareTo(other.Priority.Value); } else { - if (Priority.HasValue) { + if (this.Priority.HasValue) { return -1; } else if (other.Priority.HasValue) { return 1; diff --git a/src/DotNetOpenAuth/Xrds/XrdElement.cs b/src/DotNetOpenAuth/Xrds/XrdElement.cs index 726081c..5f90936 100644 --- a/src/DotNetOpenAuth/Xrds/XrdElement.cs +++ b/src/DotNetOpenAuth/Xrds/XrdElement.cs @@ -29,17 +29,6 @@ namespace DotNetOpenAuth.Xrds { } } - private int XriResolutionStatusCode { - get { - var n = Node.SelectSingleNode("xrd:Status", XmlNamespaceResolver); - string codeString = null; - ErrorUtilities.VerifyProtocol(n != null && !string.IsNullOrEmpty(codeString = n.GetAttribute("code", string.Empty)), XrdsStrings.XriResolutionStatusMissing); - int code; - ErrorUtilities.VerifyProtocol(int.TryParse(codeString, out code) && code >= 100 && code < 400, XrdsStrings.XriResolutionStatusMissing); - return code; - } - } - public bool IsXriResolutionSuccessful { get { return XriResolutionStatusCode == 100; @@ -60,43 +49,33 @@ namespace DotNetOpenAuth.Xrds { } } - IEnumerable<ServiceElement> searchForServiceTypeUris(Func<Protocol, string> p) { - var xpath = new StringBuilder(); - xpath.Append("xrd:Service["); - foreach (var protocol in Protocol.AllVersions) { - string typeUri = p(protocol); - if (typeUri == null) continue; - xpath.Append("xrd:Type/text()='"); - xpath.Append(typeUri); - xpath.Append("' or "); - } - xpath.Length -= 4; - xpath.Append("]"); - var services = new List<ServiceElement>(); - foreach (XPathNavigator service in Node.Select(xpath.ToString(), XmlNamespaceResolver)) { - services.Add(new ServiceElement(service, this)); + private int XriResolutionStatusCode { + get { + var n = Node.SelectSingleNode("xrd:Status", XmlNamespaceResolver); + string codeString = null; + ErrorUtilities.VerifyProtocol(n != null && !string.IsNullOrEmpty(codeString = n.GetAttribute("code", string.Empty)), XrdsStrings.XriResolutionStatusMissing); + int code; + ErrorUtilities.VerifyProtocol(int.TryParse(codeString, out code) && code >= 100 && code < 400, XrdsStrings.XriResolutionStatusMissing); + return code; } - // Put the services in their own defined priority order - services.Sort(); - return services; } /// <summary> /// Returns services for OP Identifiers. /// </summary> public IEnumerable<ServiceElement> OpenIdProviderIdentifierServices { - get { return searchForServiceTypeUris(p => p.OPIdentifierServiceTypeURI); } + get { return SearchForServiceTypeUris(p => p.OPIdentifierServiceTypeURI); } } /// <summary> /// Returns services for Claimed Identifiers. /// </summary> public IEnumerable<ServiceElement> OpenIdClaimedIdentifierServices { - get { return searchForServiceTypeUris(p => p.ClaimedIdentifierServiceTypeURI); } + get { return SearchForServiceTypeUris(p => p.ClaimedIdentifierServiceTypeURI); } } public IEnumerable<ServiceElement> OpenIdRelyingPartyReturnToServices { - get { return searchForServiceTypeUris(p => p.RPReturnToTypeURI); } + get { return SearchForServiceTypeUris(p => p.RPReturnToTypeURI); } } /// <summary> @@ -111,5 +90,26 @@ namespace DotNetOpenAuth.Xrds { } } } + + private IEnumerable<ServiceElement> SearchForServiceTypeUris(Func<Protocol, string> p) { + var xpath = new StringBuilder(); + xpath.Append("xrd:Service["); + foreach (var protocol in Protocol.AllVersions) { + string typeUri = p(protocol); + if (typeUri == null) continue; + xpath.Append("xrd:Type/text()='"); + xpath.Append(typeUri); + xpath.Append("' or "); + } + xpath.Length -= 4; + xpath.Append("]"); + var services = new List<ServiceElement>(); + foreach (XPathNavigator service in Node.Select(xpath.ToString(), XmlNamespaceResolver)) { + services.Add(new ServiceElement(service, this)); + } + // Put the services in their own defined priority order + services.Sort(); + return services; + } } } diff --git a/src/DotNetOpenAuth/Xrds/XrdsDocument.cs b/src/DotNetOpenAuth/Xrds/XrdsDocument.cs index 68e1479..9b073ca 100644 --- a/src/DotNetOpenAuth/Xrds/XrdsDocument.cs +++ b/src/DotNetOpenAuth/Xrds/XrdsDocument.cs @@ -9,10 +9,9 @@ namespace DotNetOpenAuth.Xrds { using System.IO; using System.Xml; using System.Xml.XPath; - using DotNetOpenAuth.OpenId.Provider; - using DotNetOpenAuth.OpenId.RelyingParty; - using DotNetOpenAuth.OpenId; using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId; + using DotNetOpenAuth.OpenId.RelyingParty; internal class XrdsDocument : XrdsNode { public XrdsDocument(XPathNavigator xrdsNavigator) @@ -44,11 +43,11 @@ namespace DotNetOpenAuth.Xrds { internal IEnumerable<ServiceEndpoint> CreateServiceEndpoints(UriIdentifier claimedIdentifier) { var endpoints = new List<ServiceEndpoint>(); - endpoints.AddRange(this.generateOPIdentifierServiceEndpoints(claimedIdentifier)); + endpoints.AddRange(this.GenerateOPIdentifierServiceEndpoints(claimedIdentifier)); // If any OP Identifier service elements were found, we must not proceed // to return any Claimed Identifier services. if (endpoints.Count == 0) { - endpoints.AddRange(this.generateClaimedIdentifierServiceEndpoints(claimedIdentifier)); + endpoints.AddRange(this.GenerateClaimedIdentifierServiceEndpoints(claimedIdentifier)); } Logger.DebugFormat("Total services discovered in XRDS: {0}", endpoints.Count); Logger.Debug(endpoints.ToStringDeferred(true)); @@ -57,19 +56,38 @@ namespace DotNetOpenAuth.Xrds { internal IEnumerable<ServiceEndpoint> CreateServiceEndpoints(XriIdentifier userSuppliedIdentifier) { var endpoints = new List<ServiceEndpoint>(); - endpoints.AddRange(this.generateOPIdentifierServiceEndpoints(userSuppliedIdentifier)); + endpoints.AddRange(this.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier)); // If any OP Identifier service elements were found, we must not proceed // to return any Claimed Identifier services. if (endpoints.Count == 0) { - endpoints.AddRange(generateClaimedIdentifierServiceEndpoints(userSuppliedIdentifier)); + endpoints.AddRange(this.GenerateClaimedIdentifierServiceEndpoints(userSuppliedIdentifier)); } Logger.DebugFormat("Total services discovered in XRDS: {0}", endpoints.Count); Logger.Debug(endpoints.ToStringDeferred(true)); return endpoints; } - IEnumerable<ServiceEndpoint> generateOPIdentifierServiceEndpoints(Identifier opIdentifier) { - foreach (var service in findOPIdentifierServices()) { + internal IEnumerable<RelyingPartyEndpointDescription> FindRelyingPartyReceivingEndpoints() { + foreach (var service in FindReturnToServices()) { + foreach (var uri in service.UriElements) { + yield return new RelyingPartyEndpointDescription(uri.Uri, service.TypeElementUris); + } + } + } + + internal bool IsXrdResolutionSuccessful { + get { + foreach (var xrd in this.XrdElements) { + if (!xrd.IsXriResolutionSuccessful) { + return false; + } + } + return true; + } + } + + private IEnumerable<ServiceEndpoint> GenerateOPIdentifierServiceEndpoints(Identifier opIdentifier) { + foreach (var service in FindOPIdentifierServices()) { foreach (var uri in service.UriElements) { var protocol = Protocol.FindBestVersion(p => p.OPIdentifierServiceTypeURI, service.TypeElementUris); yield return ServiceEndpoint.CreateForProviderIdentifier( @@ -79,8 +97,8 @@ namespace DotNetOpenAuth.Xrds { } } - IEnumerable<ServiceEndpoint> generateClaimedIdentifierServiceEndpoints(UriIdentifier claimedIdentifier) { - foreach (var service in findClaimedIdentifierServices()) { + private IEnumerable<ServiceEndpoint> GenerateClaimedIdentifierServiceEndpoints(UriIdentifier claimedIdentifier) { + foreach (var service in FindClaimedIdentifierServices()) { foreach (var uri in service.UriElements) { yield return ServiceEndpoint.CreateForClaimedIdentifier( claimedIdentifier, service.ProviderLocalIdentifier, @@ -89,8 +107,8 @@ namespace DotNetOpenAuth.Xrds { } } - IEnumerable<ServiceEndpoint> generateClaimedIdentifierServiceEndpoints(XriIdentifier userSuppliedIdentifier) { - foreach (var service in findClaimedIdentifierServices()) { + private IEnumerable<ServiceEndpoint> GenerateClaimedIdentifierServiceEndpoints(XriIdentifier userSuppliedIdentifier) { + foreach (var service in this.FindClaimedIdentifierServices()) { foreach (var uri in service.UriElements) { // spec section 7.3.2.3 on Claimed Id -> CanonicalID substitution if (service.Xrd.CanonicalID == null) { @@ -107,15 +125,7 @@ namespace DotNetOpenAuth.Xrds { } } - internal IEnumerable<RelyingPartyEndpointDescription> FindRelyingPartyReceivingEndpoints() { - foreach (var service in findReturnToServices()) { - foreach (var uri in service.UriElements) { - yield return new RelyingPartyEndpointDescription(uri.Uri, service.TypeElementUris); - } - } - } - - IEnumerable<ServiceElement> findOPIdentifierServices() { + private IEnumerable<ServiceElement> FindOPIdentifierServices() { foreach (var xrd in this.XrdElements) { foreach (var service in xrd.OpenIdProviderIdentifierServices) { yield return service; @@ -127,7 +137,7 @@ namespace DotNetOpenAuth.Xrds { /// Returns the OpenID-compatible services described by a given XRDS document, /// in priority order. /// </summary> - IEnumerable<ServiceElement> findClaimedIdentifierServices() { + private IEnumerable<ServiceElement> FindClaimedIdentifierServices() { foreach (var xrd in this.XrdElements) { foreach (var service in xrd.OpenIdClaimedIdentifierServices) { yield return service; @@ -135,23 +145,12 @@ namespace DotNetOpenAuth.Xrds { } } - IEnumerable<ServiceElement> findReturnToServices() { + private IEnumerable<ServiceElement> FindReturnToServices() { foreach (var xrd in this.XrdElements) { foreach (var service in xrd.OpenIdRelyingPartyReturnToServices) { yield return service; } } } - - internal bool IsXrdResolutionSuccessful { - get { - foreach (var xrd in this.XrdElements) { - if (!xrd.IsXriResolutionSuccessful) { - return false; - } - } - return true; - } - } } } diff --git a/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs b/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs index f0d58e7..391df23 100644 --- a/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs +++ b/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs @@ -23,18 +23,18 @@ namespace DotNetOpenAuth.Yadis { /// <param name="initialResponse">The initial response.</param> /// <param name="finalResponse">The final response.</param> public DiscoveryResult(Uri requestUri, DirectWebResponse initialResponse, DirectWebResponse finalResponse) { - RequestUri = requestUri; - NormalizedUri = initialResponse.FinalUri; + this.RequestUri = requestUri; + this.NormalizedUri = initialResponse.FinalUri; if (finalResponse == null) { - ContentType = initialResponse.ContentType; - ResponseText = initialResponse.Body; - IsXrds = ContentType.MediaType == ContentTypes.Xrds; + this.ContentType = initialResponse.ContentType; + this.ResponseText = initialResponse.Body; + this.IsXrds = ContentType.MediaType == ContentTypes.Xrds; } else { - ContentType = finalResponse.ContentType; - ResponseText = finalResponse.Body; - IsXrds = true; + this.ContentType = finalResponse.ContentType; + this.ResponseText = finalResponse.Body; + this.IsXrds = true; if (initialResponse != finalResponse) { - YadisLocation = finalResponse.RequestUri; + this.YadisLocation = finalResponse.RequestUri; } } } @@ -82,7 +82,7 @@ namespace DotNetOpenAuth.Yadis { /// <value><c>true</c> if the response to the userSuppliedIdentifier pointed to a different URL /// for the XRDS document.</value> public bool UsedYadisLocation { - get { return YadisLocation != null; } + get { return this.YadisLocation != null; } } } } diff --git a/src/DotNetOpenAuth/Yadis/HtmlParser.cs b/src/DotNetOpenAuth/Yadis/HtmlParser.cs index 7d1283e..fbf5d45 100644 --- a/src/DotNetOpenAuth/Yadis/HtmlParser.cs +++ b/src/DotNetOpenAuth/Yadis/HtmlParser.cs @@ -52,7 +52,7 @@ namespace DotNetOpenAuth.Yadis { } } - static Regex tagMatcher(string tagName, params string[] closeTags) { + private static Regex tagMatcher(string tagName, params string[] closeTags) { string text2; if (closeTags.Length > 0) { StringBuilder builder = new StringBuilder(); @@ -74,7 +74,7 @@ namespace DotNetOpenAuth.Yadis { tagExpr, tagName, text2), flags); } - static Regex startTagMatcher(string tag_name) { + private static Regex startTagMatcher(string tag_name) { return new Regex(string.Format(CultureInfo.InvariantCulture, startTagExpr, tag_name), flags); } } |