Documentation added

This commit is contained in:
cmrd Senya 2015-11-23 22:46:55 +03:00
parent 91546d7919
commit dba15af1d8
42 changed files with 435 additions and 15 deletions

View file

@ -1,6 +1,13 @@
module DiasporaFederation
module Entities
# this entity is sent when account was deleted on a remote pod
#
# @see Validators::AccountDeletionValidator
class AccountDeletion < Entity
# @!attribute [r] diaspora_id
# The diaspora ID of the deleted account
# @see Person#diaspora_id
# @return [String] diaspora ID
property :diaspora_id, xml_name: :diaspora_handle
end
end

View file

@ -1,9 +1,24 @@
module DiasporaFederation
module Entities
# this entity represents a comment to some kind of post (e.g. status message)
#
# @see Validators::CommentValidator
class Comment < Entity
# @!attribute [r] guid
# @see HCard#guid
# @return [String] guid
property :guid
include Relayable
# @!attribute [r] text
# @return [String] the comment text
property :text
# @!attribute [r] diaspora_id
# The diaspora ID of the person
# @see Person#diaspora_id
# @return [String] diaspora ID
property :diaspora_id, xml_name: :diaspora_handle
end
end

View file

@ -1,11 +1,30 @@
module DiasporaFederation
module Entities
# this entity represents a private conversation between users
#
# @see Validators::ConverstaionValidator
class Conversation < Entity
# @!attribute [r] guid
# @see HCard#guid
# @return [String] guid
property :guid
# @!attribute [r] subject
# @return [String] the conversation subject
property :subject
# @!attribute [r] created_at
# @return [Time] Conversation creation time
property :created_at, default: -> { Time.now.utc }
entity :messages, [Entities::Message]
# @!attribute [r] diaspora_id
# The diaspora ID of the person initiated the conversation
# @see Person#diaspora_id
# @return [String] diaspora ID
property :diaspora_id, xml_name: :diaspora_handle
property :participant_ids, xml_name: :participant_handles
end
end

View file

@ -1,10 +1,31 @@
module DiasporaFederation
module Entities
# this entity represents a like to some kind of post (e.g. status message)
#
# @see Validators::LikeValidator
class Like < Entity
# @!attribute [r] positive
# If true set a like, if false, set a dislike (dislikes are currently not
# implemented in the Diaspora's frontend).
# @return [Boolean] is it a like or a dislike
property :positive
# @!attribute [r] guid
# @see HCard#guid
# @return [String] guid
property :guid
# @!attribute [r] target_type
# a string describing a type of the target
# @return [String] target type
property :target_type
include Relayable
# @!attribute [r] diaspora_id
# The diaspora ID of the person who posts a like
# @see Person#diaspora_id
# @return [String] diaspora ID
property :diaspora_id, xml_name: :diaspora_handle
end
end

View file

@ -1,8 +1,22 @@
module DiasporaFederation
module Entities
# this entity is used to specify a location data and used embedded in a status message
#
# @see Validators::LocationValidator
class Location < Entity
# @!attribute [r] address
# A string describing your location, e.g. a city name, a street name, etc
# @return [String] address
property :address
# @!attribute [r] lat
# Geographical latitude of your location
# @return [String] latitude
property :lat
# @!attribute [r] lng
# Geographical longitude of your location
# @return [String] longitude
property :lng
end
end

View file

@ -1,11 +1,36 @@
module DiasporaFederation
module Entities
# this entity represents a private message exchanged in private conversation
#
# @see Validators::MessageValidator
class Message < Entity
# @!attribute [r] guid
# @see HCard#guid
# @return [String] guid
property :guid
include Relayable
# @!attribute [r] text
# text of the message composed by a user
# @return [String] text
property :text
# @!attribute [r] created_at
# message creation time
# @return [Time] creation time
property :created_at, default: -> { Time.now.utc }
# @!attribute [r] diaspora_id
# The diaspora ID of the message author
# @see Person#diaspora_id
# @return [String] diaspora ID
property :diaspora_id, xml_name: :diaspora_handle
# @!attribute [r] conversation_guid
# guid of a conversation this message belongs to
# @see HCard#guid
# @return [String] conversation guid
property :conversation_guid
end
end

View file

@ -1,9 +1,25 @@
module DiasporaFederation
module Entities
# participation is sent to subscribe a user on updates for some post
#
# @see Validators::Participation
class Participation < Entity
# @!attribute [r] guid
# @see HCard#guid
# @return [String] guid
property :guid
# @!attribute [r] target_type
# a string describing a type of the target to subscribe on
# @return [String] target type
property :target_type
include Relayable
# @!attribute [r] diaspora_id
# The diaspora ID of the person who subscribes on a post
# @see Person#diaspora_id
# @return [String] diaspora ID
property :diaspora_id, xml_name: :diaspora_handle
end
end

