diff options
Diffstat (limited to 'src')
35 files changed, 1075 insertions, 240 deletions
diff --git a/src/DotNetOpenAuth.Test/Mocks/TestDirectResponseMessageWithHttpStatus.cs b/src/DotNetOpenAuth.Test/Mocks/TestDirectResponseMessageWithHttpStatus.cs index d692320..20fd6c4 100644 --- a/src/DotNetOpenAuth.Test/Mocks/TestDirectResponseMessageWithHttpStatus.cs +++ b/src/DotNetOpenAuth.Test/Mocks/TestDirectResponseMessageWithHttpStatus.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.Test.Mocks { using System; using System.Collections.Generic; using System.Linq; + using System.Net; using System.Text; using DotNetOpenAuth.Messaging; @@ -23,8 +24,15 @@ namespace DotNetOpenAuth.Test.Mocks { /// <summary> /// Gets or sets the HTTP status code that the direct respones should be sent with. /// </summary> - /// <value></value> - public System.Net.HttpStatusCode HttpStatusCode { get; set; } + public HttpStatusCode HttpStatusCode { get; set; } + + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + /// <value>May be an empty collection, but must not be <c>null</c>.</value> + public WebHeaderCollection Headers { + get { return new WebHeaderCollection(); } + } #endregion } diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index d1d6bd9..f482f34 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -284,6 +284,7 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="Messaging\HostErrorException.cs" /> <Compile Include="Messaging\IHttpDirectResponse.cs" /> <Compile Include="Messaging\IExtensionMessage.cs" /> + <Compile Include="Messaging\IHttpDirectResponseContract.cs" /> <Compile Include="Messaging\IMessage.cs" /> <Compile Include="Messaging\IncomingWebResponse.cs" /> <Compile Include="Messaging\IDirectResponseProtocolMessage.cs" /> @@ -302,6 +303,22 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="Messaging\Reflection\IMessagePartEncoder.cs" /> <Compile Include="Messaging\Reflection\IMessagePartNullEncoder.cs" /> <Compile Include="Messaging\Reflection\MessageDescriptionCollection.cs" /> + <Compile Include="OAuthWrap\Messages\Assertion\AssertionRequest.cs" /> + <Compile Include="OAuthWrap\Messages\Assertion\AssertionFailedResponse.cs" /> + <Compile Include="OAuthWrap\Messages\ClientAccountAndPassword\ClientAccountUsernamePasswordFailedResponse.cs" /> + <Compile Include="OAuthWrap\Messages\ClientAccountAndPassword\ClientAccountUsernamePasswordRequest.cs" /> + <Compile Include="OAuthWrap\Messages\ClientAccountAndPassword\ClientAccountUsernamePasswordSuccessResponse.cs" /> + <Compile Include="OAuthWrap\Messages\Assertion\AssertionSuccessResponse.cs" /> + <Compile Include="OAuthWrap\Messages\UsernameAndPassword\UserNamePasswordRefreshAccessTokenFailedResponse.cs" /> + <Compile Include="OAuthWrap\Messages\UsernameAndPassword\UserNamePasswordRefreshAccessTokenSuccessResponse.cs" /> + <Compile Include="OAuthWrap\Messages\UsernameAndPassword\UserNamePasswordRefreshAccessTokenRequest.cs" /> + <Compile Include="OAuthWrap\Messages\UsernameAndPassword\UserNamePasswordCaptchaResponse.cs" /> + <Compile Include="OAuthWrap\Messages\UsernameAndPassword\UserNamePasswordVerificationResponse.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppRefreshAccessTokenFailedResponse.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppRefreshAccessTokenSuccessResponse.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppInitialAccessTokenBadClientResponse.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppInitialAccessTokenFailedResponse.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppRefreshAccessTokenRequest.cs" /> <Compile Include="OAuth\ChannelElements\ICombinedOpenIdProviderTokenManager.cs" /> <Compile Include="OAuth\ChannelElements\IConsumerDescription.cs" /> <Compile Include="OAuth\ChannelElements\IConsumerTokenManager.cs" /> @@ -590,18 +607,15 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="OAuthWrap\ChannelElements\OAuthWrapMessageFactory.cs" /> <Compile Include="OAuthWrap\ChannelElements\UriOrOutOfBandEncoding.cs" /> <Compile Include="OAuthWrap\ConsumerBase.cs" /> - <Compile Include="OAuthWrap\Messages\AccessTokenFailedResponse.cs" /> - <Compile Include="OAuthWrap\Messages\AccessTokenSuccessResponse.cs" /> - <Compile Include="OAuthWrap\Messages\AccessTokenWithConsumerNamePasswordRequest.cs" /> - <Compile Include="OAuthWrap\Messages\AccessTokenWithSamlRequest.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppInitialAccessTokenSuccessResponse.cs" /> <Compile Include="OAuthWrap\Messages\MessageBase.cs" /> - <Compile Include="OAuthWrap\Messages\AccessTokenWithVerificationCodeRequest.cs" /> - <Compile Include="OAuthWrap\Messages\UserAuthorizationInUserAgentDeniedResponse.cs" /> - <Compile Include="OAuthWrap\Messages\UserAuthorizationInUserAgentRequest.cs" /> - <Compile Include="OAuthWrap\Messages\UserAuthorizationInUserAgentGrantedResponse.cs" /> - <Compile Include="OAuthWrap\Messages\UserAuthorizationViaUsernamePasswordFailedResponse.cs" /> - <Compile Include="OAuthWrap\Messages\UserAuthorizationViaUsernamePasswordRequest.cs" /> - <Compile Include="OAuthWrap\Messages\UserAuthorizationViaUsernamePasswordSuccessResponse.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppInitialAccessTokenRequest.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppFailedResponse.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppRequest.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppSuccessResponse.cs" /> + <Compile Include="OAuthWrap\Messages\UsernameAndPassword\UserNamePasswordFailedResponse.cs" /> + <Compile Include="OAuthWrap\Messages\UsernameAndPassword\UserNamePasswordRequest.cs" /> + <Compile Include="OAuthWrap\Messages\UsernameAndPassword\UserNamePasswordSuccessResponse.cs" /> <Compile Include="OAuthWrap\Protocol.cs" /> <Compile Include="OAuthWrap\SimpleAuthStrings.Designer.cs"> <AutoGen>True</AutoGen> @@ -756,6 +770,9 @@ http://opensource.org/licenses/ms-pl.html </BootstrapperPackage> <Content Include="DotNetOpenAuth.ico" /> </ItemGroup> + <ItemGroup> + <Folder Include="OAuthWrap\Messages\RichApp\" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" /> </Project>
\ No newline at end of file diff --git a/src/DotNetOpenAuth/Messaging/IHttpDirectResponse.cs b/src/DotNetOpenAuth/Messaging/IHttpDirectResponse.cs index c0e7803..20c3d6f 100644 --- a/src/DotNetOpenAuth/Messaging/IHttpDirectResponse.cs +++ b/src/DotNetOpenAuth/Messaging/IHttpDirectResponse.cs @@ -5,16 +5,24 @@ //----------------------------------------------------------------------- namespace DotNetOpenAuth.Messaging { + using System.Diagnostics.Contracts; using System.Net; /// <summary> /// An interface that allows direct response messages to specify /// HTTP transport specific properties. /// </summary> + [ContractClass(typeof(IHttpDirectResponseContract))] public interface IHttpDirectResponse { /// <summary> - /// Gets the HTTP status code that the direct respones should be sent with. + /// Gets the HTTP status code that the direct response should be sent with. /// </summary> HttpStatusCode HttpStatusCode { get; } + + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + /// <value>May be an empty collection, but must not be <c>null</c>.</value> + WebHeaderCollection Headers { get; } } } diff --git a/src/DotNetOpenAuth/Messaging/IHttpDirectResponseContract.cs b/src/DotNetOpenAuth/Messaging/IHttpDirectResponseContract.cs new file mode 100644 index 0000000..b1ddba2 --- /dev/null +++ b/src/DotNetOpenAuth/Messaging/IHttpDirectResponseContract.cs @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------- +// <copyright file="IHttpDirectResponseContract.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Messaging { + using System; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + using System.Linq; + using System.Net; + using System.Text; + + /// <summary> + /// Contract class for the <see cref="IHttpDirectResponse"/> interface. + /// </summary> + [ContractClassFor(typeof(IHttpDirectResponse))] + public abstract class IHttpDirectResponseContract : IHttpDirectResponse { + #region IHttpDirectResponse Members + + /// <summary> + /// Gets the HTTP status code that the direct response should be sent with. + /// </summary> + /// <value></value> + HttpStatusCode IHttpDirectResponse.HttpStatusCode { + get { throw new NotImplementedException(); } + } + + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + /// <value>May be an empty collection, but must not be <c>null</c>.</value> + WebHeaderCollection IHttpDirectResponse.Headers { + get { + Contract.Ensures(Contract.Result<WebHeaderCollection>() != null); + throw new NotImplementedException(); + } + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapMessageFactory.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapMessageFactory.cs index a1a26f6..02f50d7 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapMessageFactory.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapMessageFactory.cs @@ -38,31 +38,23 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { Version version = Protocol.DefaultVersion; if (fields.ContainsKey(Protocol.wrap_client_id) && fields.ContainsKey(Protocol.wrap_callback)) { - return new UserAuthorizationInUserAgentRequest(recipient.Location, version); + return new WebAppRequest(recipient.Location, version); } if (fields.ContainsKey(Protocol.wrap_client_id) && fields.ContainsKey(Protocol.wrap_verification_code)) { - return new AccessTokenWithVerificationCodeRequest(recipient.Location, version); + return new WebAppInitialAccessTokenRequest(recipient.Location, version); } if (fields.ContainsKey(Protocol.wrap_name)) { - return new AccessTokenWithConsumerNamePasswordRequest(version); + return new ClientAccountUsernamePasswordRequest(recipient.Location, version); } if (fields.ContainsKey(Protocol.wrap_username)) { - return new UserAuthorizationViaUsernamePasswordRequest(version); - } - - if (fields.ContainsKey(Protocol.wrap_saml)) { - return new AccessTokenWithSamlRequest(version); + return new UserNamePasswordRequest(recipient.Location, version); } if (fields.ContainsKey(Protocol.wrap_verification_code)) { - return new UserAuthorizationInUserAgentGrantedResponse(recipient.Location, version); - } - - if (fields.ContainsKey(Protocol.wrap_error_reason)) { - return new UserAuthorizationInUserAgentDeniedResponse(recipient.Location, version); + return new WebAppSuccessResponse(recipient.Location, version); } return null; @@ -81,21 +73,21 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { public IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) { Version version = Protocol.DefaultVersion; - var accessTokenRequest = request as AccessTokenWithVerificationCodeRequest; + var accessTokenRequest = request as WebAppInitialAccessTokenRequest; if (accessTokenRequest != null) { if (fields.ContainsKey(Protocol.wrap_access_token)) { - return new AccessTokenSuccessResponse(accessTokenRequest); + return new WebAppInitialAccessTokenSuccessResponse(accessTokenRequest); } else { - return new AccessTokenFailedResponse(accessTokenRequest); + //return new AccessTokenWithVerificationCodeFailedResponse(accessTokenRequest); } } - var userAuthorization = request as UserAuthorizationViaUsernamePasswordRequest; + var userAuthorization = request as UserNamePasswordRequest; if (userAuthorization != null) { if (fields.ContainsKey(Protocol.wrap_verification_code)) { - return new UserAuthorizationViaUsernamePasswordSuccessResponse(userAuthorization); + return new UserNamePasswordSuccessResponse(userAuthorization); } else { - return new UserAuthorizationViaUsernamePasswordFailedResponse(userAuthorization); + //return new UserAuthorizationViaUsernamePasswordFailedResponse(userAuthorization); } } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenWithConsumerNamePasswordRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenWithConsumerNamePasswordRequest.cs deleted file mode 100644 index 83fcd75..0000000 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenWithConsumerNamePasswordRequest.cs +++ /dev/null @@ -1,41 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="AccessTokenWithConsumerNamePasswordRequest.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.OAuthWrap.Messages { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using DotNetOpenAuth.Messaging; - - /// <summary> - /// A request for an access token for a consumer application that has its - /// own (non-user affiliated) consumer name and password. - /// </summary> - internal class AccessTokenWithConsumerNamePasswordRequest : MessageBase { - /// <summary> - /// Initializes a new instance of the <see cref="AccessTokenWithConsumerNamePasswordRequest"/> class. - /// </summary> - /// <param name="version">The version.</param> - internal AccessTokenWithConsumerNamePasswordRequest(Version version) - : base(version) { - } - - /// <summary> - /// Gets or sets the account name. - /// </summary> - /// <value>The consumer name.</value> - [MessagePart(Protocol.wrap_name, IsRequired = true, AllowEmpty = false)] - public string Name { get; set; } - - /// <summary> - /// Gets or sets the account password. - /// </summary> - /// <value>The password.</value> - [MessagePart(Protocol.wrap_password, IsRequired = true, AllowEmpty = true)] - public string Password { get; set; } - } -} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenWithSamlRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenWithSamlRequest.cs deleted file mode 100644 index 6b19e13..0000000 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenWithSamlRequest.cs +++ /dev/null @@ -1,45 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="AccessTokenWithSamlRequest.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.OAuthWrap.Messages { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using DotNetOpenAuth.Messaging; - - /// <summary> - /// A request for an access token for a consumer application that can - /// issue a SAML assertion to prove its identity. - /// </summary> - internal class AccessTokenWithSamlRequest : MessageBase { - /// <summary> - /// Initializes a new instance of the <see cref="AccessTokenWithSamlRequest"/> class. - /// </summary> - /// <param name="version">The version.</param> - internal AccessTokenWithSamlRequest(Version version) - : base(version) { - } - - /// <summary> - /// Gets or sets the SAML token. - /// </summary> - /// <value>A SAML token serialized as an XML document.</value> - [MessagePart(Protocol.wrap_saml, IsRequired = true, AllowEmpty = false)] - public string Saml { get; set; } - - /// <summary> - /// Gets or sets the SWT. - /// </summary> - /// <value>The SWT (TODO: what is that?).</value> - /// <remarks> - /// The spec says that the SWT parameter is required for certain scenarios, - /// so we mark it as optional here since the scenario may or may not apply. - /// </remarks> - [MessagePart(Protocol.wrap_swt, IsRequired = false, AllowEmpty = false)] - public string Swt { get; set; } - } -} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenFailedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionFailedResponse.cs index e5c00d8..cc176c8 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenFailedResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionFailedResponse.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="AccessTokenFailedResponse.cs" company="Andrew Arnott"> +// <copyright file="AssertionFailedResponse.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -13,15 +13,15 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { using DotNetOpenAuth.Messaging; /// <summary> - /// The direct response message that may contain the reason the access token - /// was NOT returned from the Authorization Server to the Consumer. + /// A response from the Authorization Server to the Client to indicate that a + /// request for an access code failed, probably due to an invalid assertion. /// </summary> - internal class AccessTokenFailedResponse : MessageBase, IHttpDirectResponse { + internal class AssertionFailedResponse : MessageBase, IHttpDirectResponse { /// <summary> - /// Initializes a new instance of the <see cref="AccessTokenFailedResponse"/> class. + /// Initializes a new instance of the <see cref="AssertionFailedResponse"/> class. /// </summary> /// <param name="request">The request.</param> - internal AccessTokenFailedResponse(AccessTokenWithVerificationCodeRequest request) + internal AssertionFailedResponse(AssertionRequest request) : base(request) { } @@ -35,16 +35,17 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { get { return HttpStatusCode.Unauthorized; } } - #endregion - /// <summary> - /// Gets or sets the error reason. + /// Gets the HTTP headers to add to the response. /// </summary> - /// <value> - /// The reason for the failure. Among other values, it may be <c>null</c> - /// or expired_delegation_code. - /// </value> - [MessagePart(Protocol.wrap_error_reason, IsRequired = false, AllowEmpty = true)] - internal string ErrorReason { get; set; } + WebHeaderCollection IHttpDirectResponse.Headers { + get { + return new WebHeaderCollection() { + { HttpResponseHeader.WwwAuthenticate, Protocol.HttpAuthorizationScheme }, + }; + } + } + + #endregion } } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionRequest.cs new file mode 100644 index 0000000..6a553ef --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionRequest.cs @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------- +// <copyright file="AssertionRequest.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + + internal class AssertionRequest : MessageBase { + /// <summary> + /// Initializes a new instance of the <see cref="AssertionRequest"/> class. + /// </summary> + /// <param name="version">The version.</param> + /// <param name="authorizationServer">The authorization server.</param> + internal AssertionRequest(Version version, Uri authorizationServer) + : base(version, MessageTransport.Direct, authorizationServer) { + this.HttpMethods = HttpDeliveryMethods.PostRequest; + } + + /// <summary> + /// Gets or sets the format of the assertion as defined by the Authorization Server. + /// </summary> + /// <value>The assertion format.</value> + [MessagePart(Protocol.wrap_assertion_format, IsRequired = true, AllowEmpty = false)] + internal string AssertionFormat { get; set; } + + /// <summary> + /// Gets or sets the assertion. + /// </summary> + /// <value>The assertion.</value> + [MessagePart(Protocol.wrap_assertion, IsRequired = true, AllowEmpty = false)] + internal string Assertion { get; set; } + + /// <summary> + /// Gets or sets an optional authorization scope as defined by the Authorization Server. + /// </summary> + [MessagePart(Protocol.wrap_scope, IsRequired = false, AllowEmpty = true)] + internal string Scope { get; set; } + + /// <summary> + /// Checks the message state for conformity to the protocol specification + /// and throws an exception if the message is invalid. + /// </summary> + /// <remarks> + /// <para>Some messages have required fields, or combinations of fields that must relate to each other + /// in specialized ways. After deserializing a message, this method checks the state of the + /// message to see if it conforms to the protocol.</para> + /// <para>Note that this property should <i>not</i> check signatures or perform any state checks + /// outside this scope of this particular message.</para> + /// </remarks> + /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> + protected override void EnsureValidMessage() { + base.EnsureValidMessage(); + ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), SimpleAuthStrings.HttpsRequired); + } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionSuccessResponse.cs new file mode 100644 index 0000000..a934c07 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionSuccessResponse.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------- +// <copyright file="AssertionSuccessResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A response from the Authorization Server to the Client containing an access code. + /// </summary> + internal class AssertionSuccessResponse : MessageBase { + /// <summary> + /// Initializes a new instance of the <see cref="AssertionSuccessResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal AssertionSuccessResponse(ClientAccountUsernamePasswordRequest request) + : base(request) { + } + + /// <summary> + /// Gets or sets the access token. + /// </summary> + /// <value>The access token.</value> + [MessagePart(Protocol.wrap_access_token, IsRequired = true, AllowEmpty = false)] + internal string AccessToken { get; set; } + + /// <summary> + /// Gets or sets the lifetime of the access token. + /// </summary> + /// <value>The lifetime.</value> + [MessagePart(Protocol.wrap_access_token_expires_in, IsRequired = false, Encoder = typeof(TimespanSecondsEncoder))] + internal TimeSpan Lifetime { get; set; } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordFailedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordFailedResponse.cs new file mode 100644 index 0000000..d3e71e3 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordFailedResponse.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------- +// <copyright file="ClientAccountUsernamePasswordFailedResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A response from the Authorization Server to the Client to indicate that a + /// request for an access code failed, probably due to an invalid account + /// name and password. + /// </summary> + internal class ClientAccountUsernamePasswordFailedResponse : MessageBase, IHttpDirectResponse { + /// <summary> + /// Initializes a new instance of the <see cref="ClientAccountUsernamePasswordFailedResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal ClientAccountUsernamePasswordFailedResponse(ClientAccountUsernamePasswordRequest request) + : base(request) { + } + + #region IHttpDirectResponse Members + + /// <summary> + /// Gets the HTTP status code that the direct respones should be sent with. + /// </summary> + /// <value><see cref="HttpStatusCode.Unauthorized"/></value> + HttpStatusCode IHttpDirectResponse.HttpStatusCode { + get { return HttpStatusCode.Unauthorized; } + } + + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + WebHeaderCollection IHttpDirectResponse.Headers { + get { + return new WebHeaderCollection() { + { HttpResponseHeader.WwwAuthenticate, Protocol.HttpAuthorizationScheme }, + }; + } + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordRequest.cs new file mode 100644 index 0000000..27f81e8 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordRequest.cs @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------- +// <copyright file="ClientAccountUsernamePasswordRequest.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A request for an access token for a client application that has its + /// own (non-user affiliated) client name and password. + /// </summary> + /// <remarks> + /// This is somewhat analogous to 2-legged OAuth. + /// </remarks> + internal class ClientAccountUsernamePasswordRequest : MessageBase { + /// <summary> + /// Initializes a new instance of the <see cref="ClientAccountUsernamePasswordRequest"/> class. + /// </summary> + /// <param name="authorizationServer">The authorization server.</param> + /// <param name="version">The version.</param> + internal ClientAccountUsernamePasswordRequest(Uri authorizationServer, Version version) + : base(version, MessageTransport.Direct, authorizationServer) { + this.HttpMethods = HttpDeliveryMethods.PostRequest; + } + + /// <summary> + /// Gets or sets the account name. + /// </summary> + /// <value>The name on the account.</value> + [MessagePart(Protocol.wrap_name, IsRequired = true, AllowEmpty = false)] + internal string Name { get; set; } + + /// <summary> + /// Gets or sets the user's password. + /// </summary> + /// <value>The password.</value> + [MessagePart(Protocol.wrap_password, IsRequired = true, AllowEmpty = false)] + internal string Password { get; set; } + + /// <summary> + /// Gets or sets an optional authorization scope as defined by the Authorization Server. + /// </summary> + [MessagePart(Protocol.wrap_scope, IsRequired = false, AllowEmpty = true)] + internal string Scope { get; set; } + + /// <summary> + /// Checks the message state for conformity to the protocol specification + /// and throws an exception if the message is invalid. + /// </summary> + /// <remarks> + /// <para>Some messages have required fields, or combinations of fields that must relate to each other + /// in specialized ways. After deserializing a message, this method checks the state of the + /// message to see if it conforms to the protocol.</para> + /// <para>Note that this property should <i>not</i> check signatures or perform any state checks + /// outside this scope of this particular message.</para> + /// </remarks> + /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> + protected override void EnsureValidMessage() { + base.EnsureValidMessage(); + ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), SimpleAuthStrings.HttpsRequired); + } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordSuccessResponse.cs new file mode 100644 index 0000000..77129e4 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordSuccessResponse.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------- +// <copyright file="ClientAccountUsernamePasswordSuccessResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A response from the Authorization Server to the Client containing an access code. + /// </summary> + internal class ClientAccountUsernamePasswordSuccessResponse : MessageBase { + /// <summary> + /// Initializes a new instance of the <see cref="ClientAccountUsernamePasswordSuccessResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal ClientAccountUsernamePasswordSuccessResponse(ClientAccountUsernamePasswordRequest request) + : base(request) { + } + + /// <summary> + /// Gets or sets the access token. + /// </summary> + /// <value>The access token.</value> + [MessagePart(Protocol.wrap_access_token, IsRequired = true, AllowEmpty = false)] + internal string AccessToken { get; set; } + + /// <summary> + /// Gets or sets the lifetime of the access token. + /// </summary> + /// <value>The lifetime.</value> + [MessagePart(Protocol.wrap_access_token_expires_in, IsRequired = false, Encoder = typeof(TimespanSecondsEncoder))] + internal TimeSpan Lifetime { get; set; } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationViaUsernamePasswordSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationViaUsernamePasswordSuccessResponse.cs deleted file mode 100644 index 5e4e530..0000000 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationViaUsernamePasswordSuccessResponse.cs +++ /dev/null @@ -1,37 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="UserAuthorizationViaUsernamePasswordSuccessResponse.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.OAuthWrap.Messages { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using DotNetOpenAuth.Messaging; - - /// <summary> - /// A response from the Authorization Server to the Consumer containing a delegation code - /// that the Consumer should use to obtain an access token. - /// </summary> - internal class UserAuthorizationViaUsernamePasswordSuccessResponse : MessageBase { - /// <summary> - /// Initializes a new instance of the <see cref="UserAuthorizationViaUsernamePasswordSuccessResponse"/> class. - /// </summary> - /// <param name="request">The request.</param> - internal UserAuthorizationViaUsernamePasswordSuccessResponse(UserAuthorizationViaUsernamePasswordRequest request) - : base(request) { - } - - /// <summary> - /// Gets or sets the verification code. - /// </summary> - /// <value> - /// The long-lived credential assigned by the Authorization Server to this Consumer for - /// use in accessing the authorizing user's protected resources. - /// </value> - [MessagePart(Protocol.wrap_verification_code, IsRequired = true, AllowEmpty = true)] - internal string VerificationCode { get; set; } - } -} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordCaptchaResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordCaptchaResponse.cs new file mode 100644 index 0000000..c6a5fb1 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordCaptchaResponse.cs @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------- +// <copyright file="UsernamePasswordCaptchaResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A response from the Authorization Server indicating the Client must have the user + /// complete a CAPTCHA puzzle prior to authorization. + /// </summary> + internal class UsernamePasswordCaptchaResponse : MessageBase, IHttpDirectResponse { + /// <summary> + /// Initializes a new instance of the <see cref="UsernamePasswordCaptchaResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal UsernamePasswordCaptchaResponse(UserNamePasswordRequest request) + : base(request) { + } + + #region IHttpDirectResponse Members + + HttpStatusCode IHttpDirectResponse.HttpStatusCode { + get { return HttpStatusCode.BadRequest; } + } + + WebHeaderCollection IHttpDirectResponse.Headers { + get { return new WebHeaderCollection(); } + } + + #endregion + + /// <summary> + /// Gets or sets the URL to the CAPTCHA puzzle. + /// </summary> + /// <value>The captcha URL.</value> + [MessagePart(Protocol.wrap_captcha_url, IsRequired = true, AllowEmpty = false)] + internal Uri CaptchaPuzzle { get; set; } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationViaUsernamePasswordFailedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordFailedResponse.cs index 533ad2d..afb1180 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationViaUsernamePasswordFailedResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordFailedResponse.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="UserAuthorizationViaUsernamePasswordFailedResponse.cs" company="Andrew Arnott"> +// <copyright file="UserNamePasswordFailedResponse.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -17,12 +17,13 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// request for a delegation code failed, probably due to an invalid /// username and password. /// </summary> - internal class UserAuthorizationViaUsernamePasswordFailedResponse : MessageBase, IHttpDirectResponse { + internal class UserNamePasswordFailedResponse + : MessageBase, IHttpDirectResponse { /// <summary> - /// Initializes a new instance of the <see cref="UserAuthorizationViaUsernamePasswordFailedResponse"/> class. + /// Initializes a new instance of the <see cref="UserNamePasswordFailedResponse"/> class. /// </summary> /// <param name="request">The request.</param> - internal UserAuthorizationViaUsernamePasswordFailedResponse(UserAuthorizationViaUsernamePasswordRequest request) + internal UserNamePasswordFailedResponse(UserNamePasswordRequest request) : base(request) { } @@ -36,6 +37,17 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { get { return HttpStatusCode.Unauthorized; } } + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + WebHeaderCollection IHttpDirectResponse.Headers { + get { + return new WebHeaderCollection() { + { HttpResponseHeader.WwwAuthenticate, Protocol.HttpAuthorizationScheme }, + }; + } + } + #endregion /// <summary> diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenFailedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenFailedResponse.cs new file mode 100644 index 0000000..c3261f6 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenFailedResponse.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------- +// <copyright file="UserNamePasswordRefreshAccessTokenFailedResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A response from the Authorization Server to the Client to indicate that a + /// request for an access token renewal failed, probably due to an invalid + /// refresh token. + /// </summary> + internal class UserNamePasswordRefreshAccessTokenFailedResponse : MessageBase, IHttpDirectResponse { + /// <summary> + /// Initializes a new instance of the <see cref="UserNamePasswordRefreshAccessTokenFailedResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal UserNamePasswordRefreshAccessTokenFailedResponse(UserNamePasswordRefreshAccessTokenRequest request) + : base(request) { + this.HttpMethods = HttpDeliveryMethods.PostRequest; + } + + #region IHttpDirectResponse Members + + /// <summary> + /// Gets the HTTP status code that the direct respones should be sent with. + /// </summary> + /// <value><see cref="HttpStatusCode.Unauthorized"/></value> + HttpStatusCode IHttpDirectResponse.HttpStatusCode { + get { return HttpStatusCode.Unauthorized; } + } + + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + WebHeaderCollection IHttpDirectResponse.Headers { + get { + return new WebHeaderCollection() { + { HttpResponseHeader.WwwAuthenticate, Protocol.HttpAuthorizationScheme }, + }; + } + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenRequest.cs new file mode 100644 index 0000000..2dd687b --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenRequest.cs @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------- +// <copyright file="UserNamePasswordRefreshAccessTokenRequest.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A request from the client to the authorization server for a new access token + /// after a previously supplied access token has expired. + /// </summary> + internal class UserNamePasswordRefreshAccessTokenRequest : MessageBase { + /// <summary> + /// Initializes a new instance of the <see cref="UserNamePasswordRefreshAccessTokenRequest"/> class. + /// </summary> + /// <param name="authorizationServer">The authorization server.</param> + /// <param name="version">The version.</param> + internal UserNamePasswordRefreshAccessTokenRequest(Uri authorizationServer, Version version) + : base(version, MessageTransport.Direct, authorizationServer) { + this.HttpMethods = HttpDeliveryMethods.PostRequest; + } + + /// <summary> + /// Gets or sets the refresh token that was received in + /// <see cref="UserNamePasswordSuccessResponse.RefreshToken"/>. + /// </summary> + /// <value>The refresh token.</value> + [MessagePart(Protocol.wrap_refresh_token, IsRequired = true, AllowEmpty = false)] + internal string RefreshToken { get; set; } + + /// <summary> + /// Checks the message state for conformity to the protocol specification + /// and throws an exception if the message is invalid. + /// </summary> + /// <remarks> + /// <para>Some messages have required fields, or combinations of fields that must relate to each other + /// in specialized ways. After deserializing a message, this method checks the state of the + /// message to see if it conforms to the protocol.</para> + /// <para>Note that this property should <i>not</i> check signatures or perform any state checks + /// outside this scope of this particular message.</para> + /// </remarks> + /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> + protected override void EnsureValidMessage() { + base.EnsureValidMessage(); + ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), SimpleAuthStrings.HttpsRequired); + } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenSuccessResponse.cs new file mode 100644 index 0000000..501a4ee --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenSuccessResponse.cs @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------- +// <copyright file="UserNamePasswordRefreshAccessTokenSuccessResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A response from the Authorization Server to the Consumer containing a delegation code + /// that the Consumer should use to obtain an access token. + /// </summary> + internal class UserNamePasswordRefreshAccessTokenSuccessResponse : MessageBase { + /// <summary> + /// Initializes a new instance of the <see cref="UserNamePasswordRefreshAccessTokenSuccessResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal UserNamePasswordRefreshAccessTokenSuccessResponse(UserNamePasswordRefreshAccessTokenRequest request) + : base(request) { + } + + /// <summary> + /// Gets or sets the access token. + /// </summary> + /// <value>The access token.</value> + [MessagePart(Protocol.wrap_access_token, IsRequired = true, AllowEmpty = false)] + internal string AccessToken { get; set; } + + /// <summary> + /// Gets or sets the lifetime of the access token. + /// </summary> + /// <value>The lifetime.</value> + [MessagePart(Protocol.wrap_access_token_expires_in, IsRequired = false, Encoder = typeof(TimespanSecondsEncoder))] + internal TimeSpan Lifetime { get; set; } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationViaUsernamePasswordRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRequest.cs index 34a804e..380c64e 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationViaUsernamePasswordRequest.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRequest.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="UserAuthorizationViaUsernamePasswordRequest.cs" company="Andrew Arnott"> +// <copyright file="UserNamePasswordRequest.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -19,33 +19,28 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// After this request has been sent, the consumer application MUST discard /// the confidential user credentials and use the delegation code going forward. /// </remarks> - internal class UserAuthorizationViaUsernamePasswordRequest : MessageBase { + internal class UserNamePasswordRequest : MessageBase { /// <summary> - /// Initializes a new instance of the <see cref="UserAuthorizationViaUsernamePasswordRequest"/> class. + /// Initializes a new instance of the <see cref="UserNamePasswordRequest"/> class. /// </summary> + /// <param name="authorizationServer">The authorization server.</param> /// <param name="version">The version.</param> - internal UserAuthorizationViaUsernamePasswordRequest(Version version) - : base(version) { + internal UserNamePasswordRequest(Uri authorizationServer, Version version) + : base(version, MessageTransport.Direct, authorizationServer) { + this.HttpMethods = HttpDeliveryMethods.PostRequest; } /// <summary> - /// Gets or sets the consumer key. + /// Gets or sets the client identifier previously obtained from the Authorization Server. /// </summary> - /// <value>The consumer key.</value> + /// <value>The client identifier.</value> [MessagePart(Protocol.wrap_client_id, IsRequired = true, AllowEmpty = false)] internal string ClientIdentifier { get; set; } /// <summary> - /// Gets or sets the consumer secret. + /// Gets or sets the user's account username. /// </summary> - /// <value>The consumer secret.</value> - [MessagePart(Protocol.wrap_client_secret, IsRequired = true, AllowEmpty = false)] - internal string ClientSecret { get; set; } - - /// <summary> - /// Gets or sets the username. - /// </summary> - /// <value>The name of the user.</value> + /// <value>The username on the user's account.</value> [MessagePart(Protocol.wrap_username, IsRequired = true, AllowEmpty = false)] internal string UserName { get; set; } @@ -57,6 +52,27 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { internal string Password { get; set; } /// <summary> + /// Gets or sets the CAPTCHA puzzle that the user just solved, if applicable. + /// </summary> + /// <value>The captcha puzzle location.</value> + [MessagePart(Protocol.wrap_captcha_url, IsRequired = false, AllowEmpty = false)] + internal Uri CaptchaPuzzle { get; set; } + + /// <summary> + /// Gets or sets the solution to the CAPTCHA puzzle the user just solved, if applicable. + /// </summary> + /// <value>The CAPTCHA solution.</value> + [MessagePart(Protocol.wrap_captcha_solution, IsRequired = false, AllowEmpty = false)] + internal string CaptchaSolution { get; set; } + + /// <summary> + /// Gets or sets the scope. + /// </summary> + /// <value>The scope.</value> + [MessagePart(Protocol.wrap_scope, IsRequired = false, AllowEmpty = true)] + internal string Scope { get; set; } + + /// <summary> /// Checks the message state for conformity to the protocol specification /// and throws an exception if the message is invalid. /// </summary> diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordSuccessResponse.cs new file mode 100644 index 0000000..addae9f --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordSuccessResponse.cs @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------- +// <copyright file="UserNamePasswordSuccessResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A response from the Authorization Server to the Client containing a refresh token + /// and an access token. + /// </summary> + internal class UserNamePasswordSuccessResponse : MessageBase { + /// <summary> + /// Initializes a new instance of the <see cref="UserNamePasswordSuccessResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal UserNamePasswordSuccessResponse(UserNamePasswordRequest request) + : base(request) { + } + + /// <summary> + /// Gets or sets the verification code. + /// </summary> + /// <value> + /// The long-lived credential assigned by the Authorization Server to this Client for + /// use in accessing the authorizing user's protected resources. + /// </value> + [MessagePart(Protocol.wrap_refresh_token, IsRequired = true, AllowEmpty = false)] + internal string RefreshToken { get; set; } + + /// <summary> + /// Gets or sets the access token. + /// </summary> + /// <value>The access token.</value> + [MessagePart(Protocol.wrap_access_token, IsRequired = true, AllowEmpty = false)] + internal string AccessToken { get; set; } + + /// <summary> + /// Gets or sets the lifetime of the access token. + /// </summary> + /// <value>The lifetime.</value> + [MessagePart(Protocol.wrap_access_token_expires_in, IsRequired = false, Encoder = typeof(TimespanSecondsEncoder))] + internal TimeSpan Lifetime { get; set; } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordVerificationResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordVerificationResponse.cs new file mode 100644 index 0000000..bbc0788 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordVerificationResponse.cs @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------- +// <copyright file="UserNamePasswordVerificationResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + using System.Net; + + /// <summary> + /// A response from the Authorization Server to the client indicating that the user + /// must visit a URL to complete an additional verification step before proceeding. + /// </summary> + internal class UserNamePasswordVerificationResponse : MessageBase, IHttpDirectResponse { + /// <summary> + /// Initializes a new instance of the <see cref="UserNamePasswordVerificationResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal UserNamePasswordVerificationResponse(UserNamePasswordRequest request) + : base(request) { + } + + #region IHttpDirectResponse Members + + /// <summary> + /// Gets the HTTP status code that the direct response should be sent with. + /// </summary> + /// <value><see cref="HttpStatusCode.BadRequest"/></value> + HttpStatusCode IHttpDirectResponse.HttpStatusCode { + get { return HttpStatusCode.BadRequest; } + } + + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + WebHeaderCollection IHttpDirectResponse.Headers { + get { return new WebHeaderCollection(); } + } + + #endregion + + /// <summary> + /// Gets or sets the verification URL the user must visit with a browser + /// to complete some step to defeat automated attacks. + /// </summary> + /// <value>The verification URL.</value> + [MessagePart(Protocol.wrap_verification_url, IsRequired = true, AllowEmpty = false)] + internal Uri VerificationUrl { get; set; } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationInUserAgentDeniedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppFailedResponse.cs index b6e46c9..be0c32c 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationInUserAgentDeniedResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppFailedResponse.cs @@ -1,20 +1,20 @@ //----------------------------------------------------------------------- -// <copyright file="UserAuthorizationInUserAgentDeniedResponse.cs" company="Andrew Arnott"> +// <copyright file="WebAppFailedResponse.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- namespace DotNetOpenAuth.OAuthWrap.Messages { using System; - using DotNetOpenAuth.Messaging; using System.Diagnostics.Contracts; + using DotNetOpenAuth.Messaging; /// <summary> - /// The message the Authorization Server MAY use to send the user back to the Consumer + /// The message the Authorization Server MAY use to send the user back to the Client /// following the user's denial to grant Consumer with authorization of /// access to requested resources. /// </summary> - public class UserAuthorizationInUserAgentDeniedResponse : MessageBase, IDirectedProtocolMessage { + public class WebAppFailedResponse : MessageBase { /// <summary> /// A constant parameter that indicates the user refused to grant the requested authorization. /// </summary> @@ -22,11 +22,11 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { private const string ErrorReason = Protocol.wrap_error_reason_denied; /// <summary> - /// Initializes a new instance of the <see cref="UserAuthorizationInUserAgentDeniedResponse"/> class. + /// Initializes a new instance of the <see cref="WebAppFailedResponse"/> class. /// </summary> /// <param name="clientCallback">The recipient of the message.</param> /// <param name="version">The version.</param> - internal UserAuthorizationInUserAgentDeniedResponse(Uri clientCallback, Version version) : + internal WebAppFailedResponse(Uri clientCallback, Version version) : base(version, MessageTransport.Indirect, clientCallback) { Contract.Requires<ArgumentNullException>(version != null); Contract.Requires<ArgumentNullException>(clientCallback != null); diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenBadClientResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenBadClientResponse.cs new file mode 100644 index 0000000..6e46b11 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenBadClientResponse.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------- +// <copyright file="WebAppInitialAccessTokenBadClientResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A response from the Authorization Server to the Client in the event + /// that the <see cref="WebAppInitialAccessTokenRequest"/> message had an + /// invalid Client Identifier and Client Secret combination. + /// </summary> + internal class WebAppInitialAccessTokenBadClientResponse : MessageBase, IHttpDirectResponse { + /// <summary> + /// Initializes a new instance of the <see cref="WebAppInitialAccessTokenBadClientResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal WebAppInitialAccessTokenBadClientResponse(WebAppInitialAccessTokenRequest request) + : base(request) { + } + + #region IHttpDirectResponse Members + + /// <summary> + /// Gets the HTTP status code that the direct response should be sent with. + /// </summary> + /// <value></value> + HttpStatusCode IHttpDirectResponse.HttpStatusCode { + get { return System.Net.HttpStatusCode.Unauthorized; } + } + + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + /// <value>May be an empty collection, but must not be <c>null</c>.</value> + WebHeaderCollection IHttpDirectResponse.Headers { + get { + return new WebHeaderCollection() { + { HttpResponseHeader.WwwAuthenticate, Protocol.HttpAuthorizationScheme }, + }; + } + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenFailedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenFailedResponse.cs new file mode 100644 index 0000000..04983a9 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenFailedResponse.cs @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------- +// <copyright file="WebAppInitialAccessTokenFailedResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A response from the Authorization Server to the Client in the event + /// that the <see cref="WebAppInitialAccessTokenRequest"/> message had an + /// invalid calback URL or verification code. + /// </summary> + internal class WebAppInitialAccessTokenFailedResponse : MessageBase, IHttpDirectResponse { + /// <summary> + /// Initializes a new instance of the <see cref="WebAppInitialAccessTokenFailedResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal WebAppInitialAccessTokenFailedResponse(WebAppInitialAccessTokenRequest request) + : base(request) { + } + + #region IHttpDirectResponse Members + + /// <summary> + /// Gets the HTTP status code that the direct response should be sent with. + /// </summary> + /// <value></value> + HttpStatusCode IHttpDirectResponse.HttpStatusCode { + get { return System.Net.HttpStatusCode.BadRequest; } + } + + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + /// <value>May be an empty collection, but must not be <c>null</c>.</value> + WebHeaderCollection IHttpDirectResponse.Headers { + get { return new WebHeaderCollection(); } + } + + #endregion + + /// <summary> + /// Gets or sets the error reason. + /// </summary> + /// <value>"expired_verification_code" or "invalid_callback".</value> + [MessagePart(Protocol.wrap_error_reason, IsRequired = false, AllowEmpty = true)] + internal string ErrorReason { get; set; } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenWithVerificationCodeRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenRequest.cs index 1edbc1a..e4aff00 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenWithVerificationCodeRequest.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenRequest.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="AccessTokenWithVerificationCodeRequest.cs" company="Andrew Arnott"> +// <copyright file="WebAppInitialAccessTokenRequest.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -13,19 +13,23 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// A message sent by the Client directly to the Authorization Server to exchange /// the verification code for an Access Token. /// </summary> - internal class AccessTokenWithVerificationCodeRequest : MessageBase, IDirectedProtocolMessage { + /// <remarks> + /// Used by the Web App (and Rich App?) profiles. + /// </remarks> + internal class WebAppInitialAccessTokenRequest : MessageBase { /// <summary> - /// Initializes a new instance of the <see cref="AccessTokenWithVerificationCodeRequest"/> class. + /// Initializes a new instance of the <see cref="WebAppInitialAccessTokenRequest"/> class. /// </summary> /// <param name="authorizationServer">The token issuer.</param> /// <param name="version">The version.</param> - internal AccessTokenWithVerificationCodeRequest(Uri authorizationServer, Version version) + internal WebAppInitialAccessTokenRequest(Uri authorizationServer, Version version) : base(version, MessageTransport.Direct, authorizationServer) { this.HttpMethods = HttpDeliveryMethods.PostRequest; } /// <summary> /// Gets or sets the identifier by which this client is known to the Authorization Server. + /// </summary> /// <value>The client identifier.</value> [MessagePart(Protocol.wrap_client_id, IsRequired = true, AllowEmpty = false)] internal string ClientIdentifier { get; set; } @@ -39,14 +43,14 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <summary> /// Gets or sets the verification code previously communicated to the Client - /// in <see cref="UserAuthorizationInUserAgentGrantedResponse.VerificationCode"/>. + /// in <see cref="WebAppSuccessResponse.VerificationCode"/>. /// </summary> /// <value>The verification code.</value> [MessagePart(Protocol.wrap_verification_code, IsRequired = true, AllowEmpty = false)] internal string VerificationCode { get; set; } /// <summary> - /// Gets or sets the callback URL used in <see cref="UserAuthorizationInUserAgentRequest.Callback"/> + /// Gets or sets the callback URL used in <see cref="WebAppRequest.Callback"/> /// </summary> /// <value> /// The Callback URL used to obtain the Verification Code. diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenSuccessResponse.cs index 9488c49..ab5c4e2 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/AccessTokenSuccessResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenSuccessResponse.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="AccessTokenSuccessResponse.cs" company="Andrew Arnott"> +// <copyright file="WebAppInitialAccessTokenSuccessResponse.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -10,24 +10,23 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <summary> /// The direct response message that contains the access token from the Authorization Server - /// to the Consumer. + /// to the Client. /// </summary> - internal class AccessTokenSuccessResponse : MessageBase { + internal class WebAppInitialAccessTokenSuccessResponse : MessageBase { /// <summary> - /// Initializes a new instance of the <see cref="AccessTokenSuccessResponse"/> class. + /// Initializes a new instance of the <see cref="WebAppInitialAccessTokenSuccessResponse"/> class. /// </summary> /// <param name="request">The request.</param> - internal AccessTokenSuccessResponse(AccessTokenWithVerificationCodeRequest request) + internal WebAppInitialAccessTokenSuccessResponse(WebAppInitialAccessTokenRequest request) : base(request) { } /// <summary> - /// Initializes a new instance of the <see cref="AccessTokenSuccessResponse"/> class. + /// Gets or sets the refresh token. /// </summary> - /// <param name="request">The request.</param> - internal AccessTokenSuccessResponse(AccessTokenWithConsumerNamePasswordRequest request) - : base(request) { - } + /// <value>The token.</value> + [MessagePart(Protocol.wrap_refresh_token, IsRequired = true, AllowEmpty = false)] + internal string RefreshToken { get; set; } /// <summary> /// Gets or sets the access token. @@ -37,13 +36,6 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { internal string AccessToken { get; set; } /// <summary> - /// Gets or sets the refresh token. - /// </summary> - /// <value>The token.</value> - [MessagePart(Protocol.wrap_refresh_token, IsRequired = true, AllowEmpty = false)] - internal string RefreshToken { get; set; } - - /// <summary> /// Gets or sets the lifetime of the access token. /// </summary> /// <value>The lifetime.</value> diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenFailedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenFailedResponse.cs new file mode 100644 index 0000000..83be6ab --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenFailedResponse.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------- +// <copyright file="WebAppRefreshAccessTokenFailedResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A response from the Authorization Server to the Client in the event + /// that the <see cref="WebAppRefreshAccessTokenRequest"/> message had an + /// invalid calback URL or verification code. + /// </summary> + internal class WebAppRefreshAccessTokenFailedResponse : MessageBase, IHttpDirectResponse { + /// <summary> + /// Initializes a new instance of the <see cref="WebAppRefreshAccessTokenFailedResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal WebAppRefreshAccessTokenFailedResponse(WebAppRefreshAccessTokenRequest request) + : base(request) { + } + + #region IHttpDirectResponse Members + + /// <summary> + /// Gets the HTTP status code that the direct response should be sent with. + /// </summary> + /// <value></value> + HttpStatusCode IHttpDirectResponse.HttpStatusCode { + get { return System.Net.HttpStatusCode.Unauthorized; } + } + + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + /// <value>May be an empty collection, but must not be <c>null</c>.</value> + WebHeaderCollection IHttpDirectResponse.Headers { + get { + return new WebHeaderCollection() { + { HttpResponseHeader.WwwAuthenticate, Protocol.HttpAuthorizationScheme }, + }; + } + } + + #endregion + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenRequest.cs new file mode 100644 index 0000000..34c7dd3 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenRequest.cs @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------- +// <copyright file="WebAppRefreshAccessTokenRequest.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// A request from the Client to the Authorization Server to obtain + /// a new Access Token using a Refresh Token. + /// </summary> + internal class WebAppRefreshAccessTokenRequest : MessageBase { + /// <summary> + /// Initializes a new instance of the <see cref="WebAppRefreshAccessTokenRequest"/> class. + /// </summary> + /// <param name="authorizationServer">The authorization server.</param> + /// <param name="version">The version.</param> + internal WebAppRefreshAccessTokenRequest(Uri authorizationServer, Version version) + : base(version, Messaging.MessageTransport.Direct, authorizationServer) { + this.HttpMethods = Messaging.HttpDeliveryMethods.PostRequest; + } + + /// <summary> + /// Gets or sets the client identifier previously obtained from the Authorization Server. + /// </summary> + /// <value>The client identifier.</value> + [MessagePart(Protocol.wrap_client_id, IsRequired = true, AllowEmpty = false)] + internal string ClientIdentifier { get; set; } + + /// <summary> + /// Gets or sets the client secret previously obtained from the Authorization Server. + /// </summary> + /// <value>The client secret.</value> + [MessagePart(Protocol.wrap_client_secret, IsRequired = true, AllowEmpty = false)] + internal string ClientSecret { get; set; } + + /// <summary> + /// Gets or sets the refresh token that was received in + /// <see cref="UserNamePasswordSuccessResponse.RefreshToken"/>. + /// </summary> + /// <value>The refresh token.</value> + [MessagePart(Protocol.wrap_refresh_token, IsRequired = true, AllowEmpty = false)] + internal string RefreshToken { get; set; } + + /// <summary> + /// Checks the message state for conformity to the protocol specification + /// and throws an exception if the message is invalid. + /// </summary> + /// <remarks> + /// <para>Some messages have required fields, or combinations of fields that must relate to each other + /// in specialized ways. After deserializing a message, this method checks the state of the + /// message to see if it conforms to the protocol.</para> + /// <para>Note that this property should <i>not</i> check signatures or perform any state checks + /// outside this scope of this particular message.</para> + /// </remarks> + /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> + protected override void EnsureValidMessage() { + base.EnsureValidMessage(); + ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), SimpleAuthStrings.HttpsRequired); + } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenSuccessResponse.cs new file mode 100644 index 0000000..4348cdd --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenSuccessResponse.cs @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------- +// <copyright file="WebAppRefreshAccessTokenSuccessResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using System; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// The direct response message that contains the access token from the Authorization Server + /// to the Client. + /// </summary> + internal class WebAppRefreshAccessTokenSuccessResponse : MessageBase { + /// <summary> + /// Initializes a new instance of the <see cref="WebAppRefreshAccessTokenSuccessResponse"/> class. + /// </summary> + /// <param name="request">The request.</param> + internal WebAppRefreshAccessTokenSuccessResponse(WebAppRefreshAccessTokenRequest request) + : base(request) { + } + + /// <summary> + /// Gets or sets the access token. + /// </summary> + /// <value>The token.</value> + [MessagePart(Protocol.wrap_access_token, IsRequired = true, AllowEmpty = false)] + internal string AccessToken { get; set; } + + /// <summary> + /// Gets or sets the lifetime of the access token. + /// </summary> + /// <value>The lifetime.</value> + [MessagePart(Protocol.wrap_access_token_expires_in, IsRequired = false, AllowEmpty = false, Encoder = typeof(TimespanSecondsEncoder))] + internal TimeSpan? Lifetime { get; set; } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationInUserAgentRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRequest.cs index 1199e4c..6ff2648 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationInUserAgentRequest.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRequest.cs @@ -10,17 +10,17 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { using DotNetOpenAuth.OAuthWrap.ChannelElements; /// <summary> - /// A message sent by the Consumer to the Token Issuer via the user agent - /// to get the Token Issuer to obtain authorization from the user and prepare + /// A message sent by a web application Client to the AuthorizationServer + /// via the user agent to obtain authorization from the user and prepare /// to issue an access token to the Consumer if permission is granted. /// </summary> - public class UserAuthorizationInUserAgentRequest : MessageBase, IDirectedProtocolMessage { + public class WebAppRequest : MessageBase { /// <summary> - /// Initializes a new instance of the <see cref="UserAuthorizationInUserAgentRequest"/> class. + /// Initializes a new instance of the <see cref="WebAppRequest"/> class. /// </summary> /// <param name="authorizationServer">The token issuer URL to direct the user to.</param> /// <param name="version">The protocol version.</param> - public UserAuthorizationInUserAgentRequest(Uri authorizationServer, Version version) + public WebAppRequest(Uri authorizationServer, Version version) : base(version, MessageTransport.Indirect, authorizationServer) { } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationInUserAgentGrantedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppSuccessResponse.cs index f89f4b7..461174d 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/UserAuthorizationInUserAgentGrantedResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppSuccessResponse.cs @@ -1,26 +1,26 @@ //----------------------------------------------------------------------- -// <copyright file="UserAuthorizationInUserAgentGrantedResponse.cs" company="Andrew Arnott"> +// <copyright file="WebAppSuccessResponse.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- namespace DotNetOpenAuth.OAuthWrap.Messages { using System; - using DotNetOpenAuth.Messaging; using System.Diagnostics.Contracts; + using DotNetOpenAuth.Messaging; /// <summary> /// The message sent by the Authorization Server to the Consumer via the user agent /// to indicate that user authorization was granted, and to return the user /// to the Consumer where they started their experience. /// </summary> - internal class UserAuthorizationInUserAgentGrantedResponse : MessageBase, IDirectedProtocolMessage { + internal class WebAppSuccessResponse : MessageBase { /// <summary> - /// Initializes a new instance of the <see cref="UserAuthorizationInUserAgentGrantedResponse"/> class. + /// Initializes a new instance of the <see cref="WebAppSuccessResponse"/> class. /// </summary> /// <param name="clientCallback">The client callback.</param> /// <param name="version">The protocol version.</param> - internal UserAuthorizationInUserAgentGrantedResponse(Uri clientCallback, Version version) + internal WebAppSuccessResponse(Uri clientCallback, Version version) : base(version, MessageTransport.Indirect, clientCallback) { Contract.Requires<ArgumentNullException>(version != null); Contract.Requires<ArgumentNullException>(clientCallback != null); @@ -41,7 +41,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// </summary> /// <value>An opaque value defined by the client.</value> /// <remarks> - /// REQUIRED if the Client sent the value in the <see cref="UserAuthorizationRequestInUserAgentRequest"/>. + /// REQUIRED if the Client sent the value in the <see cref="WebAppRequest"/>. /// </remarks> [MessagePart(Protocol.wrap_client_state, IsRequired = false, AllowEmpty = true)] internal string ClientState { get; set; } diff --git a/src/DotNetOpenAuth/OAuthWrap/Protocol.cs b/src/DotNetOpenAuth/OAuthWrap/Protocol.cs index 4adf78c..83c0c21 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Protocol.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Protocol.cs @@ -58,6 +58,11 @@ namespace DotNetOpenAuth.OAuthWrap { internal const string wrap_verification_code = "wrap_verification_code"; /// <summary> + /// The "wrap_verification_url" string. + /// </summary> + internal const string wrap_verification_url = "wrap_verification_url"; + + /// <summary> /// The "wrap_error_reason" string. /// </summary> internal const string wrap_error_reason = "wrap_error_reason"; @@ -103,6 +108,16 @@ namespace DotNetOpenAuth.OAuthWrap { internal const string wrap_name = "wrap_name"; /// <summary> + /// The "wrap_assertion_format" string. + /// </summary> + internal const string wrap_assertion_format = "wrap_assertion_format"; + + /// <summary> + /// The "wrap_assertion" string. + /// </summary> + internal const string wrap_assertion = "wrap_assertion"; + + /// <summary> /// The "wrap_SAML" string. /// </summary> internal const string wrap_saml = "wrap_SAML"; @@ -111,5 +126,15 @@ namespace DotNetOpenAuth.OAuthWrap { /// The "wrap_SWT" string. /// </summary> internal const string wrap_swt = "wrap_SWT"; + + /// <summary> + /// The "wrap_captcha_url" string. + /// </summary> + internal const string wrap_captcha_url = "wrap_captcha_url"; + + /// <summary> + /// The "wrap_captcha_solution" string. + /// </summary> + internal const string wrap_captcha_solution = "wrap_captcha_solution"; } } diff --git a/src/DotNetOpenAuth/OAuthWrap/WebConsumer.cs b/src/DotNetOpenAuth/OAuthWrap/WebConsumer.cs index fbba0f8..3e5d6a2 100644 --- a/src/DotNetOpenAuth/OAuthWrap/WebConsumer.cs +++ b/src/DotNetOpenAuth/OAuthWrap/WebConsumer.cs @@ -52,23 +52,23 @@ namespace DotNetOpenAuth.OAuthWrap { /// </summary> public string ClientSecret { get; set; } - public UserAuthorizationInUserAgentRequest PrepareRequestUserAuthorization() { + public WebAppRequest PrepareRequestUserAuthorization() { Contract.Requires<InvalidOperationException>(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired); Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientIdentifier)); - Contract.Ensures(Contract.Result<UserAuthorizationInUserAgentRequest>() != null); - Contract.Ensures(Contract.Result<UserAuthorizationInUserAgentRequest>().ClientIdentifier == this.ClientIdentifier); + Contract.Ensures(Contract.Result<WebAppRequest>() != null); + Contract.Ensures(Contract.Result<WebAppRequest>().ClientIdentifier == this.ClientIdentifier); return this.PrepareRequestUserAuthorization(this.Channel.GetRequestFromContext().UrlBeforeRewriting); } - public UserAuthorizationInUserAgentRequest PrepareRequestUserAuthorization(Uri callback) { + public WebAppRequest PrepareRequestUserAuthorization(Uri callback) { Contract.Requires<ArgumentNullException>(callback != null); Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientIdentifier)); - Contract.Ensures(Contract.Result<UserAuthorizationInUserAgentRequest>() != null); - Contract.Ensures(Contract.Result<UserAuthorizationInUserAgentRequest>().Callback == callback); - Contract.Ensures(Contract.Result<UserAuthorizationInUserAgentRequest>().ClientIdentifier == this.ClientIdentifier); + Contract.Ensures(Contract.Result<WebAppRequest>() != null); + Contract.Ensures(Contract.Result<WebAppRequest>().Callback == callback); + Contract.Ensures(Contract.Result<WebAppRequest>().ClientIdentifier == this.ClientIdentifier); - var request = new UserAuthorizationInUserAgentRequest(this.TokenIssuer.EndpointUrl, this.TokenIssuer.Version) { + var request = new WebAppRequest(this.TokenIssuer.EndpointUrl, this.TokenIssuer.Version) { ClientIdentifier = this.ClientIdentifier, Callback = callback, }; @@ -84,7 +84,7 @@ namespace DotNetOpenAuth.OAuthWrap { IDirectedProtocolMessage message = this.Channel.ReadFromRequest(); if (message != null) { ErrorUtilities.VerifyProtocol( - message is UserAuthorizationInUserAgentGrantedResponse || message is UserAuthorizationInUserAgentDeniedResponse, + message is WebAppSuccessResponse || message is WebAppFailedResponse, MessagingStrings.UnexpectedMessageReceivedOfMany); } return message; diff --git a/src/DotNetOpenAuth/OpenId/Messages/DirectErrorResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/DirectErrorResponse.cs index ad20ff7..ec2f7d5 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/DirectErrorResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/DirectErrorResponse.cs @@ -36,6 +36,14 @@ namespace DotNetOpenAuth.OpenId.Messages { get { return HttpStatusCode.BadRequest; } } + /// <summary> + /// Gets the HTTP headers to add to the response. + /// </summary> + /// <value>May be an empty collection, but must not be <c>null</c>.</value> + WebHeaderCollection IHttpDirectResponse.Headers { + get { return new WebHeaderCollection(); } + } + #endregion /// <summary> |