summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenId/Extensions
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenId/Extensions')
-rw-r--r--src/DotNetOpenId/Extensions/AliasManager.cs60
-rw-r--r--src/DotNetOpenId/Extensions/AttributeExchange/AttributeValues.cs13
-rw-r--r--src/DotNetOpenId/Extensions/AttributeExchange/FetchRequest.cs25
-rw-r--r--src/DotNetOpenId/Extensions/AttributeExchange/FetchResponse.cs19
-rw-r--r--src/DotNetOpenId/Extensions/AttributeExchange/StoreRequest.cs12
-rw-r--r--src/DotNetOpenId/Extensions/AttributeExchange/StoreResponse.cs5
-rw-r--r--src/DotNetOpenId/Extensions/ExtensionManager.cs23
-rw-r--r--src/DotNetOpenId/Extensions/IClientScriptExtensionResponse.cs27
-rw-r--r--src/DotNetOpenId/Extensions/IExtension.cs36
-rw-r--r--src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/AuthenticationPolicies.cs7
-rw-r--r--src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/Constants.cs32
-rw-r--r--src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/NistAssuranceLevel.cs2
-rw-r--r--src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/PolicyRequest.cs93
-rw-r--r--src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs92
-rw-r--r--src/DotNetOpenId/Extensions/SimpleRegistration/ClaimsRequest.cs26
-rw-r--r--src/DotNetOpenId/Extensions/SimpleRegistration/ClaimsResponse.cs77
-rw-r--r--src/DotNetOpenId/Extensions/SimpleRegistration/Constants.cs3
17 files changed, 467 insertions, 85 deletions
diff --git a/src/DotNetOpenId/Extensions/AliasManager.cs b/src/DotNetOpenId/Extensions/AliasManager.cs
index 52308d5..f4bbb04 100644
--- a/src/DotNetOpenId/Extensions/AliasManager.cs
+++ b/src/DotNetOpenId/Extensions/AliasManager.cs
@@ -37,6 +37,61 @@ namespace DotNetOpenId.Extensions {
aliasToTypeUriMap.Add(alias, typeUri);
typeUriToAliasMap.Add(typeUri, alias);
}
+ /// <summary>
+ /// Takes a sequence of type URIs and assigns aliases for all of them.
+ /// </summary>
+ /// <param name="typeUris">The type URIs to create aliases for.</param>
+ /// <param name="preferredTypeUriToAliases">An optional dictionary of URI/alias pairs that suggest preferred aliases to use if available for certain type URIs.</param>
+ public void AssignAliases(IEnumerable<string> typeUris, IDictionary<string, string> preferredTypeUriToAliases) {
+ // First go through the actually used type URIs and see which ones have matching preferred aliases.
+ if (preferredTypeUriToAliases != null) {
+ foreach (string typeUri in typeUris) {
+ if (typeUriToAliasMap.ContainsKey(typeUri)) {
+ // this Type URI is already mapped to an alias.
+ continue;
+ }
+
+ string preferredAlias;
+ if (preferredTypeUriToAliases.TryGetValue(typeUri, out preferredAlias) && !IsAliasUsed(preferredAlias)) {
+ SetAlias(preferredAlias, typeUri);
+ }
+ }
+ }
+
+ // Now go through the whole list again and assign whatever is left now that the preferred ones
+ // have gotten their picks where available.
+ foreach (string typeUri in typeUris) {
+ if (typeUriToAliasMap.ContainsKey(typeUri)) {
+ // this Type URI is already mapped to an alias.
+ continue;
+ }
+
+ assignNewAlias(typeUri);
+ }
+ }
+ /// <summary>
+ /// Sets up aliases for any Type URIs in a dictionary that do not yet have aliases defined,
+ /// and where the given preferred alias is still available.
+ /// </summary>
+ /// <param name="preferredTypeUriToAliases">A dictionary of type URI keys and alias values.</param>
+ public void SetPreferredAliasesWhereNotSet(IDictionary<string, string> preferredTypeUriToAliases) {
+ if (preferredTypeUriToAliases == null) throw new ArgumentNullException("preferredTypeUriToAliases");
+
+ foreach (var pair in preferredTypeUriToAliases) {
+ if (typeUriToAliasMap.ContainsKey(pair.Key)) {
+ // type URI is already mapped
+ continue;
+ }
+
+ if (aliasToTypeUriMap.ContainsKey(pair.Value)) {
+ // alias is already mapped
+ continue;
+ }
+
+ // The type URI and alias are as yet unset, so go ahead and assign them.
+ SetAlias(pair.Value, pair.Key);
+ }
+ }
/// <summary>
/// Gets the Type Uri encoded by a given alias.
@@ -57,6 +112,11 @@ namespace DotNetOpenId.Extensions {
public IEnumerable<string> Aliases {
get { return aliasToTypeUriMap.Keys; }
}
+ /// <summary>
+ /// Returns a value indicating whether an alias has already been assigned to a type URI.
+ /// </summary>
+ /// <param name="alias">The alias in question.</param>
+ /// <returns>True if the alias has already been assigned. False otherwise.</returns>
public bool IsAliasUsed(string alias) {
if (string.IsNullOrEmpty(alias)) throw new ArgumentNullException("alias");
return aliasToTypeUriMap.ContainsKey(alias);
diff --git a/src/DotNetOpenId/Extensions/AttributeExchange/AttributeValues.cs b/src/DotNetOpenId/Extensions/AttributeExchange/AttributeValues.cs
index e537d7f..19abc65 100644
--- a/src/DotNetOpenId/Extensions/AttributeExchange/AttributeValues.cs
+++ b/src/DotNetOpenId/Extensions/AttributeExchange/AttributeValues.cs
@@ -18,15 +18,18 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
internal AttributeValues() {
Values = new List<string>(1);
}
- internal AttributeValues(string typeUri)
- : this() {
+ internal AttributeValues(string typeUri) {
+ if (string.IsNullOrEmpty(typeUri)) throw new ArgumentNullException("typeUri");
TypeUri = typeUri;
+ Values = new List<string>(1);
}
- internal AttributeValues(string typeUri, params string[] values) {
+ /// <summary>
+ /// Instantiates an <see cref="AttributeValues"/> object.
+ /// </summary>
+ public AttributeValues(string typeUri, params string[] values) {
if (string.IsNullOrEmpty(typeUri)) throw new ArgumentNullException("typeUri");
- if (values == null) throw new ArgumentNullException("values");
TypeUri = typeUri;
- Values = values;
+ Values = values ?? new string[0];
}
/// <summary>
diff --git a/src/DotNetOpenId/Extensions/AttributeExchange/FetchRequest.cs b/src/DotNetOpenId/Extensions/AttributeExchange/FetchRequest.cs
index b429643..1b64868 100644
--- a/src/DotNetOpenId/Extensions/AttributeExchange/FetchRequest.cs
+++ b/src/DotNetOpenId/Extensions/AttributeExchange/FetchRequest.cs
@@ -53,6 +53,9 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
#region IExtensionRequest Members
string IExtension.TypeUri { get { return Constants.TypeUri; } }
+ IEnumerable<string> IExtension.AdditionalSupportedTypeUris {
+ get { return new string[0]; }
+ }
IDictionary<string, string> IExtensionRequest.Serialize(RelyingParty.IAuthenticationRequest authenticationRequest) {
var fields = new Dictionary<string, string> {
@@ -84,7 +87,7 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
return fields;
}
- bool IExtensionRequest.Deserialize(IDictionary<string, string> fields, DotNetOpenId.Provider.IRequest request) {
+ bool IExtensionRequest.Deserialize(IDictionary<string, string> fields, DotNetOpenId.Provider.IRequest request, string typeUri) {
if (fields == null) return false;
string mode;
fields.TryGetValue("mode", out mode);
@@ -106,17 +109,16 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
allAliases.AddRange(requiredAliases);
allAliases.AddRange(optionalAliases);
if (allAliases.Count == 0) {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("Attribute Exchange extension did not provide any aliases in the if_available or required lists.");
+ Logger.Error("Attribute Exchange extension did not provide any aliases in the if_available or required lists.");
return false;
}
AliasManager aliasManager = new AliasManager();
foreach (var alias in allAliases) {
- string typeUri;
- if (fields.TryGetValue("type." + alias, out typeUri)) {
- aliasManager.SetAlias(alias, typeUri);
+ string attributeTypeUri;
+ if (fields.TryGetValue("type." + alias, out attributeTypeUri)) {
+ aliasManager.SetAlias(alias, attributeTypeUri);
AttributeRequest att = new AttributeRequest {
- TypeUri = typeUri,
+ TypeUri = attributeTypeUri,
IsRequired = requiredAliases.Contains(alias),
};
string countString;
@@ -128,8 +130,7 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
if (int.TryParse(countString, out count) && count > 0) {
att.Count = count;
} else {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("count." + alias + " could not be parsed into a positive integer.");
+ Logger.Error("count." + alias + " could not be parsed into a positive integer.");
}
}
} else {
@@ -137,8 +138,7 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
}
AddAttribute(att);
} else {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("Type URI definition of alias " + alias + " is missing.");
+ Logger.Error("Type URI definition of alias " + alias + " is missing.");
}
}
@@ -149,8 +149,7 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
List<string> result = new List<string>();
if (string.IsNullOrEmpty(aliasList)) return result;
if (aliasList.Contains(".") || aliasList.Contains("\n")) {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("Illegal characters found in Attribute Exchange alias list.");
+ Logger.ErrorFormat("Illegal characters found in Attribute Exchange alias list.");
return result;
}
result.AddRange(aliasList.Split(','));
diff --git a/src/DotNetOpenId/Extensions/AttributeExchange/FetchResponse.cs b/src/DotNetOpenId/Extensions/AttributeExchange/FetchResponse.cs
index e31a8f1..1d58851 100644
--- a/src/DotNetOpenId/Extensions/AttributeExchange/FetchResponse.cs
+++ b/src/DotNetOpenId/Extensions/AttributeExchange/FetchResponse.cs
@@ -55,6 +55,9 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
#region IExtensionResponse Members
string IExtension.TypeUri { get { return Constants.TypeUri; } }
+ IEnumerable<string> IExtension.AdditionalSupportedTypeUris {
+ get { return new string[0]; }
+ }
IDictionary<string, string> IExtensionResponse.Serialize(Provider.IRequest authenticationRequest) {
var fields = new Dictionary<string, string> {
@@ -87,7 +90,7 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
}
}
- bool IExtensionResponse.Deserialize(IDictionary<string, string> fields, IAuthenticationResponse response) {
+ bool IExtensionResponse.Deserialize(IDictionary<string, string> fields, IAuthenticationResponse response, string typeUri) {
if (fields == null) return false;
string mode;
fields.TryGetValue("mode", out mode);
@@ -113,9 +116,8 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
bool countSent = false;
string countString;
if (fields.TryGetValue("count." + alias, out countString)) {
- if (!int.TryParse(countString, out count) || count <= 0) {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("Failed to parse count.{0} value to a positive integer.");
+ if (!int.TryParse(countString, out count) || count < 0) {
+ Logger.ErrorFormat("Failed to parse count.{0} value to a non-negative integer.", alias);
continue;
}
countSent = true;
@@ -126,8 +128,7 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
if (fields.TryGetValue(string.Format(CultureInfo.InvariantCulture, "value.{0}.{1}", alias, i), out value)) {
att.Values.Add(value);
} else {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("Missing value for attribute '{0}'.", att.TypeUri);
+ Logger.ErrorFormat("Missing value for attribute '{0}'.", att.TypeUri);
continue;
}
}
@@ -136,8 +137,7 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
if (fields.TryGetValue("value." + alias, out value))
att.Values.Add(value);
else {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("Missing value for attribute '{0}'.", att.TypeUri);
+ Logger.ErrorFormat("Missing value for attribute '{0}'.", att.TypeUri);
continue;
}
}
@@ -152,8 +152,7 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
if (!pair.Key.StartsWith("type.", StringComparison.Ordinal)) continue;
string alias = pair.Key.Substring(5);
if (alias.IndexOfAny(new[] { '.', ',', ':' }) >= 0) {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("Illegal characters in alias name '{0}'.", alias);
+ Logger.ErrorFormat("Illegal characters in alias name '{0}'.", alias);
continue;
}
aliasManager.SetAlias(alias, pair.Value);
diff --git a/src/DotNetOpenId/Extensions/AttributeExchange/StoreRequest.cs b/src/DotNetOpenId/Extensions/AttributeExchange/StoreRequest.cs
index a7e2199..6b5ce2b 100644
--- a/src/DotNetOpenId/Extensions/AttributeExchange/StoreRequest.cs
+++ b/src/DotNetOpenId/Extensions/AttributeExchange/StoreRequest.cs
@@ -30,6 +30,13 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
attributesProvided.Add(attribute);
}
/// <summary>
+ /// Used by the Relying Party to add a given attribute with one or more values
+ /// to the request for storage.
+ /// </summary>
+ public void AddAttribute(string typeUri, params string[] values) {
+ AddAttribute(new AttributeValues(typeUri, values));
+ }
+ /// <summary>
/// Used by the Provider to gets the value(s) associated with a given attribute
/// that should be stored.
/// </summary>
@@ -46,6 +53,9 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
#region IExtensionRequest Members
string IExtension.TypeUri { get { return Constants.TypeUri; } }
+ IEnumerable<string> IExtension.AdditionalSupportedTypeUris {
+ get { return new string[0]; }
+ }
IDictionary<string, string> IExtensionRequest.Serialize(RelyingParty.IAuthenticationRequest authenticationRequest) {
var fields = new Dictionary<string, string> {
@@ -57,7 +67,7 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
return fields;
}
- bool IExtensionRequest.Deserialize(IDictionary<string, string> fields, DotNetOpenId.Provider.IRequest request) {
+ bool IExtensionRequest.Deserialize(IDictionary<string, string> fields, DotNetOpenId.Provider.IRequest request, string typeUri) {
if (fields == null) return false;
string mode;
fields.TryGetValue("mode", out mode);
diff --git a/src/DotNetOpenId/Extensions/AttributeExchange/StoreResponse.cs b/src/DotNetOpenId/Extensions/AttributeExchange/StoreResponse.cs
index a4e9cf1..acc0d6b 100644
--- a/src/DotNetOpenId/Extensions/AttributeExchange/StoreResponse.cs
+++ b/src/DotNetOpenId/Extensions/AttributeExchange/StoreResponse.cs
@@ -24,6 +24,9 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
#region IExtensionResponse Members
string IExtension.TypeUri { get { return Constants.TypeUri; } }
+ IEnumerable<string> IExtension.AdditionalSupportedTypeUris {
+ get { return new string[0]; }
+ }
IDictionary<string, string> IExtensionResponse.Serialize(Provider.IRequest authenticationRequest) {
var fields = new Dictionary<string, string> {
@@ -35,7 +38,7 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
return fields;
}
- bool IExtensionResponse.Deserialize(IDictionary<string, string> fields, IAuthenticationResponse response) {
+ bool IExtensionResponse.Deserialize(IDictionary<string, string> fields, IAuthenticationResponse response, string typeUri) {
if (fields == null) return false;
string mode;
if (!fields.TryGetValue("mode", out mode)) return false;
diff --git a/src/DotNetOpenId/Extensions/ExtensionManager.cs b/src/DotNetOpenId/Extensions/ExtensionManager.cs
new file mode 100644
index 0000000..9b197c9
--- /dev/null
+++ b/src/DotNetOpenId/Extensions/ExtensionManager.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace DotNetOpenId.Extensions {
+ internal class ExtensionManager {
+ /// <summary>
+ /// A list of request extensions that may be enumerated over for logging purposes.
+ /// </summary>
+ internal static Dictionary<IExtensionRequest, string> RequestExtensions = new Dictionary<IExtensionRequest, string> {
+ {new AttributeExchange.FetchRequest(), "AX fetch"},
+ {new AttributeExchange.StoreRequest(), "AX store"},
+ {new ProviderAuthenticationPolicy.PolicyRequest(), "PAPE"},
+ {new SimpleRegistration.ClaimsRequest(), "sreg"},
+ };
+ //internal static List<IExtensionResponse> ResponseExtensions = new List<IExtensionResponse> {
+ // new AttributeExchange.FetchResponse(),
+ // new AttributeExchange.StoreResponse(),
+ // new ProviderAuthenticationPolicy.PolicyResponse(),
+ // new SimpleRegistration.ClaimsResponse(),
+ //};
+ }
+}
diff --git a/src/DotNetOpenId/Extensions/IClientScriptExtensionResponse.cs b/src/DotNetOpenId/Extensions/IClientScriptExtensionResponse.cs
new file mode 100644
index 0000000..587014d
--- /dev/null
+++ b/src/DotNetOpenId/Extensions/IClientScriptExtensionResponse.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using DotNetOpenId.RelyingParty;
+
+namespace DotNetOpenId.Extensions {
+ /// <summary>
+ /// An interface that OpenID extensions can implement to allow authentication response
+ /// messages with included extensions to be processed by Javascript on the user agent.
+ /// </summary>
+ public interface IClientScriptExtensionResponse : IExtension {
+ /// <summary>
+ /// Reads the extension information on an authentication response from the provider.
+ /// </summary>
+ /// <param name="fields">The fields belonging to the extension.</param>
+ /// <param name="response">The incoming OpenID response carrying the extension.</param>
+ /// <param name="typeUri">The actual extension TypeUri that was recognized in the message.</param>
+ /// <returns>
+ /// A Javascript snippet that when executed on the user agent returns an object with
+ /// the information deserialized from the extension response.
+ /// </returns>
+ /// <remarks>
+ /// This method is called <b>before</b> the signature on the assertion response has been
+ /// verified. Therefore all information in these fields should be assumed unreliable
+ /// and potentially falsified.
+ /// </remarks>
+ string InitializeJavaScriptData(IDictionary<string, string> fields, IAuthenticationResponse response, string typeUri);
+ }
+}
diff --git a/src/DotNetOpenId/Extensions/IExtension.cs b/src/DotNetOpenId/Extensions/IExtension.cs
index 2450a8a..e43565a 100644
--- a/src/DotNetOpenId/Extensions/IExtension.cs
+++ b/src/DotNetOpenId/Extensions/IExtension.cs
@@ -11,6 +11,22 @@ namespace DotNetOpenId.Extensions {
/// Gets the TypeURI the extension uses in the OpenID protocol and in XRDS advertisements.
/// </summary>
string TypeUri { get; }
+ /// <summary>
+ /// Additional TypeURIs that are supported by this extension, in preferred order.
+ /// May be empty if none other than <see cref="TypeUri"/> is supported, but
+ /// should not be null.
+ /// </summary>
+ /// <remarks>
+ /// Useful for reading in messages with an older version of an extension.
+ /// The value in the <see cref="TypeUri"/> property is always checked before
+ /// trying this list.
+ /// If you do support multiple versions of an extension using this method,
+ /// consider adding a CreateResponse method to your request extension class
+ /// so that the response can have the context it needs to remain compatible
+ /// given the version of the extension in the request message.
+ /// The <see cref="SimpleRegistration.ClaimsRequest.CreateResponse"/> for an example.
+ /// </remarks>
+ IEnumerable<string> AdditionalSupportedTypeUris { get; }
}
/// <summary>
@@ -26,8 +42,14 @@ namespace DotNetOpenId.Extensions {
/// <summary>
/// Reads the extension information on an authentication request to the provider.
/// </summary>
- /// <returns>True if the extension found any of its parameters in the request, false otherwise.</returns>
- bool Deserialize(IDictionary<string, string> fields, Provider.IRequest request);
+ /// <param name="fields">The fields belonging to the extension.</param>
+ /// <param name="request">The incoming OpenID request carrying the extension.</param>
+ /// <param name="typeUri">The actual extension TypeUri that was recognized in the message.</param>
+ /// <returns>
+ /// True if the extension found a valid set of recognized parameters in the request,
+ /// false otherwise.
+ /// </returns>
+ bool Deserialize(IDictionary<string, string> fields, Provider.IRequest request, string typeUri);
}
/// <summary>
@@ -43,7 +65,13 @@ namespace DotNetOpenId.Extensions {
/// <summary>
/// Reads a Provider's response for extension values.
/// </summary>
- /// <returns>True if the extension found any of its parameters in the response.</returns>
- bool Deserialize(IDictionary<string, string> fields, RelyingParty.IAuthenticationResponse response);
+ /// <param name="fields">The fields belonging to the extension.</param>
+ /// <param name="response">The incoming OpenID response carrying the extension.</param>
+ /// <param name="typeUri">The actual extension TypeUri that was recognized in the message.</param>
+ /// <returns>
+ /// True if the extension found a valid set of recognized parameters in the response,
+ /// false otherwise.
+ /// </returns>
+ bool Deserialize(IDictionary<string, string> fields, RelyingParty.IAuthenticationResponse response, string typeUri);
}
}
diff --git a/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/AuthenticationPolicies.cs b/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/AuthenticationPolicies.cs
index 517525f..f505a9b 100644
--- a/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/AuthenticationPolicies.cs
+++ b/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/AuthenticationPolicies.cs
@@ -13,6 +13,13 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
/// </remarks>
public static class AuthenticationPolicies {
/// <summary>
+ /// Used in a PAPE response to indicate that no PAPE authentication policies could be satisfied.
+ /// </summary>
+ /// <remarks>
+ /// Used internally by the PAPE extension, so that users don't have to know about it.
+ /// </remarks>
+ internal const string None = "http://schemas.openid.net/pape/policies/2007/06/none";
+ /// <summary>
/// An authentication mechanism where the End User does not provide a shared secret to a party potentially under the control of the Relying Party. (Note that the potentially malicious Relying Party controls where the User-Agent is redirected to and thus may not send it to the End User's actual OpenID Provider).
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Phishing")]
diff --git a/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/Constants.cs b/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/Constants.cs
index 13fc4cf..395ea36 100644
--- a/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/Constants.cs
+++ b/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/Constants.cs
@@ -12,6 +12,24 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
/// </summary>
internal const string TypeUri = "http://specs.openid.net/extensions/pape/1.0";
/// <summary>
+ /// The namespace alias to use for OpenID 1.x interop, where aliases are not defined in the message.
+ /// </summary>
+ internal const string pape_compatibility_alias = "pape";
+ /// <summary>
+ /// The string to prepend on an Auth Level Type alias definition.
+ /// </summary>
+ internal const string AuthLevelNamespaceDeclarationPrefix = "auth_level.ns.";
+
+ internal static class AuthenticationLevels {
+ internal static readonly IDictionary<string, string> PreferredTypeUriToAliasMap = new Dictionary<string, string> {
+ { NistTypeUri, nist_compatibility_alias },
+ };
+
+ internal const string nist_compatibility_alias = "nist";
+ internal const string NistTypeUri = "http://csrc.nist.gov/publications/nistpubs/800-63/SP800-63V1_0_2.pdf";
+ }
+
+ /// <summary>
/// Parameters to be included with PAPE requests.
/// </summary>
internal static class RequestParameters {
@@ -31,6 +49,10 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
/// If no policies are requested, the RP may be interested in other information such as the authentication age.
/// </remarks>
internal const string PreferredAuthPolicies = "preferred_auth_policies";
+ /// <summary>
+ /// The space separated list of the name spaces of the custom Assurance Level that RP requests, in the order of its preference.
+ /// </summary>
+ internal const string PreferredAuthLevelTypes = "preferred_auth_level_types";
}
/// <summary>
/// Parameters to be included with PAPE responses.
@@ -58,13 +80,11 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
/// </remarks>
internal const string AuthTime = "auth_time";
/// <summary>
- /// Optional. The Assurance Level as defined by the National Institute of Standards and Technology (NIST) in Special Publication 800-63 (Burr, W., Dodson, D., and W. Polk, Ed., “Electronic Authentication Guideline,” April 2006.) [NIST_SP800‑63] corresponding to the authentication method and policies employed by the OP when authenticating the End User.
+ /// The first part of a parameter name that gives the custom string value for
+ /// the assurance level. The second part of the parameter name is the alias for
+ /// that assurance level.
/// </summary>
- /// <value>Integer value between 0 and 4 inclusive.</value>
- /// <remarks>
- /// Level 0 is not an assurance level defined by NIST, but rather SHOULD be used to signify that the OP recognizes the parameter and the End User authentication did not meet the requirements of Level 1. See Appendix A.1.2 (NIST Assurance Levels) for high-level example classifications of authentication methods within the defined levels.
- /// </remarks>
- internal const string NistAuthLevel = "nist_auth_level";
+ internal const string AuthLevelAliasPrefix = "auth_level.";
}
}
}
diff --git a/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/NistAssuranceLevel.cs b/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/NistAssuranceLevel.cs
index 2afc118..6358294 100644
--- a/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/NistAssuranceLevel.cs
+++ b/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/NistAssuranceLevel.cs
@@ -13,6 +13,8 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
/// before asserting or interpreting what these levels signify, notwithstanding
/// the brief summaries attached to each level in DotNetOpenId documentation.
/// http://csrc.nist.gov/publications/nistpubs/800-63/SP800-63V1_0_2.pdf
+ ///
+ /// See PAPE spec Appendix A.1.2 (NIST Assurance Levels) for high-level example classifications of authentication methods within the defined levels.
/// </remarks>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Nist")]
public enum NistAssuranceLevel {
diff --git a/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/PolicyRequest.cs b/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/PolicyRequest.cs
index 6493db1..eb78e1f 100644
--- a/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/PolicyRequest.cs
+++ b/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/PolicyRequest.cs
@@ -14,6 +14,7 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
/// </summary>
public PolicyRequest() {
PreferredPolicies = new List<string>(1);
+ PreferredAuthLevelTypes = new List<string>(1);
}
/// <summary>
@@ -33,6 +34,11 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
public IList<string> PreferredPolicies { get; private set; }
/// <summary>
+ /// Zero or more name spaces of the custom Assurance Level the RP requests, in the order of its preference.
+ /// </summary>
+ public IList<string> PreferredAuthLevelTypes { get; private set; }
+
+ /// <summary>
/// Tests equality between two <see cref="PolicyRequest"/> instances.
/// </summary>
public override bool Equals(object obj) {
@@ -43,6 +49,10 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
foreach(string policy in PreferredPolicies) {
if (!other.PreferredPolicies.Contains(policy)) return false;
}
+ if (PreferredAuthLevelTypes.Count != other.PreferredAuthLevelTypes.Count) return false;
+ foreach (string authLevel in PreferredAuthLevelTypes) {
+ if (!other.PreferredAuthLevelTypes.Contains(authLevel)) return false;
+ }
return true;
}
@@ -66,10 +76,23 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
// Even if empty, this parameter is required as part of the request message.
fields.Add(Constants.RequestParameters.PreferredAuthPolicies, SerializePolicies(PreferredPolicies));
+ if (PreferredAuthLevelTypes.Count > 0) {
+ AliasManager authLevelAliases = new AliasManager();
+ authLevelAliases.AssignAliases(PreferredAuthLevelTypes, Constants.AuthenticationLevels.PreferredTypeUriToAliasMap);
+
+ // Add a definition for each Auth Level Type alias.
+ foreach (string alias in authLevelAliases.Aliases) {
+ fields.Add(Constants.AuthLevelNamespaceDeclarationPrefix + alias, authLevelAliases.ResolveAlias(alias));
+ }
+
+ // Now use the aliases for those type URIs to list a preferred order.
+ fields.Add(Constants.RequestParameters.PreferredAuthLevelTypes, SerializeAuthLevels(PreferredAuthLevelTypes, authLevelAliases));
+ }
+
return fields;
}
- bool IExtensionRequest.Deserialize(IDictionary<string, string> fields, DotNetOpenId.Provider.IRequest request) {
+ bool IExtensionRequest.Deserialize(IDictionary<string, string> fields, DotNetOpenId.Provider.IRequest request, string typeUri) {
if (fields == null) return false;
if (!fields.ContainsKey(Constants.RequestParameters.PreferredAuthPolicies)) return false;
@@ -84,6 +107,16 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
PreferredPolicies.Add(policy);
}
+ PreferredAuthLevelTypes.Clear();
+ AliasManager authLevelAliases = FindIncomingAliases(fields);
+ string preferredAuthLevelAliases;
+ if (fields.TryGetValue(Constants.RequestParameters.PreferredAuthLevelTypes, out preferredAuthLevelAliases)) {
+ foreach (string authLevelAlias in preferredAuthLevelAliases.Split(' ')) {
+ if (authLevelAlias.Length == 0) continue;
+ PreferredAuthLevelTypes.Add(authLevelAliases.ResolveAlias(authLevelAlias));
+ }
+ }
+
return true;
}
@@ -95,23 +128,61 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
get { return Constants.TypeUri; }
}
+ IEnumerable<string> IExtension.AdditionalSupportedTypeUris {
+ get { return new string[0]; }
+ }
+
#endregion
static internal string SerializePolicies(IList<string> policies) {
- Debug.Assert(policies != null);
- StringBuilder policyList = new StringBuilder();
- foreach (string policy in GetUniqueItems(policies)) {
- if (policy.Contains(" ")) {
+ return ConcatenateListOfElements(policies);
+ }
+
+ private static string SerializeAuthLevels(IList<string> preferredAuthLevelTypes, AliasManager aliases) {
+ var aliasList = new List<string>();
+ foreach (string typeUri in preferredAuthLevelTypes) {
+ aliasList.Add(aliases.GetAlias(typeUri));
+ }
+
+ return ConcatenateListOfElements(aliasList);
+ }
+
+ /// <summary>
+ /// Looks at the incoming fields and figures out what the aliases and name spaces for auth level types are.
+ /// </summary>
+ internal static AliasManager FindIncomingAliases(IDictionary<string, string> fields) {
+ AliasManager aliasManager = new AliasManager();
+
+ foreach (var pair in fields) {
+ if (!pair.Key.StartsWith(Constants.AuthLevelNamespaceDeclarationPrefix, StringComparison.Ordinal)) {
+ continue;
+ }
+
+ string alias = pair.Key.Substring(Constants.AuthLevelNamespaceDeclarationPrefix.Length);
+ aliasManager.SetAlias(alias, pair.Value);
+ }
+
+ aliasManager.SetPreferredAliasesWhereNotSet(Constants.AuthenticationLevels.PreferredTypeUriToAliasMap);
+
+ return aliasManager;
+ }
+
+ internal static string ConcatenateListOfElements(IList<string> values) {
+ Debug.Assert(values != null);
+ StringBuilder valuesList = new StringBuilder();
+ foreach (string value in GetUniqueItems(values)) {
+ if (value.Contains(" ")) {
throw new FormatException(string.Format(CultureInfo.CurrentCulture,
- Strings.InvalidUri, policy));
+ Strings.InvalidUri, value));
}
- policyList.Append(policy);
- policyList.Append(" ");
+ valuesList.Append(value);
+ valuesList.Append(" ");
}
- if (policyList.Length > 0)
- policyList.Length -= 1; // remove trailing space
- return policyList.ToString();
+ if (valuesList.Length > 0)
+ valuesList.Length -= 1; // remove trailing space
+ return valuesList.ToString();
}
+
static internal IEnumerable<T> GetUniqueItems<T>(IList<T> list) {
List<T> itemsSeen = new List<T>(list.Count);
foreach (T item in list) {
diff --git a/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs b/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs
index a30c873..0f5922f 100644
--- a/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs
+++ b/src/DotNetOpenId/Extensions/ProviderAuthenticationPolicy/PolicyResponse.cs
@@ -17,6 +17,7 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
/// </summary>
public PolicyResponse() {
ActualPolicies = new List<string>(1);
+ AssuranceLevels = new Dictionary<string, string>(1);
}
/// <summary>
@@ -46,13 +47,37 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
}
}
}
+
+ /// <summary>
+ /// Optional. The Assurance Level as defined by the National Institute of Standards and Technology (NIST) in Special Publication 800-63 (Burr, W., Dodson, D., and W. Polk, Ed., “Electronic Authentication Guideline,” April 2006.) [NIST_SP800‑63] corresponding to the authentication method and policies employed by the OP when authenticating the End User. /// </summary>
+ /// <remarks> /// See PAPE spec Appendix A.1.2 (NIST Assurance Levels) for high-level example classifications of authentication methods within the defined levels. /// </remarks>
+ public NistAssuranceLevel? NistAssuranceLevel {
+ get {
+ string levelString;
+ if (AssuranceLevels.TryGetValue(Constants.AuthenticationLevels.NistTypeUri, out levelString)) {
+ return (NistAssuranceLevel)Enum.Parse(typeof(NistAssuranceLevel), levelString);
+ } else {
+ return null;
+ }
+ }
+ set {
+ if (value != null) {
+ AssuranceLevels[Constants.AuthenticationLevels.NistTypeUri] = ((int)value).ToString(CultureInfo.InvariantCulture);
+ } else {
+ AssuranceLevels.Remove(Constants.AuthenticationLevels.NistTypeUri);
+ }
+ }
+ }
+
/// <summary>
- /// Optional. The Assurance Level as defined by the National Institute of Standards and Technology (NIST) in Special Publication 800-63 (Burr, W., Dodson, D., and W. Polk, Ed., “Electronic Authentication Guideline,” April 2006.) [NIST_SP800‑63] corresponding to the authentication method and policies employed by the OP when authenticating the End User.
+ /// Gets a dictionary where keys are the authentication level type URIs and
+ /// the values are the per authentication level defined custom value.
/// </summary>
/// <remarks>
- /// See PAPE spec Appendix A.1.2 (NIST Assurance Levels) for high-level example classifications of authentication methods within the defined levels.
+ /// A very common key is <see cref="Constants.AuthenticationLevels.NistTypeUri"/>
+ /// and values for this key are available in <see cref="NistAssuranceLevel"/>.
/// </remarks>
- public NistAssuranceLevel? NistAssuranceLevel { get; set; }
+ public IDictionary<string, string> AssuranceLevels { get; private set; }
/// <summary>
/// Tests equality between two <see cref="PolicyResponse"/> instances.
@@ -61,7 +86,10 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
PolicyResponse other = obj as PolicyResponse;
if (other == null) return false;
if (AuthenticationTimeUtc != other.AuthenticationTimeUtc) return false;
- if (NistAssuranceLevel != other.NistAssuranceLevel) return false;
+ if (AssuranceLevels.Count != other.AssuranceLevels.Count) return false;
+ foreach (var pair in AssuranceLevels) {
+ if (!other.AssuranceLevels.Contains(pair)) return false;
+ }
if (ActualPolicies.Count != other.ActualPolicies.Count) return false;
foreach (string policy in ActualPolicies) {
if (!other.ActualPolicies.Contains(policy)) return false;
@@ -81,25 +109,37 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
IDictionary<string, string> IExtensionResponse.Serialize(DotNetOpenId.Provider.IRequest authenticationRequest) {
var fields = new Dictionary<string, string>();
- fields.Add(Constants.ResponseParameters.AuthPolicies, PolicyRequest.SerializePolicies(ActualPolicies));
+ fields.Add(Constants.ResponseParameters.AuthPolicies, SerializePolicies(ActualPolicies));
if (AuthenticationTimeUtc.HasValue) {
fields.Add(Constants.ResponseParameters.AuthTime, AuthenticationTimeUtc.Value.ToUniversalTime().ToString(PermissibleDateTimeFormats[0], CultureInfo.InvariantCulture));
}
- if (NistAssuranceLevel.HasValue) {
- fields.Add(Constants.ResponseParameters.NistAuthLevel, ((int)NistAssuranceLevel).ToString(CultureInfo.InvariantCulture));
+
+ if (AssuranceLevels.Count > 0) {
+ AliasManager aliases = new AliasManager();
+ aliases.AssignAliases(AssuranceLevels.Keys, Constants.AuthenticationLevels.PreferredTypeUriToAliasMap);
+
+ // Add a definition for each Auth Level Type alias.
+ foreach (string alias in aliases.Aliases) {
+ fields.Add(Constants.AuthLevelNamespaceDeclarationPrefix + alias, aliases.ResolveAlias(alias));
+ }
+
+ // Now use the aliases for those type URIs to list the individual values.
+ foreach (var pair in AssuranceLevels) {
+ fields.Add(Constants.ResponseParameters.AuthLevelAliasPrefix + aliases.GetAlias(pair.Key), pair.Value);
+ }
}
return fields;
}
- bool IExtensionResponse.Deserialize(IDictionary<string, string> fields, DotNetOpenId.RelyingParty.IAuthenticationResponse response) {
+ bool IExtensionResponse.Deserialize(IDictionary<string, string> fields, DotNetOpenId.RelyingParty.IAuthenticationResponse response, string typeUri) {
if (fields == null) return false;
if (!fields.ContainsKey(Constants.ResponseParameters.AuthPolicies)) return false;
ActualPolicies.Clear();
string[] actualPolicies = fields[Constants.ResponseParameters.AuthPolicies].Split(' ');
foreach (string policy in actualPolicies) {
- if (policy.Length > 0)
+ if (policy.Length > 0 && policy != AuthenticationPolicies.None)
ActualPolicies.Add(policy);
}
@@ -111,22 +151,18 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
authDateTime.Kind == DateTimeKind.Utc) { // may be unspecified per our option above
AuthenticationTimeUtc = authDateTime;
} else {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("Invalid format for {0} parameter: {1}",
- Constants.ResponseParameters.AuthTime, authTime);
+ Logger.ErrorFormat("Invalid format for {0} parameter: {1}",
+ Constants.ResponseParameters.AuthTime, authTime);
}
}
- NistAssuranceLevel = null;
- string nistAuthLevel;
- if (fields.TryGetValue(Constants.ResponseParameters.NistAuthLevel, out nistAuthLevel)) {
- int nistAuthLevelNumber;
- if (int.TryParse(nistAuthLevel, out nistAuthLevelNumber) &&
- nistAuthLevelNumber >= 0 && nistAuthLevelNumber <= 4) {
- NistAssuranceLevel = (NistAssuranceLevel)nistAuthLevelNumber;
- } else {
- if (TraceUtil.Switch.TraceError)
- Trace.TraceError("Invalid NIST level.");
+ AssuranceLevels.Clear();
+ AliasManager authLevelAliases = PolicyRequest.FindIncomingAliases(fields);
+ foreach (string authLevelAlias in authLevelAliases.Aliases) {
+ string authValue;
+ if (fields.TryGetValue(Constants.ResponseParameters.AuthLevelAliasPrefix + authLevelAlias, out authValue)) {
+ string authLevelType = authLevelAliases.ResolveAlias(authLevelAlias);
+ AssuranceLevels[authLevelType] = authValue;
}
}
@@ -141,6 +177,18 @@ namespace DotNetOpenId.Extensions.ProviderAuthenticationPolicy {
get { return Constants.TypeUri; }
}
+ IEnumerable<string> IExtension.AdditionalSupportedTypeUris {
+ get { return new string[0]; }
+ }
+
#endregion
+
+ static internal string SerializePolicies(IList<string> policies) {
+ if (policies.Count == 0) {
+ return AuthenticationPolicies.None;
+ } else {
+ return PolicyRequest.ConcatenateListOfElements(policies);
+ }
+ }
}
}
diff --git a/src/DotNetOpenId/Extensions/SimpleRegistration/ClaimsRequest.cs b/src/DotNetOpenId/Extensions/SimpleRegistration/ClaimsRequest.cs
index b8a8597..aab0608 100644
--- a/src/DotNetOpenId/Extensions/SimpleRegistration/ClaimsRequest.cs
+++ b/src/DotNetOpenId/Extensions/SimpleRegistration/ClaimsRequest.cs
@@ -97,7 +97,7 @@ namespace DotNetOpenId.Extensions.SimpleRegistration {
TimeZone = requestLevel;
break;
default:
- Trace.TraceWarning("OpenIdProfileRequest.SetProfileRequestFromList: Unrecognized field name '{0}'.", field);
+ Logger.WarnFormat("OpenIdProfileRequest.SetProfileRequestFromList: Unrecognized field name '{0}'.", field);
break;
}
}
@@ -128,9 +128,18 @@ namespace DotNetOpenId.Extensions.SimpleRegistration {
#region IExtensionRequest Members
string IExtension.TypeUri { get { return Constants.sreg_ns; } }
+ static readonly string[] additionalTypeUris = new string[] {
+ Constants.sreg_ns10,
+ Constants.sreg_ns11other,
+ };
+ IEnumerable<string> IExtension.AdditionalSupportedTypeUris {
+ get { return additionalTypeUris; }
+ }
- bool IExtensionRequest.Deserialize(IDictionary<string, string> args, IRequest request) {
+ bool IExtensionRequest.Deserialize(IDictionary<string, string> args, IRequest request, string typeUri) {
if (args == null) return false;
+ Debug.Assert(!string.IsNullOrEmpty(typeUri));
+ typeUriDeserializedFrom = typeUri;
string policyUrl;
if (args.TryGetValue(Constants.policy_url, out policyUrl)
@@ -168,10 +177,21 @@ namespace DotNetOpenId.Extensions.SimpleRegistration {
}
#endregion
+ string typeUriDeserializedFrom;
+ /// <summary>
+ /// Prepares a Simple Registration response extension that is compatible with the
+ /// version of Simple Registration used in the request message.
+ /// </summary>
+ public ClaimsResponse CreateResponse() {
+ if (typeUriDeserializedFrom == null) {
+ throw new InvalidOperationException(Strings.CallDeserializeBeforeCreateResponse);
+ }
+ return new ClaimsResponse(typeUriDeserializedFrom);
+ }
+
/// <summary>
/// Renders the requested information as a string.
/// </summary>
- /// <returns></returns>
public override string ToString() {
return string.Format(CultureInfo.CurrentCulture, @"Nickname = '{0}'
Email = '{1}'
diff --git a/src/DotNetOpenId/Extensions/SimpleRegistration/ClaimsResponse.cs b/src/DotNetOpenId/Extensions/SimpleRegistration/ClaimsResponse.cs
index 88f0b35..a9b0cbd 100644
--- a/src/DotNetOpenId/Extensions/SimpleRegistration/ClaimsResponse.cs
+++ b/src/DotNetOpenId/Extensions/SimpleRegistration/ClaimsResponse.cs
@@ -6,13 +6,12 @@
********************************************************/
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Net.Mail;
-using DotNetOpenId.Extensions;
+using System.Text;
using System.Xml.Serialization;
using DotNetOpenId.RelyingParty;
-using DotNetOpenId.Provider;
-using System.Collections.Generic;
namespace DotNetOpenId.Extensions.SimpleRegistration
{
@@ -22,8 +21,22 @@ namespace DotNetOpenId.Extensions.SimpleRegistration
/// authenticating user.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals"), Serializable()]
- public sealed class ClaimsResponse : IExtensionResponse
+ public sealed class ClaimsResponse : IExtensionResponse, IClientScriptExtensionResponse
{
+ string typeUriToUse;
+
+ /// <summary>
+ /// Creates an instance of the <see cref="ClaimsResponse"/> class.
+ /// </summary>
+ [Obsolete("Use ClaimsRequest.CreateResponse() instead.")]
+ public ClaimsResponse() : this(Constants.sreg_ns) {
+ }
+
+ internal ClaimsResponse(string typeUriToUse) {
+ if (string.IsNullOrEmpty(typeUriToUse)) throw new ArgumentNullException("typeUriToUse");
+ this.typeUriToUse = typeUriToUse;
+ }
+
/// <summary>
/// The nickname the user goes by.
/// </summary>
@@ -39,7 +52,7 @@ namespace DotNetOpenId.Extensions.SimpleRegistration
{
get
{
- if (Email == null) return null;
+ if (string.IsNullOrEmpty(Email)) return null;
if (string.IsNullOrEmpty(FullName))
return new MailAddress(Email);
else
@@ -104,7 +117,10 @@ namespace DotNetOpenId.Extensions.SimpleRegistration
public string TimeZone { get; set; }
#region IExtensionResponse Members
- string IExtension.TypeUri { get { return Constants.sreg_ns; } }
+ string IExtension.TypeUri { get { return typeUriToUse; } }
+ IEnumerable<string> IExtension.AdditionalSupportedTypeUris {
+ get { return new string[0]; }
+ }
/// <summary>
/// Adds the values of this struct to an authentication response being prepared
@@ -148,7 +164,7 @@ namespace DotNetOpenId.Extensions.SimpleRegistration
return fields;
}
- bool IExtensionResponse.Deserialize(IDictionary<string, string> sreg, IAuthenticationResponse response) {
+ bool IExtensionResponse.Deserialize(IDictionary<string, string> sreg, IAuthenticationResponse response, string typeUri) {
if (sreg == null) return false;
string nickname, email, fullName, dob, genderString, postalCode, country, language, timeZone;
BirthDate = null;
@@ -184,6 +200,52 @@ namespace DotNetOpenId.Extensions.SimpleRegistration
#endregion
+ #region IClientScriptExtension Members
+
+ static string createAddFieldJS(string propertyName, string value) {
+ return string.Format(CultureInfo.InvariantCulture, "{0}: {1},",
+ propertyName, Util.GetSafeJavascriptValue(value));
+ }
+
+ string IClientScriptExtensionResponse.InitializeJavaScriptData(IDictionary<string, string> sreg, IAuthenticationResponse response, string typeUri) {
+ StringBuilder builder = new StringBuilder();
+ builder.Append("{ ");
+
+ string nickname, email, fullName, dob, genderString, postalCode, country, language, timeZone;
+ if (sreg.TryGetValue(Constants.nickname, out nickname)) {
+ builder.Append(createAddFieldJS(Constants.nickname, nickname));
+ }
+ if (sreg.TryGetValue(Constants.email, out email)) {
+ builder.Append(createAddFieldJS(Constants.email, email));
+ }
+ if (sreg.TryGetValue(Constants.fullname, out fullName)) {
+ builder.Append(createAddFieldJS(Constants.fullname, fullName));
+ }
+ if (sreg.TryGetValue(Constants.dob, out dob)) {
+ builder.Append(createAddFieldJS(Constants.dob, dob));
+ }
+ if (sreg.TryGetValue(Constants.gender, out genderString)) {
+ builder.Append(createAddFieldJS(Constants.gender, genderString));
+ }
+ if (sreg.TryGetValue(Constants.postcode, out postalCode)) {
+ builder.Append(createAddFieldJS(Constants.postcode, postalCode));
+ }
+ if (sreg.TryGetValue(Constants.country, out country)) {
+ builder.Append(createAddFieldJS(Constants.country, country));
+ }
+ if (sreg.TryGetValue(Constants.language, out language)) {
+ builder.Append(createAddFieldJS(Constants.language, language));
+ }
+ if (sreg.TryGetValue(Constants.timezone, out timeZone)) {
+ builder.Append(createAddFieldJS(Constants.timezone, timeZone));
+ }
+ if (builder[builder.Length - 1] == ',') builder.Length -= 1;
+ builder.Append("}");
+ return builder.ToString();
+ }
+
+ #endregion
+
/// <summary>
/// Tests equality of two <see cref="ClaimsResponse"/> objects.
/// </summary>
@@ -223,6 +285,5 @@ namespace DotNetOpenId.Extensions.SimpleRegistration
if (one == null ^ other == null) return false;
return one.Equals(other);
}
-
}
} \ No newline at end of file
diff --git a/src/DotNetOpenId/Extensions/SimpleRegistration/Constants.cs b/src/DotNetOpenId/Extensions/SimpleRegistration/Constants.cs
index fc4066e..8aa9591 100644
--- a/src/DotNetOpenId/Extensions/SimpleRegistration/Constants.cs
+++ b/src/DotNetOpenId/Extensions/SimpleRegistration/Constants.cs
@@ -7,8 +7,9 @@ namespace DotNetOpenId.Extensions.SimpleRegistration {
/// Simple Registration constants
/// </summary>
internal static class Constants {
- internal const string TypeUri = "http://openid.net/sreg/1.0";
internal const string sreg_ns = "http://openid.net/extensions/sreg/1.1";
+ internal const string sreg_ns10 = "http://openid.net/sreg/1.0";
+ internal const string sreg_ns11other = "http://openid.net/sreg/1.1";
internal const string sreg_compatibility_alias = "sreg";
internal const string policy_url = "policy_url";
internal const string optional = "optional";