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); } }