diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2008-11-25 07:32:57 -0800 |
---|---|---|
committer | Andrew <andrewarnott@gmail.com> | 2008-11-25 07:32:57 -0800 |
commit | dbb8e6cf3329dfee52fa78a19026134eaae2bae7 (patch) | |
tree | 7f6930398658fdac29aa6896143f90b1ba037e86 /src | |
parent | 3d69557f925cb7e05e85b0b99371faaf9c2109c6 (diff) | |
download | DotNetOpenAuth-dbb8e6cf3329dfee52fa78a19026134eaae2bae7.zip DotNetOpenAuth-dbb8e6cf3329dfee52fa78a19026134eaae2bae7.tar.gz DotNetOpenAuth-dbb8e6cf3329dfee52fa78a19026134eaae2bae7.tar.bz2 |
Hundreds more stylecop fixes.
Mostly just doc bugs now.
Diffstat (limited to 'src')
27 files changed, 430 insertions, 357 deletions
diff --git a/src/DotNetOpenAuth.Test/Hosting/AspNetHost.cs b/src/DotNetOpenAuth.Test/Hosting/AspNetHost.cs index 015a00b..94bf480 100644 --- a/src/DotNetOpenAuth.Test/Hosting/AspNetHost.cs +++ b/src/DotNetOpenAuth.Test/Hosting/AspNetHost.cs @@ -22,13 +22,13 @@ namespace DotNetOpenAuth.Test.Hosting { private HttpHost httpHost; public AspNetHost() { - httpHost = HttpHost.CreateHost(this); + this.httpHost = HttpHost.CreateHost(this); ////if (!UntrustedWebRequestHandler.WhitelistHosts.Contains("localhost")) //// UntrustedWebRequestHandler.WhitelistHosts.Add("localhost"); } public Uri BaseUri { - get { return httpHost.BaseUri; } + get { return this.httpHost.BaseUri; } } public static AspNetHost CreateHost(string webDirectory) { @@ -38,11 +38,11 @@ namespace DotNetOpenAuth.Test.Hosting { } public string ProcessRequest(string url) { - return httpHost.ProcessRequest(url); + return this.httpHost.ProcessRequest(url); } public string ProcessRequest(string url, string body) { - return httpHost.ProcessRequest(url, body); + return this.httpHost.ProcessRequest(url, body); } public void BeginProcessRequest(HttpListenerContext context) { @@ -61,7 +61,7 @@ namespace DotNetOpenAuth.Test.Hosting { } public void CloseHttp() { - httpHost.Dispose(); + this.httpHost.Dispose(); } } } diff --git a/src/DotNetOpenAuth.Test/Hosting/HttpHost.cs b/src/DotNetOpenAuth.Test/Hosting/HttpHost.cs index 06001ce..3ccd8bc 100644 --- a/src/DotNetOpenAuth.Test/Hosting/HttpHost.cs +++ b/src/DotNetOpenAuth.Test/Hosting/HttpHost.cs @@ -11,7 +11,7 @@ namespace DotNetOpenAuth.Test.Hosting { using System.Net; using System.Threading; - class HttpHost : IDisposable { + internal class HttpHost : IDisposable { private HttpListener listener; private Thread listenerThread; private AspNetHost aspNetHost; @@ -33,12 +33,16 @@ namespace DotNetOpenAuth.Test.Hosting { } throw; } - this.listenerThread = new Thread(ProcessRequests); + this.listenerThread = new Thread(this.ProcessRequests); this.listenerThread.Start(); } public int Port { get; private set; } + public Uri BaseUri { + get { return new Uri("http://localhost:" + this.Port.ToString() + "/"); } + } + public static HttpHost CreateHost(AspNetHost aspNetHost) { return new HttpHost(aspNetHost); } @@ -46,17 +50,13 @@ namespace DotNetOpenAuth.Test.Hosting { public static HttpHost CreateHost(string webDirectory) { return new HttpHost(AspNetHost.CreateHost(webDirectory)); } - - public Uri BaseUri { - get { return new Uri("http://localhost:" + this.Port.ToString() + "/"); } - } - + public string ProcessRequest(string url) { - return ProcessRequest(url, null); + return this.ProcessRequest(url, null); } - + public string ProcessRequest(string url, string body) { - WebRequest request = WebRequest.Create(new Uri(BaseUri, url)); + WebRequest request = WebRequest.Create(new Uri(this.BaseUri, url)); if (body != null) { request.Method = "POST"; request.ContentLength = body.Length; @@ -81,9 +81,9 @@ namespace DotNetOpenAuth.Test.Hosting { #region IDisposable Members public void Dispose() { - listener.Close(); - listenerThread.Join(1000); - listenerThread.Abort(); + this.listener.Close(); + this.listenerThread.Join(1000); + this.listenerThread.Abort(); } #endregion diff --git a/src/DotNetOpenAuth.Test/Hosting/TestingWorkerRequest.cs b/src/DotNetOpenAuth.Test/Hosting/TestingWorkerRequest.cs index 6d1ee8d..d059c36 100644 --- a/src/DotNetOpenAuth.Test/Hosting/TestingWorkerRequest.cs +++ b/src/DotNetOpenAuth.Test/Hosting/TestingWorkerRequest.cs @@ -12,7 +12,9 @@ namespace DotNetOpenAuth.Test.Hosting { internal class TestingWorkerRequest : SimpleWorkerRequest { private Stream entityStream; + private HttpListenerContext context; + private TextWriter writer; public TestingWorkerRequest(string page, string query, Stream entityStream, TextWriter writer) @@ -20,6 +22,7 @@ namespace DotNetOpenAuth.Test.Hosting { this.entityStream = entityStream; this.writer = writer; } + public TestingWorkerRequest(HttpListenerContext context, TextWriter output) : base(context.Request.Url.LocalPath.TrimStart('/'), context.Request.Url.Query, output) { this.entityStream = context.Request.InputStream; @@ -29,66 +32,85 @@ namespace DotNetOpenAuth.Test.Hosting { public override string GetFilePath() { string filePath = this.context.Request.Url.LocalPath.Replace("/", "\\"); - if (filePath.EndsWith("\\", StringComparison.Ordinal)) + if (filePath.EndsWith("\\", StringComparison.Ordinal)) { filePath += "default.aspx"; + } return filePath; } + public override int GetLocalPort() { return this.context.Request.Url.Port; } + public override string GetServerName() { return this.context.Request.Url.Host; } + public override string GetQueryString() { return this.context.Request.Url.Query.TrimStart('?'); } + public override string GetHttpVerbName() { return this.context.Request.HttpMethod; } + public override string GetLocalAddress() { return this.context.Request.LocalEndPoint.Address.ToString(); } + public override string GetHttpVersion() { return "HTTP/1.1"; } + public override string GetProtocol() { return this.context.Request.Url.Scheme; } + public override string GetRawUrl() { return this.context.Request.RawUrl; } + public override int GetTotalEntityBodyLength() { return (int)this.context.Request.ContentLength64; } + public override string GetKnownRequestHeader(int index) { return this.context.Request.Headers[GetKnownRequestHeaderName(index)]; } + public override string GetUnknownRequestHeader(string name) { return this.context.Request.Headers[name]; } + public override bool IsEntireEntityBodyIsPreloaded() { return false; } + public override int ReadEntityBody(byte[] buffer, int size) { return this.entityStream.Read(buffer, 0, size); } + public override int ReadEntityBody(byte[] buffer, int offset, int size) { return this.entityStream.Read(buffer, offset, size); } + public override void SendCalculatedContentLength(int contentLength) { this.context.Response.ContentLength64 = contentLength; } + public override void SendStatus(int statusCode, string statusDescription) { if (this.context != null) { this.context.Response.StatusCode = statusCode; this.context.Response.StatusDescription = statusDescription; } } + public override void SendKnownResponseHeader(int index, string value) { if (this.context != null) { this.context.Response.Headers[(HttpResponseHeader)index] = value; } } + public override void SendUnknownResponseHeader(string name, string 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 08e4473..94d6f81 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs @@ -1,4 +1,10 @@ -namespace DotNetOpenAuth.Test.Mocks { +//----------------------------------------------------------------------- +// <copyright file="MockHttpRequest.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.Mocks { using System; using System.Collections.Generic; using System.Globalization; @@ -6,15 +12,22 @@ using System.Net; using System.Text; using System.Web; - using DotNetOpenAuth.OpenId.RelyingParty; - using DotNetOpenAuth.Yadis; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; + using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.Test.OpenId; + using DotNetOpenAuth.Yadis; internal class MockHttpRequest { private readonly Dictionary<Uri, DirectWebResponse> registeredMockResponses = new Dictionary<Uri, DirectWebResponse>(); + private MockHttpRequest(IDirectSslWebRequestHandler mockHandler) { + ErrorUtilities.VerifyArgumentNotNull(mockHandler, "mockHandler"); + this.MockWebRequestHandler = mockHandler; + } + + internal IDirectSslWebRequestHandler MockWebRequestHandler { get; private set; } + internal static MockHttpRequest CreateUntrustedMockHttpHandler() { TestWebRequestHandler testHandler = new TestWebRequestHandler(); UntrustedWebRequestHandler untrustedHandler = new UntrustedWebRequestHandler(testHandler); @@ -26,33 +39,31 @@ return mock; } - internal IDirectSslWebRequestHandler MockWebRequestHandler { get; private set; } - internal void RegisterMockResponse(DirectWebResponse response) { - if (response == null) throw new ArgumentNullException("response"); - if (registeredMockResponses.ContainsKey(response.RequestUri)) { + ErrorUtilities.VerifyArgumentNotNull(response, "response"); + if (this.registeredMockResponses.ContainsKey(response.RequestUri)) { Logger.WarnFormat("Mock HTTP response already registered for {0}.", response.RequestUri); } else { - registeredMockResponses.Add(response.RequestUri, response); + this.registeredMockResponses.Add(response.RequestUri, response); } } internal void RegisterMockResponse(Uri requestUri, string contentType, string responseBody) { - RegisterMockResponse(requestUri, requestUri, contentType, responseBody); + this.RegisterMockResponse(requestUri, requestUri, contentType, responseBody); } internal void RegisterMockResponse(Uri requestUri, Uri responseUri, string contentType, string responseBody) { - RegisterMockResponse(requestUri, responseUri, contentType, new WebHeaderCollection(), responseBody); + this.RegisterMockResponse(requestUri, responseUri, contentType, new WebHeaderCollection(), responseBody); } internal void RegisterMockResponse(Uri requestUri, Uri responseUri, string contentType, WebHeaderCollection headers, string responseBody) { - if (requestUri == null) throw new ArgumentNullException("requestUri"); - if (responseUri == null) throw new ArgumentNullException("responseUri"); - if (String.IsNullOrEmpty(contentType)) throw new ArgumentNullException("contentType"); + ErrorUtilities.VerifyArgumentNotNull(requestUri, "requestUri"); + ErrorUtilities.VerifyArgumentNotNull(responseUri, "responseUri"); + ErrorUtilities.VerifyNonZeroLength(contentType, "contentType"); // Set up the redirect if appropriate if (requestUri != responseUri) { - RegisterMockRedirect(requestUri, responseUri); + this.RegisterMockRedirect(requestUri, responseUri); } string contentEncoding = null; @@ -61,18 +72,17 @@ sw.Write(responseBody); sw.Flush(); stream.Seek(0, SeekOrigin.Begin); - RegisterMockResponse(new DirectWebResponse(responseUri, responseUri, headers ?? new WebHeaderCollection(), - HttpStatusCode.OK, contentType, contentEncoding, stream)); + this.RegisterMockResponse(new DirectWebResponse(responseUri, responseUri, headers ?? new WebHeaderCollection(), HttpStatusCode.OK, contentType, contentEncoding, stream)); } internal void RegisterMockXrdsResponses(IDictionary<string, string> requestUriAndResponseBody) { foreach (var pair in requestUriAndResponseBody) { - RegisterMockResponse(new Uri(pair.Key), "text/xml; saml=false; https=false; charset=UTF-8", pair.Value); + this.RegisterMockResponse(new Uri(pair.Key), "text/xml; saml=false; https=false; charset=UTF-8", pair.Value); } } internal void RegisterMockXrdsResponse(ServiceEndpoint endpoint) { - if (endpoint == null) throw new ArgumentNullException("endpoint"); + ErrorUtilities.VerifyArgumentNotNull(endpoint, "endpoint"); string identityUri; if (endpoint.ClaimedIdentifier == endpoint.Protocol.ClaimedIdentifierForOPIdentifier) { @@ -80,11 +90,11 @@ } else { identityUri = endpoint.UserSuppliedIdentifier ?? endpoint.ClaimedIdentifier; } - RegisterMockXrdsResponse(new Uri(identityUri), new ServiceEndpoint[] { endpoint }); + this.RegisterMockXrdsResponse(new Uri(identityUri), new ServiceEndpoint[] { endpoint }); } internal void RegisterMockXrdsResponse(Uri respondingUri, IEnumerable<ServiceEndpoint> endpoints) { - if (endpoints == null) throw new ArgumentNullException("endpoints"); + ErrorUtilities.VerifyArgumentNotNull(endpoints, "endpoints"); StringBuilder xrds = new StringBuilder(); xrds.AppendLine(@"<xrds:XRDS xmlns:xrds='xri://$xrds' xmlns:openid='http://openid.net/xmlns/1.0' xmlns='xri://$xrd*($v*2.0)'> @@ -103,7 +113,9 @@ } else { serviceTypeUri = endpoint.Protocol.ClaimedIdentifierServiceTypeURI; } - string xrd = string.Format(CultureInfo.InvariantCulture, template, + string xrd = string.Format( + CultureInfo.InvariantCulture, + template, HttpUtility.HtmlEncode(serviceTypeUri), HttpUtility.HtmlEncode(endpoint.ProviderEndpoint.AbsoluteUri), HttpUtility.HtmlEncode(endpoint.ProviderLocalIdentifier)); @@ -113,7 +125,7 @@ </XRD> </xrds:XRDS>"); - RegisterMockResponse(respondingUri, ContentTypes.Xrds, xrds.ToString()); + this.RegisterMockResponse(respondingUri, ContentTypes.Xrds, xrds.ToString()); } internal void RegisterMockXrdsResponse(UriIdentifier directedIdentityAssignedIdentifier, ServiceEndpoint providerEndpoint) { @@ -124,12 +136,12 @@ new string[] { providerEndpoint.Protocol.ClaimedIdentifierServiceTypeURI }, 10, 10); - RegisterMockXrdsResponse(identityEndpoint); + this.RegisterMockXrdsResponse(identityEndpoint); } internal Identifier RegisterMockXrdsResponse(string embeddedResourcePath) { UriIdentifier id = TestSupport.GetFullUrl(embeddedResourcePath); - RegisterMockResponse(id, "application/xrds+xml", TestSupport.LoadEmbeddedFile(embeddedResourcePath)); + this.RegisterMockResponse(id, "application/xrds+xml", TestSupport.LoadEmbeddedFile(embeddedResourcePath)); return id; } @@ -144,11 +156,9 @@ </Service> </XRD> </xrds:XRDS>"; - string xrds = string.Format(CultureInfo.InvariantCulture, template, - HttpUtility.HtmlEncode(Protocol.V20.RPReturnToTypeURI), - HttpUtility.HtmlEncode(rpRealmUri.AbsoluteUri)); + string xrds = string.Format(CultureInfo.InvariantCulture, template, HttpUtility.HtmlEncode(Protocol.V20.RPReturnToTypeURI), HttpUtility.HtmlEncode(rpRealmUri.AbsoluteUri)); - RegisterMockResponse(rpRealmUri, ContentTypes.Xrds, xrds); + this.RegisterMockResponse(rpRealmUri, ContentTypes.Xrds, xrds); } internal void DeleteResponse(Uri requestUri) { @@ -159,14 +169,8 @@ var redirectionHeaders = new WebHeaderCollection { { HttpResponseHeader.Location, redirectLocation.AbsoluteUri }, }; - DirectWebResponse response = new DirectWebResponse(origin, origin, - redirectionHeaders, HttpStatusCode.Redirect, null, null, new MemoryStream()); - RegisterMockResponse(response); - } - - private MockHttpRequest(IDirectSslWebRequestHandler mockHandler) { - ErrorUtilities.VerifyArgumentNotNull(mockHandler, "mockHandler"); - this.MockWebRequestHandler = mockHandler; + DirectWebResponse response = new DirectWebResponse(origin, origin, redirectionHeaders, HttpStatusCode.Redirect, null, null, new MemoryStream()); + this.RegisterMockResponse(response); } private DirectWebResponse GetMockResponse(HttpWebRequest request) { @@ -178,8 +182,7 @@ } 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()); + 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 007a1d6..782ba2b 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs @@ -7,9 +7,9 @@ namespace DotNetOpenAuth.Test.Mocks { using System; using System.Collections.Generic; - using DotNetOpenAuth.OpenId.RelyingParty; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; -using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.RelyingParty; /// <summary> /// Performs similar to an ordinary <see cref="Identifier"/>, but when called upon @@ -18,7 +18,9 @@ using DotNetOpenAuth.Messaging; /// </summary> internal class MockIdentifier : Identifier { private IEnumerable<ServiceEndpoint> endpoints; + private MockHttpRequest mockHttpRequest; + private Identifier wrappedIdentifier; public MockIdentifier(Identifier wrappedIdentifier, MockHttpRequest mockHttpRequest, IEnumerable<ServiceEndpoint> endpoints) @@ -36,6 +38,18 @@ using DotNetOpenAuth.Messaging; mockHttpRequest.RegisterMockXrdsResponse(new Uri(wrappedIdentifier.ToString()), endpoints); } + public override string ToString() { + return this.wrappedIdentifier.ToString(); + } + + public override bool Equals(object obj) { + return this.wrappedIdentifier.Equals(obj); + } + + public override int GetHashCode() { + return this.wrappedIdentifier.GetHashCode(); + } + internal override IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler) { return this.endpoints; } @@ -48,21 +62,9 @@ using DotNetOpenAuth.Messaging; // We take special care to make our wrapped identifier secure, but still // return a mocked (secure) identifier. Identifier secureWrappedIdentifier; - bool result = wrappedIdentifier.TryRequireSsl(out secureWrappedIdentifier); + bool result = this.wrappedIdentifier.TryRequireSsl(out secureWrappedIdentifier); secureIdentifier = new MockIdentifier(secureWrappedIdentifier, this.mockHttpRequest, this.endpoints); return result; } - - public override string ToString() { - return this.wrappedIdentifier.ToString(); - } - - public override bool Equals(object obj) { - return this.wrappedIdentifier.Equals(obj); - } - - public override int GetHashCode() { - return this.wrappedIdentifier.GetHashCode(); - } } } diff --git a/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs b/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs index 7bc60c7..2b012dd 100644 --- a/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs @@ -50,11 +50,11 @@ namespace DotNetOpenAuth.Test.OpenId { Assert.IsInstanceOfType(id, typeof(UriIdentifier)); Assert.AreEqual(this.uri, ((UriIdentifier)id).Uri.AbsoluteUri); // verify an HTTPS Uri - id = Identifier.Parse(uriHttps); + id = Identifier.Parse(this.uriHttps); Assert.IsInstanceOfType(id, typeof(UriIdentifier)); - Assert.AreEqual(uriHttps, ((UriIdentifier)id).Uri.AbsoluteUri); + Assert.AreEqual(this.uriHttps, ((UriIdentifier)id).Uri.AbsoluteUri); // verify that if the scheme is missing it is added automatically - id = Identifier.Parse(uriNoScheme); + id = Identifier.Parse(this.uriNoScheme); Assert.IsInstanceOfType(id, typeof(UriIdentifier)); Assert.AreEqual(this.uri, ((UriIdentifier)id).Uri.AbsoluteUri); } diff --git a/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs b/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs index 7deafef..be795c3 100644 --- a/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs +++ b/src/DotNetOpenAuth.Test/OpenId/OpenIdTestBase.cs @@ -13,13 +13,14 @@ namespace DotNetOpenAuth.Test.OpenId { using Microsoft.VisualStudio.TestTools.UnitTesting; public class OpenIdTestBase : TestBase { + internal IDirectSslWebRequestHandler RequestHandler; + + internal MockHttpRequest MockResponder; + protected RelyingPartySecuritySettings RelyingPartySecuritySettings { get; private set; } protected ProviderSecuritySettings ProviderSecuritySettings { get; private set; } - internal IDirectSslWebRequestHandler requestHandler; - internal MockHttpRequest mockResponder; - [TestInitialize] public override void SetUp() { base.SetUp(); @@ -27,8 +28,8 @@ namespace DotNetOpenAuth.Test.OpenId { this.RelyingPartySecuritySettings = RelyingPartySection.Configuration.SecuritySettings.CreateSecuritySettings(); this.ProviderSecuritySettings = ProviderSection.Configuration.SecuritySettings.CreateSecuritySettings(); - this.mockResponder = MockHttpRequest.CreateUntrustedMockHttpHandler(); - this.requestHandler = this.mockResponder.MockWebRequestHandler; + this.MockResponder = MockHttpRequest.CreateUntrustedMockHttpHandler(); + this.RequestHandler = this.MockResponder.MockWebRequestHandler; } } } diff --git a/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs b/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs index 4470b99..665c041 100644 --- a/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs +++ b/src/DotNetOpenAuth.Test/OpenId/TestSupport.cs @@ -14,63 +14,80 @@ namespace DotNetOpenAuth.Test.OpenId { using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.RelyingParty; using DotNetOpenAuth.Test.Mocks; - //using DotNetOpenAuth.Test.UI; + ////using DotNetOpenAuth.Test.UI; using log4net; public class TestSupport { - public static readonly string TestWebDirectory = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), @"..\..\src\DotNetOpenId.TestWeb")); public const string HostTestPage = "HostTest.aspx"; + public const string ProviderPage = "ProviderEndpoint.aspx"; + public const string DirectedProviderEndpoint = "DirectedProviderEndpoint.aspx"; + public const string MobileConsumerPage = "RelyingPartyMobile.aspx"; + public const string ConsumerPage = "RelyingParty.aspx"; + public const string OPDefaultPage = "OPDefault.aspx"; - public static Uri ReturnTo { - get { return TestSupport.GetFullUrl(TestSupport.ConsumerPage); } - } - public static Realm Realm { - get { return new Realm(TestSupport.GetFullUrl(TestSupport.ConsumerPage).AbsoluteUri); } - } - public readonly static ILog Logger = LogManager.GetLogger("DotNetOpenId.Test"); + + public static readonly ILog Logger = LogManager.GetLogger("DotNetOpenId.Test"); + + public static readonly string TestWebDirectory = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), @"..\..\src\DotNetOpenId.TestWeb")); + private const string IdentityPage = "IdentityEndpoint.aspx"; + private const string DirectedIdentityPage = "DirectedIdentityEndpoint.aspx"; public enum Scenarios { // Authentication test scenarios AutoApproval, + AutoApprovalAddFragment, + ApproveOnSetup, + AlwaysDeny, - // Extension test scenarios + /* Extension test scenarios */ + /// <summary> /// Provides all required and requested fields. /// </summary> ExtensionFullCooperation, + /// <summary> /// Provides only those fields marked as required. /// </summary> ExtensionPartialCooperation, } + public static Uri ReturnTo { + get { return TestSupport.GetFullUrl(TestSupport.ConsumerPage); } + } + + public static Realm Realm { + get { return new Realm(TestSupport.GetFullUrl(TestSupport.ConsumerPage).AbsoluteUri); } + } + public static Identifier GetDelegateUrl(Scenarios scenario) { return GetDelegateUrl(scenario, false); } - + public static Identifier GetDelegateUrl(Scenarios scenario, bool useSsl) { return new UriIdentifier(GetFullUrl("/" + scenario, null, useSsl)); } - + public static Uri GetFullUrl(string url) { return GetFullUrl(url, null, false); } - + public static Uri GetFullUrl(string url, string key, object value) { - return GetFullUrl(url, new Dictionary<string, string> { - { key, value.ToString() }, - }, false); + var dictionary = new Dictionary<string, string> { + { key, value.ToString() }, + }; + return GetFullUrl(url, dictionary, 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; @@ -84,8 +101,11 @@ namespace DotNetOpenAuth.Test.OpenId { /// </summary> /// <param name="path">The path of the file as it appears within the project, /// where the leading / marks the root directory of the project.</param> + /// <returns>The content of the requested resource.</returns> internal static string LoadEmbeddedFile(string path) { - if (!path.StartsWith("/")) path = "/" + path; + if (!path.StartsWith("/")) { + path = "/" + path; + } path = "DotNetOpenAuth.Test.OpenId" + path.Replace('/', '.'); Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(path); if (resource == null) { @@ -105,23 +125,24 @@ namespace DotNetOpenAuth.Test.OpenId { 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)); + var dictionary = new Dictionary<string, string> { + { "user", scenario.ToString() }, + { "version", providerVersion.ToString() }, + }; + return new UriIdentifier(GetFullUrl("/" + IdentityPage, dictionary, useSsl)); } - + internal static MockIdentifier GetMockIdentifier(Scenarios scenario, MockHttpRequest mockRequest, ProtocolVersion providerVersion) { return GetMockIdentifier(scenario, mockRequest, providerVersion, false); } - + internal static MockIdentifier GetMockIdentifier(Scenarios scenario, MockHttpRequest mockRequest, ProtocolVersion providerVersion, bool useSsl) { ServiceEndpoint se = GetServiceEndpoint(scenario, providerVersion, 10, useSsl); return new MockIdentifier(GetIdentityUrl(scenario, providerVersion, useSsl), mockRequest, new ServiceEndpoint[] { se }); } - + internal static ServiceEndpoint GetServiceEndpoint(Scenarios scenario, ProtocolVersion providerVersion, int servicePriority, bool useSsl) { return ServiceEndpoint.CreateForClaimedIdentifier( GetIdentityUrl(scenario, providerVersion, useSsl), diff --git a/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs b/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs index 1dfb173..f4433f0 100644 --- a/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs @@ -103,7 +103,7 @@ namespace DotNetOpenAuth.Test.OpenId { public void IsValid() { 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."); + Assert.IsTrue(UriIdentifier.IsValidUri(this.relativeUri), "URL lacking http:// prefix should have worked anyway."); } [TestMethod] @@ -161,8 +161,7 @@ namespace DotNetOpenAuth.Test.OpenId { [TestMethod] public void XrdsDiscoveryFromHead() { - this.mockResponder.RegisterMockResponse(new Uri("http://localhost/xrds1020.xml"), - "application/xrds+xml", TestSupport.LoadEmbeddedFile("/Discovery/xrdsdiscovery/xrds1020.xml")); + this.MockResponder.RegisterMockResponse(new Uri("http://localhost/xrds1020.xml"), "application/xrds+xml", TestSupport.LoadEmbeddedFile("/Discovery/xrdsdiscovery/xrds1020.xml")); this.DiscoverXrds("XrdsReferencedInHead.html", ProtocolVersion.V10, null); } @@ -170,7 +169,7 @@ namespace DotNetOpenAuth.Test.OpenId { 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")); + 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); } @@ -215,17 +214,17 @@ namespace DotNetOpenAuth.Test.OpenId { [TestMethod] public void DiscoveryWithRedirects() { - Identifier claimedId = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.mockResponder, ProtocolVersion.V20); + Identifier claimedId = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.MockResponder, ProtocolVersion.V20); // Add a couple of chained redirect pages that lead to the claimedId. Uri userSuppliedUri = TestSupport.GetFullUrl("/someSecurePage", null, true); Uri insecureMidpointUri = TestSupport.GetFullUrl("/insecureStop"); - this.mockResponder.RegisterMockRedirect(userSuppliedUri, insecureMidpointUri); - this.mockResponder.RegisterMockRedirect(insecureMidpointUri, new Uri(claimedId.ToString())); + this.MockResponder.RegisterMockRedirect(userSuppliedUri, insecureMidpointUri); + this.MockResponder.RegisterMockRedirect(insecureMidpointUri, new Uri(claimedId.ToString())); // don't require secure SSL discovery for this test. Identifier userSuppliedIdentifier = new UriIdentifier(userSuppliedUri, false); - Assert.AreEqual(1, userSuppliedIdentifier.Discover(this.requestHandler).Count()); + Assert.AreEqual(1, userSuppliedIdentifier.Discover(this.RequestHandler).Count()); } [TestMethod] @@ -249,80 +248,81 @@ namespace DotNetOpenAuth.Test.OpenId { Assert.IsFalse(id.TryRequireSsl(out secureId)); Assert.IsFalse(secureId.IsDiscoverySecureEndToEnd); Assert.AreEqual("http://www.yahoo.com/", secureId.ToString()); - Assert.AreEqual(0, secureId.Discover(this.requestHandler).Count()); + Assert.AreEqual(0, secureId.Discover(this.RequestHandler).Count()); id = new UriIdentifier("http://www.yahoo.com"); Assert.IsFalse(id.TryRequireSsl(out secureId)); Assert.IsFalse(secureId.IsDiscoverySecureEndToEnd); Assert.AreEqual("http://www.yahoo.com/", secureId.ToString()); - Assert.AreEqual(0, secureId.Discover(this.requestHandler).Count()); + Assert.AreEqual(0, secureId.Discover(this.RequestHandler).Count()); } [TestMethod] public void DiscoverRequireSslWithSecureRedirects() { - Identifier claimedId = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.mockResponder, ProtocolVersion.V20, true); + Identifier claimedId = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.MockResponder, ProtocolVersion.V20, true); // Add a couple of chained redirect pages that lead to the claimedId. // All redirects should be secure. Uri userSuppliedUri = TestSupport.GetFullUrl("/someSecurePage", null, true); Uri secureMidpointUri = TestSupport.GetFullUrl("/secureStop", null, true); - this.mockResponder.RegisterMockRedirect(userSuppliedUri, secureMidpointUri); - this.mockResponder.RegisterMockRedirect(secureMidpointUri, new Uri(claimedId.ToString())); + this.MockResponder.RegisterMockRedirect(userSuppliedUri, secureMidpointUri); + this.MockResponder.RegisterMockRedirect(secureMidpointUri, new Uri(claimedId.ToString())); Identifier userSuppliedIdentifier = new UriIdentifier(userSuppliedUri, true); - Assert.AreEqual(1, userSuppliedIdentifier.Discover(this.requestHandler).Count()); + Assert.AreEqual(1, userSuppliedIdentifier.Discover(this.RequestHandler).Count()); } [TestMethod, ExpectedException(typeof(ProtocolException))] public void DiscoverRequireSslWithInsecureRedirect() { - Identifier claimedId = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.mockResponder, ProtocolVersion.V20, true); + Identifier claimedId = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.MockResponder, ProtocolVersion.V20, true); // Add a couple of chained redirect pages that lead to the claimedId. // Include an insecure HTTP jump in those redirects to verify that // the ultimate endpoint is never found as a result of high security profile. Uri userSuppliedUri = TestSupport.GetFullUrl("/someSecurePage", null, true); Uri insecureMidpointUri = TestSupport.GetFullUrl("/insecureStop"); - this.mockResponder.RegisterMockRedirect(userSuppliedUri, insecureMidpointUri); - this.mockResponder.RegisterMockRedirect(insecureMidpointUri, new Uri(claimedId.ToString())); + this.MockResponder.RegisterMockRedirect(userSuppliedUri, insecureMidpointUri); + this.MockResponder.RegisterMockRedirect(insecureMidpointUri, new Uri(claimedId.ToString())); Identifier userSuppliedIdentifier = new UriIdentifier(userSuppliedUri, true); - userSuppliedIdentifier.Discover(this.requestHandler); + userSuppliedIdentifier.Discover(this.RequestHandler); } [TestMethod] public void DiscoveryRequireSslWithInsecureXrdsInSecureHtmlHead() { - var insecureXrdsSource = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.mockResponder, ProtocolVersion.V20, false); + 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); - this.mockResponder.RegisterMockResponse(secureClaimedUri, "text/html", html); + this.MockResponder.RegisterMockResponse(secureClaimedUri, "text/html", html); Identifier userSuppliedIdentifier = new UriIdentifier(secureClaimedUri, true); - Assert.AreEqual(0, userSuppliedIdentifier.Discover(this.requestHandler).Count()); + Assert.AreEqual(0, userSuppliedIdentifier.Discover(this.RequestHandler).Count()); } [TestMethod] public void DiscoveryRequireSslWithInsecureXrdsInSecureHttpHeader() { - var insecureXrdsSource = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.mockResponder, ProtocolVersion.V20, false); + var insecureXrdsSource = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.MockResponder, ProtocolVersion.V20, false); Uri secureClaimedUri = TestSupport.GetFullUrl("/secureId", null, true); string html = "<html><head></head><body></body></html>"; WebHeaderCollection headers = new WebHeaderCollection { { "X-XRDS-Location", insecureXrdsSource } }; - this.mockResponder.RegisterMockResponse(secureClaimedUri, secureClaimedUri, "text/html", headers, html); + this.MockResponder.RegisterMockResponse(secureClaimedUri, secureClaimedUri, "text/html", headers, html); Identifier userSuppliedIdentifier = new UriIdentifier(secureClaimedUri, true); - Assert.AreEqual(0, userSuppliedIdentifier.Discover(this.requestHandler).Count()); + Assert.AreEqual(0, userSuppliedIdentifier.Discover(this.RequestHandler).Count()); } [TestMethod] public void DiscoveryRequireSslWithInsecureXrdsButSecureLinkTags() { - var insecureXrdsSource = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.mockResponder, ProtocolVersion.V20, false); + var insecureXrdsSource = TestSupport.GetMockIdentifier(TestSupport.Scenarios.AutoApproval, this.MockResponder, ProtocolVersion.V20, false); Uri secureClaimedUri = TestSupport.GetFullUrl("/secureId", null, true); Identifier localIdForLinkTag = TestSupport.GetDelegateUrl(TestSupport.Scenarios.AlwaysDeny, true); - string html = string.Format(@" + string html = string.Format( + @" <html><head> <meta http-equiv='X-XRDS-Location' content='{0}'/> <!-- this one will be insecure and ignored --> <link rel='openid2.provider' href='{1}' /> @@ -331,10 +331,10 @@ namespace DotNetOpenAuth.Test.OpenId { HttpUtility.HtmlEncode(insecureXrdsSource), HttpUtility.HtmlEncode(TestSupport.GetFullUrl("/" + TestSupport.ProviderPage, null, true).AbsoluteUri), HttpUtility.HtmlEncode(localIdForLinkTag.ToString())); - this.mockResponder.RegisterMockResponse(secureClaimedUri, "text/html", html); + this.MockResponder.RegisterMockResponse(secureClaimedUri, "text/html", html); Identifier userSuppliedIdentifier = new UriIdentifier(secureClaimedUri, true); - Assert.AreEqual(localIdForLinkTag, userSuppliedIdentifier.Discover(this.requestHandler).Single().ProviderLocalIdentifier); + Assert.AreEqual(localIdForLinkTag, userSuppliedIdentifier.Discover(this.RequestHandler).Single().ProviderLocalIdentifier); } [TestMethod] @@ -342,8 +342,8 @@ namespace DotNetOpenAuth.Test.OpenId { var insecureEndpoint = TestSupport.GetServiceEndpoint(TestSupport.Scenarios.AutoApproval, ProtocolVersion.V20, 10, false); var secureEndpoint = TestSupport.GetServiceEndpoint(TestSupport.Scenarios.ApproveOnSetup, ProtocolVersion.V20, 20, true); UriIdentifier secureClaimedId = new UriIdentifier(TestSupport.GetFullUrl("/claimedId", null, true), true); - this.mockResponder.RegisterMockXrdsResponse(secureClaimedId, new ServiceEndpoint[] { insecureEndpoint, secureEndpoint }); - Assert.AreEqual(secureEndpoint.ProviderLocalIdentifier, secureClaimedId.Discover(this.requestHandler).Single().ProviderLocalIdentifier); + 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) { @@ -368,9 +368,9 @@ namespace DotNetOpenAuth.Test.OpenId { } else { throw new InvalidOperationException(); } - this.mockResponder.RegisterMockResponse(new Uri(idToDiscover), claimedId, contentType, headers ?? new WebHeaderCollection(), TestSupport.LoadEmbeddedFile(url)); + this.MockResponder.RegisterMockResponse(new Uri(idToDiscover), claimedId, contentType, headers ?? new WebHeaderCollection(), TestSupport.LoadEmbeddedFile(url)); - ServiceEndpoint se = idToDiscover.Discover(this.requestHandler).FirstOrDefault(); + 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); @@ -387,7 +387,9 @@ namespace DotNetOpenAuth.Test.OpenId { } private void DiscoverXrds(string page, ProtocolVersion version, Identifier expectedLocalId, WebHeaderCollection headers) { - if (!page.Contains(".")) page += ".xml"; + 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); } @@ -405,9 +407,9 @@ namespace DotNetOpenAuth.Test.OpenId { private void FailDiscover(string url) { UriIdentifier userSuppliedId = TestSupport.GetFullUrl(url); - this.mockResponder.RegisterMockResponse(new Uri(userSuppliedId), userSuppliedId, "text/html", TestSupport.LoadEmbeddedFile(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 + Assert.AreEqual(0, userSuppliedId.Discover(this.RequestHandler).Count()); // ... but that no endpoint info is discoverable } private void FailDiscoverHtml(string scenario) { diff --git a/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs b/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs index 4d349ff..b6b2e55 100644 --- a/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs +++ b/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs @@ -125,7 +125,7 @@ namespace DotNetOpenAuth.Test.OpenId { { "https://xri.net/=Arnott?_xrd_r=application/xrd%2Bxml;sep=false", xrds }, { "https://xri.net/=!9B72.7DD1.50A9.5CCD?_xrd_r=application/xrd%2Bxml;sep=false", xrds }, }; - this.mockResponder.RegisterMockXrdsResponses(mocks); + this.MockResponder.RegisterMockXrdsResponses(mocks); string expectedCanonicalId = "=!9B72.7DD1.50A9.5CCD"; ServiceEndpoint se = this.VerifyCanonicalId("=Arnott", expectedCanonicalId); @@ -351,7 +351,7 @@ uEyb50RJ7DWmXctSC0b3eymZ2lSXxAWNOsNy </X509Data> </KeyInfo> </XRD>"; - this.mockResponder.RegisterMockXrdsResponses(new Dictionary<string, string> { + this.MockResponder.RegisterMockXrdsResponses(new Dictionary<string, string> { { "https://xri.net/@llli?_xrd_r=application/xrd%2Bxml;sep=false", llliResponse }, { "https://xri.net/@llli*area?_xrd_r=application/xrd%2Bxml;sep=false", llliAreaResponse }, { "https://xri.net/@llli*area*canada.unattached?_xrd_r=application/xrd%2Bxml;sep=false", llliAreaCanadaUnattachedResponse }, @@ -367,7 +367,7 @@ uEyb50RJ7DWmXctSC0b3eymZ2lSXxAWNOsNy [TestMethod] public void DiscoveryCommunityInameDelegateWithoutCanonicalID() { - this.mockResponder.RegisterMockXrdsResponses(new Dictionary<string, string> { + this.MockResponder.RegisterMockXrdsResponses(new Dictionary<string, string> { { "https://xri.net/=Web*andrew.arnott?_xrd_r=application/xrd%2Bxml;sep=false", @"<?xml version='1.0' encoding='UTF-8'?> <XRD xmlns='xri://$xrd*($v*2.0)'> <Query>*andrew.arnott</Query> @@ -459,7 +459,7 @@ uEyb50RJ7DWmXctSC0b3eymZ2lSXxAWNOsNy } private ServiceEndpoint VerifyCanonicalId(Identifier iname, string expectedClaimedIdentifier) { - ServiceEndpoint se = iname.Discover(this.requestHandler).FirstOrDefault(); + 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); diff --git a/src/DotNetOpenAuth.Test/Settings.StyleCop b/src/DotNetOpenAuth.Test/Settings.StyleCop index d7b9e54..d8cb897 100644 --- a/src/DotNetOpenAuth.Test/Settings.StyleCop +++ b/src/DotNetOpenAuth.Test/Settings.StyleCop @@ -33,5 +33,15 @@ </CollectionProperty> </AnalyzerSettings> </Analyzer> + <Analyzer AnalyzerId="Microsoft.StyleCop.CSharp.MaintainabilityRules"> + <Rules> + <Rule Name="FieldsMustBePrivate"> + <RuleSettings> + <BooleanProperty Name="Enabled">False</BooleanProperty> + </RuleSettings> + </Rule> + </Rules> + <AnalyzerSettings /> + </Analyzer> </Analyzers> </StyleCopSettings>
\ No newline at end of file diff --git a/src/DotNetOpenAuth/Messaging/DirectWebResponse.cs b/src/DotNetOpenAuth/Messaging/DirectWebResponse.cs index a0462f3..45feae8 100644 --- a/src/DotNetOpenAuth/Messaging/DirectWebResponse.cs +++ b/src/DotNetOpenAuth/Messaging/DirectWebResponse.cs @@ -210,7 +210,7 @@ namespace DotNetOpenAuth.Messaging { // 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. + //// 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); diff --git a/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs b/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs index 85a7436..9a196e1 100644 --- a/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs +++ b/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs @@ -309,7 +309,7 @@ namespace DotNetOpenAuth.Messaging { } private bool IsHostBlacklisted(string host) { - return IsHostInList(host, BlacklistHosts, BlacklistHostsRegex); + return this.IsHostInList(host, this.BlacklistHosts, this.BlacklistHostsRegex); } private bool IsHostInList(string host, ICollection<string> stringList, ICollection<Regex> regexList) { @@ -341,7 +341,7 @@ namespace DotNetOpenAuth.Messaging { } private bool IsUriAllowable(Uri uri) { - Debug.Assert(uri != null); + ErrorUtilities.VerifyArgumentNotNull(uri, "uri"); if (!this.allowableSchemes.Contains(uri.Scheme)) { Logger.WarnFormat("Rejecting URL {0} because it uses a disallowed scheme.", uri); return false; @@ -365,6 +365,7 @@ namespace DotNetOpenAuth.Messaging { IPAddress hostIPAddress; if (IPAddress.TryParse(uri.DnsSafeHost, out hostIPAddress)) { byte[] addressBytes = hostIPAddress.GetAddressBytes(); + // The host is actually an IP address. switch (hostIPAddress.AddressFamily) { case System.Net.Sockets.AddressFamily.InterNetwork: diff --git a/src/DotNetOpenAuth/Messaging/UserAgentResponse.cs b/src/DotNetOpenAuth/Messaging/UserAgentResponse.cs index 5b3183d..f093161 100644 --- a/src/DotNetOpenAuth/Messaging/UserAgentResponse.cs +++ b/src/DotNetOpenAuth/Messaging/UserAgentResponse.cs @@ -26,7 +26,7 @@ namespace DotNetOpenAuth.Messaging { /// can be canceled by calling <see cref="HttpResponse.End"/> after this message /// is sent on the response stream.</para> /// </remarks> - public class UserAgentResponse { // TODO: rename this to UserAgentResponse + public class UserAgentResponse { /// <summary> /// Initializes a new instance of the <see cref="UserAgentResponse"/> class. /// </summary> diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs index d4d0b34..ebd8518 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs @@ -11,7 +11,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// An <see cref="IProviderEndpoint"/> interface with additional members for use /// in sorting for most preferred endpoint. /// </summary> - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xrds")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xrds", Justification = "Xrds is an acronym.")] public interface IXrdsProviderEndpoint : IProviderEndpoint { /// <summary> /// Gets the priority associated with this service that may have been given @@ -31,6 +31,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <summary> /// Checks for the presence of a given Type URI in an XRDS service. /// </summary> + /// <param name="typeUri">The type URI to check for.</param> + /// <returns><c>true</c> if the service type uri is present; <c>false</c> otherwise.</returns> bool IsTypeUriPresent(string typeUri); } } diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs index 9d79e82..386e9c9 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs @@ -1,3 +1,9 @@ +//----------------------------------------------------------------------- +// <copyright file="ServiceEndpoint.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + namespace DotNetOpenAuth.OpenId.RelyingParty { using System; using System.Collections.Generic; @@ -30,9 +36,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { this.uriPriority = uriPriority; } - /// <summary> + /// <remarks> /// Used for deserializing <see cref="ServiceEndpoint"/> from authentication responses. - /// </summary> + /// </remarks> private ServiceEndpoint(Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Uri providerEndpoint, Identifier providerLocalIdentifier, Protocol protocol) { this.ClaimedIdentifier = claimedIdentifier; this.UserSuppliedIdentifier = userSuppliedIdentifier; @@ -52,15 +58,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// </remarks> public Uri ProviderEndpoint { get; private set; } - /// <summary> - /// Returns true if the <see cref="ProviderEndpoint"/> is using an encrypted channel. - /// </summary> /* /// <summary> /// An Identifier for an OpenID Provider. /// </summary> public Identifier ProviderIdentifier { get; private set; } */ + /// <summary> /// Gets the Identifier that was presented by the end user to the Relying Party, /// or selected by the user at the OpenID Provider. @@ -92,7 +96,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { XriIdentifier xri = this.ClaimedIdentifier as XriIdentifier; UriIdentifier uri = this.ClaimedIdentifier as UriIdentifier; if (xri != null) { - if (UserSuppliedIdentifier == null || String.Equals(UserSuppliedIdentifier, ClaimedIdentifier, StringComparison.OrdinalIgnoreCase)) { + if (this.UserSuppliedIdentifier == null || String.Equals(this.UserSuppliedIdentifier, this.ClaimedIdentifier, StringComparison.OrdinalIgnoreCase)) { this.friendlyIdentifierForDisplay = this.ClaimedIdentifier; } else { this.friendlyIdentifierForDisplay = this.UserSuppliedIdentifier; @@ -101,10 +105,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { 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. // Since this is for display purposes, we want to reverse this and display a readable // representation of these foreign characters. - friendlyIdentifierForDisplay = Uri.UnescapeDataString(displayUri); + this.friendlyIdentifierForDisplay = Uri.UnescapeDataString(displayUri); } } else { Debug.Fail("Doh! We never should have reached here."); @@ -127,7 +132,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { public Protocol Protocol { get { if (this.protocol == null) { - this.protocol = Protocol.Detect(ProviderSupportedServiceTypeUris); + this.protocol = Protocol.Detect(this.ProviderSupportedServiceTypeUris); } if (this.protocol != null) { return this.protocol; @@ -155,10 +160,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { #endregion - internal bool IsSecure { - get { return string.Equals(this.ProviderEndpoint.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase); } - } - public static bool operator ==(ServiceEndpoint se1, ServiceEndpoint se2) { return se1.EqualsNullSafe(se2); } @@ -168,7 +169,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } public bool IsTypeUriPresent(string typeUri) { - return IsExtensionSupported(typeUri); + return this.IsExtensionSupported(typeUri); } public bool IsExtensionSupported(string extensionUri) { @@ -213,11 +214,19 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { Version IProviderEndpoint.Version { get { return Protocol.Version; } } + /// <summary> + /// Gets a value indicating whether the <see cref="ProviderEndpoint"/> is using an encrypted channel. + /// </summary> + internal bool IsSecure { + get { return string.Equals(this.ProviderEndpoint.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase); } + } + public override bool Equals(object obj) { ServiceEndpoint other = obj as ServiceEndpoint; 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 @@ -230,20 +239,20 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } public override int GetHashCode() { - return ClaimedIdentifier.GetHashCode(); + return this.ClaimedIdentifier.GetHashCode(); } public override string ToString() { StringBuilder builder = new StringBuilder(); - builder.AppendLine("ClaimedIdentifier: " + ClaimedIdentifier); - builder.AppendLine("ProviderLocalIdentifier: " + ProviderLocalIdentifier); - builder.AppendLine("ProviderEndpoint: " + ProviderEndpoint.AbsoluteUri); - builder.AppendLine("OpenID version: " + Protocol.Version); + builder.AppendLine("ClaimedIdentifier: " + this.ClaimedIdentifier); + builder.AppendLine("ProviderLocalIdentifier: " + this.ProviderLocalIdentifier); + builder.AppendLine("ProviderEndpoint: " + this.ProviderEndpoint.AbsoluteUri); + builder.AppendLine("OpenID version: " + this.Protocol.Version); builder.AppendLine("Service Type URIs:"); - if (ProviderSupportedServiceTypeUris != null) { - foreach (string serviceTypeUri in ProviderSupportedServiceTypeUris) { + if (this.ProviderSupportedServiceTypeUris != null) { + foreach (string serviceTypeUri in this.ProviderSupportedServiceTypeUris) { builder.Append("\t"); - // TODO: uncomment when we support extensions + //// TODO: uncomment when we support extensions ////var matchingExtension = Util.FirstOrDefault(ExtensionManager.RequestExtensions, ext => ext.Key.TypeUri == serviceTypeUri); ////if (matchingExtension.Key != null) { //// builder.AppendLine(string.Format(CultureInfo.CurrentCulture, "{0} ({1})", serviceTypeUri, matchingExtension.Value)); @@ -262,6 +271,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// Reads previously discovered information about an endpoint /// from a solicited authentication assertion for validation. /// </summary> + /// <param name="reader">The reader from which to deserialize the <see cref="ServiceEndpoint"/>.</param> /// <returns> /// A <see cref="ServiceEndpoint"/> object that has everything /// except the <see cref="ProviderSupportedServiceTypeUris"/> @@ -279,14 +289,17 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { return new ServiceEndpoint(claimedIdentifier, userSuppliedIdentifier, providerEndpoint, providerLocalIdentifier, protocol); } - internal static ServiceEndpoint CreateForProviderIdentifier( - Identifier providerIdentifier, Uri providerEndpoint, - string[] providerSupportedServiceTypeUris, int? servicePriority, 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); + 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) { @@ -307,6 +320,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { 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. } } diff --git a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs index b42c56d..194dafe 100644 --- a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs @@ -198,18 +198,21 @@ namespace DotNetOpenAuth.OpenId { internal override IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler) { List<ServiceEndpoint> endpoints = new List<ServiceEndpoint>(); + // Attempt YADIS discovery DiscoveryResult yadisResult = Yadis.Discover(requestHandler, this, IsDiscoverySecureEndToEnd); if (yadisResult != null) { if (yadisResult.IsXrds) { XrdsDocument xrds = new XrdsDocument(yadisResult.ResponseText); var xrdsEndpoints = xrds.CreateServiceEndpoints(yadisResult.NormalizedUri); + // Filter out insecure endpoints if high security is required. if (IsDiscoverySecureEndToEnd) { xrdsEndpoints = xrdsEndpoints.Where(se => se.IsSecure); } endpoints.AddRange(xrdsEndpoints); } + // Failing YADIS discovery of an XRDS document, we try HTML discovery. if (endpoints.Count == 0) { ServiceEndpoint ep = DiscoverFromHtml(yadisResult.NormalizedUri, yadisResult.ResponseText); @@ -334,6 +337,7 @@ namespace DotNetOpenAuth.OpenId { 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)) { diff --git a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs index 5a92737..058a8a4 100644 --- a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs @@ -150,7 +150,7 @@ namespace DotNetOpenAuth.OpenId { } internal override IEnumerable<ServiceEndpoint> Discover(IDirectSslWebRequestHandler requestHandler) { - return downloadXrds(requestHandler).CreateServiceEndpoints(this); + return this.DownloadXrds(requestHandler).CreateServiceEndpoints(this); } /// <summary> @@ -158,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 this.downloadXrds(requestHandler).CreateServiceEndpoints(userSuppliedIdentifier); + return this.DownloadXrds(requestHandler).CreateServiceEndpoints(userSuppliedIdentifier); } /// <summary> @@ -209,7 +209,7 @@ namespace DotNetOpenAuth.OpenId { return xri; } - private XrdsDocument downloadXrds(IDirectSslWebRequestHandler requestHandler) { + private XrdsDocument DownloadXrds(IDirectSslWebRequestHandler requestHandler) { XrdsDocument doc; using (var xrdsResponse = Yadis.Request(requestHandler, this.XrdsUrl, this.IsDiscoverySecureEndToEnd)) { doc = new XrdsDocument(XmlReader.Create(xrdsResponse.ResponseStream)); diff --git a/src/DotNetOpenAuth/Util.cs b/src/DotNetOpenAuth/Util.cs index 1abbccc..5ee7302 100644 --- a/src/DotNetOpenAuth/Util.cs +++ b/src/DotNetOpenAuth/Util.cs @@ -60,14 +60,16 @@ namespace DotNetOpenAuth { /// for logging complex objects without being in a conditional block. /// </remarks> internal static object ToStringDeferred<K, V>(this IEnumerable<KeyValuePair<K, V>> pairs) { - return new DelayedToString<IEnumerable<KeyValuePair<K, V>>>(pairs, p => { - var dictionary = pairs as IDictionary<K, V>; - StringBuilder sb = new StringBuilder(dictionary != null ? dictionary.Count * 40 : 200); - foreach (var pair in pairs) { - sb.AppendFormat("\t{0}: {1}{2}", pair.Key, pair.Value, Environment.NewLine); - } - return sb.ToString(); - }); + return new DelayedToString<IEnumerable<KeyValuePair<K, V>>>( + pairs, + p => { + var dictionary = pairs as IDictionary<K, V>; + StringBuilder sb = new StringBuilder(dictionary != null ? dictionary.Count * 40 : 200); + foreach (var pair in pairs) { + sb.AppendFormat("\t{0}: {1}{2}", pair.Key, pair.Value, Environment.NewLine); + } + return sb.ToString(); + }); } internal static object ToStringDeferred<T>(this IEnumerable<T> list) { @@ -75,44 +77,46 @@ namespace DotNetOpenAuth { } internal static object ToStringDeferred<T>(this IEnumerable<T> list, bool multiLineElements) { - return new DelayedToString<IEnumerable<T>>(list, l => { - StringBuilder sb = new StringBuilder(); - if (multiLineElements) { - sb.AppendLine("[{"); - foreach (T obj in l) { - // Prepare the string repersentation of the object - string objString = obj != null ? obj.ToString() : "<NULL>"; + return new DelayedToString<IEnumerable<T>>( + list, + l => { + StringBuilder sb = new StringBuilder(); + if (multiLineElements) { + sb.AppendLine("[{"); + foreach (T obj in l) { + // Prepare the string repersentation of the object + string objString = obj != null ? obj.ToString() : "<NULL>"; - // Indent every line printed - objString = objString.Replace(Environment.NewLine, Environment.NewLine + "\t"); - sb.Append("\t"); - sb.Append(objString); + // Indent every line printed + objString = objString.Replace(Environment.NewLine, Environment.NewLine + "\t"); + sb.Append("\t"); + sb.Append(objString); - if (!objString.EndsWith(Environment.NewLine)) { - sb.AppendLine(); + if (!objString.EndsWith(Environment.NewLine)) { + sb.AppendLine(); + } + sb.AppendLine("}, {"); } - sb.AppendLine("}, {"); - } - if (sb.Length > 2) { // if anything was in the enumeration - sb.Length -= 2 + Environment.NewLine.Length; // trim off the last ", {\r\n" + if (sb.Length > 2) { // if anything was in the enumeration + sb.Length -= 2 + Environment.NewLine.Length; // trim off the last ", {\r\n" + } else { + sb.Length -= 1; // trim off the opening { + } + sb.Append("]"); + return sb.ToString(); } else { - sb.Length -= 1; // trim off the opening { - } - sb.Append("]"); - return sb.ToString(); - } else { - sb.Append("{"); - foreach (T obj in l) { - sb.Append(obj != null ? obj.ToString() : "<NULL>"); - sb.AppendLine(","); - } - if (sb.Length > 1) { - sb.Length -= 1; + sb.Append("{"); + foreach (T obj in l) { + sb.Append(obj != null ? obj.ToString() : "<NULL>"); + sb.AppendLine(","); + } + if (sb.Length > 1) { + sb.Length -= 1; + } + sb.Append("}"); + return sb.ToString(); } - sb.Append("}"); - return sb.ToString(); - } - }); + }); } internal static HttpWebRequest CreatePostRequest(Uri requestUri, string body) { @@ -134,7 +138,7 @@ namespace DotNetOpenAuth { } public override string ToString() { - return this.toString(obj); + return this.toString(this.obj); } } } diff --git a/src/DotNetOpenAuth/Xrds/ServiceElement.cs b/src/DotNetOpenAuth/Xrds/ServiceElement.cs index d593f6c..ce9cd49 100644 --- a/src/DotNetOpenAuth/Xrds/ServiceElement.cs +++ b/src/DotNetOpenAuth/Xrds/ServiceElement.cs @@ -68,7 +68,9 @@ namespace DotNetOpenAuth.Xrds { #region IComparable<ServiceElement> Members public int CompareTo(ServiceElement other) { - if (other == null) return -1; + if (other == null) { + return -1; + } if (this.Priority.HasValue && other.Priority.HasValue) { return this.Priority.Value.CompareTo(other.Priority.Value); } else { diff --git a/src/DotNetOpenAuth/Xrds/UriElement.cs b/src/DotNetOpenAuth/Xrds/UriElement.cs index f47e507..8dbfad1 100644 --- a/src/DotNetOpenAuth/Xrds/UriElement.cs +++ b/src/DotNetOpenAuth/Xrds/UriElement.cs @@ -34,7 +34,7 @@ namespace DotNetOpenAuth.Xrds { if (other == null) { return -1; } - int compare = Service.CompareTo(other.Service); + int compare = this.Service.CompareTo(other.Service); if (compare != 0) { return compare; } diff --git a/src/DotNetOpenAuth/Xrds/XrdElement.cs b/src/DotNetOpenAuth/Xrds/XrdElement.cs index 5f90936..e52eb77 100644 --- a/src/DotNetOpenAuth/Xrds/XrdElement.cs +++ b/src/DotNetOpenAuth/Xrds/XrdElement.cs @@ -7,12 +7,13 @@ namespace DotNetOpenAuth.Xrds { using System; using System.Collections.Generic; + using System.Linq; using System.Text; using System.Xml.XPath; - using DotNetOpenAuth.OpenId; using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId; - class XrdElement : XrdsNode { + internal class XrdElement : XrdsNode { public XrdElement(XPathNavigator xrdElement, XrdsDocument parent) : base(xrdElement, parent) { } @@ -31,7 +32,7 @@ namespace DotNetOpenAuth.Xrds { public bool IsXriResolutionSuccessful { get { - return XriResolutionStatusCode == 100; + return this.XriResolutionStatusCode == 100; } } @@ -49,45 +50,43 @@ 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; - } - } - /// <summary> - /// Returns services for OP Identifiers. + /// Gets the services for OP Identifiers. /// </summary> public IEnumerable<ServiceElement> OpenIdProviderIdentifierServices { - get { return SearchForServiceTypeUris(p => p.OPIdentifierServiceTypeURI); } + get { return this.SearchForServiceTypeUris(p => p.OPIdentifierServiceTypeURI); } } /// <summary> - /// Returns services for Claimed Identifiers. + /// Gets the services for Claimed Identifiers. /// </summary> public IEnumerable<ServiceElement> OpenIdClaimedIdentifierServices { - get { return SearchForServiceTypeUris(p => p.ClaimedIdentifierServiceTypeURI); } + get { return this.SearchForServiceTypeUris(p => p.ClaimedIdentifierServiceTypeURI); } } public IEnumerable<ServiceElement> OpenIdRelyingPartyReturnToServices { - get { return SearchForServiceTypeUris(p => p.RPReturnToTypeURI); } + get { return this.SearchForServiceTypeUris(p => p.RPReturnToTypeURI); } } /// <summary> - /// An enumeration of all Service/URI elements, sorted in priority order. + /// Gets an enumeration of all Service/URI elements, sorted in priority order. /// </summary> public IEnumerable<UriElement> ServiceUris { get { - foreach (ServiceElement service in Services) { - foreach (UriElement uri in service.UriElements) { - yield return uri; - } - } + return from service in this.Services + from uri in service.UriElements + select uri; + } + } + + 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; } } @@ -96,7 +95,9 @@ namespace DotNetOpenAuth.Xrds { xpath.Append("xrd:Service["); foreach (var protocol in Protocol.AllVersions) { string typeUri = p(protocol); - if (typeUri == null) continue; + if (typeUri == null) { + continue; + } xpath.Append("xrd:Type/text()='"); xpath.Append(typeUri); xpath.Append("' or "); @@ -107,6 +108,7 @@ namespace DotNetOpenAuth.Xrds { 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 9b073ca..bc66f6e 100644 --- a/src/DotNetOpenAuth/Xrds/XrdsDocument.cs +++ b/src/DotNetOpenAuth/Xrds/XrdsDocument.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.Xrds { using System.Collections.Generic; using System.IO; + using System.Linq; using System.Xml; using System.Xml.XPath; using DotNetOpenAuth.Messaging; @@ -20,8 +21,10 @@ namespace DotNetOpenAuth.Xrds { XmlNamespaceResolver.AddNamespace("xrds", XrdsNode.XrdsNamespace); XmlNamespaceResolver.AddNamespace("openid10", Protocol.V10.XmlNamespace); } + public XrdsDocument(XmlReader reader) : this(new XPathDocument(reader).CreateNavigator()) { } + public XrdsDocument(string xml) : this(new XPathDocument(new StringReader(xml)).CreateNavigator()) { } @@ -41,9 +44,14 @@ namespace DotNetOpenAuth.Xrds { } } + internal bool IsXrdResolutionSuccessful { + get { return this.XrdElements.All(xrd => xrd.IsXriResolutionSuccessful); } + } + internal IEnumerable<ServiceEndpoint> CreateServiceEndpoints(UriIdentifier claimedIdentifier) { var endpoints = new List<ServiceEndpoint>(); 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) { @@ -57,6 +65,7 @@ namespace DotNetOpenAuth.Xrds { internal IEnumerable<ServiceEndpoint> CreateServiceEndpoints(XriIdentifier userSuppliedIdentifier) { var endpoints = new List<ServiceEndpoint>(); 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) { @@ -68,43 +77,22 @@ 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); - } - } - } - - internal bool IsXrdResolutionSuccessful { - get { - foreach (var xrd in this.XrdElements) { - if (!xrd.IsXriResolutionSuccessful) { - return false; - } - } - return true; - } + return from service in this.FindReturnToServices() + from uri in service.UriElements + select new RelyingPartyEndpointDescription(uri.Uri, service.TypeElementUris); } 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( - opIdentifier, uri.Uri, service.TypeElementUris, - service.Priority, uri.Priority); - } - } + return from service in this.FindOPIdentifierServices() + from uri in service.UriElements + let protocol = Protocol.FindBestVersion(p => p.OPIdentifierServiceTypeURI, service.TypeElementUris) + select ServiceEndpoint.CreateForProviderIdentifier(opIdentifier, uri.Uri, service.TypeElementUris, service.Priority, uri.Priority); } private IEnumerable<ServiceEndpoint> GenerateClaimedIdentifierServiceEndpoints(UriIdentifier claimedIdentifier) { - foreach (var service in FindClaimedIdentifierServices()) { - foreach (var uri in service.UriElements) { - yield return ServiceEndpoint.CreateForClaimedIdentifier( - claimedIdentifier, service.ProviderLocalIdentifier, - uri.Uri, service.TypeElementUris, service.Priority, uri.Priority); - } - } + return from service in this.FindClaimedIdentifierServices() + from uri in service.UriElements + select ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, service.ProviderLocalIdentifier, uri.Uri, service.TypeElementUris, service.Priority, uri.Priority); } private IEnumerable<ServiceEndpoint> GenerateClaimedIdentifierServiceEndpoints(XriIdentifier userSuppliedIdentifier) { @@ -116,41 +104,35 @@ namespace DotNetOpenAuth.Xrds { break; // skip on to next service } ErrorUtilities.VerifyProtocol(service.Xrd.IsCanonicalIdVerified, XrdsStrings.CIDVerificationFailed, userSuppliedIdentifier); + // In the case of XRI names, the ClaimedId is actually the CanonicalID. var claimedIdentifier = new XriIdentifier(service.Xrd.CanonicalID); - yield return ServiceEndpoint.CreateForClaimedIdentifier( - claimedIdentifier, userSuppliedIdentifier, service.ProviderLocalIdentifier, - uri.Uri, service.TypeElementUris, service.Priority, uri.Priority); + yield return ServiceEndpoint.CreateForClaimedIdentifier(claimedIdentifier, userSuppliedIdentifier, service.ProviderLocalIdentifier, uri.Uri, service.TypeElementUris, service.Priority, uri.Priority); } } } private IEnumerable<ServiceElement> FindOPIdentifierServices() { - foreach (var xrd in this.XrdElements) { - foreach (var service in xrd.OpenIdProviderIdentifierServices) { - yield return service; - } - } + return from xrd in this.XrdElements + from service in xrd.OpenIdProviderIdentifierServices + select service; } /// <summary> /// Returns the OpenID-compatible services described by a given XRDS document, /// in priority order. /// </summary> + /// <returns>A sequence of the services offered.</returns> private IEnumerable<ServiceElement> FindClaimedIdentifierServices() { - foreach (var xrd in this.XrdElements) { - foreach (var service in xrd.OpenIdClaimedIdentifierServices) { - yield return service; - } - } + return from xrd in this.XrdElements + from service in xrd.OpenIdClaimedIdentifierServices + select service; } private IEnumerable<ServiceElement> FindReturnToServices() { - foreach (var xrd in this.XrdElements) { - foreach (var service in xrd.OpenIdRelyingPartyReturnToServices) { - yield return service; - } - } + return from xrd in this.XrdElements + from service in xrd.OpenIdRelyingPartyReturnToServices + select service; } } } diff --git a/src/DotNetOpenAuth/Xrds/XrdsNode.cs b/src/DotNetOpenAuth/Xrds/XrdsNode.cs index a1da430..d015dcb 100644 --- a/src/DotNetOpenAuth/Xrds/XrdsNode.cs +++ b/src/DotNetOpenAuth/Xrds/XrdsNode.cs @@ -22,17 +22,18 @@ namespace DotNetOpenAuth.Xrds { protected XrdsNode(XPathNavigator node, XrdsNode parentNode) { this.Node = node; this.ParentNode = parentNode; - this.XmlNamespaceResolver = ParentNode.XmlNamespaceResolver; + this.XmlNamespaceResolver = this.ParentNode.XmlNamespaceResolver; } + protected XrdsNode(XPathNavigator document) { this.Node = document; this.XmlNamespaceResolver = new XmlNamespaceManager(document.NameTable); } protected XPathNavigator Node { get; private set; } - + protected XrdsNode ParentNode { get; private set; } - + protected XmlNamespaceManager XmlNamespaceResolver { get; private set; } } } diff --git a/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs b/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs index 391df23..5d2550e 100644 --- a/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs +++ b/src/DotNetOpenAuth/Yadis/DiscoveryResult.cs @@ -40,7 +40,7 @@ namespace DotNetOpenAuth.Yadis { } /// <summary> - /// The URI of the original YADIS discovery request. + /// Gets the URI of the original YADIS discovery request. /// This is the user supplied Identifier as given in the original /// YADIS discovery request. /// </summary> @@ -59,7 +59,7 @@ namespace DotNetOpenAuth.Yadis { public Uri YadisLocation { get; private set; } /// <summary> - /// The Content-Type associated with the <see cref="ResponseText"/>. + /// Gets the Content-Type associated with the <see cref="ResponseText"/>. /// </summary> public ContentType ContentType { get; private set; } @@ -77,10 +77,11 @@ namespace DotNetOpenAuth.Yadis { public bool IsXrds { get; private set; } /// <summary> - /// Gets whether discovery resulted in an XRDS document at a referred location. + /// Gets a value indicating whether discovery resulted in an + /// XRDS document at a referred location. /// </summary> - /// <value><c>true</c> if the response to the userSuppliedIdentifier pointed to a different URL - /// for the XRDS document.</value> + /// <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 this.YadisLocation != null; } } diff --git a/src/DotNetOpenAuth/Yadis/HtmlParser.cs b/src/DotNetOpenAuth/Yadis/HtmlParser.cs index fbf5d45..3338b9b 100644 --- a/src/DotNetOpenAuth/Yadis/HtmlParser.cs +++ b/src/DotNetOpenAuth/Yadis/HtmlParser.cs @@ -13,14 +13,14 @@ namespace DotNetOpenAuth.Yadis { using System.Web.UI.HtmlControls; internal static class HtmlParser { - private static readonly Regex attrRe = new Regex("\n# Must start with a sequence of word-characters, followed by an equals sign\n(?<attrname>(\\w|-)+)=\n\n# Then either a quoted or unquoted attribute\n(?:\n\n # Match everything that's between matching quote marks\n (?<qopen>[\"\\'])(?<attrval>.*?)\\k<qopen>\n|\n\n # If the value is not quoted, match up to whitespace\n (?<attrval>(?:[^\\s<>/]|/(?!>))+)\n)\n\n|\n\n(?<endtag>[<>])\n ", flags); - private const RegexOptions flags = (RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase); - private const string tagExpr = "\n# Starts with the tag name at a word boundary, where the tag name is\n# not a namespace\n<{0}\\b(?!:)\n \n# All of the stuff up to a \">\", hopefully attributes.\n(?<attrs>[^>]*?)\n \n(?: # Match a short tag\n />\n \n| # Match a full tag\n >\n \n (?<contents>.*?)\n \n # Closed by\n (?: # One of the specified close tags\n </?{1}\\s*>\n \n # End of the string\n | \\Z\n \n )\n \n)\n "; - private const string startTagExpr = "\n# Starts with the tag name at a word boundary, where the tag name is\n# not a namespace\n<{0}\\b(?!:)\n \n# All of the stuff up to a \">\", hopefully attributes.\n(?<attrs>[^>]*?)\n \n(?: # Match a short tag\n />\n \n| # Match a full tag\n >\n )\n "; + private static readonly Regex attrRe = new Regex("\n# Must start with a sequence of word-characters, followed by an equals sign\n(?<attrname>(\\w|-)+)=\n\n# Then either a quoted or unquoted attribute\n(?:\n\n # Match everything that's between matching quote marks\n (?<qopen>[\"\\'])(?<attrval>.*?)\\k<qopen>\n|\n\n # If the value is not quoted, match up to whitespace\n (?<attrval>(?:[^\\s<>/]|/(?!>))+)\n)\n\n|\n\n(?<endtag>[<>])\n ", Flags); + private const RegexOptions Flags = (RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase); + private const string TagExpr = "\n# Starts with the tag name at a word boundary, where the tag name is\n# not a namespace\n<{0}\\b(?!:)\n \n# All of the stuff up to a \">\", hopefully attributes.\n(?<attrs>[^>]*?)\n \n(?: # Match a short tag\n />\n \n| # Match a full tag\n >\n \n (?<contents>.*?)\n \n # Closed by\n (?: # One of the specified close tags\n </?{1}\\s*>\n \n # End of the string\n | \\Z\n \n )\n \n)\n "; + private const string StartTagExpr = "\n# Starts with the tag name at a word boundary, where the tag name is\n# not a namespace\n<{0}\\b(?!:)\n \n# All of the stuff up to a \">\", hopefully attributes.\n(?<attrs>[^>]*?)\n \n(?: # Match a short tag\n />\n \n| # Match a full tag\n >\n )\n "; - private static readonly Regex headRe = tagMatcher("head", new[] { "body" }); - private static readonly Regex htmlRe = tagMatcher("html", new string[0]); - private static readonly Regex removedRe = new Regex(@"<!--.*?-->|<!\[CDATA\[.*?\]\]>|<script\b[^>]*>.*?</script>", flags); + private static readonly Regex headRe = TagMatcher("head", new[] { "body" }); + private static readonly Regex htmlRe = TagMatcher("html", new string[0]); + private static readonly Regex removedRe = new Regex(@"<!--.*?-->|<!\[CDATA\[.*?\]\]>|<script\b[^>]*>.*?</script>", Flags); public static IEnumerable<T> HeadTags<T>(string html) where T : HtmlControl, new() { html = removedRe.Replace(html, string.Empty); @@ -31,7 +31,7 @@ namespace DotNetOpenAuth.Yadis { if (match2.Success) { string text = null; string text2 = null; - Regex regex = startTagMatcher(tagName); + Regex regex = StartTagMatcher(tagName); for (Match match3 = regex.Match(html, match2.Index, match2.Length); match3.Success; match3 = match3.NextMatch()) { int beginning = (match3.Index + tagName.Length) + 1; int length = (match3.Index + match3.Length) - beginning; @@ -52,7 +52,7 @@ namespace DotNetOpenAuth.Yadis { } } - private 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(); @@ -70,12 +70,11 @@ namespace DotNetOpenAuth.Yadis { } else { text2 = tagName; } - return new Regex(string.Format(CultureInfo.InvariantCulture, - tagExpr, tagName, text2), flags); + return new Regex(string.Format(CultureInfo.InvariantCulture, TagExpr, tagName, text2), Flags); } - private static Regex startTagMatcher(string tag_name) { - return new Regex(string.Format(CultureInfo.InvariantCulture, startTagExpr, tag_name), flags); + private static Regex StartTagMatcher(string tag_name) { + return new Regex(string.Format(CultureInfo.InvariantCulture, StartTagExpr, tag_name), Flags); } } } diff --git a/src/DotNetOpenAuth/Yadis/Yadis.cs b/src/DotNetOpenAuth/Yadis/Yadis.cs index 55d3c0c..3a7ffef 100644 --- a/src/DotNetOpenAuth/Yadis/Yadis.cs +++ b/src/DotNetOpenAuth/Yadis/Yadis.cs @@ -7,14 +7,13 @@ namespace DotNetOpenAuth.Yadis { using System; using System.IO; - using System.Net.Mime; + using System.Net; + using System.Net.Cache; using System.Web.UI.HtmlControls; using System.Xml; - using DotNetOpenAuth.OpenId; using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId; using DotNetOpenAuth.Xrds; - using System.Net.Cache; - using System.Net; internal class Yadis { internal const string HeaderName = "X-XRDS-Location"; @@ -22,19 +21,7 @@ namespace DotNetOpenAuth.Yadis { /// <summary> /// Gets or sets the cache that can be used for HTTP requests made during identifier discovery. /// </summary> - internal readonly static RequestCachePolicy IdentifierDiscoveryCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.CacheIfAvailable); - - internal static DirectWebResponse Request(IDirectSslWebRequestHandler requestHandler, Uri uri, bool requireSsl, params string[] acceptTypes) { - ErrorUtilities.VerifyArgumentNotNull(uri, "uri"); - - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); - request.CachePolicy = IdentifierDiscoveryCachePolicy; - if (acceptTypes != null) { - request.Accept = string.Join(",", acceptTypes); - } - - return requestHandler.GetResponse(request, requireSsl); - } + internal static readonly RequestCachePolicy IdentifierDiscoveryCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.CacheIfAvailable); /// <summary> /// Performs YADIS discovery on some identifier. @@ -66,7 +53,7 @@ namespace DotNetOpenAuth.Yadis { return null; } DirectWebResponse response2 = null; - if (isXrdsDocument(response)) { + if (IsXrdsDocument(response)) { Logger.Debug("An XRDS response was received from GET at user-supplied identifier."); response2 = response; } else { @@ -98,7 +85,38 @@ namespace DotNetOpenAuth.Yadis { return new DiscoveryResult(uri, response, response2); } - private static bool isXrdsDocument(DirectWebResponse response) { + /// <summary> + /// Searches an HTML document for a + /// <meta http-equiv="X-XRDS-Location" content="{YadisURL}"> + /// tag and returns the content of YadisURL. + /// </summary> + public static Uri FindYadisDocumentLocationInHtmlMetaTags(string html) { + foreach (var metaTag in HtmlParser.HeadTags<HtmlMeta>(html)) { + if (HeaderName.Equals(metaTag.HttpEquiv, StringComparison.OrdinalIgnoreCase)) { + if (metaTag.Content != null) { + Uri uri; + if (Uri.TryCreate(metaTag.Content, UriKind.Absolute, out uri)) { + return uri; + } + } + } + } + return null; + } + + internal static DirectWebResponse Request(IDirectSslWebRequestHandler requestHandler, Uri uri, bool requireSsl, params string[] acceptTypes) { + ErrorUtilities.VerifyArgumentNotNull(uri, "uri"); + + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); + request.CachePolicy = IdentifierDiscoveryCachePolicy; + if (acceptTypes != null) { + request.Accept = string.Join(",", acceptTypes); + } + + return requestHandler.GetResponse(request, requireSsl); + } + + private static bool IsXrdsDocument(DirectWebResponse response) { if (response.ContentType.MediaType == ContentTypes.Xrds) { return true; } @@ -116,23 +134,5 @@ namespace DotNetOpenAuth.Yadis { return false; } - - /// <summary> - /// Searches an HTML document for a - /// <meta http-equiv="X-XRDS-Location" content="{YadisURL}"> - /// tag and returns the content of YadisURL. - /// </summary> - public static Uri FindYadisDocumentLocationInHtmlMetaTags(string html) { - foreach (var metaTag in HtmlParser.HeadTags<HtmlMeta>(html)) { - if (HeaderName.Equals(metaTag.HttpEquiv, StringComparison.OrdinalIgnoreCase)) { - if (metaTag.Content != null) { - Uri uri; - if (Uri.TryCreate(metaTag.Content, UriKind.Absolute, out uri)) - return uri; - } - } - } - return null; - } } } |