using System;
using System.Collections.Generic;
using System.Text;
using DotNetOpenId.RelyingParty;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics;
namespace DotNetOpenId {
///
/// An Identifier is either a "http" or "https" URI, or an XRI.
///
public abstract class Identifier {
///
/// Constructs an .
///
///
/// Whether the derived class is prepared to guarantee end-to-end discovery
/// and initial redirect for authentication is performed using SSL.
///
protected Identifier(bool isDiscoverySecureEndToEnd) {
IsDiscoverySecureEndToEnd = isDiscoverySecureEndToEnd;
}
///
/// Whether this Identifier will ensure SSL is used throughout the discovery phase
/// and initial redirect of authentication.
///
///
/// If this is False, a value of True may be obtained by calling .
///
protected internal bool IsDiscoverySecureEndToEnd { get; private set; }
///
/// Converts the string representation of an Identifier to its strong type.
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates"), SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads")]
public static implicit operator Identifier(string identifier) {
if (identifier == null) return null;
return Parse(identifier);
}
///
/// Returns a strongly-typed Identifier for a given Uri.
///
[SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates")]
public static implicit operator Identifier(Uri identifier) {
if (identifier == null) return null;
return new UriIdentifier(identifier);
}
///
/// Converts an Identifier to its string representation.
///
[SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates")]
public static implicit operator String(Identifier identifier) {
if (identifier == null) return null;
return identifier.ToString();
}
///
/// Parses an identifier string and automatically determines
/// whether it is an XRI or URI.
///
/// Either a URI or XRI identifier.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings")]
public static Identifier Parse(string identifier) {
if (string.IsNullOrEmpty(identifier)) throw new ArgumentNullException("identifier");
if (XriIdentifier.IsValidXri(identifier)) {
return new XriIdentifier(identifier);
} else {
return new UriIdentifier(identifier);
}
}
///
/// Attempts to parse a string for an OpenId Identifier.
///
/// The string to be parsed.
/// The parsed Identifier form.
///
/// True if the operation was successful. False if the string was not a valid OpenId Identifier.
///
public static bool TryParse(string value, out Identifier result) {
if (IsValid(value)) {
result = Parse(value);
return true;
} else {
result = null;
return false;
}
}
///
/// Gets whether a given string represents a valid Identifier format.
///
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings")]
public static bool IsValid(string identifier) {
return XriIdentifier.IsValidXri(identifier) || UriIdentifier.IsValidUri(identifier);
}
///
/// Performs discovery on the Identifier.
///
///
/// An initialized structure containing the discovered provider endpoint information.
///
internal abstract IEnumerable Discover();
///
/// Tests equality between two s.
///
public static bool operator ==(Identifier id1, Identifier id2) {
if ((object)id1 == null ^ (object)id2 == null) return false;
if ((object)id1 == null) return true;
return id1.Equals(id2);
}
///
/// Tests inequality between two s.
///
public static bool operator !=(Identifier id1, Identifier id2) {
return !(id1 == id2);
}
///
/// Tests equality between two s.
///
public override bool Equals(object obj) {
Debug.Fail("This should be overridden in every derived class.");
return base.Equals(obj);
}
///
/// Gets the hash code for an for storage in a hashtable.
///
public override int GetHashCode() {
Debug.Fail("This should be overridden in every derived class.");
return base.GetHashCode();
}
///
/// Returns an that has no URI fragment.
/// Quietly returns the original if it is not
/// a or no fragment exists.
///
internal abstract Identifier TrimFragment();
///
/// Converts a given identifier to its secure equivalent.
/// UriIdentifiers originally created with an implied HTTP scheme change to HTTPS.
/// Discovery is made to require SSL for the entire resolution process.
///
///
/// The newly created secure identifier.
/// If the conversion fails, retains
/// this identifiers identity, but will never discover any endpoints.
///
///
/// True if the secure conversion was successful.
/// False if the Identifier was originally created with an explicit HTTP scheme.
///
internal abstract bool TryRequireSsl(out Identifier secureIdentifier);
}
}