diaspora_federation 0.2.5 → 0.3.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/Changelog.md +32 -0
- data/lib/diaspora_federation/callbacks.rb +2 -0
- data/lib/diaspora_federation/discovery/discovery.rb +11 -20
- data/lib/diaspora_federation/discovery/exceptions.rb +2 -0
- data/lib/diaspora_federation/discovery/h_card.rb +3 -12
- data/lib/diaspora_federation/discovery/web_finger.rb +33 -36
- data/lib/diaspora_federation/discovery/xrd_document.rb +15 -13
- data/lib/diaspora_federation/discovery.rb +2 -1
- data/lib/diaspora_federation/entities/account_deletion.rb +3 -1
- data/lib/diaspora_federation/entities/account_migration/signable.rb +2 -0
- data/lib/diaspora_federation/entities/account_migration.rb +10 -1
- data/lib/diaspora_federation/entities/comment.rb +3 -1
- data/lib/diaspora_federation/entities/contact.rb +2 -0
- data/lib/diaspora_federation/entities/conversation.rb +4 -2
- data/lib/diaspora_federation/entities/embed.rb +2 -0
- data/lib/diaspora_federation/entities/event.rb +2 -0
- data/lib/diaspora_federation/entities/event_participation.rb +3 -1
- data/lib/diaspora_federation/entities/like.rb +3 -1
- data/lib/diaspora_federation/entities/location.rb +2 -0
- data/lib/diaspora_federation/entities/message.rb +3 -1
- data/lib/diaspora_federation/entities/participation.rb +5 -3
- data/lib/diaspora_federation/entities/person.rb +3 -1
- data/lib/diaspora_federation/entities/photo.rb +3 -1
- data/lib/diaspora_federation/entities/poll.rb +2 -0
- data/lib/diaspora_federation/entities/poll_answer.rb +2 -0
- data/lib/diaspora_federation/entities/poll_participation.rb +3 -1
- data/lib/diaspora_federation/entities/post.rb +3 -1
- data/lib/diaspora_federation/entities/profile.rb +3 -1
- data/lib/diaspora_federation/entities/related_entity.rb +3 -1
- data/lib/diaspora_federation/entities/relayable.rb +17 -30
- data/lib/diaspora_federation/entities/reshare.rb +4 -2
- data/lib/diaspora_federation/entities/retraction.rb +6 -4
- data/lib/diaspora_federation/entities/signable.rb +3 -1
- data/lib/diaspora_federation/entities/status_message.rb +3 -1
- data/lib/diaspora_federation/entities.rb +2 -5
- data/lib/diaspora_federation/entity.rb +12 -8
- data/lib/diaspora_federation/federation/diaspora_url_parser.rb +4 -1
- data/lib/diaspora_federation/federation/fetcher.rb +3 -0
- data/lib/diaspora_federation/federation/receiver/abstract_receiver.rb +2 -0
- data/lib/diaspora_federation/federation/receiver/exceptions.rb +2 -0
- data/lib/diaspora_federation/federation/receiver/private.rb +3 -0
- data/lib/diaspora_federation/federation/receiver/public.rb +2 -0
- data/lib/diaspora_federation/federation/receiver.rb +9 -16
- data/lib/diaspora_federation/federation/sender/hydra_wrapper.rb +2 -0
- data/lib/diaspora_federation/federation/sender.rb +2 -0
- data/lib/diaspora_federation/federation.rb +2 -0
- data/lib/diaspora_federation/http_client.rb +4 -2
- data/lib/diaspora_federation/logging.rb +8 -6
- data/lib/diaspora_federation/parsers/base_parser.rb +4 -0
- data/lib/diaspora_federation/parsers/json_parser.rb +6 -1
- data/lib/diaspora_federation/parsers/relayable_json_parser.rb +3 -0
- data/lib/diaspora_federation/parsers/relayable_xml_parser.rb +2 -0
- data/lib/diaspora_federation/parsers/xml_parser.rb +19 -7
- data/lib/diaspora_federation/parsers.rb +2 -0
- data/lib/diaspora_federation/properties_dsl.rb +6 -39
- data/lib/diaspora_federation/salmon/aes.rb +5 -3
- data/lib/diaspora_federation/salmon/encrypted_magic_envelope.rb +4 -2
- data/lib/diaspora_federation/salmon/exceptions.rb +2 -20
- data/lib/diaspora_federation/salmon/magic_envelope.rb +13 -10
- data/lib/diaspora_federation/salmon.rb +3 -4
- data/lib/diaspora_federation/validators/account_deletion_validator.rb +2 -0
- data/lib/diaspora_federation/validators/account_migration_validator.rb +4 -0
- data/lib/diaspora_federation/validators/comment_validator.rb +2 -0
- data/lib/diaspora_federation/validators/contact_validator.rb +2 -0
- data/lib/diaspora_federation/validators/conversation_validator.rb +2 -0
- data/lib/diaspora_federation/validators/embed_validator.rb +2 -0
- data/lib/diaspora_federation/validators/event_participation_validator.rb +2 -0
- data/lib/diaspora_federation/validators/event_validator.rb +2 -0
- data/lib/diaspora_federation/validators/h_card_validator.rb +2 -0
- data/lib/diaspora_federation/validators/like_validator.rb +2 -0
- data/lib/diaspora_federation/validators/location_validator.rb +2 -0
- data/lib/diaspora_federation/validators/message_validator.rb +2 -0
- data/lib/diaspora_federation/validators/optional_aware_validator.rb +3 -0
- data/lib/diaspora_federation/validators/participation_validator.rb +2 -0
- data/lib/diaspora_federation/validators/person_validator.rb +2 -0
- data/lib/diaspora_federation/validators/photo_validator.rb +3 -1
- data/lib/diaspora_federation/validators/poll_answer_validator.rb +2 -0
- data/lib/diaspora_federation/validators/poll_participation_validator.rb +2 -0
- data/lib/diaspora_federation/validators/poll_validator.rb +2 -0
- data/lib/diaspora_federation/validators/profile_validator.rb +2 -0
- data/lib/diaspora_federation/validators/related_entity_validator.rb +2 -0
- data/lib/diaspora_federation/validators/relayable_validator.rb +2 -0
- data/lib/diaspora_federation/validators/reshare_validator.rb +2 -0
- data/lib/diaspora_federation/validators/retraction_validator.rb +2 -0
- data/lib/diaspora_federation/validators/rules/birthday.rb +3 -1
- data/lib/diaspora_federation/validators/rules/boolean.rb +6 -5
- data/lib/diaspora_federation/validators/rules/diaspora_id.rb +3 -1
- data/lib/diaspora_federation/validators/rules/diaspora_id_list.rb +3 -0
- data/lib/diaspora_federation/validators/rules/guid.rb +3 -1
- data/lib/diaspora_federation/validators/rules/not_nil.rb +2 -0
- data/lib/diaspora_federation/validators/rules/public_key.rb +2 -0
- data/lib/diaspora_federation/validators/rules/tag_count.rb +2 -0
- data/lib/diaspora_federation/validators/status_message_validator.rb +2 -0
- data/lib/diaspora_federation/validators/web_finger_validator.rb +2 -0
- data/lib/diaspora_federation/validators.rb +2 -0
- data/lib/diaspora_federation/version.rb +3 -1
- data/lib/diaspora_federation.rb +3 -2
- metadata +18 -37
- data/lib/diaspora_federation/discovery/host_meta.rb +0 -90
- data/lib/diaspora_federation/entities/relayable_retraction.rb +0 -66
- data/lib/diaspora_federation/entities/request.rb +0 -31
- data/lib/diaspora_federation/entities/signed_retraction.rb +0 -43
- data/lib/diaspora_federation/salmon/encrypted_slap.rb +0 -109
- data/lib/diaspora_federation/salmon/slap.rb +0 -55
- data/lib/diaspora_federation/salmon/xml_payload.rb +0 -41
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Entities
|
3
5
|
# This entity represents a photo and it is federated as a part of a status message.
|
@@ -14,7 +16,7 @@ module DiasporaFederation
|
|
14
16
|
# The diaspora* ID of the person who uploaded the photo
|
15
17
|
# @see Person#author
|
16
18
|
# @return [String] author diaspora* ID
|
17
|
-
property :author, :string
|
19
|
+
property :author, :string
|
18
20
|
|
19
21
|
# @!attribute [r] public
|
20
22
|
# Points if the photo is visible to everyone or only to some aspects
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Entities
|
3
5
|
# This entity represents a participation in poll, i.e. it is issued when a user votes for an answer in a poll.
|
@@ -5,7 +7,7 @@ module DiasporaFederation
|
|
5
7
|
# @see Validators::PollParticipationValidator
|
6
8
|
class PollParticipation < Entity
|
7
9
|
# The {PollParticipation} parent is a {Poll}
|
8
|
-
PARENT_TYPE = "Poll"
|
10
|
+
PARENT_TYPE = "Poll"
|
9
11
|
|
10
12
|
include Relayable
|
11
13
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Entities
|
3
5
|
# This is a module that defines common properties for a post which
|
@@ -30,7 +32,7 @@ module DiasporaFederation
|
|
30
32
|
# @param [Entity] entity the entity in which it is included
|
31
33
|
def self.included(entity)
|
32
34
|
entity.class_eval do
|
33
|
-
property :author, :string
|
35
|
+
property :author, :string
|
34
36
|
property :guid, :string
|
35
37
|
property :created_at, :timestamp, default: -> { Time.now.utc }
|
36
38
|
property :public, :boolean, default: false
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Entities
|
3
5
|
# This entity contains all the profile data of a person.
|
@@ -12,7 +14,7 @@ module DiasporaFederation
|
|
12
14
|
# Alias for author
|
13
15
|
# @see Profile#author
|
14
16
|
# @return [String] diaspora* ID
|
15
|
-
property :author, :string, alias: :diaspora_id
|
17
|
+
property :author, :string, alias: :diaspora_id
|
16
18
|
|
17
19
|
# @!attribute [r] edited_at
|
18
20
|
# The timestamp when the profile was edited
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Entities
|
3
5
|
# Entity meta informations for a related entity (parent or target of
|
@@ -50,7 +52,7 @@ module DiasporaFederation
|
|
50
52
|
end
|
51
53
|
|
52
54
|
# never add {RelatedEntity} to json
|
53
|
-
def to_json
|
55
|
+
def to_json(*_args)
|
54
56
|
nil
|
55
57
|
end
|
56
58
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Entities
|
3
5
|
# This is a module that defines common properties for relayable entities
|
@@ -33,12 +35,6 @@ module DiasporaFederation
|
|
33
35
|
# a target pod.
|
34
36
|
# @return [String] author signature
|
35
37
|
#
|
36
|
-
# @!attribute [r] parent_author_signature
|
37
|
-
# Contains a signature of the entity using the private key of the author of a parent post.
|
38
|
-
# @deprecated This signature isn't required anymore, because we can check the signature from
|
39
|
-
# the parent author in the MagicEnvelope.
|
40
|
-
# @return [String] parent author signature
|
41
|
-
#
|
42
38
|
# @!attribute [r] parent
|
43
39
|
# Meta information about the parent object
|
44
40
|
# @return [RelatedEntity] parent entity
|
@@ -46,11 +42,10 @@ module DiasporaFederation
|
|
46
42
|
# @param [Entity] klass the entity in which it is included
|
47
43
|
def self.included(klass)
|
48
44
|
klass.class_eval do
|
49
|
-
property :author, :string
|
45
|
+
property :author, :string
|
50
46
|
property :guid, :string
|
51
47
|
property :parent_guid, :string
|
52
48
|
property :author_signature, :string, default: nil
|
53
|
-
property :parent_author_signature, :string, default: nil
|
54
49
|
entity :parent, Entities::RelatedEntity
|
55
50
|
end
|
56
51
|
|
@@ -65,7 +60,7 @@ module DiasporaFederation
|
|
65
60
|
# @see DiasporaFederation::Entity#initialize
|
66
61
|
def initialize(data, signature_order=nil, additional_data={})
|
67
62
|
self.signature_order = signature_order if signature_order
|
68
|
-
|
63
|
+
self.additional_data = additional_data
|
69
64
|
|
70
65
|
super(data)
|
71
66
|
end
|
@@ -88,7 +83,7 @@ module DiasporaFederation
|
|
88
83
|
"#{super}#{":#{parent_type}" if respond_to?(:parent_type)}:#{parent_guid}"
|
89
84
|
end
|
90
85
|
|
91
|
-
def to_json
|
86
|
+
def to_json(*_args)
|
92
87
|
super.merge!(property_order: signature_order).tap {|json_hash|
|
93
88
|
missing_properties = json_hash[:property_order] - json_hash[:entity_data].keys
|
94
89
|
missing_properties.each {|property|
|
@@ -100,9 +95,9 @@ module DiasporaFederation
|
|
100
95
|
# The order for signing
|
101
96
|
# @return [Array]
|
102
97
|
def signature_order
|
103
|
-
@signature_order || self.class.class_props.keys.reject {|key|
|
98
|
+
@signature_order || (self.class.class_props.keys.reject {|key|
|
104
99
|
self.class.optional_props.include?(key) && public_send(key).nil?
|
105
|
-
} - %i[author_signature
|
100
|
+
} - %i[author_signature parent])
|
106
101
|
end
|
107
102
|
|
108
103
|
private
|
@@ -113,19 +108,9 @@ module DiasporaFederation
|
|
113
108
|
def sign_with_author
|
114
109
|
privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key, author)
|
115
110
|
raise AuthorPrivateKeyNotFound, "author=#{author} obj=#{self}" if privkey.nil?
|
116
|
-
sign_with_key(privkey).tap do
|
117
|
-
logger.info "event=sign status=complete signature=author_signature author=#{author} obj=#{self}"
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
# Sign with parent author key, if the parent author is local (if the private key is found)
|
122
|
-
# @return [String] A Base64 encoded signature of #signature_data with key
|
123
|
-
def sign_with_parent_author_if_available
|
124
|
-
privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key, parent.root.author)
|
125
|
-
return unless privkey
|
126
111
|
|
127
112
|
sign_with_key(privkey).tap do
|
128
|
-
logger.info "event=sign status=complete signature=
|
113
|
+
logger.info "event=sign status=complete signature=author_signature author=#{author} obj=#{self}"
|
129
114
|
end
|
130
115
|
end
|
131
116
|
|
@@ -135,8 +120,7 @@ module DiasporaFederation
|
|
135
120
|
# @return [Hash] properties with updated signatures
|
136
121
|
def enriched_properties
|
137
122
|
super.merge(additional_data).tap do |hash|
|
138
|
-
hash[:author_signature] = author_signature || sign_with_author
|
139
|
-
hash.delete(:parent_author_signature)
|
123
|
+
hash[:author_signature] = author_signature || sign_with_author unless author == parent.root.author
|
140
124
|
end
|
141
125
|
end
|
142
126
|
|
@@ -144,19 +128,22 @@ module DiasporaFederation
|
|
144
128
|
#
|
145
129
|
# @return [Hash] sorted xml elements
|
146
130
|
def xml_elements
|
147
|
-
data = super
|
148
|
-
|
149
|
-
|
150
|
-
order = signature_order + %i[author_signature parent_author_signature]
|
131
|
+
data = super
|
132
|
+
order = signature_order
|
133
|
+
order += %i[author_signature] unless author == parent.root.author
|
151
134
|
order.map {|element| [element, data[element].to_s] }.to_h
|
152
135
|
end
|
153
136
|
|
154
137
|
def signature_order=(order)
|
155
138
|
prop_names = self.class.class_props.keys.map(&:to_s)
|
156
|
-
@signature_order = order.
|
139
|
+
@signature_order = order.grep_v(/signature/)
|
157
140
|
.map {|name| prop_names.include?(name) ? name.to_sym : name }
|
158
141
|
end
|
159
142
|
|
143
|
+
def additional_data=(additional_data)
|
144
|
+
@additional_data = additional_data.reject {|name, _| name =~ /signature/ }
|
145
|
+
end
|
146
|
+
|
160
147
|
# @return [String] signature data string
|
161
148
|
def signature_data
|
162
149
|
data = normalized_properties.merge(additional_data)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Entities
|
3
5
|
# This entity represents the fact that a user reshared another user's post.
|
@@ -8,7 +10,7 @@ module DiasporaFederation
|
|
8
10
|
# The diaspora* ID of the person who reshares the post
|
9
11
|
# @see Person#author
|
10
12
|
# @return [String] diaspora* ID
|
11
|
-
property :author, :string
|
13
|
+
property :author, :string
|
12
14
|
|
13
15
|
# @!attribute [r] guid
|
14
16
|
# A random string of at least 16 chars
|
@@ -25,7 +27,7 @@ module DiasporaFederation
|
|
25
27
|
# The diaspora* ID of the person who posted the original post
|
26
28
|
# @see Person#author
|
27
29
|
# @return [String] diaspora* ID
|
28
|
-
property :root_author, :string, optional: true
|
30
|
+
property :root_author, :string, optional: true
|
29
31
|
|
30
32
|
# @!attribute [r] root_guid
|
31
33
|
# Guid of the original post
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Entities
|
3
5
|
# This entity represents a claim of deletion of a previously federated entity.
|
@@ -8,17 +10,17 @@ module DiasporaFederation
|
|
8
10
|
# The diaspora* ID of the person who deletes the entity
|
9
11
|
# @see Person#author
|
10
12
|
# @return [String] diaspora* ID
|
11
|
-
property :author, :string
|
13
|
+
property :author, :string
|
12
14
|
|
13
15
|
# @!attribute [r] target_guid
|
14
16
|
# Guid of the entity to be deleted
|
15
17
|
# @return [String] target guid
|
16
|
-
property :target_guid, :string
|
18
|
+
property :target_guid, :string
|
17
19
|
|
18
20
|
# @!attribute [r] target_type
|
19
21
|
# A string describing the type of the target
|
20
22
|
# @return [String] target type
|
21
|
-
property :target_type, :string
|
23
|
+
property :target_type, :string
|
22
24
|
|
23
25
|
# @!attribute [r] target
|
24
26
|
# Target entity
|
@@ -28,7 +30,7 @@ module DiasporaFederation
|
|
28
30
|
def sender_valid?(sender)
|
29
31
|
case target_type
|
30
32
|
when "Comment", "Like", "PollParticipation"
|
31
|
-
|
33
|
+
[target.root.author, target.author].include?(sender)
|
32
34
|
else
|
33
35
|
sender == target.author
|
34
36
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Entities
|
3
5
|
# Signable is a module that encapsulates basic signature generation/verification flow for entities.
|
@@ -5,7 +7,7 @@ module DiasporaFederation
|
|
5
7
|
include Logging
|
6
8
|
|
7
9
|
# Digest instance used for signing
|
8
|
-
DIGEST = OpenSSL::Digest
|
10
|
+
DIGEST = OpenSSL::Digest.new("SHA256")
|
9
11
|
|
10
12
|
# Sign the data with the key
|
11
13
|
#
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Entities
|
3
5
|
# This entity represents a status message sent by a user.
|
@@ -9,7 +11,7 @@ module DiasporaFederation
|
|
9
11
|
# @!attribute [r] text
|
10
12
|
# Text of the status message composed by the user
|
11
13
|
# @return [String] text of the status message
|
12
|
-
property :text, :string
|
14
|
+
property :text, :string
|
13
15
|
|
14
16
|
# @!attribute [r] edited_at
|
15
17
|
# The timestamp when the status message was edited
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
# This namespace contains all the entities used to encapsulate data that is
|
3
5
|
# passed around in the diaspora* network as part of the federation protocol.
|
@@ -44,8 +46,3 @@ require "diaspora_federation/entities/message"
|
|
44
46
|
require "diaspora_federation/entities/conversation"
|
45
47
|
|
46
48
|
require "diaspora_federation/entities/retraction"
|
47
|
-
|
48
|
-
# deprecated
|
49
|
-
require "diaspora_federation/entities/request"
|
50
|
-
require "diaspora_federation/entities/signed_retraction"
|
51
|
-
require "diaspora_federation/entities/relayable_retraction"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
# +Entity+ is the base class for all other objects used to encapsulate data
|
3
5
|
# for federation messages in the diaspora* network.
|
@@ -15,7 +17,6 @@ module DiasporaFederation
|
|
15
17
|
# property :prop
|
16
18
|
# property :optional, default: false
|
17
19
|
# property :dynamic_default, default: -> { Time.now }
|
18
|
-
# property :another_prop, xml_name: :another_name
|
19
20
|
# entity :nested, NestedEntity
|
20
21
|
# entity :multiple, [OtherEntity]
|
21
22
|
# end
|
@@ -38,10 +39,10 @@ module DiasporaFederation
|
|
38
39
|
|
39
40
|
# Invalid XML characters
|
40
41
|
# @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}]
|
42
|
+
INVALID_XML_REGEX = /[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u{10000}-\u{10FFFF}]/.freeze
|
42
43
|
|
43
44
|
# Regex to validate and find entity names
|
44
|
-
ENTITY_NAME_REGEX = "[a-z]*(?:_[a-z]*)*"
|
45
|
+
ENTITY_NAME_REGEX = "[a-z]*(?:_[a-z]*)*"
|
45
46
|
|
46
47
|
# Initializes the Entity with the given attribute hash and freezes the created
|
47
48
|
# instance it returns.
|
@@ -96,7 +97,7 @@ module DiasporaFederation
|
|
96
97
|
#
|
97
98
|
# @return [Nokogiri::XML::Element] root element containing properties as child elements
|
98
99
|
def to_xml
|
99
|
-
doc = Nokogiri::XML::
|
100
|
+
doc = Nokogiri::XML::Document.new
|
100
101
|
Nokogiri::XML::Element.new(self.class.entity_name, doc).tap do |root_element|
|
101
102
|
xml_elements.each do |name, value|
|
102
103
|
add_property_to_xml(doc, root_element, name, value)
|
@@ -149,6 +150,7 @@ module DiasporaFederation
|
|
149
150
|
# @return [Class] entity class
|
150
151
|
def self.entity_class(entity_name)
|
151
152
|
raise InvalidEntityName, "'#{entity_name}' is invalid" unless entity_name =~ /\A#{ENTITY_NAME_REGEX}\z/
|
153
|
+
|
152
154
|
class_name = entity_name.sub(/\A[a-z]/, &:upcase)
|
153
155
|
class_name.gsub!(/_([a-z])/) { Regexp.last_match[1].upcase }
|
154
156
|
|
@@ -169,7 +171,7 @@ module DiasporaFederation
|
|
169
171
|
|
170
172
|
# Renders entity to a hash representation of the entity JSON format
|
171
173
|
# @return [Hash] Returns a hash that is equal by structure to the entity in JSON format
|
172
|
-
def to_json
|
174
|
+
def to_json(*_args)
|
173
175
|
{
|
174
176
|
entity_type: self.class.entity_name,
|
175
177
|
entity_data: json_data
|
@@ -213,7 +215,7 @@ module DiasporaFederation
|
|
213
215
|
end
|
214
216
|
|
215
217
|
def setable_property?(type, val)
|
216
|
-
setable_string?(type, val) || type == :timestamp && val.is_a?(Time)
|
218
|
+
setable_string?(type, val) || (type == :timestamp && val.is_a?(Time))
|
217
219
|
end
|
218
220
|
|
219
221
|
def setable_string?(type, val)
|
@@ -231,12 +233,14 @@ module DiasporaFederation
|
|
231
233
|
|
232
234
|
def nilify(value)
|
233
235
|
return nil if value.respond_to?(:empty?) && value.empty? && !value.instance_of?(Array)
|
236
|
+
|
234
237
|
value
|
235
238
|
end
|
236
239
|
|
237
240
|
def instantiate_nested(name, value)
|
238
241
|
if value.instance_of?(Array)
|
239
242
|
return value unless value.first.instance_of?(Hash)
|
243
|
+
|
240
244
|
value.map {|hash| self.class.class_props[name].first.new(hash) }
|
241
245
|
elsif value.instance_of?(Hash)
|
242
246
|
self.class.class_props[name].new(value)
|
@@ -317,7 +321,7 @@ module DiasporaFederation
|
|
317
321
|
# Generates a hash with entity properties which is put to the "entity_data"
|
318
322
|
# field of a JSON serialized object.
|
319
323
|
# @return [Hash] object properties in JSON format
|
320
|
-
def json_data
|
324
|
+
def json_data # rubocop:disable Metrics/PerceivedComplexity
|
321
325
|
enriched_properties.map {|key, value|
|
322
326
|
type = self.class.class_props[key]
|
323
327
|
next if optional_nil_value?(key, value)
|
@@ -326,7 +330,7 @@ module DiasporaFederation
|
|
326
330
|
entity_data = value.to_json
|
327
331
|
[key, entity_data] unless entity_data.nil?
|
328
332
|
elsif type.instance_of?(Array)
|
329
|
-
entity_data = value
|
333
|
+
entity_data = value&.map(&:to_json)
|
330
334
|
[key, entity_data] unless entity_data.nil?
|
331
335
|
else
|
332
336
|
[key, value]
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Federation
|
3
5
|
# This module is for parsing and fetching linked entities.
|
@@ -10,7 +12,7 @@ module DiasporaFederation
|
|
10
12
|
(#{Validation::Rule::DiasporaId::DIASPORA_ID_REGEX})/
|
11
13
|
(#{Entity::ENTITY_NAME_REGEX})/
|
12
14
|
(#{Validation::Rule::Guid::VALID_CHARS})
|
13
|
-
}ux
|
15
|
+
}ux.freeze
|
14
16
|
|
15
17
|
# Parses all diaspora:// URLs from the text and fetches the entities from
|
16
18
|
# the remote server if needed.
|
@@ -25,6 +27,7 @@ module DiasporaFederation
|
|
25
27
|
private_class_method def self.fetch_entity(author, type, guid)
|
26
28
|
class_name = Entity.entity_class(type).to_s.rpartition("::").last
|
27
29
|
return if DiasporaFederation.callbacks.trigger(:fetch_related_entity, class_name, guid)
|
30
|
+
|
28
31
|
Fetcher.fetch_public(author, type, guid)
|
29
32
|
rescue => e # rubocop:disable Style/RescueStandardError
|
30
33
|
logger.error "Failed to fetch linked entity #{type}:#{guid}: #{e.class}: #{e.message}"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Federation
|
3
5
|
# This module is for fetching entities from other pods.
|
@@ -10,6 +12,7 @@ module DiasporaFederation
|
|
10
12
|
def self.fetch_public(author, entity_type, guid)
|
11
13
|
type = entity_name(entity_type).to_s
|
12
14
|
raise "Already fetching ..." if fetching[type].include?(guid)
|
15
|
+
|
13
16
|
fetch_from_url(author, type, guid)
|
14
17
|
rescue => e # rubocop:disable Style/RescueStandardError
|
15
18
|
raise NotFetchable, "Failed to fetch #{entity_type}:#{guid} from #{author}: #{e.class}: #{e.message}"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Federation
|
3
5
|
# This module parses and receives entities.
|
@@ -6,14 +8,9 @@ module DiasporaFederation
|
|
6
8
|
|
7
9
|
# Receive a public message
|
8
10
|
# @param [String] data message to receive
|
9
|
-
|
10
|
-
|
11
|
-
magic_env =
|
12
|
-
Salmon::Slap.from_xml(data)
|
13
|
-
else
|
14
|
-
magic_env_xml = Nokogiri::XML(data).root
|
15
|
-
Salmon::MagicEnvelope.unenvelop(magic_env_xml)
|
16
|
-
end
|
11
|
+
def self.receive_public(data)
|
12
|
+
magic_env_xml = Nokogiri::XML(data).root
|
13
|
+
magic_env = Salmon::MagicEnvelope.unenvelop(magic_env_xml)
|
17
14
|
Public.new(magic_env).receive
|
18
15
|
rescue => e # rubocop:disable Style/RescueStandardError
|
19
16
|
logger.error "failed to receive public message: #{e.class}: #{e.message}"
|
@@ -26,15 +23,11 @@ module DiasporaFederation
|
|
26
23
|
# @param [OpenSSL::PKey::RSA] recipient_private_key recipient private key to decrypt the message
|
27
24
|
# @param [Object] recipient_id the identifier to persist the entity for the correct user,
|
28
25
|
# see +receive_entity+ callback
|
29
|
-
|
30
|
-
def self.receive_private(data, recipient_private_key, recipient_id, legacy=false)
|
26
|
+
def self.receive_private(data, recipient_private_key, recipient_id)
|
31
27
|
raise ArgumentError, "no recipient key provided" unless recipient_private_key.instance_of?(OpenSSL::PKey::RSA)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
magic_env_xml = Salmon::EncryptedMagicEnvelope.decrypt(data, recipient_private_key)
|
36
|
-
Salmon::MagicEnvelope.unenvelop(magic_env_xml)
|
37
|
-
end
|
28
|
+
|
29
|
+
magic_env_xml = Salmon::EncryptedMagicEnvelope.decrypt(data, recipient_private_key)
|
30
|
+
magic_env = Salmon::MagicEnvelope.unenvelop(magic_env_xml)
|
38
31
|
Private.new(magic_env, recipient_id).receive
|
39
32
|
rescue => e # rubocop:disable Style/RescueStandardError
|
40
33
|
logger.error "failed to receive private message for #{recipient_id}: #{e.class}: #{e.message}"
|
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "faraday"
|
2
|
-
require "faraday_middleware
|
4
|
+
require "faraday_middleware"
|
3
5
|
|
4
6
|
module DiasporaFederation
|
5
7
|
# A wrapper for {https://github.com/lostisland/faraday Faraday}
|
@@ -30,7 +32,7 @@ module DiasporaFederation
|
|
30
32
|
}
|
31
33
|
|
32
34
|
@connection = Faraday::Connection.new(options) do |builder|
|
33
|
-
builder.
|
35
|
+
builder.response :follow_redirects, limit: DiasporaFederation.http_redirect_limit
|
34
36
|
builder.adapter Faraday.default_adapter
|
35
37
|
end
|
36
38
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
# Logging module for the diaspora* federation
|
3
5
|
#
|
@@ -15,15 +17,15 @@ module DiasporaFederation
|
|
15
17
|
#
|
16
18
|
# Use the logging-gem if available, else use a default logger.
|
17
19
|
def logger
|
18
|
-
@logger ||=
|
20
|
+
@logger ||= if defined?(::Logging::Logger)
|
19
21
|
# Use logging-gem if available
|
20
|
-
|
21
|
-
|
22
|
+
::Logging::Logger[self]
|
23
|
+
elsif defined?(::Rails)
|
22
24
|
# Use rails logger if running in rails and no logging-gem is available
|
23
|
-
|
24
|
-
|
25
|
+
::Rails.logger
|
26
|
+
else
|
25
27
|
# fallback logger
|
26
|
-
@logger = Logger.new(
|
28
|
+
@logger = Logger.new($stdout)
|
27
29
|
@logger.level = Logger::INFO
|
28
30
|
@logger
|
29
31
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Parsers
|
3
5
|
# +BaseParser+ is an abstract class which is used for defining parsers for different
|
@@ -36,6 +38,7 @@ module DiasporaFederation
|
|
36
38
|
text.to_i if text =~ /\A\d+\z/
|
37
39
|
when :boolean
|
38
40
|
return true if text =~ /\A(true|t|yes|y|1)\z/i
|
41
|
+
|
39
42
|
false if text =~ /\A(false|f|no|n|0)\z/i
|
40
43
|
else
|
41
44
|
text
|
@@ -44,6 +47,7 @@ module DiasporaFederation
|
|
44
47
|
|
45
48
|
def assert_parsability_of(entity_class)
|
46
49
|
return if entity_class == entity_type.entity_name
|
50
|
+
|
47
51
|
raise InvalidRootNode, "'#{entity_class}' can't be parsed by #{entity_type.name}"
|
48
52
|
end
|
49
53
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiasporaFederation
|
2
4
|
module Parsers
|
3
5
|
# This is a parser of JSON serialized object. JSON object format is defined by
|
@@ -16,7 +18,7 @@ module DiasporaFederation
|
|
16
18
|
|
17
19
|
def parse_entity_data(entity_data)
|
18
20
|
hash = entity_data.map {|key, value|
|
19
|
-
property = entity_type.
|
21
|
+
property = entity_type.class_props.keys.find {|name| name.to_s == key }
|
20
22
|
if property
|
21
23
|
type = entity_type.class_props[property]
|
22
24
|
[property, parse_element_from_value(type, entity_data[key])]
|
@@ -30,12 +32,14 @@ module DiasporaFederation
|
|
30
32
|
|
31
33
|
def parse_element_from_value(type, value)
|
32
34
|
return if value.nil?
|
35
|
+
|
33
36
|
if %i[integer boolean timestamp].include?(type) && !value.is_a?(String)
|
34
37
|
value
|
35
38
|
elsif type.instance_of?(Symbol)
|
36
39
|
parse_string(type, value)
|
37
40
|
elsif type.instance_of?(Array)
|
38
41
|
raise DeserializationError, "Expected array for #{type}" unless value.respond_to?(:map)
|
42
|
+
|
39
43
|
value.map {|element|
|
40
44
|
type.first.from_json(element)
|
41
45
|
}
|
@@ -49,6 +53,7 @@ module DiasporaFederation
|
|
49
53
|
prop if json_hash[prop].nil?
|
50
54
|
}.compact.join(", ")
|
51
55
|
raise DeserializationError, "Required properties are missing in JSON object: #{missing}" unless missing.empty?
|
56
|
+
|
52
57
|
assert_parsability_of(json_hash["entity_type"])
|
53
58
|
end
|
54
59
|
|