View file

@ -1,15 +1,57 @@
module DiasporaFederation
module Entities
# this entity represents photo and it is federated as a part of a status message
#
# @see Validators::PhotoValidator
class Photo < Entity
# @!attribute [r] guid
# @see HCard#guid
# @return [String] guid
property :guid
# @!attribute [r] diaspora_id
# The diaspora ID of the person who uploaded the photo
# @see Person#diaspora_id
# @return [String] diaspora ID
property :diaspora_id, xml_name: :diaspora_handle
# @!attribute [r] public
# Points if the photo is visible to everyone or only to some aspects
# @return [Boolean] is it public
property :public, default: false
# @!attribute [r] created_at
# photo entity creation time
# @return [Time] creation time
property :created_at, default: -> { Time.now.utc }
# @!attribute [r] remote_photo_path
# an url of the photo on a remote server
# @return [String] remote photo url
property :remote_photo_path
# @!attribute [r] remote_photo_name
# @return [String] remote photo name
property :remote_photo_name
# @!attribute [r] text
# @return [String] text
property :text, default: nil
# @!attribute [r] status_message_guid
# guid of a status message this message belongs to
# @see HCard#guid
# @return [String] guid
property :status_message_guid
# @!attribute [r] height
# photo height
# @return [String] height
property :height
# @!attribute [r] width
# photo width
# @return [String] width
property :width
end
end

View file

@ -1,8 +1,22 @@
module DiasporaFederation
module Entities
# this entity represents a poll ant it is federated as an optional part of a status message
#
# @see Validators::PollValidator
class Poll < Entity
# @!attribute [r] guid
# @see HCard#guid
# @return [String] guid
property :guid
# @!attribute [r] question
# Text of the question posed by a user
# @return [String] question
property :question
# @!attribute [r] poll_answers
# array of possible answer to the poll
# @return [[Entities::PollAnswer]] poll answers
entity :poll_answers, [Entities::PollAnswer]
end
end

View file

@ -1,7 +1,17 @@
module DiasporaFederation
module Entities
# this entity represents a poll answer and is federated as a part of the Poll entity
#
# @see Validators::PollAnswerValidator
class PollAnswer < Entity
# @!attribute [r] guid
# @see HCard#guid
# @return [String] guid
property :guid
# @!attribute [r] answer
# Text of the answer
# @return [String] answer
property :answer
end
end

View file

@ -1,9 +1,26 @@
module DiasporaFederation
module Entities
# this entity represents a participation in poll, i.e. it is issued when a user votes for an answer in a poll
#
# @see Validators::PollParticipationValidator
class PollParticipation < Entity
# @!attribute [r] guid
# @see HCard#guid
# @return [String] guid
property :guid
include Relayable
# @!attribute [r] diaspora_id
# The diaspora ID of the person who voted in the poll
# @see Person#diaspora_id
# @return [String] diaspora ID
property :diaspora_id, xml_name: :diaspora_handle
# @!attribute [r] poll_answer_guid
# guid of the answer selected by user
# @see HCard#guid
# @return [String] poll answer guid
property :poll_answer_guid
end
end

View file

@ -1,10 +1,32 @@
module DiasporaFederation
module Entities
# 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 also are signed and signing/verificating
# logic is embedded into Salmon XML processing code.
module Relayable
# on inclusion of this module the required properties for a relayable are added to the object that includes it
def self.included(model)
model.class_eval do
# @!attribute [r] parent_guid
# @see HCard#guid
# @return [String] parent guid
property :parent_guid
# @!attribute [r] parent_author_signature
# Contains a signature of the entity using the private key of the author of a parent post
# This signature is required only when federation from upstream (parent) post author to
# downstream subscribers. This is the case when the parent author has to resend a relayable
# received from one of his subscribers to all others.
#
# @return [String] parent author signature
property :parent_author_signature, default: nil
# @!attribute [r] author_signature
# Contains a signature of the entity using the private key of the author of a post itself.
# The presence of this signature is mandatory. Without it the entity won't be accepted by
# a target pod.
# @return [String] author signature
property :author_signature, default: nil
end
end
@ -20,6 +42,7 @@ module DiasporaFederation
xml
end
# Exception raised when verify_signatures fails to verify signatures (signatures are wrong)
class SignatureVerificationFailed < ArgumentError
end
@ -41,6 +64,11 @@ module DiasporaFederation
end
end
# Adds signatures to a given hash with the keys of the author and the parent
# if the signatures are not in the hash yet and if the keys are available.
#
# @param [Hash] data hash given for a signing
# @return [Hash] reference to the input hash
def self.update_signatures!(data)
if data[:author_signature].nil?
pkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_id, data[:diaspora_id])

