using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Globalization;
using DotNetOpenId.Provider;
using DotNetOpenId.RelyingParty;
namespace DotNetOpenId.Extensions.SimpleRegistration {
///
/// Carries the request/require/none demand state of the simple registration fields.
///
#pragma warning disable 0659, 0661
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals")]
public sealed class ClaimsRequest : IExtensionRequest {
///
/// The level of interest a relying party has in the nickname of the user.
///
public DemandLevel Nickname { get; set; }
///
/// The level of interest a relying party has in the email of the user.
///
public DemandLevel Email { get; set; }
///
/// The level of interest a relying party has in the full name of the user.
///
public DemandLevel FullName { get; set; }
///
/// The level of interest a relying party has in the birthdate of the user.
///
public DemandLevel BirthDate { get; set; }
///
/// The level of interest a relying party has in the gender of the user.
///
public DemandLevel Gender { get; set; }
///
/// The level of interest a relying party has in the postal code of the user.
///
public DemandLevel PostalCode { get; set; }
///
/// The level of interest a relying party has in the Country of the user.
///
public DemandLevel Country { get; set; }
///
/// The level of interest a relying party has in the language of the user.
///
public DemandLevel Language { get; set; }
///
/// The level of interest a relying party has in the time zone of the user.
///
public DemandLevel TimeZone { get; set; }
///
/// The URL the consumer site provides for the authenticating user to review
/// for how his claims will be used by the consumer web site.
///
public Uri PolicyUrl { get; set; }
///
/// Sets the profile request properties according to a list of
/// field names that might have been passed in the OpenId query dictionary.
///
///
/// The list of field names that should receive a given
/// . These field names should match
/// the OpenId specification for field names, omitting the 'openid.sreg' prefix.
///
/// The none/request/require state of the listed fields.
internal void SetProfileRequestFromList(ICollection fieldNames, DemandLevel requestLevel) {
foreach (string field in fieldNames) {
switch (field) {
case Constants.nickname:
Nickname = requestLevel;
break;
case Constants.email:
Email = requestLevel;
break;
case Constants.fullname:
FullName = requestLevel;
break;
case Constants.dob:
BirthDate = requestLevel;
break;
case Constants.gender:
Gender = requestLevel;
break;
case Constants.postcode:
PostalCode = requestLevel;
break;
case Constants.country:
Country = requestLevel;
break;
case Constants.language:
Language = requestLevel;
break;
case Constants.timezone:
TimeZone = requestLevel;
break;
default:
Logger.WarnFormat("OpenIdProfileRequest.SetProfileRequestFromList: Unrecognized field name '{0}'.", field);
break;
}
}
}
string[] assembleProfileFields(DemandLevel level) {
List fields = new List(10);
if (Nickname == level)
fields.Add(Constants.nickname);
if (Email == level)
fields.Add(Constants.email);
if (FullName == level)
fields.Add(Constants.fullname);
if (BirthDate == level)
fields.Add(Constants.dob);
if (Gender == level)
fields.Add(Constants.gender);
if (PostalCode == level)
fields.Add(Constants.postcode);
if (Country == level)
fields.Add(Constants.country);
if (Language == level)
fields.Add(Constants.language);
if (TimeZone == level)
fields.Add(Constants.timezone);
return fields.ToArray();
}
#region IExtensionRequest Members
string IExtension.TypeUri { get { return Constants.sreg_ns; } }
static readonly string[] additionalTypeUris = new string[] {
Constants.sreg_ns10,
Constants.sreg_ns11other,
};
IEnumerable IExtension.AdditionalSupportedTypeUris {
get { return additionalTypeUris; }
}
bool IExtensionRequest.Deserialize(IDictionary 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)
&& !string.IsNullOrEmpty(policyUrl)) {
PolicyUrl = new Uri(policyUrl);
}
string optionalFields;
if (args.TryGetValue(Constants.optional, out optionalFields)) {
SetProfileRequestFromList(optionalFields.Split(','), DemandLevel.Request);
}
string requiredFields;
if (args.TryGetValue(Constants.required, out requiredFields)) {
SetProfileRequestFromList(requiredFields.Split(','), DemandLevel.Require);
}
return true;
}
///
/// Adds a description of the information the relying party site would like
/// the Provider to include with a positive authentication assertion as an
/// extension to an authentication request.
///
IDictionary IExtensionRequest.Serialize(RelyingParty.IAuthenticationRequest request) {
var fields = new Dictionary();
if (PolicyUrl != null)
fields.Add(Constants.policy_url, PolicyUrl.AbsoluteUri);
fields.Add(Constants.required, string.Join(",", assembleProfileFields(DemandLevel.Require)));
fields.Add(Constants.optional, string.Join(",", assembleProfileFields(DemandLevel.Request)));
return fields;
}
#endregion
string typeUriDeserializedFrom;
///
/// Prepares a Simple Registration response extension that is compatible with the
/// version of Simple Registration used in the request message.
///
public ClaimsResponse CreateResponse() {
return new ClaimsResponse(typeUriDeserializedFrom);
}
///
/// Renders the requested information as a string.
///
public override string ToString() {
return string.Format(CultureInfo.CurrentCulture, @"Nickname = '{0}'
Email = '{1}'
FullName = '{2}'
Birthdate = '{3}'
Gender = '{4}'
PostalCode = '{5}'
Country = '{6}'
Language = '{7}'
TimeZone = '{8}'", Nickname, Email, FullName, BirthDate, Gender, PostalCode, Country, Language, TimeZone);
}
///
/// Tests equality between two structs.
///
public static bool operator ==(ClaimsRequest one, ClaimsRequest other) {
if ((object)one == null && (object)other == null) return true;
if ((object)one == null ^ (object)other == null) return false;
return one.Equals(other);
}
///
/// Tests inequality between two structs.
///
public static bool operator !=(ClaimsRequest one, ClaimsRequest other) {
return !(one == other);
}
///
/// Tests equality between two structs.
///
public override bool Equals(object obj) {
ClaimsRequest other = obj as ClaimsRequest;
if (other == null) return false;
return
safeEquals(this.BirthDate, other.BirthDate) &&
safeEquals(this.Country, other.Country) &&
safeEquals(this.Language, other.Language) &&
safeEquals(this.Email, other.Email) &&
safeEquals(this.FullName, other.FullName) &&
safeEquals(this.Gender, other.Gender) &&
safeEquals(this.Nickname, other.Nickname) &&
safeEquals(this.PostalCode, other.PostalCode) &&
safeEquals(this.TimeZone, other.TimeZone) &&
safeEquals(this.PolicyUrl, other.PolicyUrl);
}
static bool safeEquals(object one, object other) {
if (one == null && other == null) return true;
if (one == null ^ other == null) return false;
return one.Equals(other);
}
}
}