diff options
29 files changed, 221 insertions, 314 deletions
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index c32eda4..d0c4d94 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -303,30 +303,28 @@ 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\IClientTokenManager.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\IMessageWithClientState.cs" /> <Compile Include="OAuthWrap\Messages\RichApp\RichAppAccessTokenRequest.cs" /> - <Compile Include="OAuthWrap\Messages\RichApp\RichAppRefreshAccessTokenRequest.cs" /> <Compile Include="OAuthWrap\Messages\RichApp\RichAppRequest.cs" /> <Compile Include="OAuthWrap\Messages\RichApp\RichAppResponse.cs" /> <Compile Include="OAuthWrap\Messages\RichApp\RichAppAccessTokenSuccessResponse.cs" /> <Compile Include="OAuthWrap\Messages\RichApp\RichAppAccessTokenFailedResponse.cs" /> - <Compile Include="OAuthWrap\Messages\RichApp\RichAppRefreshAccessTokenSuccessResponse.cs" /> <Compile Include="OAuthWrap\Messages\UnauthorizedResponse.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\RefreshAccessTokenFailedResponse.cs" /> + <Compile Include="OAuthWrap\Messages\RefreshAccessTokenSuccessResponse.cs" /> + <Compile Include="OAuthWrap\Messages\RefreshAccessTokenRequest.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="OAuthWrap\Messages\WebApp\WebAppAccessTokenBadClientResponse.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppAccessTokenFailedResponse.cs" /> + <Compile Include="OAuthWrap\WrapUtilities.cs" /> <Compile Include="OAuth\ChannelElements\ICombinedOpenIdProviderTokenManager.cs" /> <Compile Include="OAuth\ChannelElements\IConsumerDescription.cs" /> <Compile Include="OAuth\ChannelElements\IConsumerTokenManager.cs" /> @@ -614,9 +612,9 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="OAuthWrap\ChannelElements\OAuthWrapChannel.cs" /> <Compile Include="OAuthWrap\ChannelElements\OAuthWrapMessageFactory.cs" /> <Compile Include="OAuthWrap\ClientBase.cs" /> - <Compile Include="OAuthWrap\Messages\WebApp\WebAppInitialAccessTokenSuccessResponse.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppAccessTokenSuccessResponse.cs" /> <Compile Include="OAuthWrap\Messages\MessageBase.cs" /> - <Compile Include="OAuthWrap\Messages\WebApp\WebAppInitialAccessTokenRequest.cs" /> + <Compile Include="OAuthWrap\Messages\WebApp\WebAppAccessTokenRequest.cs" /> <Compile Include="OAuthWrap\Messages\WebApp\WebAppFailedResponse.cs" /> <Compile Include="OAuthWrap\Messages\WebApp\WebAppRequest.cs" /> <Compile Include="OAuthWrap\Messages\WebApp\WebAppSuccessResponse.cs" /> @@ -624,10 +622,10 @@ http://opensource.org/licenses/ms-pl.html <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"> + <Compile Include="OAuthWrap\OAuthWrapStrings.Designer.cs"> <AutoGen>True</AutoGen> <DesignTime>True</DesignTime> - <DependentUpon>SimpleAuthStrings.resx</DependentUpon> + <DependentUpon>OAuthWrapStrings.resx</DependentUpon> </Compile> <Compile Include="OAuthWrap\AuthorizationServerDescription.cs" /> <Compile Include="OAuthWrap\WebAppClient.cs" /> @@ -743,9 +741,9 @@ http://opensource.org/licenses/ms-pl.html <EmbeddedResource Include="OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.js"> <Copyright>$(StandardCopyright)</Copyright> </EmbeddedResource> - <EmbeddedResource Include="OAuthWrap\SimpleAuthStrings.resx"> + <EmbeddedResource Include="OAuthWrap\OAuthWrapStrings.resx"> <Generator>ResXFileCodeGenerator</Generator> - <LastGenOutput>SimpleAuthStrings.Designer.cs</LastGenOutput> + <LastGenOutput>OAuthWrapStrings.Designer.cs</LastGenOutput> </EmbeddedResource> <EmbeddedResource Include="Strings.sr.resx" /> <EmbeddedResource Include="Xrds\XrdsStrings.sr.resx" /> diff --git a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapMessageFactory.cs b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapMessageFactory.cs index 02f50d7..b3b9abb 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapMessageFactory.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ChannelElements/OAuthWrapMessageFactory.cs @@ -42,7 +42,7 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { } if (fields.ContainsKey(Protocol.wrap_client_id) && fields.ContainsKey(Protocol.wrap_verification_code)) { - return new WebAppInitialAccessTokenRequest(recipient.Location, version); + return new WebAppAccessTokenRequest(recipient.Location, version); } if (fields.ContainsKey(Protocol.wrap_name)) { @@ -73,10 +73,10 @@ namespace DotNetOpenAuth.OAuthWrap.ChannelElements { public IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) { Version version = Protocol.DefaultVersion; - var accessTokenRequest = request as WebAppInitialAccessTokenRequest; + var accessTokenRequest = request as WebAppAccessTokenRequest; if (accessTokenRequest != null) { if (fields.ContainsKey(Protocol.wrap_access_token)) { - return new WebAppInitialAccessTokenSuccessResponse(accessTokenRequest); + return new WebAppAccessTokenSuccessResponse(accessTokenRequest); } else { //return new AccessTokenWithVerificationCodeFailedResponse(accessTokenRequest); } diff --git a/src/DotNetOpenAuth/OAuthWrap/ClientBase.cs b/src/DotNetOpenAuth/OAuthWrap/ClientBase.cs index b277df1..a36759d 100644 --- a/src/DotNetOpenAuth/OAuthWrap/ClientBase.cs +++ b/src/DotNetOpenAuth/OAuthWrap/ClientBase.cs @@ -40,7 +40,7 @@ namespace DotNetOpenAuth.OAuthWrap { public Channel Channel { get; private set; } /// <summary> - /// Adds the necessary HTTP header to an HTTP request for protected resources + /// Adds the necessary HTTP Authorization header to an HTTP request for protected resources /// so that the Service Provider will allow the request through. /// </summary> /// <param name="request">The request for protected resources from the service provider.</param> diff --git a/src/DotNetOpenAuth/OAuthWrap/IClientTokenManager.cs b/src/DotNetOpenAuth/OAuthWrap/IClientTokenManager.cs new file mode 100644 index 0000000..4cedaee --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/IClientTokenManager.cs @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------- +// <copyright file="IClientTokenManager.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; +using System.Diagnostics.Contracts; + + [ContractClass(typeof(IClientTokenManagerContract))] + public interface IClientTokenManager { + IWrapAuthorization GetAuthorizationState(Uri callbackUrl, string clientState); + } + + internal class IClientTokenManagerContract : IClientTokenManager { + private IClientTokenManagerContract() { + } + + #region IClientTokenManager Members + + IWrapAuthorization IClientTokenManager.GetAuthorizationState(Uri callbackUrl, string clientState) { + Contract.Requires<ArgumentNullException>(callbackUrl != null); + throw new NotImplementedException(); + } + + #endregion + } + + + public interface IWrapAuthorization { + Uri Callback { get; set; } + string RefreshToken { get; set; } + string AccessToken { get; set; } + DateTime? AccessTokenExpirationUtc { get; set; } + string Scope { get; set; } + + void Delete(); + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionRequest.cs index 1489d12..cfd537a 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionRequest.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/Assertion/AssertionRequest.cs @@ -59,7 +59,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> protected override void EnsureValidMessage() { base.EnsureValidMessage(); - ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), SimpleAuthStrings.HttpsRequired); + ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), OAuthWrapStrings.HttpsRequired); } } } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordRequest.cs index 27f81e8..9f47c57 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordRequest.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordRequest.cs @@ -63,7 +63,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> protected override void EnsureValidMessage() { base.EnsureValidMessage(); - ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), SimpleAuthStrings.HttpsRequired); + ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), OAuthWrapStrings.HttpsRequired); } } } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordSuccessResponse.cs index 77129e4..186827c 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordSuccessResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/ClientAccountAndPassword/ClientAccountUsernamePasswordSuccessResponse.cs @@ -24,6 +24,13 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { } /// <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 access token. /// </summary> /// <value>The access token.</value> diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/IMessageWithClientState.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/IMessageWithClientState.cs new file mode 100644 index 0000000..8054d27 --- /dev/null +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/IMessageWithClientState.cs @@ -0,0 +1,13 @@ +//----------------------------------------------------------------------- +// <copyright file="IMessageWithClientState.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuthWrap.Messages { + using DotNetOpenAuth.Messaging; + + internal interface IMessageWithClientState : IProtocolMessage { + string ClientState { get; set; } + } +} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenFailedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/RefreshAccessTokenFailedResponse.cs index d2a7c70..43629c5 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenFailedResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/RefreshAccessTokenFailedResponse.cs @@ -10,12 +10,15 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// request for an access token renewal failed, probably due to an invalid /// refresh token. /// </summary> - internal class UserNamePasswordRefreshAccessTokenFailedResponse : UnauthorizedResponse { + /// <remarks> + /// This message type is shared by the Web App, Rich App, and Username/Password profiles. + /// </remarks> + internal class RefreshAccessTokenFailedResponse : UnauthorizedResponse { /// <summary> - /// Initializes a new instance of the <see cref="UserNamePasswordRefreshAccessTokenFailedResponse"/> class. + /// Initializes a new instance of the <see cref="RefreshAccessTokenFailedResponse"/> class. /// </summary> /// <param name="request">The request.</param> - internal UserNamePasswordRefreshAccessTokenFailedResponse(UserNamePasswordRefreshAccessTokenRequest request) + internal RefreshAccessTokenFailedResponse(RefreshAccessTokenRequest request) : base(request) { } } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/RefreshAccessTokenRequest.cs index 2dd687b..d72a958 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenRequest.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/RefreshAccessTokenRequest.cs @@ -13,17 +13,20 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <summary> /// A request from the client to the authorization server for a new access token - /// after a previously supplied access token has expired. + /// using a refresh token, after a previously supplied access token has expired. /// </summary> - internal class UserNamePasswordRefreshAccessTokenRequest : MessageBase { + /// <remarks> + /// This message type is shared by the Web App, Rich App, and Username/Password profiles. + /// </remarks> + internal class RefreshAccessTokenRequest : MessageBase { /// <summary> - /// Initializes a new instance of the <see cref="UserNamePasswordRefreshAccessTokenRequest"/> class. + /// Initializes a new instance of the <see cref="RefreshAccessTokenRequest"/> class. /// </summary> - /// <param name="authorizationServer">The authorization server.</param> + /// <param name="refreshTokenEndpoint">The authorization server's Refresh Token endpoint.</param> /// <param name="version">The version.</param> - internal UserNamePasswordRefreshAccessTokenRequest(Uri authorizationServer, Version version) - : base(version, MessageTransport.Direct, authorizationServer) { - this.HttpMethods = HttpDeliveryMethods.PostRequest; + internal RefreshAccessTokenRequest(Uri refreshTokenEndpoint, Version version) + : base(version, MessageTransport.Direct, refreshTokenEndpoint) { + this.HttpMethods = HttpDeliveryMethods.PostRequest; } /// <summary> @@ -48,7 +51,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> protected override void EnsureValidMessage() { base.EnsureValidMessage(); - ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), SimpleAuthStrings.HttpsRequired); + ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), OAuthWrapStrings.HttpsRequired); } } } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/RefreshAccessTokenSuccessResponse.cs index 501a4ee..8a2b14a 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRefreshAccessTokenSuccessResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/RefreshAccessTokenSuccessResponse.cs @@ -15,12 +15,15 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// 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 { + /// <remarks> + /// This message type is shared by the Web App, Rich App, and Username/Password profiles. + /// </remarks> + internal class RefreshAccessTokenSuccessResponse : MessageBase { /// <summary> - /// Initializes a new instance of the <see cref="UserNamePasswordRefreshAccessTokenSuccessResponse"/> class. + /// Initializes a new instance of the <see cref="RefreshAccessTokenSuccessResponse"/> class. /// </summary> /// <param name="request">The request.</param> - internal UserNamePasswordRefreshAccessTokenSuccessResponse(UserNamePasswordRefreshAccessTokenRequest request) + internal RefreshAccessTokenSuccessResponse(RefreshAccessTokenRequest request) : base(request) { } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/RichApp/RichAppAccessTokenRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/RichApp/RichAppAccessTokenRequest.cs index f509977..f0ad943 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/RichApp/RichAppAccessTokenRequest.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/RichApp/RichAppAccessTokenRequest.cs @@ -55,7 +55,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> protected override void EnsureValidMessage() { base.EnsureValidMessage(); - ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), SimpleAuthStrings.HttpsRequired); + ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), OAuthWrapStrings.HttpsRequired); } } } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/RichApp/RichAppRefreshAccessTokenRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/RichApp/RichAppRefreshAccessTokenRequest.cs deleted file mode 100644 index c41f949..0000000 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/RichApp/RichAppRefreshAccessTokenRequest.cs +++ /dev/null @@ -1,35 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="RichAppRefreshAccessTokenRequest.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 message from the Client to the Authorization Server requesting a new Access Token. - /// </summary> - internal class RichAppRefreshAccessTokenRequest : MessageBase { - /// <summary> - /// Initializes a new instance of the <see cref="RichAppRefreshAccessTokenRequest"/> class. - /// </summary> - /// <param name="authorizationServer">The authorization server.</param> - /// <param name="version">The version.</param> - internal RichAppRefreshAccessTokenRequest(Uri authorizationServer, Version version) - : base(version, MessageTransport.Direct, authorizationServer) { - } - - /// <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; } - } -} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/RichApp/RichAppRefreshAccessTokenSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/RichApp/RichAppRefreshAccessTokenSuccessResponse.cs deleted file mode 100644 index ad9f6f2..0000000 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/RichApp/RichAppRefreshAccessTokenSuccessResponse.cs +++ /dev/null @@ -1,41 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="RichAppRefreshAccessTokenSuccessResponse.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 RichAppRefreshAccessTokenSuccessResponse : MessageBase { - /// <summary> - /// Initializes a new instance of the <see cref="RichAppRefreshAccessTokenSuccessResponse"/> class. - /// </summary> - /// <param name="request">The request.</param> - internal RichAppRefreshAccessTokenSuccessResponse(RichAppRefreshAccessTokenRequest 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/UsernameAndPassword/UserNamePasswordRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRequest.cs index 380c64e..b4a72ff 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRequest.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/UsernameAndPassword/UserNamePasswordRequest.cs @@ -86,7 +86,8 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> protected override void EnsureValidMessage() { base.EnsureValidMessage(); - ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), SimpleAuthStrings.HttpsRequired); + ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), OAuthWrapStrings.HttpsRequired); + ErrorUtilities.VerifyProtocol((this.CaptchaPuzzle == null) == (this.CaptchaSolution == null), "CAPTCHA puzzle and solution must either be both absent or both present."); } } } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenBadClientResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppAccessTokenBadClientResponse.cs index b9e5349..6758e93 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenBadClientResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppAccessTokenBadClientResponse.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="WebAppInitialAccessTokenBadClientResponse.cs" company="Andrew Arnott"> +// <copyright file="WebAppAccessTokenBadClientResponse.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -7,15 +7,15 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <summary> /// A response from the Authorization Server to the Client in the event - /// that the <see cref="WebAppInitialAccessTokenRequest"/> message had an + /// that the <see cref="WebAppAccessTokenRequest"/> message had an /// invalid Client Identifier and Client Secret combination. /// </summary> - internal class WebAppInitialAccessTokenBadClientResponse : UnauthorizedResponse { + internal class WebAppAccessTokenBadClientResponse : UnauthorizedResponse { /// <summary> - /// Initializes a new instance of the <see cref="WebAppInitialAccessTokenBadClientResponse"/> class. + /// Initializes a new instance of the <see cref="WebAppAccessTokenBadClientResponse"/> class. /// </summary> /// <param name="request">The request.</param> - internal WebAppInitialAccessTokenBadClientResponse(WebAppInitialAccessTokenRequest request) + internal WebAppAccessTokenBadClientResponse(WebAppAccessTokenRequest request) : base(request) { } } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenFailedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppAccessTokenFailedResponse.cs index 04983a9..7cdc2a9 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenFailedResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppAccessTokenFailedResponse.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="WebAppInitialAccessTokenFailedResponse.cs" company="Andrew Arnott"> +// <copyright file="WebAppAccessTokenFailedResponse.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -14,15 +14,15 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <summary> /// A response from the Authorization Server to the Client in the event - /// that the <see cref="WebAppInitialAccessTokenRequest"/> message had an + /// that the <see cref="WebAppAccessTokenRequest"/> message had an /// invalid calback URL or verification code. /// </summary> - internal class WebAppInitialAccessTokenFailedResponse : MessageBase, IHttpDirectResponse { + internal class WebAppAccessTokenFailedResponse : MessageBase, IHttpDirectResponse { /// <summary> - /// Initializes a new instance of the <see cref="WebAppInitialAccessTokenFailedResponse"/> class. + /// Initializes a new instance of the <see cref="WebAppAccessTokenFailedResponse"/> class. /// </summary> /// <param name="request">The request.</param> - internal WebAppInitialAccessTokenFailedResponse(WebAppInitialAccessTokenRequest request) + internal WebAppAccessTokenFailedResponse(WebAppAccessTokenRequest request) : base(request) { } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppAccessTokenRequest.cs index e4aff00..904207e 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenRequest.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppAccessTokenRequest.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="WebAppInitialAccessTokenRequest.cs" company="Andrew Arnott"> +// <copyright file="WebAppAccessTokenRequest.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { using System; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuthWrap.ChannelElements; + using System.Diagnostics.Contracts; /// <summary> /// A message sent by the Client directly to the Authorization Server to exchange @@ -16,18 +17,29 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <remarks> /// Used by the Web App (and Rich App?) profiles. /// </remarks> - internal class WebAppInitialAccessTokenRequest : MessageBase { + internal class WebAppAccessTokenRequest : MessageBase { /// <summary> - /// Initializes a new instance of the <see cref="WebAppInitialAccessTokenRequest"/> class. + /// Initializes a new instance of the <see cref="WebAppAccessTokenRequest"/> class. /// </summary> - /// <param name="authorizationServer">The token issuer.</param> + /// <param name="accessTokenEndpoint">The Authorization Server's access token endpoint URL.</param> /// <param name="version">The version.</param> - internal WebAppInitialAccessTokenRequest(Uri authorizationServer, Version version) - : base(version, MessageTransport.Direct, authorizationServer) { + internal WebAppAccessTokenRequest(Uri accessTokenEndpoint, Version version) + : base(version, MessageTransport.Direct, accessTokenEndpoint) { this.HttpMethods = HttpDeliveryMethods.PostRequest; } /// <summary> + /// Initializes a new instance of the <see cref="WebAppAccessTokenRequest"/> class. + /// </summary> + /// <param name="authorizationServer">The authorization server.</param> + internal WebAppAccessTokenRequest(AuthorizationServerDescription authorizationServer) + : this(authorizationServer.AccessTokenEndpoint, authorizationServer.Version) { + Contract.Requires<ArgumentNullException>(authorizationServer != null); + Contract.Requires<ArgumentException>(authorizationServer.Version != null); + Contract.Requires<ArgumentException>(authorizationServer.AccessTokenEndpoint != null); + } + + /// <summary> /// Gets or sets the identifier by which this client is known to the Authorization Server. /// </summary> /// <value>The client identifier.</value> @@ -72,7 +84,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> protected override void EnsureValidMessage() { base.EnsureValidMessage(); - ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), SimpleAuthStrings.HttpsRequired); + ErrorUtilities.VerifyProtocol(this.Recipient.IsTransportSecure(), OAuthWrapStrings.HttpsRequired); } } } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppAccessTokenSuccessResponse.cs index ab5c4e2..ec44712 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppInitialAccessTokenSuccessResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppAccessTokenSuccessResponse.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="WebAppInitialAccessTokenSuccessResponse.cs" company="Andrew Arnott"> +// <copyright file="WebAppAccessTokenSuccessResponse.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -12,12 +12,12 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// The direct response message that contains the access token from the Authorization Server /// to the Client. /// </summary> - internal class WebAppInitialAccessTokenSuccessResponse : MessageBase { + internal class WebAppAccessTokenSuccessResponse : MessageBase { /// <summary> - /// Initializes a new instance of the <see cref="WebAppInitialAccessTokenSuccessResponse"/> class. + /// Initializes a new instance of the <see cref="WebAppAccessTokenSuccessResponse"/> class. /// </summary> /// <param name="request">The request.</param> - internal WebAppInitialAccessTokenSuccessResponse(WebAppInitialAccessTokenRequest request) + internal WebAppAccessTokenSuccessResponse(WebAppAccessTokenRequest request) : base(request) { } diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppFailedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppFailedResponse.cs index f1de4e9..fd7f546 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppFailedResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppFailedResponse.cs @@ -14,7 +14,7 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { /// following the user's denial to grant Consumer with authorization of /// access to requested resources. /// </summary> - internal class WebAppFailedResponse : MessageBase { + internal class WebAppFailedResponse : MessageBase, IMessageWithClientState { /// <summary> /// A constant parameter that indicates the user refused to grant the requested authorization. /// </summary> diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenFailedResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenFailedResponse.cs deleted file mode 100644 index 7138145..0000000 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenFailedResponse.cs +++ /dev/null @@ -1,22 +0,0 @@ -//----------------------------------------------------------------------- -// <copyright file="WebAppRefreshAccessTokenFailedResponse.cs" company="Andrew Arnott"> -// Copyright (c) Andrew Arnott. All rights reserved. -// </copyright> -//----------------------------------------------------------------------- - -namespace DotNetOpenAuth.OAuthWrap.Messages { - /// <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 : UnauthorizedResponse { - /// <summary> - /// Initializes a new instance of the <see cref="WebAppRefreshAccessTokenFailedResponse"/> class. - /// </summary> - /// <param name="request">The request.</param> - internal WebAppRefreshAccessTokenFailedResponse(WebAppRefreshAccessTokenRequest request) - : base(request) { - } - } -} diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenRequest.cs deleted file mode 100644 index 34c7dd3..0000000 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenRequest.cs +++ /dev/null @@ -1,68 +0,0 @@ -//----------------------------------------------------------------------- -// <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 deleted file mode 100644 index 4348cdd..0000000 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRefreshAccessTokenSuccessResponse.cs +++ /dev/null @@ -1,38 +0,0 @@ -//----------------------------------------------------------------------- -// <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/WebApp/WebAppRequest.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRequest.cs index b0424b2..5166342 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRequest.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppRequest.cs @@ -8,20 +8,34 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { using System; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuthWrap.ChannelElements; + using System.Diagnostics.Contracts; /// <summary> /// 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> - internal class WebAppRequest : MessageBase { + internal class WebAppRequest : MessageBase, IMessageWithClientState { /// <summary> /// 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="userAuthorizationEndpoint">The Authorization Server's user authorization URL to direct the user to.</param> /// <param name="version">The protocol version.</param> - internal WebAppRequest(Uri authorizationServer, Version version) - : base(version, MessageTransport.Indirect, authorizationServer) { + internal WebAppRequest(Uri userAuthorizationEndpoint, Version version) + : base(version, MessageTransport.Indirect, userAuthorizationEndpoint) { + Contract.Requires<ArgumentNullException>(userAuthorizationEndpoint != null); + Contract.Requires<ArgumentNullException>(version != null); + } + + /// <summary> + /// Initializes a new instance of the <see cref="WebAppRequest"/> class. + /// </summary> + /// <param name="authorizationServer">The authorization server.</param> + internal WebAppRequest(AuthorizationServerDescription authorizationServer) + : this(authorizationServer.UserAuthorizationEndpoint, authorizationServer.Version) { + Contract.Requires<ArgumentNullException>(authorizationServer != null); + Contract.Requires<ArgumentException>(authorizationServer.Version != null); + Contract.Requires<ArgumentException>(authorizationServer.UserAuthorizationEndpoint != null); } /// <summary> diff --git a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppSuccessResponse.cs b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppSuccessResponse.cs index 461174d..ec13da4 100644 --- a/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppSuccessResponse.cs +++ b/src/DotNetOpenAuth/OAuthWrap/Messages/WebApp/WebAppSuccessResponse.cs @@ -10,11 +10,11 @@ namespace DotNetOpenAuth.OAuthWrap.Messages { using DotNetOpenAuth.Messaging; /// <summary> - /// The message sent by the Authorization Server to the Consumer via the user agent + /// The message sent by the Authorization Server to the Client via the user agent /// to indicate that user authorization was granted, and to return the user - /// to the Consumer where they started their experience. + /// to the Client where they started their experience. /// </summary> - internal class WebAppSuccessResponse : MessageBase { + internal class WebAppSuccessResponse : MessageBase, IMessageWithClientState { /// <summary> /// Initializes a new instance of the <see cref="WebAppSuccessResponse"/> class. /// </summary> diff --git a/src/DotNetOpenAuth/OAuthWrap/SimpleAuthStrings.Designer.cs b/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.Designer.cs index 8cf74ed..27879c4 100644 --- a/src/DotNetOpenAuth/OAuthWrap/SimpleAuthStrings.Designer.cs +++ b/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version:4.0.30118.0 +// Runtime Version:4.0.30128.0 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -22,14 +22,14 @@ namespace DotNetOpenAuth.OAuthWrap { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class SimpleAuthStrings { + internal class OAuthWrapStrings { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal SimpleAuthStrings() { + internal OAuthWrapStrings() { } /// <summary> @@ -39,7 +39,7 @@ namespace DotNetOpenAuth.OAuthWrap { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DotNetOpenAuth.OAuthWrap.SimpleAuthStrings", typeof(SimpleAuthStrings).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DotNetOpenAuth.OAuthWrap.OAuthWrapStrings", typeof(OAuthWrapStrings).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/DotNetOpenAuth/OAuthWrap/SimpleAuthStrings.resx b/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.resx index b8a8d62..b8a8d62 100644 --- a/src/DotNetOpenAuth/OAuthWrap/SimpleAuthStrings.resx +++ b/src/DotNetOpenAuth/OAuthWrap/OAuthWrapStrings.resx diff --git a/src/DotNetOpenAuth/OAuthWrap/WebAppClient.cs b/src/DotNetOpenAuth/OAuthWrap/WebAppClient.cs index a21b587..f107180 100644 --- a/src/DotNetOpenAuth/OAuthWrap/WebAppClient.cs +++ b/src/DotNetOpenAuth/OAuthWrap/WebAppClient.cs @@ -21,28 +21,12 @@ namespace DotNetOpenAuth.OAuthWrap { /// <summary> /// Initializes a new instance of the <see cref="WebAppClient"/> class. /// </summary> - /// <param name="authorizationServer">The token issuer.</param> + /// <param name="authorizationServer">The authorization server.</param> public WebAppClient(AuthorizationServerDescription authorizationServer) : base(authorizationServer) { } /// <summary> - /// Initializes a new instance of the <see cref="WebAppClient"/> class. - /// </summary> - /// <param name="tokenIssuerEndpoint">The token issuer endpoint.</param> - public WebAppClient(Uri tokenIssuerEndpoint) - : base(tokenIssuerEndpoint) { - } - - /// <summary> - /// Initializes a new instance of the <see cref="WebAppClient"/> class. - /// </summary> - /// <param name="tokenIssuerEndpoint">The token issuer endpoint.</param> - public WebAppClient(string tokenIssuerEndpoint) - : base(tokenIssuerEndpoint) { - } - - /// <summary> /// Gets or sets the identifier by which this client is known to the Authorization Server. /// </summary> public string ClientIdentifier { get; set; } @@ -52,42 +36,72 @@ namespace DotNetOpenAuth.OAuthWrap { /// </summary> public string ClientSecret { get; set; } - 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<WebAppRequest>() != null); - Contract.Ensures(Contract.Result<WebAppRequest>().ClientIdentifier == this.ClientIdentifier); - - return this.PrepareRequestUserAuthorization(this.Channel.GetRequestFromContext().UrlBeforeRewriting); - } + public IClientTokenManager TokenManager { get; set; } - public WebAppRequest PrepareRequestUserAuthorization(Uri callback) { - Contract.Requires<ArgumentNullException>(callback != null); + public WebAppRequest PrepareRequestUserAuthorization(IWrapAuthorization authorizationState) { + Contract.Requires<ArgumentNullException>(authorizationState != null); + Contract.Requires<InvalidOperationException>(authorizationState.Callback != null || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired); Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientIdentifier)); Contract.Ensures(Contract.Result<WebAppRequest>() != null); - Contract.Ensures(Contract.Result<WebAppRequest>().Callback == callback); + Contract.Ensures(Contract.Result<WebAppRequest>().Callback == authorizationState.Callback); Contract.Ensures(Contract.Result<WebAppRequest>().ClientIdentifier == this.ClientIdentifier); - var request = new WebAppRequest(this.AuthorizationServer.EndpointUrl, this.AuthorizationServer.Version) { + if (authorizationState.Callback == null) { + authorizationState.Callback = this.Channel.GetRequestFromContext().UrlBeforeRewriting; + } + + var request = new WebAppRequest(this.AuthorizationServer) { ClientIdentifier = this.ClientIdentifier, - Callback = callback, + Callback = authorizationState.Callback, + Scope = authorizationState.Scope, }; + return request; } - public IDirectedProtocolMessage ProcessUserAuthorization() { + public IWrapAuthorization ProcessUserAuthorization() { + Contract.Requires<InvalidOperationException>(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired); return this.ProcessUserAuthorization(this.Channel.GetRequestFromContext()); } - public IDirectedProtocolMessage ProcessUserAuthorization(HttpRequestInfo request) { + public IWrapAuthorization ProcessUserAuthorization(HttpRequestInfo request) { Contract.Requires<ArgumentNullException>(request != null); - IDirectedProtocolMessage message = this.Channel.ReadFromRequest(); - if (message != null) { - ErrorUtilities.VerifyProtocol( - message is WebAppSuccessResponse || message is WebAppFailedResponse, - MessagingStrings.UnexpectedMessageReceivedOfMany); + Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientIdentifier)); + Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.ClientSecret)); + var response = this.Channel.ReadFromRequest<IMessageWithClientState>(request); + if (response != null) { + IWrapAuthorization authorizationState = this.TokenManager.GetAuthorizationState(request.UrlBeforeRewriting, response.ClientState); + ErrorUtilities.VerifyProtocol(authorizationState != null, "Unexpected OAuth WRAP authorization response received with callback and client state that does not match an expected value."); + var success = response as WebAppSuccessResponse; + var failure = response as WebAppFailedResponse; + ErrorUtilities.VerifyProtocol(success != null || failure != null, MessagingStrings.UnexpectedMessageReceivedOfMany); + if (success != null) { + var accessTokenRequest = new WebAppAccessTokenRequest(this.AuthorizationServer) { + ClientSecret = this.ClientSecret, + ClientIdentifier = this.ClientIdentifier, + Callback = authorizationState.Callback, + VerificationCode = success.VerificationCode, + }; + IProtocolMessage accessTokenResponse = this.Channel.Request(accessTokenRequest); + var accessTokenSuccess = accessTokenResponse as WebAppAccessTokenSuccessResponse; + var badClientAccessTokenResponse = accessTokenResponse as WebAppAccessTokenBadClientResponse; + var failedAccessTokenResponse = accessTokenResponse as WebAppAccessTokenFailedResponse; + if (accessTokenSuccess != null) { + authorizationState.AccessToken = accessTokenSuccess.AccessToken; + authorizationState.RefreshToken = accessTokenSuccess.RefreshToken; + authorizationState.AccessTokenExpirationUtc = DateTime.UtcNow + accessTokenSuccess.Lifetime; + } else if (badClientAccessTokenResponse != null) { + ErrorUtilities.ThrowProtocol("Failed to obtain access token due to invalid Client Identifier or Client Secret."); + } else { // failedAccessTokenResponse != null + ErrorUtilities.ThrowProtocol("Failed to obtain access token. Authorization Server reports reason: {0}", failedAccessTokenResponse.ErrorReason); + } + } else { // failure + } + + return authorizationState; } - return message; + + return null; } } } diff --git a/src/DotNetOpenAuth/OAuthWrap/WrapUtilities.cs b/src/DotNetOpenAuth/OAuthWrap/WrapUtilities.cs index 5c391be..a892364 100644 --- a/src/DotNetOpenAuth/OAuthWrap/WrapUtilities.cs +++ b/src/DotNetOpenAuth/OAuthWrap/WrapUtilities.cs @@ -18,7 +18,7 @@ namespace DotNetOpenAuth.OAuthWrap { /// </summary> public static class WrapUtilities { /// <summary> - /// Authorizes an HTTP request using an OAuth WRAP access token. + /// Authorizes an HTTP request using an OAuth WRAP access token in an HTTP Authorization header. /// </summary> /// <param name="request">The request to authorize.</param> /// <param name="accessToken">The access token previously obtained from the Authorization Server.</param> |