View file

@ -1,10 +1,51 @@
module DiasporaFederation
module Entities
# this entity represents a claim of deletion of a previously federated
# relayable entity ({Entities::Comment}, {Entities::Like})
#
# There are two cases of federation of the RelayableRetraction.
# Retraction from the dowstream object owner is when an author of the
# relayable (e.g. Comment) deletes it himself. In this case only target_author_signature
# is filled and retraction is sent to the commented post's author. Here
# he (upstream object owner) signes it with parent's author key and fills
# signature in parent_author_signature and sends it to other pods where
# other participating people present. This is the second case - retraction
# from the upstream object owner.
# Retraction from the upstream object owner can also be performed by the
# upstream object owner himself - he has a right to delete comments on his posts.
# In any case in the retraction by the upstream author target_author_signature
# is not checked, only parent_author_signature is checked.
#
# @see Validators::RelayableRetractionValidator
class RelayableRetraction < Entity
# @!attribute [r] parent_author_signature
# Contains a signature of the entity using the private key of the author of a parent post
# This signature is mandatory only when federation from an upstream author to the subscribers.
# @return [String] parent author signature
property :parent_author_signature
# @!attribute [r] target_guid
# guid of a post to be deleted
# @see HCard#guid
# @return [String] target guid
property :target_guid
# @!attribute [r] target_type
# @return [String] target type
property :target_type
# @!attribute [r] sender_id
# The diaspora ID of the person who deletes a post
# @see Person#diaspora_id
# @return [String] diaspora ID
property :sender_id, xml_name: :sender_handle
# @!attribute [r] target_author_signature
# Contains a signature of the entity using the private key of the
# author of a federated relayable entity ({Entities::Comment}, {Entities::Like})
# This signature is mandatory only when federation from the subscriber to an upstream
# author is done.
# @return [String] target author signature
property :target_author_signature
end
end

View file

@ -1,7 +1,20 @@
module DiasporaFederation
module Entities
# this entity represents a sharing request for a user. A user issues it
# when she wants to share her private posts with the recipient.
#
# @see Validators::RequestValidator
class Request < Entity
# @!attribute [r] sender_id
# The diaspora ID of the person who shares his private posts
# @see Person#diaspora_id
# @return [String] sender ID
property :sender_id, xml_name: :sender_handle
# @!attribute [r] recipient_id
# The diaspora ID of the person who will be shared with
# @see Person#diaspora_id
# @return [String] recipient ID
property :recipient_id, xml_name: :recipient_handle
end
end

View file

@ -1,12 +1,45 @@
module DiasporaFederation
module Entities
# this entity represents the fact the a user reshared some other user's post
#
# @see Validators::ReshareValidator
class Reshare < Entity
# @!attribute [r] diaspora_id
# The diaspora ID of the person who posted the original post
# @see Person#diaspora_id
# @return [String] diaspora ID
property :root_diaspora_id # inconsistent, everywhere else it's "handle"
# @!attribute [r] root_guid
# guid of the original post
# @see HCard#guid
# @return [String] root guid
property :root_guid
# @!attribute [r] guid
# @see HCard#guid
# @return [String] guid
property :guid
# @!attribute [r] diaspora_id
# The diaspora ID of the person who reshares a post
# @see Person#diaspora_id
# @return [String] diaspora ID
property :diaspora_id, xml_name: :diaspora_handle
# @!attribute [r] public
# has no meaning at the moment
# @return [Boolean] public
property :public, default: true # always true? (we only reshare public posts)
# @!attribute [r] created_at
# reshare entity creation time
# @return [Time] creation time
property :created_at, default: -> { Time.now.utc }
# @!attribute [r] provider_display_name
# a string that describes a means by which a user has posted the reshare
# @return [String] provider display name
property :provider_display_name, default: nil
end
end

View file

@ -1,8 +1,24 @@
module DiasporaFederation
module Entities
# this entity represents a claim of deletion of a previously federated
# entity that is not a post or a relayable (now it includes only {Entities::Photo})
#
# @see Validators::RetractionValidator
class Retraction < Entity
# @!attribute [r] post_guid
# guid of a post to be deleted
# @see HCard#guid
# @return [String] post guid
property :post_guid
# @!attribute [r] diaspora_id
# The diaspora ID of the person who deletes a post
# @see Person#diaspora_id
# @return [String] diaspora ID
property :diaspora_id, xml_name: :diaspora_handle
# @!attribute [r] type
# @return [String] type
property :type
end
end

