module DiasporaFederation::Entities::Relayable
This is a module that defines common properties for relayable entities which include Like
, Comment
, Participation
, Message
, etc. Each relayable has a parent, identified by guid. Relayables are also signed and signing/verification logic is embedded into Salmon
XML processing code.
Attributes
Additional properties from parsed input object @return [Hash] additional elements
Public Class Methods
On inclusion of this module the required properties for a relayable are added to the object that includes it.
@!attribute [r] author
The diaspora* ID of the author @see Person#author @return [String] diaspora* ID
@!attribute [r] guid
A random string of at least 16 chars @see Validation::Rule::Guid @return [String] comment guid
@!attribute [r] parent_guid
@see StatusMessage#guid @return [String] parent guid
@!attribute [r] author_signature
Contains a signature of the entity using the private key of the author of a relayable itself. The presence of this signature is mandatory. Without it the entity won't be accepted by a target pod. @return [String] author signature
@!attribute [r] parent
Meta information about the parent object @return [RelatedEntity] parent entity
@param [Entity] klass the entity in which it is included
# File lib/diaspora_federation/entities/relayable.rb, line 43 def self.included(klass) klass.class_eval do property :author, :string property :guid, :string property :parent_guid, :string property :author_signature, :string, default: nil entity :parent, Entities::RelatedEntity end klass.extend Parsing end
Initializes a new relayable Entity
with order and additional xml elements
@param [Hash] data entity data @param [Array] signature_order
order for the signature @param [Hash] additional_data
additional xml elements @see DiasporaFederation::Entity#initialize
# File lib/diaspora_federation/entities/relayable.rb, line 61 def initialize(data, signature_order=nil, additional_data={}) self.signature_order = signature_order if signature_order self.additional_data = additional_data super(data) end
Public Instance Methods
# File lib/diaspora_federation/entities/relayable.rb, line 77 def sender_valid?(sender) (sender == author && parent.root.local) || sender == parent.root.author end
The order for signing @return [Array]
# File lib/diaspora_federation/entities/relayable.rb, line 97 def signature_order @signature_order || (self.class.class_props.keys.reject {|key| self.class.optional_props.include?(key) && public_send(key).nil? } - %i[author_signature parent]) end
# File lib/diaspora_federation/entities/relayable.rb, line 86 def to_json(*_args) super.merge!(property_order: signature_order).tap {|json_hash| missing_properties = json_hash[:property_order] - json_hash[:entity_data].keys missing_properties.each {|property| json_hash[:entity_data][property] = nil } } end
@return [String] string representation of this object
# File lib/diaspora_federation/entities/relayable.rb, line 82 def to_s "#{super}#{":#{parent_type}" if respond_to?(:parent_type)}:#{parent_guid}" end
Verifies the author_signature
if needed. @see DiasporaFederation::Entities::Signable#verify_signature
@raise [SignatureVerificationFailed] if the signature is not valid @raise [PublicKeyNotFound] if no public key is found
DiasporaFederation::Entities::Signable#verify_signature
# File lib/diaspora_federation/entities/relayable.rb, line 73 def verify_signature super(author, :author_signature) unless author == parent.root.author end
Private Instance Methods
# File lib/diaspora_federation/entities/relayable.rb, line 143 def additional_data=(additional_data) @additional_data = additional_data.reject {|name, _| name =~ /signature/ } end
Update the signatures with the keys of the author and the parent if the signatures are not there yet and if the keys are available.
@return [Hash] properties with updated signatures
# File lib/diaspora_federation/entities/relayable.rb, line 121 def enriched_properties super.merge(additional_data).tap do |hash| hash[:author_signature] = author_signature || sign_with_author unless author == parent.root.author end end
@return [String] signature data string
# File lib/diaspora_federation/entities/relayable.rb, line 148 def signature_data data = normalized_properties.merge(additional_data) signature_order.map {|name| data[name] }.join(";") end
# File lib/diaspora_federation/entities/relayable.rb, line 137 def signature_order=(order) prop_names = self.class.class_props.keys.map(&:to_s) @signature_order = order.grep_v(/signature/) .map {|name| prop_names.include?(name) ? name.to_sym : name } end
Sort all XML elements according to the order used for the signatures.
@return [Hash] sorted xml elements
# File lib/diaspora_federation/entities/relayable.rb, line 130 def xml_elements data = super order = signature_order order += %i[author_signature] unless author == parent.root.author order.to_h {|element| [element, data[element].to_s] } end