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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f1cc502235f056676364d5b56b814650f284c8e5
4
- data.tar.gz: 2b031425ffe4b1b5d83ac789ee674dc0f31f423a
3
+ metadata.gz: 704840223f25af1abc3fa00ed7d0cc931d45665e
4
+ data.tar.gz: cf78859d34900183ca8c5ee07ab7a24357239369
5
5
  SHA512:
6
- metadata.gz: 0f4691907170170b696306f6c65cfc2855e9b95b166850f1c72c5f96fdbe6657c0cf31cb6b8ab3cf55369da424103388d0e24be445e34cf61daaa1b2ad1a187a
7
- data.tar.gz: 12e1dde41d27bd0ee229a2befd99a6d6329bd7aca49f822e3d29c0a79e6135892238672321cdf1ad64813b78e441552fc318733729415f32c1f0983b42c4a4b8
6
+ metadata.gz: 632e343a34a267c990681ce3f34ab39cdf47f8807cb7f3ec56fd98b49e9bb801f9dd0b9c8c018f0e8bc86356ddb37a320858a2741be19bb79e6498cab1627cda
7
+ data.tar.gz: 4c7c62f615b3caeae02bde51718136c5be9696cdd768257db25d563bb7c9323a01081d778fc87f262ff90adbc31c06c64a364bb95172a66c273229c284058d08
@@ -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: data[:subject],
156
- alias_url: parse_alias(data[:aliases]),
157
- hcard_url: parse_link(links, REL_HCARD),
158
- seed_url: parse_link(links, REL_SEED),
159
- profile_url: parse_link(links, REL_PROFILE),
160
- atom_url: parse_link(links, REL_ATOM),
161
- salmon_url: parse_link(links, REL_SALMON),
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: parse_link(links, REL_GUID),
165
- public_key: (Base64.strict_decode64(public_key) if 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: REL_HCARD,
186
- type: "text/html",
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: REL_GUID,
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: REL_PROFILE,
199
- type: "text/html",
200
- href: @profile_url}
201
- doc.links << {rel: REL_ATOM,
202
- type: "application/atom+xml",
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.find {|l| l[:rel] == rel }
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
@@ -33,6 +33,10 @@ module DiasporaFederation
33
33
  # @see Conversation#guid
34
34
  # @return [String] conversation guid
35
35
  property :conversation_guid
36
+
37
+ def self.get_target_entity_type(*)
38
+ "Conversation"
39
+ end
36
40
  end
37
41
  end
38
42
  end
@@ -23,6 +23,10 @@ module DiasporaFederation
23
23
  # @see PollAnswer#guid
24
24
  # @return [String] poll answer guid
25
25
  property :poll_answer_guid
26
+
27
+ def self.get_target_entity_type(*)
28
+ "Poll"
29
+ end
26
30
  end
27
31
  end
28
32
  end
@@ -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(:entity_author_is_local?, "Post", data[:parent_guid])
65
- verify_parent_signature(data) unless author_is_local
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(:fetch_author_public_key_by_entity_guid, "Post", data[:parent_guid])
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
- "Post",
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
@@ -1,3 +1,5 @@
1
+ require "json"
2
+
1
3
  module DiasporaFederation
2
4
  module Salmon
3
5
  # +EncryptedSlap+ provides class methods for generating and parsing encrypted
@@ -99,7 +99,9 @@ module DiasporaFederation
99
99
  end
100
100
  }]
101
101
 
102
- Entities::Relayable.verify_signatures(data) if klass.included_modules.include?(Entities::Relayable)
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
@@ -1,4 +1,4 @@
1
1
  module DiasporaFederation
2
2
  # the gem version
3
- VERSION = "0.0.9"
3
+ VERSION = "0.0.10"
4
4
  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.9
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-13 00:00:00.000000000 Z
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.6.4
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.6.4
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