summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth2/OAuth2ChannelTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs2
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingUtilities.cs1
-rw-r--r--src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs24
-rw-r--r--src/DotNetOpenAuth/OAuth2/ChannelElements/AuthServerAllFlowsBindingElement.cs8
-rw-r--r--src/DotNetOpenAuth/OAuth2/IConsumerDescription.cs49
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs1
-rw-r--r--src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs5
-rw-r--r--src/DotNetOpenAuth/OAuth2/OAuthStrings.Designer.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth2/OAuthStrings.resx2
-rw-r--r--src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs14
-rw-r--r--src/DotNetOpenAuth/OAuth2/WebServerClient.cs1
13 files changed, 93 insertions, 20 deletions
diff --git a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs
index 2514f68..0e82154 100644
--- a/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs
+++ b/src/DotNetOpenAuth.Test/OAuth2/MessageFactoryTests.cs
@@ -105,7 +105,7 @@ namespace DotNetOpenAuth.Test.OAuth2 {
{ Protocol.client_secret, "abc" },
{ Protocol.grant_type, "basic-credentials" },
{ Protocol.username, "abc" },
- { Protocol.password , "abc" },
+ { Protocol.password, "abc" },
};
IDirectedProtocolMessage request = this.messageFactory.GetNewRequestMessage(this.recipient, fields);
Assert.IsInstanceOf(typeof(AccessTokenResourceOwnerPasswordCredentialsRequest), request);
diff --git a/src/DotNetOpenAuth.Test/OAuth2/OAuth2ChannelTests.cs b/src/DotNetOpenAuth.Test/OAuth2/OAuth2ChannelTests.cs
index 51d0656..c263eb6 100644
--- a/src/DotNetOpenAuth.Test/OAuth2/OAuth2ChannelTests.cs
+++ b/src/DotNetOpenAuth.Test/OAuth2/OAuth2ChannelTests.cs
@@ -1,5 +1,5 @@
//-----------------------------------------------------------------------
-// <copyright file="OAuthWrapChannelTests.cs" company="Andrew Arnott">
+// <copyright file="OAuth2ChannelTests.cs" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
diff --git a/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs b/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs
index fa1ed40..6c13c5e 100644
--- a/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs
+++ b/src/DotNetOpenAuth.Test/OAuth2/OAuth2TestBase.cs
@@ -1,5 +1,5 @@
//-----------------------------------------------------------------------
-// <copyright file="OAuthWrapTestBase.cs" company="Andrew Arnott">
+// <copyright file="OAuth2TestBase.cs" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
index 9dbd1b9..08c536a 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
@@ -935,7 +935,6 @@ namespace DotNetOpenAuth.Messaging {
/// Tests whether two arrays are equal in contents and ordering,
/// guaranteeing roughly equivalent execution time regardless of where a signature mismatch may exist.
/// </summary>
- /// <typeparam name="T">The type of elements in the arrays.</typeparam>
/// <param name="first">The first array in the comparison. May not be null.</param>
/// <param name="second">The second array in the comparison. May not be null.</param>
/// <returns>True if the arrays equal; false otherwise.</returns>
diff --git a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs
index 9eefb9d..f98dc79 100644
--- a/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs
+++ b/src/DotNetOpenAuth/OAuth2/AuthorizationServer.cs
@@ -66,6 +66,13 @@ namespace DotNetOpenAuth.OAuth2 {
return message;
}
+ /// <summary>
+ /// Approves an authorization request and sends an HTTP response to the user agent to redirect the user back to the Client.
+ /// </summary>
+ /// <param name="authorizationRequest">The authorization request to approve.</param>
+ /// <param name="username">The username of the account that approved the request (or whose data will be accessed by the client).</param>
+ /// <param name="scopes">The scope of access the client should be granted. If <c>null</c>, all scopes in the original request will be granted.</param>
+ /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
public void ApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string username, IEnumerable<string> scopes = null, Uri callback = null) {
Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest");
@@ -74,6 +81,11 @@ namespace DotNetOpenAuth.OAuth2 {
this.Channel.Send(response);
}
+ /// <summary>
+ /// Rejects an authorization request and sends an HTTP response to the user agent to redirect the user back to the Client.
+ /// </summary>
+ /// <param name="authorizationRequest">The authorization request to disapprove.</param>
+ /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
public void RejectAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, Uri callback = null) {
Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest");
@@ -123,6 +135,14 @@ namespace DotNetOpenAuth.OAuth2 {
return response;
}
+ /// <summary>
+ /// Approves an authorization request.
+ /// </summary>
+ /// <param name="authorizationRequest">The authorization request to approve.</param>
+ /// <param name="username">The username of the account that approved the request (or whose data will be accessed by the client).</param>
+ /// <param name="scopes">The scope of access the client should be granted. If <c>null</c>, all scopes in the original request will be granted.</param>
+ /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
+ /// <returns>The authorization response message to send to the Client.</returns>
public EndUserAuthorizationSuccessResponseBase PrepareApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest, string username, IEnumerable<string> scopes = null, Uri callback = null) {
Contract.Requires<ArgumentNullException>(authorizationRequest != null, "authorizationRequest");
Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(username));
@@ -196,8 +216,8 @@ namespace DotNetOpenAuth.OAuth2 {
}
var client = this.AuthorizationServerServices.GetClient(authorizationRequest.ClientIdentifier);
- if (client.Callback != null) {
- return client.Callback;
+ if (client.AllowedCallbacks.Any()) {
+ return client.AllowedCallbacks.First();
}
throw ErrorUtilities.ThrowProtocol(OAuthStrings.NoCallback);
diff --git a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthServerAllFlowsBindingElement.cs b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthServerAllFlowsBindingElement.cs
index 1bf8c79..7e69ae1 100644
--- a/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthServerAllFlowsBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuth2/ChannelElements/AuthServerAllFlowsBindingElement.cs
@@ -71,8 +71,12 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
var authorizationRequest = message as EndUserAuthorizationRequest;
if (authorizationRequest != null) {
var client = this.AuthorizationServer.GetClientOrThrow(authorizationRequest.ClientIdentifier);
- ErrorUtilities.VerifyProtocol(client.Callback == null || client.Callback == authorizationRequest.Callback, OAuthStrings.CallbackMismatch, client.Callback, authorizationRequest.Callback);
- ErrorUtilities.VerifyProtocol(client.Callback != null || authorizationRequest.Callback != null, OAuthStrings.NoCallback);
+ ErrorUtilities.VerifyProtocol(
+ !client.AllowedCallbacks.Any() || client.AllowedCallbacks.Contains(authorizationRequest.Callback),
+ OAuthStrings.CallbackMismatch,
+ String.Join(" ", client.AllowedCallbacks.Select(v => v.AbsoluteUri).ToArray()),
+ authorizationRequest.Callback);
+ ErrorUtilities.VerifyProtocol(client.AllowedCallbacks.Any() || authorizationRequest.Callback != null, OAuthStrings.NoCallback);
return MessageProtections.None;
}
diff --git a/src/DotNetOpenAuth/OAuth2/IConsumerDescription.cs b/src/DotNetOpenAuth/OAuth2/IConsumerDescription.cs
index 4e2bc4f..f37bc9f 100644
--- a/src/DotNetOpenAuth/OAuth2/IConsumerDescription.cs
+++ b/src/DotNetOpenAuth/OAuth2/IConsumerDescription.cs
@@ -6,10 +6,13 @@
namespace DotNetOpenAuth.OAuth2 {
using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
/// <summary>
/// A description of a client from an Authorization Server's point of view.
/// </summary>
+ [ContractClass(typeof(IConsumerDescriptionContract))]
public interface IConsumerDescription {
/// <summary>
/// Gets the client secret.
@@ -17,9 +20,49 @@ namespace DotNetOpenAuth.OAuth2 {
string Secret { get; }
/// <summary>
- /// Gets the callback URI that this client has pre-registered with the service provider, if any.
+ /// Gets the allowed callback URIs that this client has pre-registered with the service provider, if any.
/// </summary>
- /// <value>A URI that user authorization responses should be directed to; or <c>null</c> if no preregistered callback was arranged.</value>
- Uri Callback { get; }
+ /// <value>The URIs that user authorization responses may be directed to; must not be <c>null</c>, but may be empty.</value>
+ /// <remarks>
+ /// The first element in this list (if any) will be used as the default client redirect URL if the client sends an authorization request without a redirect URL.
+ /// If the list is empty, any callback is allowed for this client.
+ /// </remarks>
+ List<Uri> AllowedCallbacks { get; }
+ }
+
+ /// <summary>
+ /// Contract class for the <see cref="IConsumerDescription"/> interface.
+ /// </summary>
+ [ContractClassFor(typeof(IConsumerDescription))]
+ internal abstract class IConsumerDescriptionContract : IConsumerDescription {
+ #region IConsumerDescription Members
+
+ /// <summary>
+ /// Gets the client secret.
+ /// </summary>
+ /// <value></value>
+ string IConsumerDescription.Secret {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets the allowed callback URIs that this client has pre-registered with the service provider, if any.
+ /// </summary>
+ /// <value>
+ /// The URIs that user authorization responses may be directed to; must not be <c>null</c>, but may be empty.
+ /// </value>
+ /// <remarks>
+ /// The first element in this list (if any) will be used as the default client redirect URL if the client sends an authorization request without a redirect URL.
+ /// If the list is empty, any callback is allowed for this client.
+ /// </remarks>
+ List<Uri> IConsumerDescription.AllowedCallbacks {
+ get {
+ Contract.Ensures(Contract.Result<List<Uri>>() != null);
+ Contract.Ensures(Contract.Result<List<Uri>>().TrueForAll(v => v != null && v.IsAbsoluteUri));
+ throw new NotImplementedException();
+ }
+ }
+
+ #endregion
}
}
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs
index f15f190..e325dd7 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/AccessTokenRefreshRequest.cs
@@ -39,7 +39,6 @@ namespace DotNetOpenAuth.OAuth2.Messages {
get { return CodeOrTokenType.RefreshToken; }
}
-
/// <summary>
/// Gets or sets the verification code or refresh/access token.
/// </summary>
diff --git a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs
index b125c67..14677f3 100644
--- a/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs
+++ b/src/DotNetOpenAuth/OAuth2/Messages/EndUserAuthorizationFailedResponse.cs
@@ -13,9 +13,12 @@ namespace DotNetOpenAuth.OAuth2.Messages {
using System.Text;
using DotNetOpenAuth.Messaging;
+ /// <summary>
+ /// The message that an Authorization Server responds to a Client with when the user denies a user authorization request.
+ /// </summary>
public class EndUserAuthorizationFailedResponse : MessageBase, IMessageWithClientState {
/// <summary>
- /// Initializes a new instance of the <see cref="EndUserAuthorizationSuccessResponseBase"/> class.
+ /// Initializes a new instance of the <see cref="EndUserAuthorizationFailedResponse"/> class.
/// </summary>
/// <param name="clientCallback">The URL to redirect to so the client receives the message. This may not be built into the request message if the client pre-registered the URL with the authorization server.</param>
/// <param name="version">The protocol version.</param>
diff --git a/src/DotNetOpenAuth/OAuth2/OAuthStrings.Designer.cs b/src/DotNetOpenAuth/OAuth2/OAuthStrings.Designer.cs
index f4a74cc..7b2c3c2 100644
--- a/src/DotNetOpenAuth/OAuth2/OAuthStrings.Designer.cs
+++ b/src/DotNetOpenAuth/OAuth2/OAuthStrings.Designer.cs
@@ -70,7 +70,7 @@ namespace DotNetOpenAuth.OAuth2 {
}
/// <summary>
- /// Looks up a localized string similar to Client&apos;s pre-registered callback URL ({0}) does not match the one found in the authorization request ({1})..
+ /// Looks up a localized string similar to None of the client&apos;s pre-registered callback URLs ({0}) match the one found in the authorization request ({1})..
/// </summary>
internal static string CallbackMismatch {
get {
diff --git a/src/DotNetOpenAuth/OAuth2/OAuthStrings.resx b/src/DotNetOpenAuth/OAuth2/OAuthStrings.resx
index dacd9fc..c5b2cdc 100644
--- a/src/DotNetOpenAuth/OAuth2/OAuthStrings.resx
+++ b/src/DotNetOpenAuth/OAuth2/OAuthStrings.resx
@@ -121,7 +121,7 @@
<value>The requested access scope ("{0}") exceeds the grant scope ("{1}").</value>
</data>
<data name="CallbackMismatch" xml:space="preserve">
- <value>Client's pre-registered callback URL ({0}) does not match the one found in the authorization request ({1}).</value>
+ <value>None of the client's pre-registered callback URLs ({0}) match the one found in the authorization request ({1}).</value>
</data>
<data name="CannotObtainAccessTokenWithReason" xml:space="preserve">
<value>Failed to obtain access token. Authorization Server reports reason: {0}</value>
diff --git a/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs b/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs
index 79ef278..64a6d0c 100644
--- a/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs
+++ b/src/DotNetOpenAuth/OAuth2/OAuthUtilities.cs
@@ -18,6 +18,9 @@ namespace DotNetOpenAuth.OAuth2 {
/// Some common utility methods for OAuth 2.0.
/// </summary>
public static class OAuthUtilities {
+ /// <summary>
+ /// The <see cref="StringComparer"/> instance to use when comparing scope equivalence.
+ /// </summary>
public static readonly StringComparer ScopeStringComparer = StringComparer.Ordinal;
/// <summary>
@@ -62,10 +65,8 @@ namespace DotNetOpenAuth.OAuth2 {
/// <summary>
/// Identifies individual scope elements
/// </summary>
- /// <param name="scope">The scope.</param>
- /// <param name="scopeComparer">The scope comparer, allowing scopes to be case sensitive or insensitive.
- /// Usually <see cref="StringComparer.Ordinal"/> or <see cref="StringComparer.OrdinalIgnoreCase"/>.</param>
- /// <returns></returns>
+ /// <param name="scope">The space-delimited list of scopes.</param>
+ /// <returns>A set of individual scopes, with any duplicates removed.</returns>
public static HashSet<string> SplitScopes(string scope) {
if (string.IsNullOrEmpty(scope)) {
return new HashSet<string>();
@@ -74,6 +75,11 @@ namespace DotNetOpenAuth.OAuth2 {
return new HashSet<string>(scope.Split(scopeDelimiter, StringSplitOptions.RemoveEmptyEntries), ScopeStringComparer);
}
+ /// <summary>
+ /// Serializes a set of scopes as a space-delimited list.
+ /// </summary>
+ /// <param name="scopes">The scopes to serialize.</param>
+ /// <returns>A space-delimited list.</returns>
public static string JoinScopes(HashSet<string> scopes) {
Contract.Requires<ArgumentNullException>(scopes != null, "scopes");
return string.Join(" ", scopes.ToArray());
diff --git a/src/DotNetOpenAuth/OAuth2/WebServerClient.cs b/src/DotNetOpenAuth/OAuth2/WebServerClient.cs
index 0998619..d50ab8f 100644
--- a/src/DotNetOpenAuth/OAuth2/WebServerClient.cs
+++ b/src/DotNetOpenAuth/OAuth2/WebServerClient.cs
@@ -40,7 +40,6 @@ namespace DotNetOpenAuth.OAuth2 {
/// </summary>
/// <param name="scope">The scope of authorized access requested.</param>
/// <param name="state">The state of the client that should be sent back with the authorization response.</param>
- /// <returns>The authorization request as an HTTP response that causes a redirect.</returns>
public void RequestUserAuthorization(IEnumerable<string> scope = null, string state = null) {
this.PrepareRequestUserAuthorization(scope, state).Send();
}