use private_class_method with returned symbol of def

This commit is contained in:
Benjamin Neff 2016-06-20 03:35:26 +02:00
parent fc1336632c
commit 206b8d1eb9
17 changed files with 43 additions and 86 deletions

View file

@ -253,43 +253,37 @@ module DiasporaFederation
# HTML document.
# @param [LibXML::XML::Document] doc HTML document
# @return [Boolean] validation result
def self.html_document_complete?(doc)
private_class_method def self.html_document_complete?(doc)
!(doc.at_css(SELECTORS[:fn]).nil? || doc.at_css(SELECTORS[:nickname]).nil? ||
doc.at_css(SELECTORS[:url]).nil? || doc.at_css(SELECTORS[:photo]).nil?)
end
private_class_method :html_document_complete?
def self.parse_html_and_validate(html_string)
private_class_method def self.parse_html_and_validate(html_string)
raise ArgumentError, "hcard html is not a string" unless html_string.instance_of?(String)
doc = Nokogiri::HTML::Document.parse(html_string)
raise InvalidData, "hcard html incomplete" unless html_document_complete?(doc)
doc
end
private_class_method :parse_html_and_validate
def self.element_from_doc(doc, selector)
private_class_method def self.element_from_doc(doc, selector)
doc.at_css(SELECTORS[selector])
end
private_class_method :element_from_doc
def self.content_from_doc(doc, content_selector)
private_class_method def self.content_from_doc(doc, content_selector)
element_from_doc(doc, content_selector).content
end
private_class_method :content_from_doc
def self.photo_from_doc(doc, photo_selector)
private_class_method def self.photo_from_doc(doc, photo_selector)
element_from_doc(doc, photo_selector)["src"]
end
private_class_method :photo_from_doc
# @deprecated hack for old hcard
# @todo remove this when all pods have the new generator
def self.guid_from_doc(doc)
private_class_method def self.guid_from_doc(doc)
uid_element = element_from_doc(doc, :uid)
uid_element.content unless uid_element[:class].include? "nickname"
end
private_class_method :guid_from_doc
end
end
end

View file

@ -75,19 +75,17 @@ module DiasporaFederation
# Applies some basic sanity-checking to the given URL
# @param [String] url validation subject
# @return [Boolean] validation result
def self.webfinger_url_valid?(url)
private_class_method def self.webfinger_url_valid?(url)
!url.nil? && url.instance_of?(String) && url =~ %r{^https?:\/\/.*\/.*\{uri\}.*}i
end
private_class_method :webfinger_url_valid?
# Gets the webfinger url from an XRD data structure
# @param [Hash] data extracted data
# @return [String] webfinger url
def self.webfinger_url_from_xrd(data)
private_class_method def self.webfinger_url_from_xrd(data)
link = data[:links].find {|l| l[:rel] == "lrdd" }
return link[:template] unless link.nil?
end
private_class_method :webfinger_url_from_xrd
end
end
end

View file

@ -187,13 +187,12 @@ module DiasporaFederation
# @param [String] webfinger_xml WebFinger XML string
# @return [Hash] data XML data
# @raise [InvalidData] if the given XML string is invalid or incomplete
def self.parse_xml_and_validate(webfinger_xml)
private_class_method def self.parse_xml_and_validate(webfinger_xml)
XrdDocument.xml_data(webfinger_xml).tap do |data|
valid = data.key?(:subject) && data.key?(:links)
raise InvalidData, "webfinger xml is incomplete" unless valid
end
end
private_class_method :parse_xml_and_validate
def add_links_to(doc)
doc.links << {rel: REL_HCARD, type: "text/html", href: @hcard_url}
@ -216,33 +215,29 @@ module DiasporaFederation
##################################
end
def self.find_link(links, rel)
private_class_method def self.find_link(links, rel)
links.find {|l| l[:rel] == rel }
end
private_class_method :find_link
def self.parse_link(links, rel)
private_class_method def self.parse_link(links, rel)
element = find_link(links, rel)
element ? element[:href] : nil
end
private_class_method :parse_link
def self.parse_link_template(links, rel)
private_class_method def self.parse_link_template(links, rel)
element = find_link(links, rel)
element ? element[:template] : nil
end
private_class_method :parse_link_template
# this method is used to parse the alias_url from the XML.
# * redmatrix has sometimes no alias, return nil
# * old pods had quotes around the alias url, this can be removed later
# * friendica has two aliases and the first is with "acct:": return only an URL starting with http (or https)
def self.parse_alias(aliases)
private_class_method def self.parse_alias(aliases)
return nil unless aliases
# TODO: Old pods had quotes around alias. Remove the +map+ in next line, when all pods use this gem
aliases.map {|a| a.gsub(/\A"|"\Z/, "") }.find {|a| a.start_with?("http") }
end
private_class_method :parse_alias
end
end
end

