diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2013-03-07 17:00:03 -0800 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2013-03-07 17:00:03 -0800 |
commit | bc505e8b3846ee97bec3860acce7d0d92b814955 (patch) | |
tree | 24c39d720943dac08754d095e5720565500eed3c /src | |
parent | 5c50924246387b6d9a5ce668fb389b5ec7d93434 (diff) | |
download | DotNetOpenAuth-bc505e8b3846ee97bec3860acce7d0d92b814955.zip DotNetOpenAuth-bc505e8b3846ee97bec3860acce7d0d92b814955.tar.gz DotNetOpenAuth-bc505e8b3846ee97bec3860acce7d0d92b814955.tar.bz2 |
Many more unit test build fixes and product touch-ups.
Diffstat (limited to 'src')
23 files changed, 401 insertions, 578 deletions
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs index 421a09e..e7edb66 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs @@ -92,9 +92,10 @@ namespace DotNetOpenAuth.OAuth2 { /// </returns> /// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception> [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "unauthorizedclient", Justification = "Protocol required.")] - public async Task<EndUserAuthorizationRequest> ReadAuthorizationRequestAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) { - request = request ?? this.Channel.GetRequestFromContext(); - var message = await this.Channel.TryReadFromRequestAsync<EndUserAuthorizationRequest>(request.AsHttpRequestMessage(), cancellationToken); + public async Task<EndUserAuthorizationRequest> ReadAuthorizationRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) { + Requires.NotNull(request, "request"); + + var message = await this.Channel.TryReadFromRequestAsync<EndUserAuthorizationRequest>(request, cancellationToken); if (message != null) { if (message.ResponseType == EndUserAuthorizationResponseType.AuthorizationCode) { // Clients with no secrets can only request implicit grant types. @@ -110,41 +111,44 @@ namespace DotNetOpenAuth.OAuth2 { /// Reads in a client's request for the Authorization Server to obtain permission from /// the user to authorize the Client's access of some protected resource(s). /// </summary> - /// <param name="requestUri">The URL that carries the authorization request.</param> + /// <param name="request">The HTTP request to read from.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// The incoming request, or null if no OAuth message was attached. /// </returns> /// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception> - public Task<EndUserAuthorizationRequest> ReadAuthorizationRequestAsync(Uri requestUri, CancellationToken cancellationToken = default(CancellationToken)) { - var httpInfo = HttpRequestInfo.Create(HttpMethod.Get.Method, requestUri); - return this.ReadAuthorizationRequestAsync(httpInfo, cancellationToken); + public Task<EndUserAuthorizationRequest> ReadAuthorizationRequestAsync( + HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) { + request = request ?? this.Channel.GetRequestFromContext(); + return this.ReadAuthorizationRequestAsync(request.AsHttpRequestMessage(), cancellationToken); } /// <summary> - /// Handles an incoming request to the authorization server's token endpoint. + /// Reads in a client's request for the Authorization Server to obtain permission from + /// the user to authorize the Client's access of some protected resource(s). /// </summary> - /// <param name="request">The HTTP request.</param> - /// <returns>The HTTP response to send to the client.</returns> - public Task<HttpResponseMessage> HandleTokenRequestAsync(HttpRequestMessage request) { - return this.HandleTokenRequestAsync(new HttpRequestInfo(request)); + /// <param name="requestUri">The URL that carries the authorization request.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns> + /// The incoming request, or null if no OAuth message was attached. + /// </returns> + /// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception> + public Task<EndUserAuthorizationRequest> ReadAuthorizationRequestAsync(Uri requestUri, CancellationToken cancellationToken = default(CancellationToken)) { + var request = new HttpRequestMessage(HttpMethod.Get, requestUri); + return this.ReadAuthorizationRequestAsync(request, cancellationToken); } /// <summary> /// Handles an incoming request to the authorization server's token endpoint. /// </summary> /// <param name="request">The HTTP request.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns> - /// The HTTP response to send to the client. - /// </returns> - public async Task<HttpResponseMessage> HandleTokenRequestAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) { - request = request ?? this.Channel.GetRequestFromContext(); + /// <returns>The HTTP response to send to the client.</returns> + public async Task<HttpResponseMessage> HandleTokenRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) { + Requires.NotNull(request, "request"); - AccessTokenRequestBase requestMessage; IProtocolMessage responseMessage; try { - requestMessage = await this.Channel.TryReadFromRequestAsync<AccessTokenRequestBase>(request.AsHttpRequestMessage(), cancellationToken); + AccessTokenRequestBase requestMessage = await this.Channel.TryReadFromRequestAsync<AccessTokenRequestBase>(request, cancellationToken); if (requestMessage != null) { var accessTokenResult = this.AuthorizationServerServices.CreateAccessToken(requestMessage); ErrorUtilities.VerifyHost(accessTokenResult != null, "IAuthorizationServerHost.CreateAccessToken must not return null."); @@ -176,6 +180,19 @@ namespace DotNetOpenAuth.OAuth2 { } /// <summary> + /// Handles an incoming request to the authorization server's token endpoint. + /// </summary> + /// <param name="request">The HTTP request.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns> + /// The HTTP response to send to the client. + /// </returns> + public Task<HttpResponseMessage> HandleTokenRequestAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) { + request = request ?? this.Channel.GetRequestFromContext(); + return this.HandleTokenRequestAsync(request.AsHttpRequestMessage(), cancellationToken); + } + + /// <summary> /// Prepares a response to inform the Client that the user has rejected the Client's authorization request. /// </summary> /// <param name="authorizationRequest">The authorization request.</param> diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs index a11b81b..aba0290 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs @@ -36,10 +36,11 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { }; /// <summary> - /// Initializes a new instance of the <see cref="OAuth2ClientChannel"/> class. + /// Initializes a new instance of the <see cref="OAuth2ClientChannel" /> class. /// </summary> - internal OAuth2ClientChannel() - : base(MessageTypes) { + /// <param name="hostFactories">The host factories.</param> + internal OAuth2ClientChannel(IHostFactories hostFactories) + : base(MessageTypes, hostFactories: hostFactories) { } /// <summary> diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs index ea5dcf5..9730321 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs @@ -34,10 +34,10 @@ namespace DotNetOpenAuth.OAuth2 { /// The tool to use to apply client credentials to authenticated requests to the Authorization Server. /// May be <c>null</c> for clients with no secret or other means of authentication. /// </param> - protected ClientBase(AuthorizationServerDescription authorizationServer, string clientIdentifier = null, ClientCredentialApplicator clientCredentialApplicator = null) { + protected ClientBase(AuthorizationServerDescription authorizationServer, string clientIdentifier = null, ClientCredentialApplicator clientCredentialApplicator = null, IHostFactories hostFactories = null) { Requires.NotNull(authorizationServer, "authorizationServer"); this.AuthorizationServer = authorizationServer; - this.Channel = new OAuth2ClientChannel(); + this.Channel = new OAuth2ClientChannel(hostFactories); this.ClientIdentifier = clientIdentifier; this.ClientCredentialApplicator = clientCredentialApplicator; } diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/UserAgentClient.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/UserAgentClient.cs index d56b308..7a52c0f 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/UserAgentClient.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/UserAgentClient.cs @@ -28,8 +28,8 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="authorizationServer">The token issuer.</param> /// <param name="clientIdentifier">The client identifier.</param> /// <param name="clientSecret">The client secret.</param> - public UserAgentClient(AuthorizationServerDescription authorizationServer, string clientIdentifier = null, string clientSecret = null) - : this(authorizationServer, clientIdentifier, DefaultSecretApplicator(clientSecret)) { + public UserAgentClient(AuthorizationServerDescription authorizationServer, string clientIdentifier = null, string clientSecret = null, IHostFactories hostFactories = null) + : this(authorizationServer, clientIdentifier, DefaultSecretApplicator(clientSecret), hostFactories) { } /// <summary> @@ -39,8 +39,8 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="tokenEndpoint">The token endpoint.</param> /// <param name="clientIdentifier">The client identifier.</param> /// <param name="clientSecret">The client secret.</param> - public UserAgentClient(Uri authorizationEndpoint, Uri tokenEndpoint, string clientIdentifier = null, string clientSecret = null) - : this(authorizationEndpoint, tokenEndpoint, clientIdentifier, DefaultSecretApplicator(clientSecret)) { + public UserAgentClient(Uri authorizationEndpoint, Uri tokenEndpoint, string clientIdentifier = null, string clientSecret = null, IHostFactories hostFactories = null) + : this(authorizationEndpoint, tokenEndpoint, clientIdentifier, DefaultSecretApplicator(clientSecret), hostFactories) { } /// <summary> @@ -53,8 +53,8 @@ namespace DotNetOpenAuth.OAuth2 { /// The tool to use to apply client credentials to authenticated requests to the Authorization Server. /// May be <c>null</c> for clients with no secret or other means of authentication. /// </param> - public UserAgentClient(Uri authorizationEndpoint, Uri tokenEndpoint, string clientIdentifier, ClientCredentialApplicator clientCredentialApplicator) - : this(new AuthorizationServerDescription { AuthorizationEndpoint = authorizationEndpoint, TokenEndpoint = tokenEndpoint }, clientIdentifier, clientCredentialApplicator) { + public UserAgentClient(Uri authorizationEndpoint, Uri tokenEndpoint, string clientIdentifier, ClientCredentialApplicator clientCredentialApplicator, IHostFactories hostFactories = null) + : this(new AuthorizationServerDescription { AuthorizationEndpoint = authorizationEndpoint, TokenEndpoint = tokenEndpoint }, clientIdentifier, clientCredentialApplicator, hostFactories) { Requires.NotNull(authorizationEndpoint, "authorizationEndpoint"); Requires.NotNull(tokenEndpoint, "tokenEndpoint"); } @@ -68,8 +68,8 @@ namespace DotNetOpenAuth.OAuth2 { /// The tool to use to apply client credentials to authenticated requests to the Authorization Server. /// May be <c>null</c> for clients with no secret or other means of authentication. /// </param> - public UserAgentClient(AuthorizationServerDescription authorizationServer, string clientIdentifier, ClientCredentialApplicator clientCredentialApplicator) - : base(authorizationServer, clientIdentifier, clientCredentialApplicator) { + public UserAgentClient(AuthorizationServerDescription authorizationServer, string clientIdentifier, ClientCredentialApplicator clientCredentialApplicator, IHostFactories hostFactories = null) + : base(authorizationServer, clientIdentifier, clientCredentialApplicator, hostFactories) { } /// <summary> diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs index c8eb69d..4e9011a 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/WebServerClient.cs @@ -31,26 +31,26 @@ namespace DotNetOpenAuth.OAuth2 { private const string XsrfCookieName = "DotNetOpenAuth.WebServerClient.XSRF-Session"; /// <summary> - /// Initializes a new instance of the <see cref="WebServerClient"/> class. + /// Initializes a new instance of the <see cref="WebServerClient" /> class. /// </summary> /// <param name="authorizationServer">The authorization server.</param> /// <param name="clientIdentifier">The client identifier.</param> /// <param name="clientSecret">The client secret.</param> - public WebServerClient(AuthorizationServerDescription authorizationServer, string clientIdentifier = null, string clientSecret = null) - : this(authorizationServer, clientIdentifier, DefaultSecretApplicator(clientSecret)) { + /// <param name="hostFactories">The host factories.</param> + public WebServerClient(AuthorizationServerDescription authorizationServer, string clientIdentifier = null, string clientSecret = null, IHostFactories hostFactories = null) + : this(authorizationServer, clientIdentifier, DefaultSecretApplicator(clientSecret), hostFactories) { } /// <summary> - /// Initializes a new instance of the <see cref="WebServerClient"/> class. + /// Initializes a new instance of the <see cref="WebServerClient" /> class. /// </summary> /// <param name="authorizationServer">The authorization server.</param> /// <param name="clientIdentifier">The client identifier.</param> - /// <param name="clientCredentialApplicator"> - /// The tool to use to apply client credentials to authenticated requests to the Authorization Server. - /// May be <c>null</c> for clients with no secret or other means of authentication. - /// </param> - public WebServerClient(AuthorizationServerDescription authorizationServer, string clientIdentifier, ClientCredentialApplicator clientCredentialApplicator) - : base(authorizationServer, clientIdentifier, clientCredentialApplicator) { + /// <param name="clientCredentialApplicator">The tool to use to apply client credentials to authenticated requests to the Authorization Server. + /// May be <c>null</c> for clients with no secret or other means of authentication.</param> + /// <param name="hostFactories"></param> + public WebServerClient(AuthorizationServerDescription authorizationServer, string clientIdentifier, ClientCredentialApplicator clientCredentialApplicator, IHostFactories hostFactories = null) + : base(authorizationServer, clientIdentifier, clientCredentialApplicator, hostFactories) { } /// <summary> @@ -131,22 +131,32 @@ namespace DotNetOpenAuth.OAuth2 { /// <param name="request">The incoming HTTP request that may carry an authorization response.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The authorization state that contains the details of the authorization.</returns> - public async Task<IAuthorizationState> ProcessUserAuthorizationAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) { + public Task<IAuthorizationState> ProcessUserAuthorizationAsync( + HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) { + request = request ?? this.Channel.GetRequestFromContext(); + return this.ProcessUserAuthorizationAsync(request.AsHttpRequestMessage(), cancellationToken); + } + + /// <summary> + /// Processes the authorization response from an authorization server, if available. + /// </summary> + /// <param name="request">The incoming HTTP request that may carry an authorization response.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>The authorization state that contains the details of the authorization.</returns> + public async Task<IAuthorizationState> ProcessUserAuthorizationAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) { + Requires.NotNull(request, "request"); RequiresEx.ValidState(!string.IsNullOrEmpty(this.ClientIdentifier), Strings.RequiredPropertyNotYetPreset, "ClientIdentifier"); RequiresEx.ValidState(this.ClientCredentialApplicator != null, Strings.RequiredPropertyNotYetPreset, "ClientCredentialApplicator"); - request = request ?? this.Channel.GetRequestFromContext(); - var response = await this.Channel.TryReadFromRequestAsync<IMessageWithClientState>(request.AsHttpRequestMessage(), cancellationToken); + var response = await this.Channel.TryReadFromRequestAsync<IMessageWithClientState>(request, cancellationToken); if (response != null) { - Uri callback = request.GetPublicFacingUrl().StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(response)); + Uri callback = request.RequestUri.StripMessagePartsFromQueryString(this.Channel.MessageDescriptions.Get(response)); IAuthorizationState authorizationState; if (this.AuthorizationTracker != null) { authorizationState = this.AuthorizationTracker.GetAuthorizationState(callback, response.ClientState); ErrorUtilities.VerifyProtocol(authorizationState != null, ClientStrings.AuthorizationResponseUnexpectedMismatch); } else { - var context = this.Channel.GetHttpContext(); - - HttpCookie cookie = request.Cookies[XsrfCookieName]; + HttpCookie cookie = request.Headers.Cookies[XsrfCookieName]; ErrorUtilities.VerifyProtocol(cookie != null && string.Equals(response.ClientState, cookie.Value, StringComparison.Ordinal), ClientStrings.AuthorizationResponseUnexpectedMismatch); authorizationState = new AuthorizationState { Callback = callback }; } diff --git a/src/DotNetOpenAuth.Test/CoordinatorBase.cs b/src/DotNetOpenAuth.Test/CoordinatorBase.cs index 6a3ad86..83b9e6e 100644 --- a/src/DotNetOpenAuth.Test/CoordinatorBase.cs +++ b/src/DotNetOpenAuth.Test/CoordinatorBase.cs @@ -9,6 +9,7 @@ namespace DotNetOpenAuth.Test { using System.Collections.Generic; using System.Net; using System.Net.Http; + using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using DotNetOpenAuth.Messaging; @@ -55,6 +56,20 @@ namespace DotNetOpenAuth.Test { internal Handler By(Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> handler) { return new Handler(this.Uri) { MessageHandler = handler }; } + + internal Handler By(Func<HttpRequestMessage, HttpResponseMessage> handler) { + return By((req, ct) => Task.FromResult(handler(req))); + } + + internal Handler By(string responseContent, string contentType, HttpStatusCode statusCode = HttpStatusCode.OK) { + return By( + req => { + var response = new HttpResponseMessage(statusCode); + response.Content = new StringContent(responseContent); + response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType); + return response; + }); + } } private class MyHostFactories : IHostFactories { @@ -82,7 +97,7 @@ namespace DotNetOpenAuth.Test { protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { foreach (var handler in this.handlers) { - if (handler.Uri.AbsolutePath == request.RequestUri.AbsolutePath) { + if (handler.Uri.IsBaseOf(request.RequestUri) && handler.Uri.AbsolutePath == request.RequestUri.AbsolutePath) { var response = await handler.MessageHandler(request, cancellationToken); if (response != null) { return response; diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj index a355ab6..5e6791b 100644 --- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj +++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj @@ -130,8 +130,6 @@ <Compile Include="Mocks\InMemoryTokenManager.cs" /> <Compile Include="Mocks\MockHttpMessageHandler.cs" /> <Compile Include="Mocks\MockHttpRequest.cs" /> - <Compile Include="Mocks\MockIdentifier.cs" /> - <Compile Include="Mocks\MockIdentifierDiscoveryService.cs" /> <Compile Include="Mocks\MockOpenIdExtension.cs" /> <Compile Include="Mocks\MockRealm.cs" /> <Compile Include="Mocks\MockTransformationBindingElement.cs" /> @@ -153,7 +151,6 @@ <Compile Include="OAuth2\MessageFactoryTests.cs" /> <Compile Include="OAuth2\ResourceServerTests.cs" /> <Compile Include="OAuth2\UserAgentClientAuthorizeTests.cs" /> - <Compile Include="OAuth2\OAuth2Coordinator.cs" /> <Compile Include="OAuth2\OAuth2TestBase.cs" /> <Compile Include="OAuth2\WebServerClientAuthorizeTests.cs" /> <Compile Include="OAuth\ChannelElements\HmacSha1SigningBindingElementTests.cs" /> @@ -326,6 +323,10 @@ <Project>{60426312-6AE5-4835-8667-37EDEA670222}</Project> <Name>DotNetOpenAuth.Core</Name> </ProjectReference> + <ProjectReference Include="..\DotNetOpenAuth.OAuth.Common\DotNetOpenAuth.OAuth.Common.csproj"> + <Project>{115217c5-22cd-415c-a292-0dd0238cdd89}</Project> + <Name>DotNetOpenAuth.OAuth.Common</Name> + </ProjectReference> <ProjectReference Include="..\DotNetOpenAuth.OAuth.Consumer\DotNetOpenAuth.OAuth.Consumer.csproj"> <Project>{B202E40D-4663-4A2B-ACDA-865F88FF7CAA}</Project> <Name>DotNetOpenAuth.OAuth.Consumer</Name> @@ -382,6 +383,14 @@ <Project>{75E13AAE-7D51-4421-ABFD-3F3DC91F576E}</Project> <Name>DotNetOpenAuth.OpenId.UI</Name> </ProjectReference> + <ProjectReference Include="..\DotNetOpenAuth.OpenIdInfoCard.UI\DotNetOpenAuth.OpenIdInfoCard.UI.csproj"> + <Project>{3a8347e8-59a5-4092-8842-95c75d7d2f36}</Project> + <Name>DotNetOpenAuth.OpenIdInfoCard.UI</Name> + </ProjectReference> + <ProjectReference Include="..\DotNetOpenAuth.OpenIdOAuth\DotNetOpenAuth.OpenIdOAuth.csproj"> + <Project>{4bfaa336-5df3-4f27-82d3-06d13240e8ab}</Project> + <Name>DotNetOpenAuth.OpenIdOAuth</Name> + </ProjectReference> <ProjectReference Include="..\DotNetOpenAuth.OpenId\DotNetOpenAuth.OpenId.csproj"> <Project>{3896A32A-E876-4C23-B9B8-78E17D134CD3}</Project> <Name>DotNetOpenAuth.OpenId</Name> diff --git a/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs b/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs index b54c11b..9050fad 100644 --- a/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs +++ b/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs @@ -15,16 +15,25 @@ namespace DotNetOpenAuth.Test.Messaging { using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; + using DotNetOpenAuth.OpenId; using DotNetOpenAuth.Test.Mocks; using NUnit.Framework; [TestFixture] public class ChannelTests : MessagingTestBase { [Test, ExpectedException(typeof(ArgumentNullException))] - public void CtorNull() { - // This bad channel is deliberately constructed to pass null to - // its protected base class' constructor. - new TestBadChannel(true); + public void CtorNullFirstParameter() { + new TestBadChannel(null, new IChannelBindingElement[0], new DefaultOpenIdHostFactories()); + } + + [Test, ExpectedException(typeof(ArgumentNullException))] + public void CtorNullSecondParameter() { + new TestBadChannel(new TestMessageFactory(), null, new DefaultOpenIdHostFactories()); + } + + [Test, ExpectedException(typeof(ArgumentNullException))] + public void CtorNullThirdParameter() { + new TestBadChannel(new TestMessageFactory(), new IChannelBindingElement[0], null); } [Test] @@ -93,20 +102,20 @@ namespace DotNetOpenAuth.Test.Messaging { [Test, ExpectedException(typeof(ArgumentNullException))] public void SendIndirectMessage301GetNullMessage() { - TestBadChannel badChannel = new TestBadChannel(false); + TestBadChannel badChannel = new TestBadChannel(); badChannel.Create301RedirectResponse(null, new Dictionary<string, string>()); } [Test, ExpectedException(typeof(ArgumentException))] public void SendIndirectMessage301GetEmptyRecipient() { - TestBadChannel badChannel = new TestBadChannel(false); + TestBadChannel badChannel = new TestBadChannel(); var message = new TestDirectedMessage(MessageTransport.Indirect); badChannel.Create301RedirectResponse(message, new Dictionary<string, string>()); } [Test, ExpectedException(typeof(ArgumentNullException))] public void SendIndirectMessage301GetNullFields() { - TestBadChannel badChannel = new TestBadChannel(false); + TestBadChannel badChannel = new TestBadChannel(); var message = new TestDirectedMessage(MessageTransport.Indirect); message.Recipient = new Uri("http://someserver"); badChannel.Create301RedirectResponse(message, null); @@ -138,20 +147,20 @@ namespace DotNetOpenAuth.Test.Messaging { [Test, ExpectedException(typeof(ArgumentNullException))] public void SendIndirectMessageFormPostNullMessage() { - TestBadChannel badChannel = new TestBadChannel(false); + TestBadChannel badChannel = new TestBadChannel(); badChannel.CreateFormPostResponse(null, new Dictionary<string, string>()); } [Test, ExpectedException(typeof(ArgumentException))] public void SendIndirectMessageFormPostEmptyRecipient() { - TestBadChannel badChannel = new TestBadChannel(false); + TestBadChannel badChannel = new TestBadChannel(); var message = new TestDirectedMessage(MessageTransport.Indirect); badChannel.CreateFormPostResponse(message, new Dictionary<string, string>()); } [Test, ExpectedException(typeof(ArgumentNullException))] public void SendIndirectMessageFormPostNullFields() { - TestBadChannel badChannel = new TestBadChannel(false); + TestBadChannel badChannel = new TestBadChannel(); var message = new TestDirectedMessage(MessageTransport.Indirect); message.Recipient = new Uri("http://someserver"); badChannel.CreateFormPostResponse(message, null); @@ -176,19 +185,19 @@ namespace DotNetOpenAuth.Test.Messaging { [Test, ExpectedException(typeof(ArgumentNullException))] public void SendIndirectMessageNull() { - TestBadChannel badChannel = new TestBadChannel(false); + TestBadChannel badChannel = new TestBadChannel(); badChannel.PrepareIndirectResponse(null); } [Test, ExpectedException(typeof(ArgumentNullException))] public void ReceiveNull() { - TestBadChannel badChannel = new TestBadChannel(false); + TestBadChannel badChannel = new TestBadChannel(); badChannel.Receive(null, null); } [Test] public void ReceiveUnrecognizedMessage() { - TestBadChannel badChannel = new TestBadChannel(false); + TestBadChannel badChannel = new TestBadChannel(); Assert.IsNull(badChannel.Receive(new Dictionary<string, string>(), null)); } @@ -208,13 +217,13 @@ namespace DotNetOpenAuth.Test.Messaging { [Test, ExpectedException(typeof(InvalidOperationException))] public void GetRequestFromContextNoContext() { HttpContext.Current = null; - TestBadChannel badChannel = new TestBadChannel(false); + TestBadChannel badChannel = new TestBadChannel(); badChannel.GetRequestFromContext(); } [Test, ExpectedException(typeof(ArgumentNullException))] public async Task ReadFromRequestNull() { - TestBadChannel badChannel = new TestBadChannel(false); + TestBadChannel badChannel = new TestBadChannel(); await badChannel.ReadFromRequestAsync(null, CancellationToken.None); } @@ -251,15 +260,16 @@ namespace DotNetOpenAuth.Test.Messaging { public void MessageExpirationWithoutTamperResistance() { new TestChannel( new TestMessageFactory(), - new StandardExpirationBindingElement()); + new IChannelBindingElement[] { new StandardExpirationBindingElement() }, + new DefaultOpenIdHostFactories()); } [Test, ExpectedException(typeof(ProtocolException))] public async Task TooManyBindingElementsProvidingSameProtection() { Channel channel = new TestChannel( new TestMessageFactory(), - new MockSigningBindingElement(), - new MockSigningBindingElement()); + new IChannelBindingElement[] { new MockSigningBindingElement(), new MockSigningBindingElement() }, + new DefaultOpenIdHostFactories()); await channel.ProcessOutgoingMessageTestHookAsync(new TestSignedDirectedMessage()); } @@ -273,11 +283,8 @@ namespace DotNetOpenAuth.Test.Messaging { Channel channel = new TestChannel( new TestMessageFactory(), - sign, - replay, - expire, - transformB, - transformA); + new[] { sign, replay, expire, transformB, transformA }, + new DefaultOpenIdHostFactories()); Assert.AreEqual(5, channel.BindingElements.Count); Assert.AreSame(transformB, channel.BindingElements[0]); diff --git a/src/DotNetOpenAuth.Test/Messaging/MessagingTestBase.cs b/src/DotNetOpenAuth.Test/Messaging/MessagingTestBase.cs index 9e0cc99..567b2ad 100644 --- a/src/DotNetOpenAuth.Test/Messaging/MessagingTestBase.cs +++ b/src/DotNetOpenAuth.Test/Messaging/MessagingTestBase.cs @@ -55,7 +55,7 @@ namespace DotNetOpenAuth.Test { public override void SetUp() { base.SetUp(); - this.Channel = new TestChannel(); + ////this.Channel = new TestChannel(); } internal static HttpRequestMessage CreateHttpRequestInfo(HttpMethod method, IDictionary<string, string> fields) { @@ -101,7 +101,8 @@ namespace DotNetOpenAuth.Test { } var typeProvider = new TestMessageFactory(signing, expiration, replay); - return new TestChannel(typeProvider, bindingElements.ToArray()); + ////return new TestChannel(typeProvider, bindingElements.ToArray()); + return null; } internal static IDictionary<string, string> GetStandardTestFields(FieldFill fill) { diff --git a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs index d20671e..469a412 100644 --- a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs +++ b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs @@ -10,7 +10,9 @@ namespace DotNetOpenAuth.Test.Mocks { using System.Globalization; using System.IO; using System.Net; + using System.Net.Http; using System.Text; + using System.Threading.Tasks; using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; @@ -19,71 +21,8 @@ namespace DotNetOpenAuth.Test.Mocks { using DotNetOpenAuth.Yadis; using Validation; - internal class MockHttpRequest { - private readonly Dictionary<Uri, IncomingWebResponse> registeredMockResponses = new Dictionary<Uri, IncomingWebResponse>(); - - private MockHttpRequest(IDirectWebRequestHandler mockHandler) { - Requires.NotNull(mockHandler, "mockHandler"); - this.MockWebRequestHandler = mockHandler; - } - - internal IDirectWebRequestHandler MockWebRequestHandler { get; private set; } - - internal static MockHttpRequest CreateUntrustedMockHttpHandler() { - TestWebRequestHandler testHandler = new TestWebRequestHandler(); - UntrustedWebRequestHandler untrustedHandler = new UntrustedWebRequestHandler(testHandler); - if (!untrustedHandler.WhitelistHosts.Contains("localhost")) { - untrustedHandler.WhitelistHosts.Add("localhost"); - } - untrustedHandler.WhitelistHosts.Add(OpenIdTestBase.OPUri.Host); - MockHttpRequest mock = new MockHttpRequest(untrustedHandler); - testHandler.Callback = mock.GetMockResponse; - return mock; - } - - internal void RegisterMockResponse(IncomingWebResponse response) { - Requires.NotNull(response, "response"); - if (this.registeredMockResponses.ContainsKey(response.RequestUri)) { - Logger.Http.WarnFormat("Mock HTTP response already registered for {0}.", response.RequestUri); - } else { - this.registeredMockResponses.Add(response.RequestUri, response); - } - } - - internal void RegisterMockResponse(Uri requestUri, string contentType, string responseBody) { - this.RegisterMockResponse(requestUri, requestUri, contentType, responseBody); - } - - internal void RegisterMockResponse(Uri requestUri, Uri responseUri, string contentType, string responseBody) { - this.RegisterMockResponse(requestUri, responseUri, contentType, new WebHeaderCollection(), responseBody); - } - - internal void RegisterMockResponse(Uri requestUri, Uri responseUri, string contentType, WebHeaderCollection headers, string responseBody) { - Requires.NotNull(requestUri, "requestUri"); - Requires.NotNull(responseUri, "responseUri"); - Requires.NotNullOrEmpty(contentType, "contentType"); - - // Set up the redirect if appropriate - if (requestUri != responseUri) { - this.RegisterMockRedirect(requestUri, responseUri); - } - - string contentEncoding = null; - MemoryStream stream = new MemoryStream(); - StreamWriter sw = new StreamWriter(stream); - sw.Write(responseBody); - sw.Flush(); - stream.Seek(0, SeekOrigin.Begin); - this.RegisterMockResponse(new CachedDirectWebResponse(responseUri, responseUri, headers ?? new WebHeaderCollection(), HttpStatusCode.OK, contentType, contentEncoding, stream)); - } - - internal void RegisterMockXrdsResponses(IDictionary<string, string> requestUriAndResponseBody) { - foreach (var pair in requestUriAndResponseBody) { - this.RegisterMockResponse(new Uri(pair.Key), "text/xml; saml=false; https=false; charset=UTF-8", pair.Value); - } - } - - internal void RegisterMockXrdsResponse(IdentifierDiscoveryResult endpoint) { + internal static class MockHttpRequest { + internal static CoordinatorBase.Handler RegisterMockXrdsResponse(IdentifierDiscoveryResult endpoint) { Requires.NotNull(endpoint, "endpoint"); string identityUri; @@ -92,13 +31,14 @@ namespace DotNetOpenAuth.Test.Mocks { } else { identityUri = endpoint.UserSuppliedIdentifier ?? endpoint.ClaimedIdentifier; } - this.RegisterMockXrdsResponse(new Uri(identityUri), new IdentifierDiscoveryResult[] { endpoint }); + + return RegisterMockXrdsResponse(new Uri(identityUri), new IdentifierDiscoveryResult[] { endpoint }); } - internal void RegisterMockXrdsResponse(Uri respondingUri, IEnumerable<IdentifierDiscoveryResult> endpoints) { + internal static CoordinatorBase.Handler RegisterMockXrdsResponse(Uri respondingUri, IEnumerable<IdentifierDiscoveryResult> endpoints) { Requires.NotNull(endpoints, "endpoints"); - StringBuilder xrds = new StringBuilder(); + var 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)'> <XRD>"); foreach (var endpoint in endpoints) { @@ -127,10 +67,10 @@ namespace DotNetOpenAuth.Test.Mocks { </XRD> </xrds:XRDS>"); - this.RegisterMockResponse(respondingUri, ContentTypes.Xrds, xrds.ToString()); + return CoordinatorBase.Handle(respondingUri).By(xrds.ToString(), ContentTypes.Xrds); } - internal void RegisterMockXrdsResponse(UriIdentifier directedIdentityAssignedIdentifier, IdentifierDiscoveryResult providerEndpoint) { + internal static CoordinatorBase.Handler RegisterMockXrdsResponse(UriIdentifier directedIdentityAssignedIdentifier, IdentifierDiscoveryResult providerEndpoint) { IdentifierDiscoveryResult identityEndpoint = IdentifierDiscoveryResult.CreateForClaimedIdentifier( directedIdentityAssignedIdentifier, directedIdentityAssignedIdentifier, @@ -138,16 +78,16 @@ namespace DotNetOpenAuth.Test.Mocks { new ProviderEndpointDescription(providerEndpoint.ProviderEndpoint, providerEndpoint.Capabilities), 10, 10); - this.RegisterMockXrdsResponse(identityEndpoint); + return RegisterMockXrdsResponse(identityEndpoint); } - internal Identifier RegisterMockXrdsResponse(string embeddedResourcePath) { - UriIdentifier id = new Uri(new Uri("http://localhost/"), embeddedResourcePath); - this.RegisterMockResponse(id, "application/xrds+xml", OpenIdTestBase.LoadEmbeddedFile(embeddedResourcePath)); - return id; + internal static CoordinatorBase.Handler RegisterMockXrdsResponse(string embeddedResourcePath, out Identifier id) { + id = new Uri(new Uri("http://localhost/"), embeddedResourcePath); + return CoordinatorBase.Handle(new Uri(id)) + .By(OpenIdTestBase.LoadEmbeddedFile(embeddedResourcePath), "application/xrds+xml"); } - internal void RegisterMockRPDiscovery() { + internal static CoordinatorBase.Handler RegisterMockRPDiscovery(bool ssl) { string template = @"<xrds:XRDS xmlns:xrds='xri://$xrds' xmlns:openid='http://openid.net/xmlns/1.0' xmlns='xri://$xrd*($v*2.0)'> <XRD> <Service priority='10'> @@ -164,45 +104,14 @@ namespace DotNetOpenAuth.Test.Mocks { HttpUtility.HtmlEncode(OpenIdTestBase.RPRealmUri.AbsoluteUri), HttpUtility.HtmlEncode(OpenIdTestBase.RPRealmUriSsl.AbsoluteUri)); - this.RegisterMockResponse(OpenIdTestBase.RPRealmUri, ContentTypes.Xrds, xrds); - this.RegisterMockResponse(OpenIdTestBase.RPRealmUriSsl, ContentTypes.Xrds, xrds); + return new CoordinatorBase.Handler(ssl ? OpenIdTestBase.RPRealmUriSsl : OpenIdTestBase.RPRealmUri) + .By(xrds, ContentTypes.Xrds); } - internal void DeleteResponse(Uri requestUri) { - this.registeredMockResponses.Remove(requestUri); - } - - internal void RegisterMockRedirect(Uri origin, Uri redirectLocation) { - var redirectionHeaders = new WebHeaderCollection { - { HttpResponseHeader.Location, redirectLocation.AbsoluteUri }, - }; - IncomingWebResponse response = new CachedDirectWebResponse(origin, origin, redirectionHeaders, HttpStatusCode.Redirect, null, null, new MemoryStream()); - this.RegisterMockResponse(response); - } - - internal void RegisterMockNotFound(Uri requestUri) { - CachedDirectWebResponse errorResponse = new CachedDirectWebResponse( - requestUri, - requestUri, - new WebHeaderCollection(), - HttpStatusCode.NotFound, - "text/plain", - Encoding.UTF8.WebName, - new MemoryStream(Encoding.UTF8.GetBytes("Not found."))); - this.RegisterMockResponse(errorResponse); - } - - private IncomingWebResponse GetMockResponse(HttpWebRequest request) { - IncomingWebResponse 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.Http.WarnFormat("Unexpected HTTP request: {0}", request.RequestUri); - return new CachedDirectWebResponse(request.RequestUri, request.RequestUri, new WebHeaderCollection(), HttpStatusCode.NotFound, "text/html", null, new MemoryStream()); - } + internal static CoordinatorBase.Handler RegisterMockRedirect(Uri origin, Uri redirectLocation) { + var response = new HttpResponseMessage(HttpStatusCode.Redirect); + response.Headers.Location = redirectLocation; + return new CoordinatorBase.Handler(origin).By(req => response); } } } diff --git a/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs b/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs deleted file mode 100644 index f020923..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs +++ /dev/null @@ -1,71 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="MockIdentifier.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.Collections.Generic; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.RelyingParty; - using Validation; - - /// <summary> - /// Performs similar to an ordinary <see cref="Identifier"/>, but when called upon - /// 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> - internal class MockIdentifier : Identifier { - private IEnumerable<IdentifierDiscoveryResult> endpoints; - - private MockHttpRequest mockHttpRequest; - - private Identifier wrappedIdentifier; - - public MockIdentifier(Identifier wrappedIdentifier, MockHttpRequest mockHttpRequest, IEnumerable<IdentifierDiscoveryResult> endpoints) - : base(wrappedIdentifier.OriginalString, false) { - Requires.NotNull(wrappedIdentifier, "wrappedIdentifier"); - Requires.NotNull(mockHttpRequest, "mockHttpRequest"); - Requires.NotNull(endpoints, "endpoints"); - - this.wrappedIdentifier = wrappedIdentifier; - this.endpoints = endpoints; - this.mockHttpRequest = mockHttpRequest; - - // Register a mock HTTP response to enable discovery of this identifier within the RP - // without having to host an ASP.NET site within the test. - mockHttpRequest.RegisterMockXrdsResponse(new Uri(wrappedIdentifier.ToString()), endpoints); - } - - internal IEnumerable<IdentifierDiscoveryResult> DiscoveryEndpoints { - get { return this.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 Identifier TrimFragment() { - return this; - } - - internal override bool TryRequireSsl(out Identifier secureIdentifier) { - // We take special care to make our wrapped identifier secure, but still - // return a mocked (secure) identifier. - Identifier secureWrappedIdentifier; - bool result = this.wrappedIdentifier.TryRequireSsl(out secureWrappedIdentifier); - secureIdentifier = new MockIdentifier(secureWrappedIdentifier, this.mockHttpRequest, this.endpoints); - return result; - } - } -} diff --git a/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs b/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs deleted file mode 100644 index 3fd7517..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/MockIdentifierDiscoveryService.cs +++ /dev/null @@ -1,45 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="MockIdentifierDiscoveryService.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.Mocks { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading.Tasks; - using DotNetOpenAuth.Messaging; - using DotNetOpenAuth.OpenId; - using DotNetOpenAuth.OpenId.RelyingParty; - - internal class MockIdentifierDiscoveryService : IIdentifierDiscoveryService { - /// <summary> - /// Initializes a new instance of the <see cref="MockIdentifierDiscoveryService"/> class. - /// </summary> - public MockIdentifierDiscoveryService() { - } - - #region IIdentifierDiscoveryService Members - - /// <summary> - /// Performs discovery on the specified identifier. - /// </summary> - /// <param name="identifier">The identifier to perform discovery on.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns> - /// A sequence of service endpoints yielded by discovery. Must not be null, but may be empty. - /// </returns> - public Task<IdentifierDiscoveryServiceResult> DiscoverAsync(Identifier identifier, System.Threading.CancellationToken cancellationToken) { - var mockIdentifier = identifier as MockIdentifier; - if (mockIdentifier == null) { - return Task.FromResult(new IdentifierDiscoveryServiceResult(Enumerable.Empty<IdentifierDiscoveryResult>(), abortDiscoveryChain: false)); - } - - return Task.FromResult(new IdentifierDiscoveryServiceResult(mockIdentifier.DiscoveryEndpoints, abortDiscoveryChain: true)); - } - - #endregion - } -} diff --git a/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs b/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs index 2a8e7b9..344598f 100644 --- a/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs +++ b/src/DotNetOpenAuth.Test/Mocks/TestBadChannel.cs @@ -12,13 +12,27 @@ namespace DotNetOpenAuth.Test.Mocks { using System.Threading.Tasks; using System.Web; using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId; /// <summary> /// A Channel derived type that passes null to the protected constructor. /// </summary> internal class TestBadChannel : Channel { - internal TestBadChannel(bool badConstructorParam) - : base(badConstructorParam ? null : new TestMessageFactory()) { + /// <summary> + /// Initializes a new instance of the <see cref="TestBadChannel" /> class. + /// </summary> + /// <param name="messageFactory">The message factory. Could be <see cref="TestMessageFactory"/></param> + /// <param name="bindingElements">The binding elements.</param> + /// <param name="hostFactories">The host factories.</param> + internal TestBadChannel(IMessageFactory messageFactory, IChannelBindingElement[] bindingElements, IHostFactories hostFactories) + : base(messageFactory, bindingElements, hostFactories) { + } + + /// <summary> + /// Initializes a new instance of the <see cref="TestBadChannel"/> class. + /// </summary> + internal TestBadChannel() + : this(new TestMessageFactory(), new IChannelBindingElement[0], new DefaultOpenIdHostFactories()) { } internal new void Create301RedirectResponse(IDirectedProtocolMessage message, IDictionary<string, string> fields, bool payloadInFragment = false) { diff --git a/src/DotNetOpenAuth.Test/Mocks/TestChannel.cs b/src/DotNetOpenAuth.Test/Mocks/TestChannel.cs index 1472231..5b318d5 100644 --- a/src/DotNetOpenAuth.Test/Mocks/TestChannel.cs +++ b/src/DotNetOpenAuth.Test/Mocks/TestChannel.cs @@ -8,21 +8,26 @@ namespace DotNetOpenAuth.Test.Mocks { using System; using System.Collections.Generic; using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Reflection; + using DotNetOpenAuth.OpenId; internal class TestChannel : Channel { - internal TestChannel() - : this(new TestMessageFactory()) { + internal TestChannel(IHostFactories hostFactories = null) + : this(new TestMessageFactory(), new IChannelBindingElement[0], hostFactories ?? new DefaultOpenIdHostFactories()) { } - internal TestChannel(MessageDescriptionCollection messageDescriptions) - : this() { + internal TestChannel(MessageDescriptionCollection messageDescriptions, IHostFactories hostFactories = null) + : this(hostFactories) { this.MessageDescriptions = messageDescriptions; } - internal TestChannel(IMessageFactory messageTypeProvider, params IChannelBindingElement[] bindingElements) - : base(messageTypeProvider, bindingElements) { + internal TestChannel(IMessageFactory messageTypeProvider, IChannelBindingElement[] bindingElements, IHostFactories hostFactories) + : base(messageTypeProvider, bindingElements, hostFactories) { } /// <summary> @@ -40,15 +45,15 @@ namespace DotNetOpenAuth.Test.Mocks { return base.Receive(fields, recipient); } - protected override IDictionary<string, string> ReadFromResponseCore(IncomingWebResponse response) { + protected override Task<IDictionary<string, string>> ReadFromResponseCoreAsync(HttpResponseMessage response, CancellationToken cancellationToken) { throw new NotImplementedException("ReadFromResponseInternal"); } - protected override HttpWebRequest CreateHttpRequest(IDirectedProtocolMessage request) { + protected override HttpRequestMessage CreateHttpRequest(IDirectedProtocolMessage request) { throw new NotImplementedException("CreateHttpRequest"); } - protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) { + protected override HttpResponseMessage PrepareDirectResponse(IProtocolMessage response) { throw new NotImplementedException("SendDirectMessageResponse"); } } diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs index 49260eb..e436143 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/HmacSha1SigningBindingElementTests.cs @@ -5,6 +5,8 @@ //----------------------------------------------------------------------- namespace DotNetOpenAuth.Test.OAuth.ChannelElements { + using System.Net.Http; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Reflection; using DotNetOpenAuth.OAuth; @@ -33,7 +35,7 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { ((ITamperResistantOAuthMessage)message).ConsumerSecret = "ExJXsYl7Or8OfK98"; ((ITamperResistantOAuthMessage)message).TokenSecret = "b197333b-470a-43b3-bcd7-49d6d2229c4c"; var signedMessage = (ITamperResistantOAuthMessage)message; - signedMessage.HttpMethod = "GET"; + signedMessage.HttpMethod = HttpMethod.Get; signedMessage.SignatureMethod = "HMAC-SHA1"; MessageDictionary dictionary = this.MessageDescriptions.GetAccessor(message); dictionary["oauth_timestamp"] = "1353545248"; diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs index b081038..7e29940 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs @@ -10,7 +10,10 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { using System.Collections.Specialized; using System.IO; using System.Net; + using System.Net.Http; using System.Text; + using System.Threading; + using System.Threading.Tasks; using System.Web; using System.Xml; using DotNetOpenAuth.Messaging; @@ -28,7 +31,6 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { private SigningBindingElementBase signingElement; private INonceStore nonceStore; private DotNetOpenAuth.OAuth.ServiceProviderSecuritySettings serviceProviderSecuritySettings = DotNetOpenAuth.Configuration.OAuthElement.Configuration.ServiceProvider.SecuritySettings.CreateSecuritySettings(); - private DotNetOpenAuth.OAuth.ConsumerSecuritySettings consumerSecuritySettings = DotNetOpenAuth.Configuration.OAuthElement.Configuration.Consumer.SecuritySettings.CreateSecuritySettings(); [SetUp] public override void SetUp() { @@ -43,22 +45,17 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { [Test, ExpectedException(typeof(ArgumentException))] public void CtorNullSigner() { - new OAuthConsumerChannel(null, this.nonceStore, new InMemoryTokenManager(), this.consumerSecuritySettings, new TestMessageFactory()); + new OAuthServiceProviderChannel(null, this.nonceStore, new InMemoryTokenManager(), this.serviceProviderSecuritySettings, new TestMessageFactory()); } [Test, ExpectedException(typeof(ArgumentNullException))] public void CtorNullStore() { - new OAuthConsumerChannel(new RsaSha1ServiceProviderSigningBindingElement(new InMemoryTokenManager()), null, new InMemoryTokenManager(), this.consumerSecuritySettings, new TestMessageFactory()); + new OAuthServiceProviderChannel(new RsaSha1ServiceProviderSigningBindingElement(new InMemoryTokenManager()), null, new InMemoryTokenManager(), this.serviceProviderSecuritySettings, new TestMessageFactory()); } [Test, ExpectedException(typeof(ArgumentNullException))] public void CtorNullTokenManager() { - new OAuthConsumerChannel(new RsaSha1ServiceProviderSigningBindingElement(new InMemoryTokenManager()), this.nonceStore, null, this.consumerSecuritySettings, new TestMessageFactory()); - } - - [Test] - public void CtorSimpleConsumer() { - new OAuthConsumerChannel(new RsaSha1ServiceProviderSigningBindingElement(new InMemoryTokenManager()), this.nonceStore, (IConsumerTokenManager)new InMemoryTokenManager(), this.consumerSecuritySettings); + new OAuthServiceProviderChannel(new RsaSha1ServiceProviderSigningBindingElement(new InMemoryTokenManager()), this.nonceStore, null, this.serviceProviderSecuritySettings, new TestMessageFactory()); } [Test] @@ -67,8 +64,8 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { } [Test] - public void ReadFromRequestAuthorization() { - this.ParameterizedReceiveTest(HttpDeliveryMethods.AuthorizationHeaderRequest); + public async Task ReadFromRequestAuthorization() { + await this.ParameterizedReceiveTestAsync(HttpDeliveryMethods.AuthorizationHeaderRequest); } /// <summary> @@ -76,7 +73,7 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { /// from the Authorization header, the query string and the entity form data. /// </summary> [Test] - public void ReadFromRequestAuthorizationScattered() { + public async Task ReadFromRequestAuthorizationScattered() { // Start by creating a standard POST HTTP request. var postedFields = new Dictionary<string, string> { { "age", "15" }, @@ -97,7 +94,7 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { var requestInfo = new HttpRequestInfo("POST", builder.Uri, form: postedFields.ToNameValueCollection(), headers: headers); - IDirectedProtocolMessage requestMessage = this.channel.ReadFromRequest(requestInfo); + IDirectedProtocolMessage requestMessage = await this.channel.ReadFromRequestAsync(requestInfo.AsHttpRequestMessage(), CancellationToken.None); Assert.IsNotNull(requestMessage); Assert.IsInstanceOf<TestMessage>(requestMessage); @@ -108,36 +105,35 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { } [Test] - public void ReadFromRequestForm() { - this.ParameterizedReceiveTest(HttpDeliveryMethods.PostRequest); + public async Task ReadFromRequestForm() { + await this.ParameterizedReceiveTestAsync(HttpDeliveryMethods.PostRequest); } [Test] - public void ReadFromRequestQueryString() { - this.ParameterizedReceiveTest(HttpDeliveryMethods.GetRequest); + public async Task ReadFromRequestQueryString() { + await this.ParameterizedReceiveTestAsync(HttpDeliveryMethods.GetRequest); } [Test] - public void SendDirectMessageResponse() { + public async Task SendDirectMessageResponse() { IProtocolMessage message = new TestDirectedMessage { Age = 15, Name = "Andrew", Location = new Uri("http://hostb/pathB"), }; - OutgoingWebResponse response = this.channel.PrepareResponse(message); - Assert.AreSame(message, response.OriginalMessage); - Assert.AreEqual(HttpStatusCode.OK, response.Status); - Assert.AreEqual(2, response.Headers.Count); + var response = await this.channel.PrepareResponseAsync(message); + Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); + Assert.AreEqual(Channel.HttpFormUrlEncodedContentType, response.Content.Headers.ContentType.MediaType); - NameValueCollection body = HttpUtility.ParseQueryString(response.Body); + NameValueCollection body = HttpUtility.ParseQueryString(await response.Content.ReadAsStringAsync()); Assert.AreEqual("15", body["age"]); Assert.AreEqual("Andrew", body["Name"]); Assert.AreEqual("http://hostb/pathB", body["Location"]); } [Test] - public void ReadFromResponse() { + public async Task ReadFromResponse() { var fields = new Dictionary<string, string> { { "age", "15" }, { "Name", "Andrew" }, @@ -150,7 +146,9 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { writer.Write(MessagingUtilities.CreateQueryString(fields)); writer.Flush(); ms.Seek(0, SeekOrigin.Begin); - IDictionary<string, string> deserializedFields = this.channel.ReadFromResponseCoreTestHook(new CachedDirectWebResponse { CachedResponseStream = ms }); + IDictionary<string, string> deserializedFields = await this.channel.ReadFromResponseCoreAsyncTestHook( + new HttpResponseMessage { Content = new StreamContent(ms) }, + CancellationToken.None); Assert.AreEqual(fields.Count, deserializedFields.Count); foreach (string key in fields.Keys) { Assert.AreEqual(fields[key], deserializedFields[key]); @@ -158,34 +156,34 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { } [Test, ExpectedException(typeof(ArgumentNullException))] - public void RequestNull() { - this.channel.Request(null); + public async Task RequestNull() { + await this.channel.RequestAsync(null, CancellationToken.None); } [Test, ExpectedException(typeof(ArgumentException))] - public void RequestNullRecipient() { + public async Task RequestNullRecipient() { IDirectedProtocolMessage message = new TestDirectedMessage(MessageTransport.Direct); - this.channel.Request(message); + await this.channel.RequestAsync(message, CancellationToken.None); } [Test, ExpectedException(typeof(NotSupportedException))] - public void RequestBadPreferredScheme() { + public async Task RequestBadPreferredScheme() { TestDirectedMessage message = new TestDirectedMessage(MessageTransport.Direct); message.Recipient = new Uri("http://localtest"); message.HttpMethods = HttpDeliveryMethods.None; - this.channel.Request(message); + await this.channel.RequestAsync(message, CancellationToken.None); } [Test] - public void RequestUsingAuthorizationHeader() { - this.ParameterizedRequestTest(HttpDeliveryMethods.AuthorizationHeaderRequest); + public async Task RequestUsingAuthorizationHeader() { + await this.ParameterizedRequestTestAsync(HttpDeliveryMethods.AuthorizationHeaderRequest); } /// <summary> /// Verifies that message parts can be distributed to the query, form, and Authorization header. /// </summary> [Test] - public void RequestUsingAuthorizationHeaderScattered() { + public async Task RequestUsingAuthorizationHeaderScattered() { TestDirectedMessage request = new TestDirectedMessage(MessageTransport.Direct) { Age = 15, Name = "Andrew", @@ -201,9 +199,9 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { request.Recipient = new Uri("http://localhost/?appearinquery=queryish"); request.HttpMethods = HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.PostRequest; - HttpWebRequest webRequest = this.channel.InitializeRequest(request); + var webRequest = await this.channel.InitializeRequestAsync(request, CancellationToken.None); Assert.IsNotNull(webRequest); - Assert.AreEqual("POST", webRequest.Method); + Assert.AreEqual(HttpMethod.Post, webRequest.Method); Assert.AreEqual(request.Recipient, webRequest.RequestUri); var declaredParts = new Dictionary<string, string> { @@ -213,23 +211,23 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { { "Timestamp", XmlConvert.ToString(request.Timestamp, XmlDateTimeSerializationMode.Utc) }, }; - Assert.AreEqual(CreateAuthorizationHeader(declaredParts), webRequest.Headers[HttpRequestHeader.Authorization]); + Assert.AreEqual(CreateAuthorizationHeader(declaredParts), webRequest.Headers.Authorization.ToString()); Assert.AreEqual("appearinform=formish", this.webRequestHandler.RequestEntityAsString); } [Test] - public void RequestUsingGet() { - this.ParameterizedRequestTest(HttpDeliveryMethods.GetRequest); + public async Task RequestUsingGet() { + await this.ParameterizedRequestTestAsync(HttpDeliveryMethods.GetRequest); } [Test] - public void RequestUsingPost() { - this.ParameterizedRequestTest(HttpDeliveryMethods.PostRequest); + public async Task RequestUsingPost() { + await this.ParameterizedRequestTestAsync(HttpDeliveryMethods.PostRequest); } [Test] - public void RequestUsingHead() { - this.ParameterizedRequestTest(HttpDeliveryMethods.HeadRequest); + public async Task RequestUsingHead() { + await this.ParameterizedRequestTestAsync(HttpDeliveryMethods.HeadRequest); } /// <summary> @@ -238,14 +236,14 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { [Test] public void SendDirectMessageResponseHonorsHttpStatusCodes() { IProtocolMessage message = MessagingTestBase.GetStandardTestMessage(MessagingTestBase.FieldFill.AllRequired); - OutgoingWebResponse directResponse = this.channel.PrepareDirectResponseTestHook(message); - Assert.AreEqual(HttpStatusCode.OK, directResponse.Status); + var directResponse = this.channel.PrepareDirectResponseTestHook(message); + Assert.AreEqual(HttpStatusCode.OK, directResponse.StatusCode); var httpMessage = new TestDirectResponseMessageWithHttpStatus(); MessagingTestBase.GetStandardTestMessage(MessagingTestBase.FieldFill.AllRequired, httpMessage); httpMessage.HttpStatusCode = HttpStatusCode.NotAcceptable; directResponse = this.channel.PrepareDirectResponseTestHook(httpMessage); - Assert.AreEqual(HttpStatusCode.NotAcceptable, directResponse.Status); + Assert.AreEqual(HttpStatusCode.NotAcceptable, directResponse.StatusCode); } private static string CreateAuthorizationHeader(IDictionary<string, string> fields) { @@ -296,7 +294,7 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { return new HttpRequestInfo(request.Method, request.RequestUri, request.Headers, postEntity); } - private void ParameterizedRequestTest(HttpDeliveryMethods scheme) { + private async Task ParameterizedRequestTestAsync(HttpDeliveryMethods scheme) { TestDirectedMessage request = new TestDirectedMessage(MessageTransport.Direct) { Age = 15, Name = "Andrew", @@ -306,12 +304,12 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { HttpMethods = scheme, }; - CachedDirectWebResponse rawResponse = null; - this.webRequestHandler.Callback = (req) => { + HttpResponseMessage rawResponse = null; + this.webRequestHandler.Callback = async req => { Assert.IsNotNull(req); - HttpRequestInfo reqInfo = ConvertToRequestInfo(req, this.webRequestHandler.RequestEntityStream); - Assert.AreEqual(MessagingUtilities.GetHttpVerb(scheme), reqInfo.HttpMethod); - var incomingMessage = this.channel.ReadFromRequest(reqInfo) as TestMessage; + HttpRequestMessage reqInfo = ConvertToRequestInfo(req, this.webRequestHandler.RequestEntityStream); + Assert.AreEqual(MessagingUtilities.GetHttpVerb(scheme), reqInfo.Method); + var incomingMessage = (await this.channel.ReadFromRequestAsync(reqInfo, CancellationToken.None)) as TestMessage; Assert.IsNotNull(incomingMessage); Assert.AreEqual(request.Age, incomingMessage.Age); Assert.AreEqual(request.Name, incomingMessage.Name); @@ -324,12 +322,12 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { { "Location", request.Location.AbsoluteUri }, { "Timestamp", XmlConvert.ToString(request.Timestamp, XmlDateTimeSerializationMode.Utc) }, }; - rawResponse = new CachedDirectWebResponse(); - rawResponse.SetResponse(MessagingUtilities.CreateQueryString(responseFields)); + rawResponse = new HttpResponseMessage(); + rawResponse.Content = new StringContent(MessagingUtilities.CreateQueryString(responseFields)); return rawResponse; }; - IProtocolMessage response = this.channel.Request(request); + IProtocolMessage response = await this.channel.RequestAsync(request, CancellationToken.None); Assert.IsNotNull(response); Assert.IsInstanceOf<TestMessage>(response); TestMessage responseMessage = (TestMessage)response; @@ -338,7 +336,7 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { Assert.AreEqual(request.Location, responseMessage.Location); } - private void ParameterizedReceiveTest(HttpDeliveryMethods scheme) { + private async Task ParameterizedReceiveTestAsync(HttpDeliveryMethods scheme) { var fields = new Dictionary<string, string> { { "age", "15" }, { "Name", "Andrew" }, @@ -346,7 +344,7 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { { "Timestamp", XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc) }, { "realm", "someValue" }, }; - IProtocolMessage requestMessage = this.channel.ReadFromRequest(CreateHttpRequestInfo(scheme, fields)); + IProtocolMessage requestMessage = await this.channel.ReadFromRequestAsync(CreateHttpRequestInfo(scheme, fields).AsHttpRequestMessage(), CancellationToken.None); Assert.IsNotNull(requestMessage); Assert.IsInstanceOf<TestMessage>(requestMessage); TestMessage testMessage = (TestMessage)requestMessage; diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs index b3869e7..b8d4f2b 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs @@ -5,6 +5,9 @@ //----------------------------------------------------------------------- namespace DotNetOpenAuth.Test.OAuth.ChannelElements { + using System.Threading; + using System.Threading.Tasks; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.ChannelElements; @@ -15,20 +18,20 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { [TestFixture] public class PlaintextSigningBindingElementTest { [Test] - public void HttpsSignatureGeneration() { + public async Task HttpsSignatureGeneration() { SigningBindingElementBase target = new PlaintextSigningBindingElement(); target.Channel = new TestChannel(); MessageReceivingEndpoint endpoint = new MessageReceivingEndpoint("https://localtest", HttpDeliveryMethods.GetRequest); ITamperResistantOAuthMessage message = new UnauthorizedTokenRequest(endpoint, Protocol.Default.Version); message.ConsumerSecret = "cs"; message.TokenSecret = "ts"; - Assert.IsNotNull(target.ProcessOutgoingMessage(message)); + Assert.IsNotNull(await target.ProcessOutgoingMessageAsync(message, CancellationToken.None)); Assert.AreEqual("PLAINTEXT", message.SignatureMethod); Assert.AreEqual("cs&ts", message.Signature); } [Test] - public void HttpsSignatureVerification() { + public async Task HttpsSignatureVerification() { MessageReceivingEndpoint endpoint = new MessageReceivingEndpoint("https://localtest", HttpDeliveryMethods.GetRequest); ITamperProtectionChannelBindingElement target = new PlaintextSigningBindingElement(); target.Channel = new TestChannel(); @@ -37,11 +40,11 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { message.TokenSecret = "ts"; message.SignatureMethod = "PLAINTEXT"; message.Signature = "cs&ts"; - Assert.IsNotNull(target.ProcessIncomingMessage(message)); + Assert.IsNotNull(target.ProcessIncomingMessageAsync(message, CancellationToken.None)); } [Test] - public void HttpsSignatureVerificationNotApplicable() { + public async Task HttpsSignatureVerificationNotApplicable() { SigningBindingElementBase target = new PlaintextSigningBindingElement(); target.Channel = new TestChannel(); MessageReceivingEndpoint endpoint = new MessageReceivingEndpoint("https://localtest", HttpDeliveryMethods.GetRequest); @@ -50,11 +53,11 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { message.TokenSecret = "ts"; message.SignatureMethod = "ANOTHERALGORITHM"; message.Signature = "somethingelse"; - Assert.AreEqual(MessageProtections.None, target.ProcessIncomingMessage(message), "PLAINTEXT binding element should opt-out where it doesn't understand."); + Assert.AreEqual(MessageProtections.None, await target.ProcessIncomingMessageAsync(message, CancellationToken.None), "PLAINTEXT binding element should opt-out where it doesn't understand."); } [Test] - public void HttpSignatureGeneration() { + public async Task HttpSignatureGeneration() { SigningBindingElementBase target = new PlaintextSigningBindingElement(); target.Channel = new TestChannel(); MessageReceivingEndpoint endpoint = new MessageReceivingEndpoint("http://localtest", HttpDeliveryMethods.GetRequest); @@ -63,13 +66,13 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { message.TokenSecret = "ts"; // Since this is (non-encrypted) HTTP, so the plain text signer should not be used - Assert.IsNull(target.ProcessOutgoingMessage(message)); + Assert.IsNull(await target.ProcessOutgoingMessageAsync(message, CancellationToken.None)); Assert.IsNull(message.SignatureMethod); Assert.IsNull(message.Signature); } [Test] - public void HttpSignatureVerification() { + public async Task HttpSignatureVerification() { SigningBindingElementBase target = new PlaintextSigningBindingElement(); target.Channel = new TestChannel(); MessageReceivingEndpoint endpoint = new MessageReceivingEndpoint("http://localtest", HttpDeliveryMethods.GetRequest); @@ -78,7 +81,7 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { message.TokenSecret = "ts"; message.SignatureMethod = "PLAINTEXT"; message.Signature = "cs%26ts"; - Assert.IsNull(target.ProcessIncomingMessage(message), "PLAINTEXT signature binding element should refuse to participate in non-encrypted messages."); + Assert.IsNull(await target.ProcessIncomingMessageAsync(message, CancellationToken.None), "PLAINTEXT signature binding element should refuse to participate in non-encrypted messages."); } } } diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs index 490399c..e356c64 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/SigningBindingElementBaseTests.cs @@ -6,6 +6,8 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { using System.Collections.Generic; + using System.Net.Http; + using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Reflection; using DotNetOpenAuth.OAuth; @@ -80,7 +82,7 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { message.AccessToken = "tokenpublic"; var signedMessage = (ITamperResistantOAuthMessage)message; - signedMessage.HttpMethod = "GET"; + signedMessage.HttpMethod = HttpMethod.Get; signedMessage.SignatureMethod = "HMAC-SHA1"; MessageDictionary dictionary = this.MessageDescriptions.GetAccessor(message); @@ -115,7 +117,7 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements { message.ConsumerKey = "nerdbank.org"; ((ITamperResistantOAuthMessage)message).ConsumerSecret = "nerdbanksecret"; var signedMessage = (ITamperResistantOAuthMessage)message; - signedMessage.HttpMethod = "GET"; + signedMessage.HttpMethod = HttpMethod.Get; signedMessage.SignatureMethod = "HMAC-SHA1"; MessageDictionary dictionary = messageDescriptions.GetAccessor(message); dictionary["oauth_timestamp"] = "1222665749"; diff --git a/src/DotNetOpenAuth.Test/OAuth/ServiceProviderDescriptionTests.cs b/src/DotNetOpenAuth.Test/OAuth/ServiceProviderDescriptionTests.cs index cdc8de5..3da3112 100644 --- a/src/DotNetOpenAuth.Test/OAuth/ServiceProviderDescriptionTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth/ServiceProviderDescriptionTests.cs @@ -11,7 +11,7 @@ namespace DotNetOpenAuth.Test.OAuth { using NUnit.Framework; /// <summary> - /// Tests for the <see cref="ServiceProviderEndpoints"/> class. + /// Tests for the <see cref="ServiceProviderHostDescription"/> class. /// </summary> [TestFixture] public class ServiceProviderDescriptionTests : TestBase { @@ -20,8 +20,8 @@ namespace DotNetOpenAuth.Test.OAuth { /// </summary> [Test] public void UserAuthorizationUriTest() { - ServiceProviderDescription target = new ServiceProviderDescription(); - MessageReceivingEndpoint expected = new MessageReceivingEndpoint("http://localhost/authorization", HttpDeliveryMethods.GetRequest); + var target = new ServiceProviderHostDescription(); + var expected = new MessageReceivingEndpoint("http://localhost/authorization", HttpDeliveryMethods.GetRequest); MessageReceivingEndpoint actual; target.UserAuthorizationEndpoint = expected; actual = target.UserAuthorizationEndpoint; @@ -36,8 +36,8 @@ namespace DotNetOpenAuth.Test.OAuth { /// </summary> [Test] public void RequestTokenUriTest() { - var target = new ServiceProviderDescription(); - MessageReceivingEndpoint expected = new MessageReceivingEndpoint("http://localhost/requesttoken", HttpDeliveryMethods.GetRequest); + var target = new ServiceProviderHostDescription(); + var expected = new MessageReceivingEndpoint("http://localhost/requesttoken", HttpDeliveryMethods.GetRequest); MessageReceivingEndpoint actual; target.RequestTokenEndpoint = expected; actual = target.RequestTokenEndpoint; @@ -53,7 +53,7 @@ namespace DotNetOpenAuth.Test.OAuth { /// </summary> [Test, ExpectedException(typeof(ArgumentException))] public void RequestTokenUriWithOAuthParametersTest() { - var target = new ServiceProviderDescription(); + var target = new ServiceProviderHostDescription(); target.RequestTokenEndpoint = new MessageReceivingEndpoint("http://localhost/requesttoken?oauth_token=something", HttpDeliveryMethods.GetRequest); } @@ -62,7 +62,7 @@ namespace DotNetOpenAuth.Test.OAuth { /// </summary> [Test] public void AccessTokenUriTest() { - var target = new ServiceProviderDescription(); + var target = new ServiceProviderHostDescription(); MessageReceivingEndpoint expected = new MessageReceivingEndpoint("http://localhost/accesstoken", HttpDeliveryMethods.GetRequest); MessageReceivingEndpoint actual; target.AccessTokenEndpoint = expected; diff --git a/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs b/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs index e8f7172..b280e76 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/AuthorizationServerTests.cs @@ -8,7 +8,9 @@ namespace DotNetOpenAuth.Test.OAuth2 { using System; using System.Collections.Generic; using System.Linq; + using System.Net.Http; using System.Text; + using System.Threading; using System.Threading.Tasks; using DotNetOpenAuth.OAuth2; using DotNetOpenAuth.OAuth2.ChannelElements; @@ -25,38 +27,42 @@ namespace DotNetOpenAuth.Test.OAuth2 { /// Verifies that authorization server responds with an appropriate error response. /// </summary> [Test] - public void ErrorResponseTest() { - var coordinator = new OAuth2Coordinator<UserAgentClient>( - AuthorizationServerDescription, - AuthorizationServerMock, - new UserAgentClient(AuthorizationServerDescription), - client => { + public async Task ErrorResponseTest() { + var coordinator = new CoordinatorBase( + async (hostFactories, ct) => { var request = new AccessTokenAuthorizationCodeRequestC(AuthorizationServerDescription) { ClientIdentifier = ClientId, ClientSecret = ClientSecret, AuthorizationCode = "foo" }; - - var response = client.Channel.Request<AccessTokenFailedResponse>(request); + var client = new UserAgentClient(AuthorizationServerDescription, hostFactories: hostFactories); + var response = await client.Channel.RequestAsync<AccessTokenFailedResponse>(request, CancellationToken.None); Assert.That(response.Error, Is.Not.Null.And.Not.Empty); Assert.That(response.Error, Is.EqualTo(Protocol.AccessTokenRequestErrorCodes.InvalidRequest)); }, - server => { - server.HandleTokenRequest().Respond(); - }); - coordinator.Run(); + CoordinatorBase.Handle(AuthorizationServerDescription.TokenEndpoint).By(async (req, ct) => { + var server = new AuthorizationServer(AuthorizationServerMock); + return await server.HandleTokenRequestAsync(req, ct); + })); + await coordinator.RunAsync(); } [Test] - public void DecodeRefreshToken() { + public async Task DecodeRefreshToken() { var refreshTokenSource = new TaskCompletionSource<string>(); - var coordinator = new OAuth2Coordinator<WebServerClient>( - AuthorizationServerDescription, - AuthorizationServerMock, - new WebServerClient(AuthorizationServerDescription), - client => { + var coordinator = new CoordinatorBase( + async (hostFactories, ct) => { + var client = new WebServerClient(AuthorizationServerDescription); try { - var authState = new AuthorizationState(TestScopes) { - Callback = ClientCallback, - }; - client.PrepareRequestUserAuthorization(authState).Respond(); - var result = client.ProcessUserAuthorization(); + var authState = new AuthorizationState(TestScopes) { Callback = ClientCallback, }; + var authRedirectResponse = await client.PrepareRequestUserAuthorizationAsync(authState, ct); + Uri authCompleteUri; + using (var httpClient = hostFactories.CreateHttpClient()) { + using (var response = await httpClient.GetAsync(authRedirectResponse.Headers.Location)) { + response.EnsureSuccessStatusCode(); + authCompleteUri = response.Headers.Location; + } + } + + var authCompleteRequest = new HttpRequestMessage(HttpMethod.Get, authCompleteUri); + authCompleteRequest.Headers.Add("Cookie", string.Join("; ", authRedirectResponse.Headers.GetValues("Set-Cookie"))); + var result = await client.ProcessUserAuthorizationAsync(authCompleteRequest, ct); Assert.That(result.AccessToken, Is.Not.Null.And.Not.Empty); Assert.That(result.RefreshToken, Is.Not.Null.And.Not.Empty); refreshTokenSource.SetResult(result.RefreshToken); @@ -64,20 +70,28 @@ namespace DotNetOpenAuth.Test.OAuth2 { refreshTokenSource.TrySetCanceled(); } }, - server => { - var request = server.ReadAuthorizationRequest(); - Assert.That(request, Is.Not.Null); - server.ApproveAuthorizationRequest(request, ResourceOwnerUsername); - server.HandleTokenRequest().Respond(); - var authorization = server.DecodeRefreshToken(refreshTokenSource.Task.Result); - Assert.That(authorization, Is.Not.Null); - Assert.That(authorization.User, Is.EqualTo(ResourceOwnerUsername)); - }); - coordinator.Run(); + CoordinatorBase.Handle(AuthorizationServerDescription.AuthorizationEndpoint).By( + async (req, ct) => { + var server = new AuthorizationServer(AuthorizationServerMock); + var request = await server.ReadAuthorizationRequestAsync(req, ct); + Assert.That(request, Is.Not.Null); + var response = server.PrepareApproveAuthorizationRequest(request, ResourceOwnerUsername); + return await server.Channel.PrepareResponseAsync(response); + }), + CoordinatorBase.Handle(AuthorizationServerDescription.TokenEndpoint).By( + async (req, ct) => { + var server = new AuthorizationServer(AuthorizationServerMock); + var response = await server.HandleTokenRequestAsync(req, ct); + var authorization = server.DecodeRefreshToken(refreshTokenSource.Task.Result); + Assert.That(authorization, Is.Not.Null); + Assert.That(authorization.User, Is.EqualTo(ResourceOwnerUsername)); + return response; + })); + await coordinator.RunAsync(); } [Test] - public void ResourceOwnerScopeOverride() { + public async Task ResourceOwnerScopeOverride() { var clientRequestedScopes = new[] { "scope1", "scope2" }; var serverOverriddenScopes = new[] { "scope1", "differentScope" }; var authServerMock = CreateAuthorizationServerMock(); @@ -89,25 +103,26 @@ namespace DotNetOpenAuth.Test.OAuth2 { response.ApprovedScope.UnionWith(serverOverriddenScopes); return response; }); - var coordinator = new OAuth2Coordinator<WebServerClient>( - AuthorizationServerDescription, - authServerMock.Object, - new WebServerClient(AuthorizationServerDescription), - client => { - var authState = new AuthorizationState(TestScopes) { - Callback = ClientCallback, - }; - var result = client.ExchangeUserCredentialForToken(ResourceOwnerUsername, ResourceOwnerPassword, clientRequestedScopes); - Assert.That(result.Scope, Is.EquivalentTo(serverOverriddenScopes)); - }, - server => { - server.HandleTokenRequest().Respond(); - }); - coordinator.Run(); + + // AuthorizationServerDescription, + //authServerMock.Object, + //new WebServerClient(AuthorizationServerDescription), + var coordinator = new CoordinatorBase( + async (hostFactories, ct) => { + var client = new WebServerClient(AuthorizationServerDescription, hostFactories: hostFactories); + var result = await client.ExchangeUserCredentialForTokenAsync(ResourceOwnerUsername, ResourceOwnerPassword, clientRequestedScopes, ct); + Assert.That(result.Scope, Is.EquivalentTo(serverOverriddenScopes)); + }, + CoordinatorBase.Handle(AuthorizationServerDescription.TokenEndpoint).By( + async (req, ct) => { + var server = new AuthorizationServer(authServerMock.Object); + return await server.HandleTokenRequestAsync(req, ct); + })); + await coordinator.RunAsync(); } [Test] - public void CreateAccessTokenSeesAuthorizingUserResourceOwnerGrant() { + public async Task CreateAccessTokenSeesAuthorizingUserResourceOwnerGrant() { var authServerMock = CreateAuthorizationServerMock(); authServerMock .Setup(a => a.CheckAuthorizeResourceOwnerCredentialGrant(ResourceOwnerUsername, ResourceOwnerPassword, It.IsAny<IAccessTokenRequest>())) @@ -116,25 +131,22 @@ namespace DotNetOpenAuth.Test.OAuth2 { Assert.That(req.UserName, Is.EqualTo(ResourceOwnerUsername)); return response; }); - var coordinator = new OAuth2Coordinator<WebServerClient>( - AuthorizationServerDescription, - authServerMock.Object, - new WebServerClient(AuthorizationServerDescription), - client => { - var authState = new AuthorizationState(TestScopes) { - Callback = ClientCallback, - }; - var result = client.ExchangeUserCredentialForToken(ResourceOwnerUsername, ResourceOwnerPassword, TestScopes); + var coordinator = new CoordinatorBase( + async (hostFactories, ct) => { + var client = new WebServerClient(AuthorizationServerDescription, hostFactories: hostFactories); + var result = await client.ExchangeUserCredentialForTokenAsync(ResourceOwnerUsername, ResourceOwnerPassword, TestScopes, ct); Assert.That(result.AccessToken, Is.Not.Null); }, - server => { - server.HandleTokenRequest().Respond(); - }); - coordinator.Run(); + CoordinatorBase.Handle(AuthorizationServerDescription.TokenEndpoint).By( + async (req, ct) => { + var server = new AuthorizationServer(authServerMock.Object); + return await server.HandleTokenRequestAsync(req, ct); + })); + await coordinator.RunAsync(); } [Test] - public void CreateAccessTokenSeesAuthorizingUserClientCredentialGrant() { + public async Task CreateAccessTokenSeesAuthorizingUserClientCredentialGrant() { var authServerMock = CreateAuthorizationServerMock(); authServerMock .Setup(a => a.CheckAuthorizeClientCredentialsGrant(It.IsAny<IAccessTokenRequest>())) @@ -142,25 +154,22 @@ namespace DotNetOpenAuth.Test.OAuth2 { Assert.That(req.UserName, Is.Null); return new AutomatedAuthorizationCheckResponse(req, true); }); - var coordinator = new OAuth2Coordinator<WebServerClient>( - AuthorizationServerDescription, - authServerMock.Object, - new WebServerClient(AuthorizationServerDescription), - client => { - var authState = new AuthorizationState(TestScopes) { - Callback = ClientCallback, - }; - var result = client.GetClientAccessToken(TestScopes); + var coordinator = new CoordinatorBase( + async (hostFactories, ct) => { + var client = new WebServerClient(AuthorizationServerDescription, hostFactories: hostFactories); + var result = await client.GetClientAccessTokenAsync(TestScopes, ct); Assert.That(result.AccessToken, Is.Not.Null); }, - server => { - server.HandleTokenRequest().Respond(); - }); - coordinator.Run(); + CoordinatorBase.Handle(AuthorizationServerDescription.TokenEndpoint).By( + async (req, ct) => { + var server = new AuthorizationServer(authServerMock.Object); + return await server.HandleTokenRequestAsync(req, ct); + })); + await coordinator.RunAsync(); } [Test] - public void CreateAccessTokenSeesAuthorizingUserAuthorizationCodeGrant() { + public async Task CreateAccessTokenSeesAuthorizingUserAuthorizationCodeGrant() { var authServerMock = CreateAuthorizationServerMock(); authServerMock .Setup(a => a.IsAuthorizationValid(It.IsAny<IAuthorizationDescription>())) @@ -168,30 +177,44 @@ namespace DotNetOpenAuth.Test.OAuth2 { Assert.That(req.User, Is.EqualTo(ResourceOwnerUsername)); return true; }); - var coordinator = new OAuth2Coordinator<WebServerClient>( - AuthorizationServerDescription, - authServerMock.Object, - new WebServerClient(AuthorizationServerDescription), - client => { + var coordinator = new CoordinatorBase( + async (hostFactories, ct) => { + var client = new WebServerClient(AuthorizationServerDescription, hostFactories: hostFactories); var authState = new AuthorizationState(TestScopes) { Callback = ClientCallback, }; - client.PrepareRequestUserAuthorization(authState).Respond(); - var result = client.ProcessUserAuthorization(); + var authRedirectResponse = await client.PrepareRequestUserAuthorizationAsync(authState, ct); + Uri authCompleteUri; + using (var httpClient = hostFactories.CreateHttpClient()) { + using (var response = await httpClient.GetAsync(authRedirectResponse.Headers.Location)) { + response.EnsureSuccessStatusCode(); + authCompleteUri = response.Headers.Location; + } + } + + var authCompleteRequest = new HttpRequestMessage(HttpMethod.Get, authCompleteUri); + var result = await client.ProcessUserAuthorizationAsync(authCompleteRequest, ct); Assert.That(result.AccessToken, Is.Not.Null.And.Not.Empty); Assert.That(result.RefreshToken, Is.Not.Null.And.Not.Empty); }, - server => { - var request = server.ReadAuthorizationRequest(); - Assert.That(request, Is.Not.Null); - server.ApproveAuthorizationRequest(request, ResourceOwnerUsername); - server.HandleTokenRequest().Respond(); - }); - coordinator.Run(); + CoordinatorBase.Handle(AuthorizationServerDescription.TokenEndpoint).By( + async (req, ct) => { + var server = new AuthorizationServer(authServerMock.Object); + var request = await server.ReadAuthorizationRequestAsync(req, ct); + Assert.That(request, Is.Not.Null); + var response = server.PrepareApproveAuthorizationRequest(request, ResourceOwnerUsername); + return await server.Channel.PrepareResponseAsync(response); + }), + CoordinatorBase.Handle(AuthorizationServerDescription.TokenEndpoint).By( + async (req, ct) => { + var server = new AuthorizationServer(authServerMock.Object); + return await server.HandleTokenRequestAsync(req, ct); + })); + await coordinator.RunAsync(); } [Test] - public void ClientCredentialScopeOverride() { + public async Task ClientCredentialScopeOverride() { var clientRequestedScopes = new[] { "scope1", "scope2" }; var serverOverriddenScopes = new[] { "scope1", "differentScope" }; var authServerMock = CreateAuthorizationServerMock(); @@ -203,21 +226,21 @@ namespace DotNetOpenAuth.Test.OAuth2 { response.ApprovedScope.UnionWith(serverOverriddenScopes); return response; }); - var coordinator = new OAuth2Coordinator<WebServerClient>( - AuthorizationServerDescription, - authServerMock.Object, - new WebServerClient(AuthorizationServerDescription), - client => { + var coordinator = new CoordinatorBase( + async (hostFactories, ct) => { + var client = new WebServerClient(AuthorizationServerDescription, hostFactories: hostFactories); var authState = new AuthorizationState(TestScopes) { Callback = ClientCallback, }; - var result = client.GetClientAccessToken(clientRequestedScopes); + var result = await client.GetClientAccessTokenAsync(clientRequestedScopes, ct); Assert.That(result.Scope, Is.EquivalentTo(serverOverriddenScopes)); }, - server => { - server.HandleTokenRequest().Respond(); - }); - coordinator.Run(); + CoordinatorBase.Handle(AuthorizationServerDescription.TokenEndpoint).By( + async (req, ct) => { + var server = new AuthorizationServer(authServerMock.Object); + return await server.HandleTokenRequestAsync(req, ct); + })); + await coordinator.RunAsync(); } } } diff --git a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs index 52b5371..810d830 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs @@ -31,7 +31,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { var authServerChannel = new OAuth2AuthorizationServerChannel(new Mock<IAuthorizationServerHost>().Object, new Mock<ClientAuthenticationModule>().Object); this.authServerMessageFactory = authServerChannel.MessageFactoryTestHook; - var clientChannel = new OAuth2ClientChannel(); + var clientChannel = new OAuth2ClientChannel(null); this.clientMessageFactory = clientChannel.MessageFactoryTestHook; } diff --git a/src/DotNetOpenAuth.Test/OAuth2/OAuth2Coordinator.cs b/src/DotNetOpenAuth.Test/OAuth2/OAuth2Coordinator.cs deleted file mode 100644 index eeda125..0000000 --- a/src/DotNetOpenAuth.Test/OAuth2/OAuth2Coordinator.cs +++ /dev/null @@ -1,74 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="OAuth2Coordinator.cs" company="Outercurve Foundation"> -// Copyright (c) Outercurve Foundation. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.Test.OAuth2 { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Net; - using System.Text; - using DotNetOpenAuth.OAuth2; - using DotNetOpenAuth.Test.Mocks; - using Validation; - - internal class OAuth2Coordinator<TClient> : CoordinatorBase<TClient, AuthorizationServer> - where TClient : ClientBase { - private readonly AuthorizationServerDescription serverDescription; - private readonly IAuthorizationServerHost authServerHost; - private readonly TClient client; - - internal OAuth2Coordinator( - AuthorizationServerDescription serverDescription, - IAuthorizationServerHost authServerHost, - TClient client, - Action<TClient> clientAction, - Action<AuthorizationServer> authServerAction) - : base(clientAction, authServerAction) { - Requires.NotNull(serverDescription, "serverDescription"); - Requires.NotNull(authServerHost, "authServerHost"); - Requires.NotNull(client, "client"); - - this.serverDescription = serverDescription; - this.authServerHost = authServerHost; - this.client = client; - - this.client.ClientIdentifier = OAuth2TestBase.ClientId; - this.client.ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(OAuth2TestBase.ClientSecret); - } - - internal override void Run() { - var authServer = new AuthorizationServer(this.authServerHost); - - var rpCoordinatingChannel = new CoordinatingOAuth2ClientChannel(this.client.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter); - var opCoordinatingChannel = new CoordinatingOAuth2AuthServerChannel(authServer.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter); - rpCoordinatingChannel.RemoteChannel = opCoordinatingChannel; - opCoordinatingChannel.RemoteChannel = rpCoordinatingChannel; - - this.client.Channel = rpCoordinatingChannel; - authServer.Channel = opCoordinatingChannel; - - this.RunCore(this.client, authServer); - } - - private static Action<WebServerClient> WrapAction(Action<WebServerClient> action) { - Requires.NotNull(action, "action"); - - return client => { - action(client); - ((CoordinatingChannel)client.Channel).Close(); - }; - } - - private static Action<AuthorizationServer> WrapAction(Action<AuthorizationServer> action) { - Requires.NotNull(action, "action"); - - return authServer => { - action(authServer); - ((CoordinatingChannel)authServer.Channel).Close(); - }; - } - } -} diff --git a/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs b/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs index 395b18c..f01b5b7 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs @@ -37,10 +37,7 @@ namespace DotNetOpenAuth.Test.OAuth2 { TokenEndpoint = new Uri("https://authserver/token"), }; - protected static readonly IClientDescription ClientDescription = new ClientDescription( - ClientSecret, - ClientCallback, - ClientType.Confidential); + protected static readonly IClientDescription ClientDescription = new ClientDescription(ClientSecret, ClientCallback); protected static readonly IAuthorizationServerHost AuthorizationServerMock = CreateAuthorizationServerMock().Object; |