diaspora_federation 0.0.13 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +15 -32
- data/lib/diaspora_federation.rb +9 -31
- data/lib/diaspora_federation/discovery/h_card.rb +8 -15
- data/lib/diaspora_federation/discovery/host_meta.rb +2 -4
- data/lib/diaspora_federation/discovery/web_finger.rb +11 -11
- data/lib/diaspora_federation/discovery/xrd_document.rb +4 -8
- data/lib/diaspora_federation/entities.rb +2 -0
- data/lib/diaspora_federation/entities/account_deletion.rb +5 -0
- data/lib/diaspora_federation/entities/comment.rb +3 -6
- data/lib/diaspora_federation/entities/contact.rb +5 -0
- data/lib/diaspora_federation/entities/conversation.rb +10 -1
- data/lib/diaspora_federation/entities/message.rb +29 -4
- data/lib/diaspora_federation/entities/participation.rb +24 -0
- data/lib/diaspora_federation/entities/poll_participation.rb +3 -6
- data/lib/diaspora_federation/entities/profile.rb +5 -0
- data/lib/diaspora_federation/entities/related_entity.rb +33 -0
- data/lib/diaspora_federation/entities/relayable.rb +55 -40
- data/lib/diaspora_federation/entities/relayable_retraction.rb +21 -12
- data/lib/diaspora_federation/entities/request.rb +6 -2
- data/lib/diaspora_federation/entities/reshare.rb +5 -0
- data/lib/diaspora_federation/entities/retraction.rb +37 -0
- data/lib/diaspora_federation/entities/signed_retraction.rb +16 -5
- data/lib/diaspora_federation/entities/status_message.rb +11 -0
- data/lib/diaspora_federation/entity.rb +73 -30
- data/lib/diaspora_federation/federation/fetcher.rb +11 -1
- data/lib/diaspora_federation/federation/receiver.rb +10 -0
- data/lib/diaspora_federation/federation/receiver/abstract_receiver.rb +18 -4
- data/lib/diaspora_federation/federation/receiver/exceptions.rb +4 -0
- data/lib/diaspora_federation/federation/receiver/public.rb +10 -0
- data/lib/diaspora_federation/federation/sender.rb +1 -1
- data/lib/diaspora_federation/http_client.rb +1 -2
- data/lib/diaspora_federation/logging.rb +6 -0
- data/lib/diaspora_federation/properties_dsl.rb +4 -2
- data/lib/diaspora_federation/salmon/encrypted_magic_envelope.rb +2 -2
- data/lib/diaspora_federation/salmon/encrypted_slap.rb +3 -5
- data/lib/diaspora_federation/salmon/exceptions.rb +1 -1
- data/lib/diaspora_federation/salmon/magic_envelope.rb +16 -17
- data/lib/diaspora_federation/salmon/slap.rb +1 -2
- data/lib/diaspora_federation/salmon/xml_payload.rb +1 -2
- data/lib/diaspora_federation/validators.rb +2 -0
- data/lib/diaspora_federation/validators/conversation_validator.rb +2 -0
- data/lib/diaspora_federation/validators/message_validator.rb +2 -2
- data/lib/diaspora_federation/validators/participation_validator.rb +3 -2
- data/lib/diaspora_federation/validators/poll_validator.rb +1 -0
- data/lib/diaspora_federation/validators/related_entity_validator.rb +12 -0
- data/lib/diaspora_federation/validators/relayable_retraction_validator.rb +1 -1
- data/lib/diaspora_federation/validators/relayable_validator.rb +1 -0
- data/lib/diaspora_federation/validators/retraction_validator.rb +1 -1
- data/lib/diaspora_federation/validators/rules/diaspora_id.rb +8 -11
- data/lib/diaspora_federation/validators/rules/diaspora_id_count.rb +1 -1
- data/lib/diaspora_federation/validators/signed_retraction_validator.rb +1 -1
- data/lib/diaspora_federation/validators/status_message_validator.rb +2 -0
- data/lib/diaspora_federation/validators/web_finger_validator.rb +2 -2
- data/lib/diaspora_federation/version.rb +1 -1
- metadata +9 -7
@@ -30,10 +30,15 @@ module DiasporaFederation
|
|
30
30
|
# @return [String] author signature
|
31
31
|
property :target_author_signature, default: nil
|
32
32
|
|
33
|
+
# @!attribute [r] target
|
34
|
+
# target entity
|
35
|
+
# @return [RelatedEntity] target entity
|
36
|
+
entity :target, Entities::RelatedEntity
|
37
|
+
|
33
38
|
# use only {Retraction} for receive
|
34
39
|
# @return [Retraction] instance as normal retraction
|
35
40
|
def to_retraction
|
36
|
-
Retraction.new(author: author, target_guid: target_guid, target_type: target_type)
|
41
|
+
Retraction.new(author: author, target_guid: target_guid, target_type: target_type, target: target)
|
37
42
|
end
|
38
43
|
|
39
44
|
# Create signature for a retraction
|
@@ -44,14 +49,20 @@ module DiasporaFederation
|
|
44
49
|
Base64.strict_encode64(privkey.sign(Relayable::DIGEST, [ret.target_guid, ret.target_type].join(";")))
|
45
50
|
end
|
46
51
|
|
52
|
+
# @return [String] string representation of this object
|
53
|
+
def to_s
|
54
|
+
"SignedRetraction:#{target_type}:#{target_guid}"
|
55
|
+
end
|
56
|
+
|
47
57
|
private
|
48
58
|
|
49
59
|
# @param [Nokogiri::XML::Element] root_node xml nodes
|
50
60
|
# @return [Retraction] instance
|
51
|
-
def self.populate_entity(root_node)
|
52
|
-
|
61
|
+
private_class_method def self.populate_entity(root_node)
|
62
|
+
entity_data = entity_data(root_node)
|
63
|
+
entity_data[:target] = Retraction.send(:fetch_target, entity_data[:target_type], entity_data[:target_guid])
|
64
|
+
new(entity_data).to_retraction
|
53
65
|
end
|
54
|
-
private_class_method :populate_entity
|
55
66
|
|
56
67
|
# It updates also the signatures with the keys of the author and the parent
|
57
68
|
# if the signatures are not there yet and if the keys are available.
|
@@ -64,7 +75,7 @@ module DiasporaFederation
|
|
64
75
|
end
|
65
76
|
|
66
77
|
def sign_with_author
|
67
|
-
privkey = DiasporaFederation.callbacks.trigger(:
|
78
|
+
privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key, author)
|
68
79
|
SignedRetraction.sign_with_key(privkey, self) unless privkey.nil?
|
69
80
|
end
|
70
81
|
end
|
@@ -30,6 +30,17 @@ module DiasporaFederation
|
|
30
30
|
# shows whether the status message is visible to everyone or only to some aspects
|
31
31
|
# @return [Boolean] is it public
|
32
32
|
property :public, default: false
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def validate
|
37
|
+
super
|
38
|
+
photos.each do |photo|
|
39
|
+
if photo.author != author
|
40
|
+
raise ValidationError, "nested #{photo} has different author: author=#{author} obj=#{self}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
33
44
|
end
|
34
45
|
end
|
35
46
|
end
|
@@ -34,6 +34,11 @@ module DiasporaFederation
|
|
34
34
|
# are intended to be immutable data containers, only.
|
35
35
|
class Entity
|
36
36
|
extend PropertiesDSL
|
37
|
+
include Logging
|
38
|
+
|
39
|
+
# Invalid XML characters
|
40
|
+
# @see https://www.w3.org/TR/REC-xml/#charsets "Extensible Markup Language (XML) 1.0"
|
41
|
+
INVALID_XML_REGEX = /[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u{10000}-\u{10FFFF}]/
|
37
42
|
|
38
43
|
# Initializes the Entity with the given attribute hash and freezes the created
|
39
44
|
# instance it returns.
|
@@ -50,27 +55,35 @@ module DiasporaFederation
|
|
50
55
|
# @param [Hash] data entity data
|
51
56
|
# @return [Entity] new instance
|
52
57
|
def initialize(data)
|
58
|
+
logger.debug "create entity #{self.class} with data: #{data}"
|
53
59
|
raise ArgumentError, "expected a Hash" unless data.is_a?(Hash)
|
60
|
+
|
54
61
|
entity_data = self.class.resolv_aliases(data)
|
55
|
-
|
56
|
-
unless missing_props.empty?
|
57
|
-
raise ArgumentError, "missing required properties: #{missing_props.join(', ')}"
|
58
|
-
end
|
62
|
+
validate_missing_props(entity_data)
|
59
63
|
|
60
64
|
self.class.default_values.merge(entity_data).each do |name, value|
|
61
|
-
instance_variable_set("@#{name}", nilify(value)) if setable?(name, value)
|
65
|
+
instance_variable_set("@#{name}", instantiate_nested(name, nilify(value))) if setable?(name, value)
|
62
66
|
end
|
63
67
|
|
64
68
|
freeze
|
65
69
|
validate
|
66
70
|
end
|
67
71
|
|
68
|
-
# Returns a Hash representing this Entity (attributes => values)
|
72
|
+
# Returns a Hash representing this Entity (attributes => values).
|
73
|
+
# Nested entities are also converted to a Hash.
|
69
74
|
# @return [Hash] entity data (mostly equal to the hash used for initialization).
|
70
75
|
def to_h
|
71
|
-
|
72
|
-
|
73
|
-
|
76
|
+
properties.map {|key, value|
|
77
|
+
type = self.class.class_props[key]
|
78
|
+
|
79
|
+
if type == String || value.nil?
|
80
|
+
[key, value]
|
81
|
+
elsif type.instance_of?(Class)
|
82
|
+
[key, value.to_h]
|
83
|
+
elsif type.instance_of?(Array)
|
84
|
+
[key, value.map(&:to_h)]
|
85
|
+
end
|
86
|
+
}.to_h
|
74
87
|
end
|
75
88
|
|
76
89
|
# Returns the XML representation for this entity constructed out of
|
@@ -131,8 +144,18 @@ module DiasporaFederation
|
|
131
144
|
Entities.const_get(class_name)
|
132
145
|
end
|
133
146
|
|
147
|
+
# @return [String] string representation of this object
|
148
|
+
def to_s
|
149
|
+
"#{self.class.name.rpartition('::').last}#{":#{guid}" if respond_to?(:guid)}"
|
150
|
+
end
|
151
|
+
|
134
152
|
private
|
135
153
|
|
154
|
+
def validate_missing_props(entity_data)
|
155
|
+
missing_props = self.class.missing_props(entity_data)
|
156
|
+
raise ArgumentError, "missing required properties: #{missing_props.join(', ')}" unless missing_props.empty?
|
157
|
+
end
|
158
|
+
|
136
159
|
def setable?(name, val)
|
137
160
|
type = self.class.class_props[name]
|
138
161
|
return false if type.nil? # property undefined
|
@@ -145,18 +168,30 @@ module DiasporaFederation
|
|
145
168
|
end
|
146
169
|
|
147
170
|
def setable_nested?(type, val)
|
148
|
-
type.
|
171
|
+
type.instance_of?(Class) && type.ancestors.include?(Entity) && (val.is_a?(Entity) || val.is_a?(Hash))
|
149
172
|
end
|
150
173
|
|
151
174
|
def setable_multi?(type, val)
|
152
|
-
type.instance_of?(Array) && val.instance_of?(Array) &&
|
175
|
+
type.instance_of?(Array) && val.instance_of?(Array) &&
|
176
|
+
(val.all? {|v| v.instance_of?(type.first) } || val.all? {|v| v.instance_of?(Hash) })
|
153
177
|
end
|
154
178
|
|
155
179
|
def nilify(value)
|
156
|
-
return nil if value.respond_to?(:empty?) && value.empty?
|
180
|
+
return nil if value.respond_to?(:empty?) && value.empty? && !value.instance_of?(Array)
|
157
181
|
value
|
158
182
|
end
|
159
183
|
|
184
|
+
def instantiate_nested(name, value)
|
185
|
+
if value.instance_of?(Array)
|
186
|
+
return value unless value.first.instance_of?(Hash)
|
187
|
+
value.map {|hash| self.class.class_props[name].first.new(hash) }
|
188
|
+
elsif value.instance_of?(Hash)
|
189
|
+
self.class.class_props[name].new(value)
|
190
|
+
else
|
191
|
+
value
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
160
195
|
def validate
|
161
196
|
validator_name = "#{self.class.name.split('::').last}Validator"
|
162
197
|
return unless Validators.const_defined? validator_name
|
@@ -173,8 +208,15 @@ module DiasporaFederation
|
|
173
208
|
"Failed validation for properties: #{errors.join(' | ')}"
|
174
209
|
end
|
175
210
|
|
211
|
+
# @return [Hash] hash with all properties
|
212
|
+
def properties
|
213
|
+
self.class.class_props.keys.each_with_object({}) do |prop, hash|
|
214
|
+
hash[prop] = public_send(prop)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
176
218
|
def xml_elements
|
177
|
-
|
219
|
+
properties.map {|name, value| [name, self.class.class_props[name] == String ? value.to_s : value] }.to_h
|
178
220
|
end
|
179
221
|
|
180
222
|
def add_property_to_xml(doc, root_element, name, value)
|
@@ -183,7 +225,8 @@ module DiasporaFederation
|
|
183
225
|
else
|
184
226
|
# call #to_xml for each item and append to root
|
185
227
|
[*value].compact.each do |item|
|
186
|
-
|
228
|
+
child = item.to_xml
|
229
|
+
root_element << child if child
|
187
230
|
end
|
188
231
|
end
|
189
232
|
end
|
@@ -192,26 +235,30 @@ module DiasporaFederation
|
|
192
235
|
def simple_node(doc, name, value)
|
193
236
|
xml_name = self.class.xml_names[name]
|
194
237
|
Nokogiri::XML::Element.new(xml_name ? xml_name.to_s : name, doc).tap do |node|
|
195
|
-
node.content = value unless value.empty?
|
238
|
+
node.content = value.gsub(INVALID_XML_REGEX, "\uFFFD") unless value.empty?
|
196
239
|
end
|
197
240
|
end
|
198
241
|
|
199
242
|
# @param [Nokogiri::XML::Element] root_node xml nodes
|
200
243
|
# @return [Entity] instance
|
201
|
-
def self.populate_entity(root_node)
|
202
|
-
entity_data
|
203
|
-
|
204
|
-
}]
|
244
|
+
private_class_method def self.populate_entity(root_node)
|
245
|
+
new(entity_data(root_node))
|
246
|
+
end
|
205
247
|
|
206
|
-
|
248
|
+
# @param [Nokogiri::XML::Element] root_node xml nodes
|
249
|
+
# @return [Hash] entity data
|
250
|
+
private_class_method def self.entity_data(root_node)
|
251
|
+
class_props.map {|name, type|
|
252
|
+
value = parse_element_from_node(name, type, root_node)
|
253
|
+
[name, value] if value
|
254
|
+
}.compact.to_h
|
207
255
|
end
|
208
|
-
private_class_method :populate_entity
|
209
256
|
|
210
257
|
# @param [String] name property name to parse
|
211
258
|
# @param [Class] type target type to parse
|
212
259
|
# @param [Nokogiri::XML::Element] root_node XML node to parse
|
213
260
|
# @return [Object] parsed data
|
214
|
-
def self.parse_element_from_node(name, type, root_node)
|
261
|
+
private_class_method def self.parse_element_from_node(name, type, root_node)
|
215
262
|
if type == String
|
216
263
|
parse_string_from_node(name, root_node)
|
217
264
|
elsif type.instance_of?(Array)
|
@@ -220,41 +267,37 @@ module DiasporaFederation
|
|
220
267
|
parse_entity_from_node(type, root_node)
|
221
268
|
end
|
222
269
|
end
|
223
|
-
private_class_method :parse_element_from_node
|
224
270
|
|
225
271
|
# create simple entry in data hash
|
226
272
|
#
|
227
273
|
# @param [String] name xml tag to parse
|
228
274
|
# @param [Nokogiri::XML::Element] root_node XML root_node to parse
|
229
275
|
# @return [String] data
|
230
|
-
def self.parse_string_from_node(name, root_node)
|
276
|
+
private_class_method def self.parse_string_from_node(name, root_node)
|
231
277
|
node = root_node.xpath(name.to_s)
|
232
278
|
node = root_node.xpath(xml_names[name].to_s) if node.empty?
|
233
279
|
node.first.text if node.any?
|
234
280
|
end
|
235
|
-
private_class_method :parse_string_from_node
|
236
281
|
|
237
282
|
# create an entry in the data hash for the nested entity
|
238
283
|
#
|
239
284
|
# @param [Class] type target type to parse
|
240
285
|
# @param [Nokogiri::XML::Element] root_node XML node to parse
|
241
286
|
# @return [Entity] parsed child entity
|
242
|
-
def self.parse_entity_from_node(type, root_node)
|
287
|
+
private_class_method def self.parse_entity_from_node(type, root_node)
|
243
288
|
node = root_node.xpath(type.entity_name)
|
244
289
|
type.from_xml(node.first) if node.any?
|
245
290
|
end
|
246
|
-
private_class_method :parse_entity_from_node
|
247
291
|
|
248
292
|
# collect all nested children of that type and create an array in the data hash
|
249
293
|
#
|
250
294
|
# @param [Class] type target type to parse
|
251
295
|
# @param [Nokogiri::XML::Element] root_node XML node to parse
|
252
296
|
# @return [Array<Entity>] array with parsed child entities
|
253
|
-
def self.parse_array_from_node(type, root_node)
|
297
|
+
private_class_method def self.parse_array_from_node(type, root_node)
|
254
298
|
node = root_node.xpath(type.entity_name)
|
255
|
-
node.map {|child| type.from_xml(child) }
|
299
|
+
node.map {|child| type.from_xml(child) } unless node.empty?
|
256
300
|
end
|
257
|
-
private_class_method :parse_array_from_node
|
258
301
|
|
259
302
|
# Raised, if entity is not valid
|
260
303
|
class ValidationError < RuntimeError
|
@@ -7,7 +7,9 @@ module DiasporaFederation
|
|
7
7
|
# @param [Symbol, String] entity_type snake_case version of the entity class
|
8
8
|
# @param [String] guid guid of the entity to fetch
|
9
9
|
def self.fetch_public(author, entity_type, guid)
|
10
|
-
url = DiasporaFederation.callbacks.trigger(
|
10
|
+
url = DiasporaFederation.callbacks.trigger(
|
11
|
+
:fetch_person_url_to, author, "/fetch/#{entity_name(entity_type)}/#{guid}"
|
12
|
+
)
|
11
13
|
response = HttpClient.get(url)
|
12
14
|
raise "Failed to fetch #{url}: #{response.status}" unless response.success?
|
13
15
|
|
@@ -18,6 +20,14 @@ module DiasporaFederation
|
|
18
20
|
raise NotFetchable, "Failed to fetch #{entity_type}:#{guid} from #{author}: #{e.class}: #{e.message}"
|
19
21
|
end
|
20
22
|
|
23
|
+
private_class_method def self.entity_name(class_name)
|
24
|
+
return class_name if class_name =~ /^[a-z]*(_[a-z]*)*$/
|
25
|
+
|
26
|
+
raise DiasporaFederation::Entity::UnknownEntity, class_name unless Entities.const_defined?(class_name)
|
27
|
+
|
28
|
+
class_name.gsub(/(.)([A-Z])/, '\1_\2').downcase
|
29
|
+
end
|
30
|
+
|
21
31
|
# Raised, if the entity is not fetchable
|
22
32
|
class NotFetchable < RuntimeError
|
23
33
|
end
|
@@ -2,6 +2,8 @@ module DiasporaFederation
|
|
2
2
|
module Federation
|
3
3
|
# this module is for parse and receive entities.
|
4
4
|
module Receiver
|
5
|
+
extend Logging
|
6
|
+
|
5
7
|
# receive a public message
|
6
8
|
# @param [String] data message to receive
|
7
9
|
# @param [Boolean] legacy use old slap parser
|
@@ -13,6 +15,10 @@ module DiasporaFederation
|
|
13
15
|
Salmon::MagicEnvelope.unenvelop(magic_env_xml)
|
14
16
|
end
|
15
17
|
Public.new(magic_env).receive
|
18
|
+
rescue => e
|
19
|
+
logger.error "failed to receive public message: #{e.class}: #{e.message}"
|
20
|
+
logger.debug "received data:\n#{data}"
|
21
|
+
raise e
|
16
22
|
end
|
17
23
|
|
18
24
|
# receive a private message
|
@@ -30,6 +36,10 @@ module DiasporaFederation
|
|
30
36
|
Salmon::MagicEnvelope.unenvelop(magic_env_xml)
|
31
37
|
end
|
32
38
|
Private.new(magic_env, recipient_id).receive
|
39
|
+
rescue => e
|
40
|
+
logger.error "failed to receive private message for #{recipient_id}: #{e.class}: #{e.message}"
|
41
|
+
logger.debug "received data:\n#{data}"
|
42
|
+
raise e
|
33
43
|
end
|
34
44
|
end
|
35
45
|
end
|
@@ -3,6 +3,8 @@ module DiasporaFederation
|
|
3
3
|
module Receiver
|
4
4
|
# common functionality for receivers
|
5
5
|
class AbstractReceiver
|
6
|
+
include Logging
|
7
|
+
|
6
8
|
# create a new receiver
|
7
9
|
# @param [MagicEnvelope] magic_envelope the received magic envelope
|
8
10
|
# @param [Object] recipient_id the identifier of the recipient of a private message
|
@@ -14,20 +16,32 @@ module DiasporaFederation
|
|
14
16
|
|
15
17
|
# validate and receive the entity
|
16
18
|
def receive
|
17
|
-
|
18
|
-
|
19
|
+
validate_and_receive
|
20
|
+
rescue => e
|
21
|
+
logger.error "failed to receive #{entity}"
|
22
|
+
raise e
|
19
23
|
end
|
20
24
|
|
21
25
|
private
|
22
26
|
|
23
27
|
attr_reader :entity, :sender, :recipient_id
|
24
28
|
|
29
|
+
def validate_and_receive
|
30
|
+
validate
|
31
|
+
DiasporaFederation.callbacks.trigger(:receive_entity, entity, recipient_id)
|
32
|
+
logger.info "successfully received #{entity} from person #{sender}#{" for #{recipient_id}" if recipient_id}"
|
33
|
+
end
|
34
|
+
|
25
35
|
def validate
|
26
|
-
raise InvalidSender unless sender_valid?
|
36
|
+
raise InvalidSender, "invalid sender: #{sender}" unless sender_valid?
|
27
37
|
end
|
28
38
|
|
29
39
|
def sender_valid?
|
30
|
-
|
40
|
+
if entity.respond_to?(:sender_valid?)
|
41
|
+
entity.sender_valid?(sender)
|
42
|
+
else
|
43
|
+
sender == entity.author
|
44
|
+
end
|
31
45
|
end
|
32
46
|
end
|
33
47
|
end
|
@@ -8,6 +8,10 @@ module DiasporaFederation
|
|
8
8
|
# Raised, if receiving a private message without recipient.
|
9
9
|
class RecipientRequired < RuntimeError
|
10
10
|
end
|
11
|
+
|
12
|
+
# Raised, if receiving a message with public receiver which is not public but should be.
|
13
|
+
class NotPublic < RuntimeError
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
13
17
|
end
|
@@ -3,6 +3,16 @@ module DiasporaFederation
|
|
3
3
|
module Receiver
|
4
4
|
# receiver for public entities
|
5
5
|
class Public < AbstractReceiver
|
6
|
+
private
|
7
|
+
|
8
|
+
def validate
|
9
|
+
super
|
10
|
+
raise NotPublic if entity_can_be_public_but_it_is_not?
|
11
|
+
end
|
12
|
+
|
13
|
+
def entity_can_be_public_but_it_is_not?
|
14
|
+
entity.respond_to?(:public) && !entity.public
|
15
|
+
end
|
6
16
|
end
|
7
17
|
end
|
8
18
|
end
|
@@ -24,7 +24,7 @@ module DiasporaFederation
|
|
24
24
|
def self.private(sender_id, obj_str, targets)
|
25
25
|
hydra = HydraWrapper.new(sender_id, obj_str)
|
26
26
|
targets.each {|url, xml| hydra.insert_job(url, xml) }
|
27
|
-
|
27
|
+
hydra.send.map {|url| [url, targets[url]] }.to_h
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -23,7 +23,7 @@ module DiasporaFederation
|
|
23
23
|
@connection.dup
|
24
24
|
end
|
25
25
|
|
26
|
-
def self.create_default_connection
|
26
|
+
private_class_method def self.create_default_connection
|
27
27
|
options = {
|
28
28
|
request: {timeout: DiasporaFederation.http_timeout},
|
29
29
|
ssl: {ca_file: DiasporaFederation.certificate_authorities}
|
@@ -36,6 +36,5 @@ module DiasporaFederation
|
|
36
36
|
|
37
37
|
@connection.headers["User-Agent"] = DiasporaFederation.http_user_agent
|
38
38
|
end
|
39
|
-
private_class_method :create_default_connection
|
40
39
|
end
|
41
40
|
end
|
@@ -3,6 +3,12 @@ module DiasporaFederation
|
|
3
3
|
#
|
4
4
|
# it uses the logging-gem if available
|
5
5
|
module Logging
|
6
|
+
# add +logger+ also as class method when included
|
7
|
+
# @param [Class] klass the class into which the module is included
|
8
|
+
def self.included(klass)
|
9
|
+
klass.extend(self)
|
10
|
+
end
|
11
|
+
|
6
12
|
private
|
7
13
|
|
8
14
|
# get the logger for this class
|