//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange { using System; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Messages; /// /// The Attribute Exchange Store message, response leg. /// [Serializable] public sealed class StoreResponse : ExtensionBase { /// /// The factory method that may be used in deserialization of this message. /// internal static readonly StandardOpenIdExtensionFactory.CreateDelegate Factory = (typeUri, data, baseMessage, isProviderRole) => { if (typeUri == Constants.TypeUri && !isProviderRole) { string mode; if (data.TryGetValue("mode", out mode) && (mode == SuccessMode || mode == FailureMode)) { return new StoreResponse(); } } return null; }; /// /// The value of the mode parameter used to express a successful store operation. /// private const string SuccessMode = "store_response_success"; /// /// The value of the mode parameter used to express a store operation failure. /// private const string FailureMode = "store_response_failure"; /// /// Initializes a new instance of the class /// to represent a successful store operation. /// public StoreResponse() : base(new Version(1, 0), Constants.TypeUri, null) { this.Succeeded = true; } /// /// Initializes a new instance of the class /// to represent a failed store operation. /// /// The reason for failure. public StoreResponse(string failureReason) : this() { this.Succeeded = false; this.FailureReason = failureReason; } /// /// Gets or sets a value indicating whether the storage request succeeded. /// /// Defaults to true. public bool Succeeded { get { return this.Mode == SuccessMode; } set { this.Mode = value ? SuccessMode : FailureMode; } } /// /// Gets or sets the reason for the failure, if applicable. /// [MessagePart("error", IsRequired = false)] public string FailureReason { get; set; } /// /// Gets a value indicating whether this extension is signed by the Provider. /// /// /// true if this instance is signed by the Provider; otherwise, false. /// public bool IsSignedByProvider { get { return this.IsSignedByRemoteParty; } } /// /// Gets or sets the mode argument. /// /// One of 'store_response_success' or 'store_response_failure'. [MessagePart("mode", IsRequired = true)] private string Mode { get; set; } /// /// Determines whether the specified is equal to the current . /// /// The to compare with the current . /// /// true if the specified is equal to the current ; otherwise, false. /// /// /// The parameter is null. /// public override bool Equals(object obj) { var other = obj as StoreResponse; if (other == null) { return false; } if (this.Version != other.Version) { return false; } if (this.Succeeded != other.Succeeded) { return false; } if (this.FailureReason != other.FailureReason) { return false; } return true; } /// /// Serves as a hash function for a particular type. /// /// /// A hash code for the current . /// public override int GetHashCode() { unchecked { int hashCode = this.Version.GetHashCode(); hashCode += this.Succeeded ? 0 : 1; if (this.FailureReason != null) { hashCode += this.FailureReason.GetHashCode(); } return hashCode; } } /// /// Checks the message state for conformity to the protocol specification /// and throws an exception if the message is invalid. /// /// /// Some messages have required fields, or combinations of fields that must relate to each other /// in specialized ways. After deserializing a message, this method checks the state of the /// message to see if it conforms to the protocol. /// Note that this property should not check signatures or perform any state checks /// outside this scope of this particular message. /// /// Thrown if the message is invalid. protected override void EnsureValidMessage() { base.EnsureValidMessage(); ErrorUtilities.VerifyProtocol( this.Mode == SuccessMode || this.Mode == FailureMode, MessagingStrings.UnexpectedMessagePartValue, "mode", this.Mode); } } }