View file

@ -132,34 +132,31 @@ module DiasporaFederation
end
end
def self.parse_xrd_document(xrd_doc)
private_class_method def self.parse_xrd_document(xrd_doc)
raise ArgumentError unless xrd_doc.instance_of?(String)
doc = Nokogiri::XML::Document.parse(xrd_doc)
raise InvalidDocument, "Not an XRD document" if !doc.root || doc.root.name != "XRD"
doc
end
private_class_method :parse_xrd_document
def self.parse_aliases_from_xml_doc(doc, data)
private_class_method def self.parse_aliases_from_xml_doc(doc, data)
aliases = []
doc.xpath("xrd:XRD/xrd:Alias", NS).each do |node|
aliases << node.content
end
data[:aliases] = aliases unless aliases.empty?
end
private_class_method :parse_aliases_from_xml_doc
def self.parse_properties_from_xml_doc(doc, data)
private_class_method def self.parse_properties_from_xml_doc(doc, data)
properties = {}
doc.xpath("xrd:XRD/xrd:Property", NS).each do |node|
properties[node[:type]] = node.children.empty? ? nil : node.content
end
data[:properties] = properties unless properties.empty?
end
private_class_method :parse_properties_from_xml_doc
def self.parse_links_from_xml_doc(doc, data)
private_class_method def self.parse_links_from_xml_doc(doc, data)
links = []
doc.xpath("xrd:XRD/xrd:Link", NS).each do |node|
link = {}
@ -170,7 +167,6 @@ module DiasporaFederation
end
data[:links] = links unless links.empty?
end
private_class_method :parse_links_from_xml_doc
end
end
end

View file

@ -55,10 +55,9 @@ module DiasporaFederation
# @deprecated remove after {Message} doesn't include {Relayable} anymore
# @param [Nokogiri::XML::Element] root_node xml nodes
# @return [Entity] instance
def self.populate_entity(root_node)
private_class_method def self.populate_entity(root_node)
new({parent_guid: nil, parent: nil}.merge(entity_data(root_node)))
end
private_class_method :populate_entity
end
end
end

View file

@ -27,10 +27,9 @@ module DiasporaFederation
# @deprecated remove after {Participation} doesn't include {Relayable} anymore
# @param [Nokogiri::XML::Element] root_node xml nodes
# @return [Entity] instance
def self.populate_entity(root_node)
private_class_method def self.populate_entity(root_node)
new(entity_data(root_node).merge(parent: nil))
end
private_class_method :populate_entity
end
end
end

View file

@ -73,12 +73,11 @@ module DiasporaFederation
# @param [Nokogiri::XML::Element] root_node xml nodes
# @return [Retraction] instance
def self.populate_entity(root_node)
private_class_method def self.populate_entity(root_node)
entity_data = entity_data(root_node)
entity_data[:target] = Retraction.send(:fetch_target, entity_data[:target_type], entity_data[:target_guid])
new(entity_data).to_retraction
end
private_class_method :populate_entity
# It updates also the signatures with the keys of the author and the parent
# if the signatures are not there yet and if the keys are available.

View file

@ -31,10 +31,9 @@ module DiasporaFederation
# @param [Nokogiri::XML::Element] root_node xml nodes
# @return [Retraction] instance
def self.populate_entity(root_node)
private_class_method def self.populate_entity(root_node)
super(root_node).to_contact
end
private_class_method :populate_entity
end
end
end

View file

@ -41,19 +41,17 @@ module DiasporaFederation
# @param [Nokogiri::XML::Element] root_node xml nodes
# @return [Retraction] instance
def self.populate_entity(root_node)
private_class_method def self.populate_entity(root_node)
entity_data = entity_data(root_node)
entity_data[:target] = fetch_target(entity_data[:target_type], entity_data[:target_guid])
new(entity_data)
end
private_class_method :populate_entity
def self.fetch_target(target_type, target_guid)
private_class_method def self.fetch_target(target_type, target_guid)
DiasporaFederation.callbacks.trigger(:fetch_related_entity, target_type, target_guid).tap do |target|
raise TargetNotFound, "not found: #{target_type}:#{target_guid}" unless target
end
end
private_class_method :fetch_target
# Raised, if the target of the {Retraction} was not found.
class TargetNotFound < RuntimeError

View file

@ -58,12 +58,11 @@ module DiasporaFederation
# @param [Nokogiri::XML::Element] root_node xml nodes
# @return [Retraction] instance
def self.populate_entity(root_node)
private_class_method def self.populate_entity(root_node)
entity_data = entity_data(root_node)
entity_data[:target] = Retraction.send(:fetch_target, entity_data[:target_type], entity_data[:target_guid])
new(entity_data).to_retraction
end
private_class_method :populate_entity
# It updates also the signatures with the keys of the author and the parent
# if the signatures are not there yet and if the keys are available.

