diaspora_federation 0.0.9 → 0.0.10
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/lib/diaspora_federation.rb +18 -0
- data/lib/diaspora_federation/discovery/web_finger.rb +38 -27
- data/lib/diaspora_federation/entities/message.rb +4 -0
- data/lib/diaspora_federation/entities/poll_participation.rb +4 -0
- data/lib/diaspora_federation/entities/relayable.rb +20 -8
- data/lib/diaspora_federation/receiver.rb +28 -0
- data/lib/diaspora_federation/receiver/private.rb +19 -0
- data/lib/diaspora_federation/receiver/public.rb +13 -0
- data/lib/diaspora_federation/salmon/encrypted_slap.rb +2 -0
- data/lib/diaspora_federation/salmon/xml_payload.rb +3 -1
- data/lib/diaspora_federation/version.rb +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 704840223f25af1abc3fa00ed7d0cc931d45665e
|
4
|
+
data.tar.gz: cf78859d34900183ca8c5ee07ab7a24357239369
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 632e343a34a267c990681ce3f34ab39cdf47f8807cb7f3ec56fd98b49e9bb801f9dd0b9c8c018f0e8bc86356ddb37a320858a2741be19bb79e6498cab1627cda
|
7
|
+
data.tar.gz: 4c7c62f615b3caeae02bde51718136c5be9696cdd768257db25d563bb7c9323a01081d778fc87f262ff90adbc31c06c64a364bb95172a66c273229c284058d08
|
data/lib/diaspora_federation.rb
CHANGED
@@ -12,6 +12,7 @@ require "diaspora_federation/entities"
|
|
12
12
|
|
13
13
|
require "diaspora_federation/discovery"
|
14
14
|
require "diaspora_federation/salmon"
|
15
|
+
require "diaspora_federation/receiver"
|
15
16
|
|
16
17
|
# diaspora* federation library
|
17
18
|
module DiasporaFederation
|
@@ -27,6 +28,9 @@ module DiasporaFederation
|
|
27
28
|
fetch_author_public_key_by_entity_guid
|
28
29
|
entity_author_is_local?
|
29
30
|
fetch_entity_author_id_by_guid
|
31
|
+
queue_public_receive
|
32
|
+
queue_private_receive
|
33
|
+
save_entity_after_receive
|
30
34
|
)
|
31
35
|
|
32
36
|
class << self
|
@@ -121,6 +125,20 @@ module DiasporaFederation
|
|
121
125
|
# @param [String] guid of the entity
|
122
126
|
# @return [String] Diaspora ID of the person
|
123
127
|
#
|
128
|
+
# queue_public_receive
|
129
|
+
# Queue a public salmon xml to process in background
|
130
|
+
# @param [String] xml salmon xml
|
131
|
+
#
|
132
|
+
# queue_private_receive
|
133
|
+
# Queue a private salmon xml to process in background
|
134
|
+
# @param [String] guid guid of the receiver person
|
135
|
+
# @param [String] xml salmon xml
|
136
|
+
# @return [Boolean] true if successful, false if the user was not found
|
137
|
+
#
|
138
|
+
# save_entity_after_receive
|
139
|
+
# After the xml was parsed and processed the gem calls this callback to persist the entity
|
140
|
+
# @param [DiasporaFederation::Entity] entity the received entity after processing
|
141
|
+
#
|
124
142
|
# @see Callbacks#on
|
125
143
|
#
|
126
144
|
# @example
|
@@ -75,6 +75,10 @@ module DiasporaFederation
|
|
75
75
|
# Panzer draft for Salmon, paragraph 3.3
|
76
76
|
property :salmon_url
|
77
77
|
|
78
|
+
# @!attribute [r] subscribe_url
|
79
|
+
# This url is used to find another user on the home-pod of the user in the webfinger.
|
80
|
+
property :subscribe_url
|
81
|
+
|
78
82
|
# @!attribute [r] guid
|
79
83
|
# @deprecated Either convert these to +Property+ elements or move to the
|
80
84
|
# +hCard+, which actually has fields for an +UID+ defined in the +vCard+
|
@@ -121,6 +125,9 @@ module DiasporaFederation
|
|
121
125
|
# +salmon_url+ link relation
|
122
126
|
REL_SALMON = "salmon"
|
123
127
|
|
128
|
+
# +subscribe_url+ link relation
|
129
|
+
REL_SUBSCRIBE = "http://ostatus.org/schema/1.0/subscribe"
|
130
|
+
|
124
131
|
# @deprecated This should be a +Property+ or moved to the +hcard+, but +Link+
|
125
132
|
# is inappropriate according to the specification (will affect older
|
126
133
|
# Diaspora* installations).
|
@@ -152,17 +159,19 @@ module DiasporaFederation
|
|
152
159
|
public_key = parse_link(links, REL_PUBKEY)
|
153
160
|
|
154
161
|
new(
|
155
|
-
acct_uri:
|
156
|
-
alias_url:
|
157
|
-
hcard_url:
|
158
|
-
seed_url:
|
159
|
-
profile_url:
|
160
|
-
atom_url:
|
161
|
-
salmon_url:
|
162
|
+
acct_uri: data[:subject],
|
163
|
+
alias_url: parse_alias(data[:aliases]),
|
164
|
+
hcard_url: parse_link(links, REL_HCARD),
|
165
|
+
seed_url: parse_link(links, REL_SEED),
|
166
|
+
profile_url: parse_link(links, REL_PROFILE),
|
167
|
+
atom_url: parse_link(links, REL_ATOM),
|
168
|
+
salmon_url: parse_link(links, REL_SALMON),
|
169
|
+
|
170
|
+
subscribe_url: parse_link_template(links, REL_SUBSCRIBE),
|
162
171
|
|
163
172
|
# TODO: remove me! ##########
|
164
|
-
guid:
|
165
|
-
public_key:
|
173
|
+
guid: parse_link(links, REL_GUID),
|
174
|
+
public_key: (Base64.strict_decode64(public_key) if public_key)
|
166
175
|
)
|
167
176
|
end
|
168
177
|
|
@@ -182,27 +191,18 @@ module DiasporaFederation
|
|
182
191
|
private_class_method :parse_xml_and_validate
|
183
192
|
|
184
193
|
def add_links_to(doc)
|
185
|
-
doc.links << {rel:
|
186
|
-
|
187
|
-
href: @hcard_url}
|
188
|
-
doc.links << {rel: REL_SEED,
|
189
|
-
type: "text/html",
|
190
|
-
href: @seed_url}
|
194
|
+
doc.links << {rel: REL_HCARD, type: "text/html", href: @hcard_url}
|
195
|
+
doc.links << {rel: REL_SEED, type: "text/html", href: @seed_url}
|
191
196
|
|
192
197
|
# TODO: remove me! ##############
|
193
|
-
doc.links << {rel:
|
194
|
-
type: "text/html",
|
195
|
-
href: @guid}
|
198
|
+
doc.links << {rel: REL_GUID, type: "text/html", href: @guid}
|
196
199
|
##################################
|
197
200
|
|
198
|
-
doc.links << {rel:
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
href: @atom_url}
|
204
|
-
doc.links << {rel: REL_SALMON,
|
205
|
-
href: @salmon_url}
|
201
|
+
doc.links << {rel: REL_PROFILE, type: "text/html", href: @profile_url}
|
202
|
+
doc.links << {rel: REL_ATOM, type: "application/atom+xml", href: @atom_url}
|
203
|
+
doc.links << {rel: REL_SALMON, href: @salmon_url}
|
204
|
+
|
205
|
+
doc.links << {rel: REL_SUBSCRIBE, template: @subscribe_url}
|
206
206
|
|
207
207
|
# TODO: remove me! ##############
|
208
208
|
doc.links << {rel: REL_PUBKEY,
|
@@ -211,12 +211,23 @@ module DiasporaFederation
|
|
211
211
|
##################################
|
212
212
|
end
|
213
213
|
|
214
|
+
def self.find_link(links, rel)
|
215
|
+
links.find {|l| l[:rel] == rel }
|
216
|
+
end
|
217
|
+
private_class_method :find_link
|
218
|
+
|
214
219
|
def self.parse_link(links, rel)
|
215
|
-
element = links
|
220
|
+
element = find_link(links, rel)
|
216
221
|
element ? element[:href] : nil
|
217
222
|
end
|
218
223
|
private_class_method :parse_link
|
219
224
|
|
225
|
+
def self.parse_link_template(links, rel)
|
226
|
+
element = find_link(links, rel)
|
227
|
+
element ? element[:template] : nil
|
228
|
+
end
|
229
|
+
private_class_method :parse_link_template
|
230
|
+
|
220
231
|
# this method is used to parse the alias_url from the XML.
|
221
232
|
# * redmatrix has sometimes no alias, return nil
|
222
233
|
# * old pods had quotes around the alias url, this can be removed later
|
@@ -31,6 +31,10 @@ module DiasporaFederation
|
|
31
31
|
property :parent_guid
|
32
32
|
property :parent_author_signature, default: nil
|
33
33
|
property :author_signature, default: nil
|
34
|
+
|
35
|
+
def self.get_target_entity_type(data)
|
36
|
+
data[:target_type] || "Post"
|
37
|
+
end
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
@@ -40,7 +44,7 @@ module DiasporaFederation
|
|
40
44
|
def to_xml
|
41
45
|
entity_xml.tap do |xml|
|
42
46
|
hash = to_h
|
43
|
-
Relayable.update_signatures!(hash)
|
47
|
+
Relayable.update_signatures!(hash, self.class)
|
44
48
|
|
45
49
|
xml.at_xpath("author_signature").content = hash[:author_signature]
|
46
50
|
xml.at_xpath("parent_author_signature").content = hash[:parent_author_signature]
|
@@ -54,21 +58,29 @@ module DiasporaFederation
|
|
54
58
|
# verifies the signatures (+author_signature+ and +parent_author_signature+ if needed)
|
55
59
|
# @param [Hash] data hash with data to verify
|
56
60
|
# @raise [SignatureVerificationFailed] if the signature is not valid or no public key is found
|
57
|
-
def self.verify_signatures(data)
|
61
|
+
def self.verify_signatures(data, klass)
|
58
62
|
pkey = DiasporaFederation.callbacks.trigger(:fetch_public_key_by_diaspora_id, data[:diaspora_id])
|
59
63
|
raise SignatureVerificationFailed, "failed to fetch public key for #{data[:diaspora_id]}" if pkey.nil?
|
60
64
|
raise SignatureVerificationFailed, "wrong author_signature" unless Signing.verify_signature(
|
61
65
|
data, data[:author_signature], pkey
|
62
66
|
)
|
63
67
|
|
64
|
-
author_is_local = DiasporaFederation.callbacks.trigger(
|
65
|
-
|
68
|
+
author_is_local = DiasporaFederation.callbacks.trigger(
|
69
|
+
:entity_author_is_local?,
|
70
|
+
klass.get_target_entity_type(data),
|
71
|
+
data[:parent_guid]
|
72
|
+
)
|
73
|
+
verify_parent_signature(data, klass) unless author_is_local
|
66
74
|
end
|
67
75
|
|
68
76
|
# this happens only on downstream federation
|
69
77
|
# @param [Hash] data hash with data to verify
|
70
|
-
def self.verify_parent_signature(data)
|
71
|
-
pkey = DiasporaFederation.callbacks.trigger(
|
78
|
+
def self.verify_parent_signature(data, klass)
|
79
|
+
pkey = DiasporaFederation.callbacks.trigger(
|
80
|
+
:fetch_author_public_key_by_entity_guid,
|
81
|
+
klass.get_target_entity_type(data),
|
82
|
+
data[:parent_guid]
|
83
|
+
)
|
72
84
|
raise SignatureVerificationFailed,
|
73
85
|
"failed to fetch public key for author of #{data[:parent_guid]}" if pkey.nil?
|
74
86
|
raise SignatureVerificationFailed, "wrong parent_author_signature" unless Signing.verify_signature(
|
@@ -81,7 +93,7 @@ module DiasporaFederation
|
|
81
93
|
# if the signatures are not in the hash yet and if the keys are available.
|
82
94
|
#
|
83
95
|
# @param [Hash] data hash given for a signing
|
84
|
-
def self.update_signatures!(data)
|
96
|
+
def self.update_signatures!(data, klass)
|
85
97
|
if data[:author_signature].nil?
|
86
98
|
pkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, data[:diaspora_id])
|
87
99
|
data[:author_signature] = Signing.sign_with_key(data, pkey) unless pkey.nil?
|
@@ -90,7 +102,7 @@ module DiasporaFederation
|
|
90
102
|
if data[:parent_author_signature].nil?
|
91
103
|
pkey = DiasporaFederation.callbacks.trigger(
|
92
104
|
:fetch_author_private_key_by_entity_guid,
|
93
|
-
|
105
|
+
klass.get_target_entity_type(data),
|
94
106
|
data[:parent_guid]
|
95
107
|
)
|
96
108
|
data[:parent_author_signature] = Signing.sign_with_key(data, pkey) unless pkey.nil?
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module DiasporaFederation
|
2
|
+
# Raised if failed to fetch a public key of the sender of the received message
|
3
|
+
class SenderKeyNotFound < Exception
|
4
|
+
end
|
5
|
+
|
6
|
+
# Raised if recipient private key is missing for a private receive
|
7
|
+
class RecipientKeyNotFound < Exception
|
8
|
+
end
|
9
|
+
|
10
|
+
# Common base for Private and Public receivers
|
11
|
+
# @see Receiver::Public
|
12
|
+
# @see Receiver::Private
|
13
|
+
class Receiver
|
14
|
+
def initialize(salmon_xml)
|
15
|
+
@salmon_xml = salmon_xml
|
16
|
+
end
|
17
|
+
|
18
|
+
def receive!
|
19
|
+
sender_id = slap.author_id
|
20
|
+
public_key = DiasporaFederation.callbacks.trigger(:fetch_public_key_by_diaspora_id, sender_id)
|
21
|
+
raise SenderKeyNotFound if public_key.nil?
|
22
|
+
DiasporaFederation.callbacks.trigger(:save_entity_after_receive, slap.entity(public_key))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
require "diaspora_federation/receiver/private"
|
28
|
+
require "diaspora_federation/receiver/public"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DiasporaFederation
|
2
|
+
class Receiver
|
3
|
+
# Receiver::Private is used to receive private messages, which are addressed to a specific user, encrypted with his
|
4
|
+
# public key and packed using Salmon::EncryptedSlap
|
5
|
+
class Private < Receiver
|
6
|
+
def initialize(salmon_xml, recipient_private_key)
|
7
|
+
super(salmon_xml)
|
8
|
+
raise RecipientKeyNotFound if recipient_private_key.nil?
|
9
|
+
@recipient_private_key = recipient_private_key
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def slap
|
15
|
+
@salmon ||= Salmon::EncryptedSlap.from_xml(@salmon_xml, @recipient_private_key)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module DiasporaFederation
|
2
|
+
class Receiver
|
3
|
+
# Receiver::Public is used to receive public messages, which are not addressed to a specific user, unencrypted
|
4
|
+
# and packed using Salmon::Slap
|
5
|
+
class Public < Receiver
|
6
|
+
protected
|
7
|
+
|
8
|
+
def slap
|
9
|
+
@salmon ||= Salmon::Slap.from_xml(@salmon_xml)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -99,7 +99,9 @@ module DiasporaFederation
|
|
99
99
|
end
|
100
100
|
}]
|
101
101
|
|
102
|
-
|
102
|
+
if klass.included_modules.include?(Entities::Relayable)
|
103
|
+
Entities::Relayable.verify_signatures(data, klass)
|
104
|
+
end
|
103
105
|
|
104
106
|
klass.new(data)
|
105
107
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: diaspora_federation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Neff
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '1.6'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.6.
|
22
|
+
version: 1.6.7.1
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: '1.6'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 1.6.
|
32
|
+
version: 1.6.7.1
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: faraday
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,6 +131,9 @@ files:
|
|
131
131
|
- lib/diaspora_federation/fetcher.rb
|
132
132
|
- lib/diaspora_federation/logging.rb
|
133
133
|
- lib/diaspora_federation/properties_dsl.rb
|
134
|
+
- lib/diaspora_federation/receiver.rb
|
135
|
+
- lib/diaspora_federation/receiver/private.rb
|
136
|
+
- lib/diaspora_federation/receiver/public.rb
|
134
137
|
- lib/diaspora_federation/salmon.rb
|
135
138
|
- lib/diaspora_federation/salmon/aes.rb
|
136
139
|
- lib/diaspora_federation/salmon/encrypted_slap.rb
|