View file

@ -1,9 +1,30 @@
module DiasporaFederation
module Entities
# this entity represents a claim of deletion of a previously federated
# entity of post type ({Entities::StatusMessage})
#
# @see Validators::SignedRetractionValidator
class SignedRetraction < Entity
# @!attribute [r] target_guid
# guid of a post to be deleted
# @see HCard#guid
# @return [String] target guid
property :target_guid
# @!attribute [r] target_type
# @return [String] target type
property :target_type
# @!attribute [r] sender_id
# The diaspora ID of the person who deletes a post
# @see Person#diaspora_id
# @return [String] diaspora ID
property :sender_id, xml_name: :sender_handle
# @!attribute [r] author_signature
# Contains a signature of the entity using the private key of the author of a post
# This signature is mandatory.
# @return [String] author signature
property :target_author_signature
end
end

View file

@ -1,14 +1,53 @@
module DiasporaFederation
module Entities
# this entity represents a status message sent by a user
#
# @see Validators::StatusMessageValidator
class StatusMessage < Entity
# @!attribute [r] raw_message
# text of the status message composed by a user
# @return [String] text of the status message
property :raw_message
# @!attribute [r] photos
# optional photos attached to the status message
# @return [[Entities::Photo]] photos
entity :photos, [Entities::Photo], default: []
# @!attribute [r] location
# optional location attached to the status message
# @return [Entities::Location] location
entity :location, Entities::Location, default: nil
# @!attribute [r] poll
# optional poll attached to the status message
# @return [Entities::Poll] poll
entity :poll, Entities::Poll, default: nil
# @!attribute [r] guid
# @see HCard#guid
# @return [String] guid
property :guid
# @!attribute [r] diaspora_id
# The diaspora ID of the person who posts the status message
# @see Person#diaspora_id
# @return [String] diaspora ID
property :diaspora_id, xml_name: :diaspora_handle
# @!attribute [r] public
# Points if the status message is visible to everyone or only to some aspects
# @return [Boolean] is it public
property :public, default: false
# @!attribute [r] created_at
# status message entity creation time
# @return [Time] creation time
property :created_at, default: -> { Time.now.utc }
# @!attribute [r] provider_display_name
# a string that describes a means by which a user has posted the status message
# @return [String] provider display name
property :provider_display_name, default: nil
end
end

View file

@ -17,7 +17,6 @@ module DiasporaFederation
# @param [String] data plain input
# @param [String] key AES key
# @param [String] iv AES initialization vector
# @param [Hash] key_and_iv { key: "...", iv: "..." }
# @return [String] base64 encoded ciphertext
def self.encrypt(data, key, iv)
raise ArgumentError unless data.instance_of?(String)

View file

@ -112,8 +112,8 @@ module DiasporaFederation
end
# decrypts and reads the data from the encrypted XML header
# @param [String] base64 encoded, encrypted header data
# @param [OpenSSL::PKey::RSA] private_key for decryption
# @param [String] data base64 encoded, encrypted header data
# @param [OpenSSL::PKey::RSA] pkey private key for decryption
# @return [Hash] { iv: "...", aes_key: "...", author_id: "..." }
def self.header_data(data, pkey)
header_elem = decrypt_header(data, pkey)
@ -128,8 +128,8 @@ module DiasporaFederation
private_class_method :header_data
# decrypts the xml header
# @param [String] base64 encoded, encrypted header data
# @param [OpenSSL::PKey::RSA] private_key for decryption
# @param [String] data base64 encoded, encrypted header data
# @param [OpenSSL::PKey::RSA] pkey private key for decryption
# @return [Nokogiri::XML::Element] header xml document
def self.decrypt_header(data, pkey)
cipher_header = JSON.parse(Base64.decode64(data))
@ -142,10 +142,10 @@ module DiasporaFederation
# encrypt the header xml with an AES cipher and encrypt the cipher params
# with the recipients public_key
# @param [String] diaspora_handle
# @param [Hash] envelope cipher params
# @param [OpenSSL::PKey::RSA] recipient public_key
# @param parent_node [Nokogiri::XML::Element] parent element for insering in XML document
# @param [String] author_id diaspora_handle
# @param [Hash] envelope_key envelope cipher params
# @param [OpenSSL::PKey::RSA] pubkey recipient public_key
# @param [Nokogiri::XML::Element] xml parent element for inserting in XML document
def self.encrypted_header(author_id, envelope_key, pubkey, xml)
data = header_xml(author_id, strict_base64_encode(envelope_key))
key = AES.generate_key_and_iv
@ -161,8 +161,8 @@ module DiasporaFederation
private_class_method :encrypted_header
# generate the header xml string, including the author, aes_key and iv
# @param [String] diaspora_handle of the author
# @param [Hash] { key: "...", iv: "..." } (values in base64)
# @param [String] author_id diaspora_handle of the author
# @param [Hash] envelope_key { key: "...", iv: "..." } (values in base64)
# @return [String] header XML string
def self.header_xml(author_id, envelope_key)
builder = Nokogiri::XML::Builder.new do |xml|