View file

@ -241,26 +241,24 @@ module DiasporaFederation
# @param [Nokogiri::XML::Element] root_node xml nodes
# @return [Entity] instance
def self.populate_entity(root_node)
private_class_method def self.populate_entity(root_node)
new(entity_data(root_node))
end
private_class_method :populate_entity
# @param [Nokogiri::XML::Element] root_node xml nodes
# @return [Hash] entity data
def self.entity_data(root_node)
private_class_method def self.entity_data(root_node)
Hash[class_props.map {|name, type|
value = parse_element_from_node(name, type, root_node)
[name, value] if value
}.compact]
end
private_class_method :entity_data
# @param [String] name property name to parse
# @param [Class] type target type to parse
# @param [Nokogiri::XML::Element] root_node XML node to parse
# @return [Object] parsed data
def self.parse_element_from_node(name, type, root_node)
private_class_method def self.parse_element_from_node(name, type, root_node)
if type == String
parse_string_from_node(name, root_node)
elsif type.instance_of?(Array)
@ -269,41 +267,37 @@ module DiasporaFederation
parse_entity_from_node(type, root_node)
end
end
private_class_method :parse_element_from_node
# create simple entry in data hash
#
# @param [String] name xml tag to parse
# @param [Nokogiri::XML::Element] root_node XML root_node to parse
# @return [String] data
def self.parse_string_from_node(name, root_node)
private_class_method def self.parse_string_from_node(name, root_node)
node = root_node.xpath(name.to_s)
node = root_node.xpath(xml_names[name].to_s) if node.empty?
node.first.text if node.any?
end
private_class_method :parse_string_from_node
# create an entry in the data hash for the nested entity
#
# @param [Class] type target type to parse
# @param [Nokogiri::XML::Element] root_node XML node to parse
# @return [Entity] parsed child entity
def self.parse_entity_from_node(type, root_node)
private_class_method def self.parse_entity_from_node(type, root_node)
node = root_node.xpath(type.entity_name)
type.from_xml(node.first) if node.any?
end
private_class_method :parse_entity_from_node
# collect all nested children of that type and create an array in the data hash
#
# @param [Class] type target type to parse
# @param [Nokogiri::XML::Element] root_node XML node to parse
# @return [Array<Entity>] array with parsed child entities
def self.parse_array_from_node(type, root_node)
private_class_method def self.parse_array_from_node(type, root_node)
node = root_node.xpath(type.entity_name)
node.map {|child| type.from_xml(child) } unless node.empty?
end
private_class_method :parse_array_from_node
# Raised, if entity is not valid
class ValidationError < RuntimeError

View file

@ -20,14 +20,13 @@ module DiasporaFederation
raise NotFetchable, "Failed to fetch #{entity_type}:#{guid} from #{author}: #{e.class}: #{e.message}"
end
def self.entity_name(class_name)
private_class_method def self.entity_name(class_name)
return class_name if class_name =~ /^[a-z]*(_[a-z]*)*$/
raise DiasporaFederation::Entity::UnknownEntity, class_name unless Entities.const_defined?(class_name)
class_name.gsub(/(.)([A-Z])/, '\1_\2').downcase
end
private_class_method :entity_name
# Raised, if the entity is not fetchable
class NotFetchable < RuntimeError

View file