View file

@ -126,7 +126,7 @@ module DiasporaFederation
@rsa_pkey.sign(DIGEST, subject)
end
# @param [Nokogiri::XML::Element]
# @param [Nokogiri::XML::Element] env envelope
def self.envelope_valid?(env)
(env.instance_of?(Nokogiri::XML::Element) &&
env.name == "env" &&
@ -137,8 +137,8 @@ module DiasporaFederation
end
private_class_method :envelope_valid?
# @param [Nokogiri::XML::Element]
# @param [OpenSSL::PKey::RSA] public_key
# @param [Nokogiri::XML::Element] env
# @param [OpenSSL::PKey::RSA] pkey public key
def self.signature_valid?(env, pkey)
subject = sig_subject([Base64.urlsafe_decode64(env.at_xpath("me:data").content),
env.at_xpath("me:data")["type"],
@ -153,7 +153,7 @@ module DiasporaFederation
# constructs the signature subject.
# the given array should consist of the data, data_type (mimetype), encoding
# and the algorithm
# @param [Array<String>]
# @param [Array<String>] data_arr
def self.sig_subject(data_arr)
data_arr.map {|i| Base64.urlsafe_encode64(i) }.join(".")
end

View file

@ -1,4 +1,5 @@
module DiasporaFederation
# this module defines operations of signing an arbitrary hash with an arbitrary key
module Signing
extend Logging
# @param [OpenSSL::PKey::RSA] key An RSA key

View file

@ -1,17 +1,25 @@
require "diaspora_federation/test/factories"
module DiasporaFederation
# This module incapsulates helper functions maybe wanted by a testsuite of a diaspora_federation gem user application
module Test
# Sort hash according to an entity class's property sequence.
# This is used for rspec tests in order to generate correct input hash to
# compare results with.
#
# @param [Hash] data input hash for sorting
# @param [Entity.Class] klass entity type to sort according to
# @return [Hash] sorted hash
def self.sort_hash(data, klass)
klass.class_props.map { |prop|
[prop[:name], data[prop[:name]]] unless data[prop[:name]].nil?
}.compact.to_h
end
# Generates attributes for entity constructor with correct signatures in it
#
# @param [Symbol] entity_type type to generate attributes for
# @return [Hash] hash with correct signatures
def self.relayable_attributes_with_signatures(entity_type)
DiasporaFederation::Entities::Relayable.update_signatures!(
sort_hash(FactoryGirl.attributes_for(entity_type), FactoryGirl.factory_by_name(entity_type).build_class)

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::AccountDeletion}
class AccountDeletionValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::Comment}
class CommentValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::Conversation}
class ConversationValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::Like}
class LikeValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::Location}
class LocationValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::Message}
class MessageValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::Participation}
class ParticipationValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::Photo}
class PhotoValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::PollAnswer}
class PollAnswerValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::PollParticipation}
class PollParticipationValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::Poll}
class PollValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::RelayableRetraction}
class RelayableRetractionValidator < Validation::Validator
include Validation

View file

@ -1,6 +1,8 @@
module DiasporaFederation
module Validators
# This is included to validatros which validate entities which include {Entities::Relayable}
module RelayableValidator
# when this module is included in a Validator child it adds rules for relayable validation
def self.included(model)
model.class_eval do
rule :parent_guid, :guid

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::Request}
class RequestValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::Reshare}
class ReshareValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::Retraction}
class RetractionValidator < Validation::Validator
include Validation

View file

@ -15,6 +15,8 @@ module Validation
@params = params
end
# The error key for this rule
# @return [Symbol] error key
def error_key
:diaspora_id_count
end

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::SignedRetraction}
class SignedRetractionValidator < Validation::Validator
include Validation

View file

@ -1,5 +1,6 @@
module DiasporaFederation
module Validators
# This validates a {Entities::StatusMessage}
class StatusMessageValidator < Validation::Validator
include Validation