@ -23,7 +23,7 @@ module DiasporaFederation
@connection.dup
end
def self.create_default_connection
private_class_method def self.create_default_connection
options = {
request: {timeout: DiasporaFederation.http_timeout},
ssl: {ca_file: DiasporaFederation.certificate_authorities}
@ -36,6 +36,5 @@ module DiasporaFederation
@connection.headers["User-Agent"] = DiasporaFederation.http_user_agent
end
private_class_method :create_default_connection
end
end

View file

@ -140,7 +140,7 @@ module DiasporaFederation
# @param [String] data base64 encoded, encrypted header data
# @param [OpenSSL::PKey::RSA] privkey private key for decryption
# @return [Hash] { iv: "...", aes_key: "...", author_id: "..." }
def self.header_data(data, privkey)
private_class_method def self.header_data(data, privkey)
header_elem = decrypt_header(data, privkey)
raise InvalidHeader unless header_elem.name == "decrypted_header"
@ -150,20 +150,18 @@ module DiasporaFederation
{iv: iv, aes_key: key, author_id: author_id}
end
private_class_method :header_data
# decrypts the xml header
# @param [String] data base64 encoded, encrypted header data
# @param [OpenSSL::PKey::RSA] privkey private key for decryption
# @return [Nokogiri::XML::Element] header xml document
def self.decrypt_header(data, privkey)
private_class_method def self.decrypt_header(data, privkey)
cipher_header = JSON.parse(Base64.decode64(data))
key = JSON.parse(privkey.private_decrypt(Base64.decode64(cipher_header["aes_key"])))
xml = AES.decrypt(cipher_header["ciphertext"], Base64.decode64(key["key"]), Base64.decode64(key["iv"]))
Nokogiri::XML::Document.parse(xml).root
end
private_class_method :decrypt_header
# encrypt the header xml with an AES cipher and encrypt the cipher params
# with the recipients public_key

View file

@ -165,18 +165,17 @@ module DiasporaFederation
end
# @param [Nokogiri::XML::Element] env magic envelope XML
def self.envelope_valid?(env)
private_class_method def self.envelope_valid?(env)
(env.instance_of?(Nokogiri::XML::Element) &&
env.name == "env" &&
!env.at_xpath("me:data").content.empty? &&
!env.at_xpath("me:sig").content.empty?)
end
private_class_method :envelope_valid?
# @param [Nokogiri::XML::Element] env magic envelope XML
# @param [String] sender diaspora-ID of the sender or nil
# @return [Boolean]
def self.signature_valid?(env, sender)
private_class_method def self.signature_valid?(env, sender)
subject = sig_subject([Base64.urlsafe_decode64(env.at_xpath("me:data").content),
env.at_xpath("me:data")["type"],
env.at_xpath("me:encoding").content,
@ -188,51 +187,45 @@ module DiasporaFederation
sig = Base64.urlsafe_decode64(env.at_xpath("me:sig").content)
sender_key.verify(DIGEST, sig, subject)
end
private_class_method :signature_valid?
# reads the +key_id+ from the magic envelope
# @param [Nokogiri::XML::Element] env magic envelope XML
# @return [String] diaspora-ID of the sender
def self.sender(env)
private_class_method def self.sender(env)
key_id = env.at_xpath("me:sig")["key_id"]
raise InvalidEnvelope, "no key_id" unless key_id # TODO: move to `envelope_valid?`
Base64.urlsafe_decode64(key_id)
end
private_class_method :sender
# constructs the signature subject.
# the given array should consist of the data, data_type (mimetype), encoding
# and the algorithm
# @param [Array<String>] data_arr
# @return [String] signature subject
def self.sig_subject(data_arr)
private_class_method def self.sig_subject(data_arr)
data_arr.map {|i| Base64.urlsafe_encode64(i) }.join(".")
end
private_class_method :sig_subject
# @param [Nokogiri::XML::Element] magic_env magic envelope XML
# @return [Boolean]
def self.encoding_valid?(magic_env)
private_class_method def self.encoding_valid?(magic_env)
magic_env.at_xpath("me:encoding").content == ENCODING
end
private_class_method :encoding_valid?
# @param [Nokogiri::XML::Element] magic_env magic envelope XML
# @return [Boolean]
def self.algorithm_valid?(magic_env)
private_class_method def self.algorithm_valid?(magic_env)
magic_env.at_xpath("me:alg").content == ALGORITHM
end
private_class_method :algorithm_valid?
# @param [Nokogiri::XML::Element] magic_env magic envelope XML
# @param [Hash] cipher_params hash containing the key and iv
# @return [String] data
def self.read_and_decrypt_data(magic_env, cipher_params)
private_class_method def self.read_and_decrypt_data(magic_env, cipher_params)
data = Base64.urlsafe_decode64(magic_env.at_xpath("me:data").content)
data = AES.decrypt(data, cipher_params[:key], cipher_params[:iv]) unless cipher_params.nil?
data
end
private_class_method :read_and_decrypt_data
end
end
end

View file

@ -86,12 +86,11 @@ module DiasporaFederation
# Parses the magic envelop from the document.
#
# @param [Nokogiri::XML::Document] doc Salmon XML Document
def self.magic_env_from_doc(doc)
private_class_method def self.magic_env_from_doc(doc)
doc.at_xpath("d:diaspora/me:env", Slap::NS).tap do |env|
raise MissingMagicEnvelope if env.nil?
end
end
private_class_method :magic_env_from_doc
end
end
end

View file

@ -51,11 +51,10 @@ module DiasporaFederation
end
# @param [Nokogiri::XML::Element] element
def self.xml_wrapped?(element)
private_class_method def self.xml_wrapped?(element)
(element.name == "XML" && !element.at_xpath("post").nil? &&
!element.at_xpath("post").children.empty?)
end
private_class_method :xml_wrapped?
end
end
end