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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -32
  3. data/lib/diaspora_federation.rb +9 -31
  4. data/lib/diaspora_federation/discovery/h_card.rb +8 -15
  5. data/lib/diaspora_federation/discovery/host_meta.rb +2 -4
  6. data/lib/diaspora_federation/discovery/web_finger.rb +11 -11
  7. data/lib/diaspora_federation/discovery/xrd_document.rb +4 -8
  8. data/lib/diaspora_federation/entities.rb +2 -0
  9. data/lib/diaspora_federation/entities/account_deletion.rb +5 -0
  10. data/lib/diaspora_federation/entities/comment.rb +3 -6
  11. data/lib/diaspora_federation/entities/contact.rb +5 -0
  12. data/lib/diaspora_federation/entities/conversation.rb +10 -1
  13. data/lib/diaspora_federation/entities/message.rb +29 -4
  14. data/lib/diaspora_federation/entities/participation.rb +24 -0
  15. data/lib/diaspora_federation/entities/poll_participation.rb +3 -6
  16. data/lib/diaspora_federation/entities/profile.rb +5 -0
  17. data/lib/diaspora_federation/entities/related_entity.rb +33 -0
  18. data/lib/diaspora_federation/entities/relayable.rb +55 -40
  19. data/lib/diaspora_federation/entities/relayable_retraction.rb +21 -12
  20. data/lib/diaspora_federation/entities/request.rb +6 -2
  21. data/lib/diaspora_federation/entities/reshare.rb +5 -0
  22. data/lib/diaspora_federation/entities/retraction.rb +37 -0
  23. data/lib/diaspora_federation/entities/signed_retraction.rb +16 -5
  24. data/lib/diaspora_federation/entities/status_message.rb +11 -0
  25. data/lib/diaspora_federation/entity.rb +73 -30
  26. data/lib/diaspora_federation/federation/fetcher.rb +11 -1
  27. data/lib/diaspora_federation/federation/receiver.rb +10 -0
  28. data/lib/diaspora_federation/federation/receiver/abstract_receiver.rb +18 -4
  29. data/lib/diaspora_federation/federation/receiver/exceptions.rb +4 -0
  30. data/lib/diaspora_federation/federation/receiver/public.rb +10 -0
  31. data/lib/diaspora_federation/federation/sender.rb +1 -1
  32. data/lib/diaspora_federation/http_client.rb +1 -2
  33. data/lib/diaspora_federation/logging.rb +6 -0
  34. data/lib/diaspora_federation/properties_dsl.rb +4 -2
  35. data/lib/diaspora_federation/salmon/encrypted_magic_envelope.rb +2 -2
  36. data/lib/diaspora_federation/salmon/encrypted_slap.rb +3 -5
  37. data/lib/diaspora_federation/salmon/exceptions.rb +1 -1
  38. data/lib/diaspora_federation/salmon/magic_envelope.rb +16 -17
  39. data/lib/diaspora_federation/salmon/slap.rb +1 -2
  40. data/lib/diaspora_federation/salmon/xml_payload.rb +1 -2
  41. data/lib/diaspora_federation/validators.rb +2 -0
  42. data/lib/diaspora_federation/validators/conversation_validator.rb +2 -0
  43. data/lib/diaspora_federation/validators/message_validator.rb +2 -2
  44. data/lib/diaspora_federation/validators/participation_validator.rb +3 -2
  45. data/lib/diaspora_federation/validators/poll_validator.rb +1 -0
  46. data/lib/diaspora_federation/validators/related_entity_validator.rb +12 -0
  47. data/lib/diaspora_federation/validators/relayable_retraction_validator.rb +1 -1
  48. data/lib/diaspora_federation/validators/relayable_validator.rb +1 -0
  49. data/lib/diaspora_federation/validators/retraction_validator.rb +1 -1
  50. data/lib/diaspora_federation/validators/rules/diaspora_id.rb +8 -11
  51. data/lib/diaspora_federation/validators/rules/diaspora_id_count.rb +1 -1
  52. data/lib/diaspora_federation/validators/signed_retraction_validator.rb +1 -1
  53. data/lib/diaspora_federation/validators/status_message_validator.rb +2 -0
  54. data/lib/diaspora_federation/validators/web_finger_validator.rb +2 -2
  55. data/lib/diaspora_federation/version.rb +1 -1
  56. metadata +9 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1eab26d24aadd05dde520265d1fc2cae76cb71bb
4
- data.tar.gz: 0454bedd0f5cef501c7a99d04a1e67db3f13db9e
3
+ metadata.gz: f071a159d911e2981ecdd64fb43a6b35818517f5
4
+ data.tar.gz: 4b134feae0ef5815171db1bfda9535f50f83307b
5
5
  SHA512:
6
- metadata.gz: 6ed6351f1780275bfa7856e288ca6f23b202e8b34f54dae9d109ced23b8bb6c4815dfb1df171a29b0974737551b04694ff05750138ac5cbfe9a2866733da8d0c
7
- data.tar.gz: 9fa0cb00be0cce4ee0c5aa1ffca7e33decb7e3f9afd9fc2019e898432f6dc57adf30ee5ab600256145756dc2395738eb607fc54970cd8728c5ad03a941af3ff0
6
+ metadata.gz: 8b721717d3f9e6464adaeb94f4c590633cab55b5877219048ea0ee21a0bee8112297e268a5d29f1557af145e35becce6a71696a13e8d30f6b7324a1cedf5867d
7
+ data.tar.gz: 42b735837e07a028b3317045e82d1971fe786dfbb80df597ada691070800899935da49d349d80667624d13d78024bc73ca8f781b7d17fb177e61568ff1306058
data/README.md CHANGED
@@ -1,29 +1,24 @@
1
1
  # diaspora* federation library
2
+ ### A library that provides functionalities needed for the diaspora\* federation protocol
2
3
 
3
- **A library that provides functionalities needed for the diaspora* federation protocol**
4
+ **master:** [![Build Status master](https://travis-ci.org/diaspora/diaspora_federation.svg?branch=master)](https://travis-ci.org/diaspora/diaspora_federation) |
5
+ **develop:** [![Build Status develop](https://travis-ci.org/diaspora/diaspora_federation.svg?branch=develop)](https://travis-ci.org/diaspora/diaspora_federation)
4
6
 
5
- **master:** [![Build Status master](https://travis-ci.org/SuperTux88/diaspora_federation.svg?branch=master)](https://travis-ci.org/SuperTux88/diaspora_federation)
6
- **develop:** [![Build Status develop](https://travis-ci.org/SuperTux88/diaspora_federation.svg?branch=develop)](https://travis-ci.org/SuperTux88/diaspora_federation)
7
-
8
- [![Code Climate](https://codeclimate.com/github/SuperTux88/diaspora_federation/badges/gpa.svg)](https://codeclimate.com/github/SuperTux88/diaspora_federation)
9
- [![Test Coverage](https://codeclimate.com/github/SuperTux88/diaspora_federation/badges/coverage.svg)](https://codeclimate.com/github/SuperTux88/diaspora_federation/coverage)
10
- [![Dependency Status](https://gemnasium.com/SuperTux88/diaspora_federation.svg)](https://gemnasium.com/SuperTux88/diaspora_federation)
11
- [![Inline docs](https://inch-ci.org/github/SuperTux88/diaspora_federation.svg?branch=master)](https://inch-ci.org/github/SuperTux88/diaspora_federation)
7
+ [![Code Climate](https://codeclimate.com/github/diaspora/diaspora_federation/badges/gpa.svg)](https://codeclimate.com/github/diaspora/diaspora_federation)
8
+ [![Test Coverage](https://codeclimate.com/github/diaspora/diaspora_federation/badges/coverage.svg)](https://codeclimate.com/github/diaspora/diaspora_federation/coverage)
9
+ [![Dependency Status](https://gemnasium.com/diaspora/diaspora_federation.svg)](https://gemnasium.com/diaspora/diaspora_federation)
10
+ [![Inline docs](https://inch-ci.org/github/diaspora/diaspora_federation.svg?branch=master)](https://inch-ci.org/github/diaspora/diaspora_federation)
12
11
  [![Gem Version](https://badge.fury.io/rb/diaspora_federation.svg)](https://badge.fury.io/rb/diaspora_federation)
13
12
 
14
13
  [Documentation](http://www.rubydoc.info/gems/diaspora_federation/) |
15
- [Bugtracker](https://github.com/SuperTux88/diaspora_federation/issues)
16
-
17
- ## Library
14
+ [Bugtracker](https://github.com/diaspora/diaspora_federation/issues)
18
15
 
19
- The ```diaspora_federation``` gem provides the functionality for de-/serialization and de-/encryption of Entities
20
- in the protocols used for communication among the various installations of Diaspora*
16
+ This repository contains two gems:
21
17
 
22
- ## Rails Engine
18
+ * `diaspora_federation` provides the functionality for de-/serialization and de-/encryption of Entities in the protocols used for communication among the various installations of diaspora\*.
19
+ * `diaspora_federation-rails` is a rails engine that adds the diaspora\* federation protocol to a rails app.
23
20
 
24
- The ```diaspora_federation-rails``` gem is a rails engine that adds the diaspora* federation protocol to a rails app.
25
-
26
- ### Usage
21
+ ## Usage
27
22
 
28
23
  Add the gem to your ```Gemfile```:
29
24
 
@@ -61,22 +56,10 @@ DiasporaFederation.configure do |config|
61
56
  end
62
57
  ```
63
58
 
64
- ## Development
65
-
66
- **!!! This gem is currently under heavy development, so every release can contain breaking changes !!!**
67
-
68
- If you want to help, please contact me, help is welcome.
69
-
70
- After the first stable release, this repo will be moved to the [diaspora organization](https://github.com/diaspora/).
71
-
72
- ## Diaspora
73
-
74
- A privacy-aware, distributed, open source social network
59
+ ## Contributing
75
60
 
76
- Links:
77
- [Project site](https://diasporafoundation.org) |
78
- [Wiki](https://wiki.diasporafoundation.org)
61
+ See [our contribution guide](/CONTRIBUTING.md) for more information on how to contribute to the diaspora\* federation library.
79
62
 
80
63
  ## License
81
64
 
82
- This gem is published under the terms of the "GNU Affero General Public License". See the LICENSE file for the exact wording.
65
+ [GNU Affero General Public License](/LICENSE).
@@ -23,12 +23,9 @@ module DiasporaFederation
23
23
  fetch_person_for_webfinger
24
24
  fetch_person_for_hcard
25
25
  save_person_after_webfinger
26
- fetch_private_key_by_diaspora_id
27
- fetch_author_private_key_by_entity_guid
28
- fetch_public_key_by_diaspora_id
29
- fetch_author_public_key_by_entity_guid
30
- entity_author_is_local?
31
- fetch_entity_author_id_by_guid
26
+ fetch_private_key
27
+ fetch_public_key
28
+ fetch_related_entity
32
29
  queue_public_receive
33
30
  queue_private_receive
34
31
  receive_entity
@@ -146,40 +143,21 @@ module DiasporaFederation
146
143
  # so the application saves the person data
147
144
  # @param [DiasporaFederation::Entities::Person] person data
148
145
  #
149
- # fetch_private_key_by_diaspora_id
146
+ # fetch_private_key
150
147
  # Fetches a private key of a person by her Diaspora ID from the application
151
148
  # @param [String] Diaspora ID of the person
152
149
  # @return [OpenSSL::PKey::RSA] key
153
150
  #
154
- # fetch_author_private_key_by_entity_guid
155
- # Fetches a private key of the person who authored an entity identified by a given guid
156
- # @param [String] entity_type (Post, Comment, Like, etc)
157
- # @param [String] guid of the entity
158
- # @return [OpenSSL::PKey::RSA] key
159
- #
160
- # fetch_public_key_by_diaspora_id
151
+ # fetch_public_key
161
152
  # Fetches a public key of a person by her Diaspora ID from the application
162
153
  # @param [String] Diaspora ID of the person
163
154
  # @return [OpenSSL::PKey::RSA] key
164
155
  #
165
- # fetch_author_public_key_by_entity_guid
166
- # Fetches a public key of the person who authored an entity identified by a given guid
167
- # @param [String] entity_type (Post, Comment, Like, etc)
168
- # @param [String] guid of the entity
169
- # @return [OpenSSL::PKey::RSA] key
170
- #
171
- # entity_author_is_local?
172
- # Reports if the author of the entity identified by a given guid is local on the pod
173
- # where we operate.
174
- # @param [String] entity_type (Post, Comment, Like, etc)
175
- # @param [String] guid of the entity
176
- # @return [Boolean]
177
- #
178
- # fetch_entity_author_id_by_guid
179
- # Fetches Diaspora ID of the person who authored the entity identified by a given guid
156
+ # fetch_related_entity
157
+ # Fetches a related entity by a given guid
180
158
  # @param [String] entity_type (Post, Comment, Like, etc)
181
159
  # @param [String] guid of the entity
182
- # @return [String] Diaspora ID of the person
160
+ # @return [DiasporaFederation::Entities::RelatedEntity] related entity
183
161
  #
184
162
  # queue_public_receive
185
163
  # Queue a public salmon xml to process in background
@@ -267,7 +245,7 @@ module DiasporaFederation
267
245
  end
268
246
  end
269
247
 
270
- # raised, if the engine is not configured correctly
248
+ # Raised, if the engine is not configured correctly
271
249
  class ConfigurationError < RuntimeError
272
250
  end
273
251
  end
@@ -60,7 +60,7 @@ module DiasporaFederation
60
60
  # installations).
61
61
  #
62
62
  # @return [String] link to the pod
63
- property :url
63
+ property :url, default: nil
64
64
 
65
65
  # @!attribute [r] public_key
66
66
  # When a user is created on the pod, the pod MUST generate a pgp keypair
@@ -163,7 +163,6 @@ module DiasporaFederation
163
163
  guid: guid_from_doc(doc),
164
164
  nickname: content_from_doc(doc, :nickname),
165
165
  full_name: content_from_doc(doc, :fn),
166
- url: element_from_doc(doc, :url)["href"],
167
166
  photo_large_url: photo_from_doc(doc, :photo),
168
167
  photo_medium_url: photo_from_doc(doc, :photo_medium),
169
168
  photo_small_url: photo_from_doc(doc, :photo_small),
@@ -253,43 +252,37 @@ module DiasporaFederation
253
252
  # HTML document.
254
253
  # @param [LibXML::XML::Document] doc HTML document
255
254
  # @return [Boolean] validation result
256
- def self.html_document_complete?(doc)
255
+ private_class_method def self.html_document_complete?(doc)
257
256
  !(doc.at_css(SELECTORS[:fn]).nil? || doc.at_css(SELECTORS[:nickname]).nil? ||
258
- doc.at_css(SELECTORS[:url]).nil? || doc.at_css(SELECTORS[:photo]).nil?)
257
+ doc.at_css(SELECTORS[:photo]).nil?)
259
258
  end
260
- private_class_method :html_document_complete?
261
259
 
262
- def self.parse_html_and_validate(html_string)
260
+ private_class_method def self.parse_html_and_validate(html_string)
263
261
  raise ArgumentError, "hcard html is not a string" unless html_string.instance_of?(String)
264
262
 
265
263
  doc = Nokogiri::HTML::Document.parse(html_string)
266
264
  raise InvalidData, "hcard html incomplete" unless html_document_complete?(doc)
267
265
  doc
268
266
  end
269
- private_class_method :parse_html_and_validate
270
267
 
271
- def self.element_from_doc(doc, selector)
268
+ private_class_method def self.element_from_doc(doc, selector)
272
269
  doc.at_css(SELECTORS[selector])
273
270
  end
274
- private_class_method :element_from_doc
275
271
 
276
- def self.content_from_doc(doc, content_selector)
272
+ private_class_method def self.content_from_doc(doc, content_selector)
277
273
  element_from_doc(doc, content_selector).content
278
274
  end
279
- private_class_method :content_from_doc
280
275
 
281
- def self.photo_from_doc(doc, photo_selector)
276
+ private_class_method def self.photo_from_doc(doc, photo_selector)
282
277
  element_from_doc(doc, photo_selector)["src"]
283
278
  end
284
- private_class_method :photo_from_doc
285
279
 
286
280
  # @deprecated hack for old hcard
287
281
  # @todo remove this when all pods have the new generator
288
- def self.guid_from_doc(doc)
282
+ private_class_method def self.guid_from_doc(doc)
289
283
  uid_element = element_from_doc(doc, :uid)
290
284
  uid_element.content unless uid_element[:class].include? "nickname"
291
285
  end
292
- private_class_method :guid_from_doc
293
286
  end
294
287
  end
295
288
  end
@@ -75,19 +75,17 @@ module DiasporaFederation
75
75
  # Applies some basic sanity-checking to the given URL
76
76
  # @param [String] url validation subject
77
77
  # @return [Boolean] validation result
78
- def self.webfinger_url_valid?(url)
78
+ private_class_method def self.webfinger_url_valid?(url)
79
79
  !url.nil? && url.instance_of?(String) && url =~ %r{^https?:\/\/.*\/.*\{uri\}.*}i
80
80
  end
81
- private_class_method :webfinger_url_valid?
82
81
 
83
82
  # Gets the webfinger url from an XRD data structure
84
83
  # @param [Hash] data extracted data
85
84
  # @return [String] webfinger url
86
- def self.webfinger_url_from_xrd(data)
85
+ private_class_method def self.webfinger_url_from_xrd(data)
87
86
  link = data[:links].find {|l| l[:rel] == "lrdd" }
88
87
  return link[:template] unless link.nil?
89
88
  end
90
- private_class_method :webfinger_url_from_xrd
91
89
  end
92
90
  end
93
91
  end
@@ -71,7 +71,7 @@ module DiasporaFederation
71
71
  # @!attribute [r] salmon_url
72
72
  # @note could be nil
73
73
  # @return [String] salmon endpoint url
74
- # @see http://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-salmon-00.html#SMLR
74
+ # @see https://cdn.rawgit.com/salmon-protocol/salmon-protocol/master/draft-panzer-salmon-00.html#SMLR
75
75
  # Panzer draft for Salmon, paragraph 3.3
76
76
  property :salmon_url
77
77
 
@@ -175,6 +175,11 @@ module DiasporaFederation
175
175
  )
176
176
  end
177
177
 
178
+ # @return [String] string representation of this object
179
+ def to_s
180
+ "WebFinger:#{acct_uri}"
181
+ end
182
+
178
183
  private
179
184
 
180
185
  # Parses the XML string to a Hash and does some rudimentary checking on
@@ -182,13 +187,12 @@ module DiasporaFederation
182
187
  # @param [String] webfinger_xml WebFinger XML string
183
188
  # @return [Hash] data XML data
184
189
  # @raise [InvalidData] if the given XML string is invalid or incomplete
185
- def self.parse_xml_and_validate(webfinger_xml)
190
+ private_class_method def self.parse_xml_and_validate(webfinger_xml)
186
191
  XrdDocument.xml_data(webfinger_xml).tap do |data|
187
192
  valid = data.key?(:subject) && data.key?(:links)
188
193
  raise InvalidData, "webfinger xml is incomplete" unless valid
189
194
  end
190
195
  end
191
- private_class_method :parse_xml_and_validate
192
196
 
193
197
  def add_links_to(doc)
194
198
  doc.links << {rel: REL_HCARD, type: "text/html", href: @hcard_url}
@@ -211,33 +215,29 @@ module DiasporaFederation
211
215
  ##################################
212
216
  end
213
217
 
214
- def self.find_link(links, rel)
218
+ private_class_method def self.find_link(links, rel)
215
219
  links.find {|l| l[:rel] == rel }
216
220
  end
217
- private_class_method :find_link
218
221
 
219
- def self.parse_link(links, rel)
222
+ private_class_method def self.parse_link(links, rel)
220
223
  element = find_link(links, rel)
221
224
  element ? element[:href] : nil
222
225
  end
223
- private_class_method :parse_link
224
226
 
225
- def self.parse_link_template(links, rel)
227
+ private_class_method def self.parse_link_template(links, rel)
226
228
  element = find_link(links, rel)
227
229
  element ? element[:template] : nil
228
230
  end
229
- private_class_method :parse_link_template
230
231
 
231
232
  # this method is used to parse the alias_url from the XML.
232
233
  # * redmatrix has sometimes no alias, return nil
233
234
  # * old pods had quotes around the alias url, this can be removed later
234
235
  # * friendica has two aliases and the first is with "acct:": return only an URL starting with http (or https)
235
- def self.parse_alias(aliases)
236
+ private_class_method def self.parse_alias(aliases)
236
237
  return nil unless aliases
237
238
  # TODO: Old pods had quotes around alias. Remove the +map+ in next line, when all pods use this gem
238
239
  aliases.map {|a| a.gsub(/\A"|"\Z/, "") }.find {|a| a.start_with?("http") }
239
240
  end
240
- private_class_method :parse_alias
241
241
  end
242
242
  end
243
243
  end
@@ -132,34 +132,31 @@ module DiasporaFederation
132
132
  end
133
133
  end
134
134
 
135
- def self.parse_xrd_document(xrd_doc)
135
+ private_class_method def self.parse_xrd_document(xrd_doc)
136
136
  raise ArgumentError unless xrd_doc.instance_of?(String)
137
137
 
138
138
  doc = Nokogiri::XML::Document.parse(xrd_doc)
139
139
  raise InvalidDocument, "Not an XRD document" if !doc.root || doc.root.name != "XRD"
140
140
  doc
141
141
  end
142
- private_class_method :parse_xrd_document
143
142
 
144
- def self.parse_aliases_from_xml_doc(doc, data)
143
+ private_class_method def self.parse_aliases_from_xml_doc(doc, data)
145
144
  aliases = []
146
145
  doc.xpath("xrd:XRD/xrd:Alias", NS).each do |node|
147
146
  aliases << node.content
148
147
  end
149
148
  data[:aliases] = aliases unless aliases.empty?
150
149
  end
151
- private_class_method :parse_aliases_from_xml_doc
152
150
 
153
- def self.parse_properties_from_xml_doc(doc, data)
151
+ private_class_method def self.parse_properties_from_xml_doc(doc, data)
154
152
  properties = {}
155
153
  doc.xpath("xrd:XRD/xrd:Property", NS).each do |node|
156
154
  properties[node[:type]] = node.children.empty? ? nil : node.content
157
155
  end
158
156
  data[:properties] = properties unless properties.empty?
159
157
  end
160
- private_class_method :parse_properties_from_xml_doc
161
158
 
162
- def self.parse_links_from_xml_doc(doc, data)
159
+ private_class_method def self.parse_links_from_xml_doc(doc, data)
163
160
  links = []
164
161
  doc.xpath("xrd:XRD/xrd:Link", NS).each do |node|
165
162
  link = {}
@@ -170,7 +167,6 @@ module DiasporaFederation
170
167
  end
171
168
  data[:links] = links unless links.empty?
172
169
  end
173
- private_class_method :parse_links_from_xml_doc
174
170
  end
175
171
  end
176
172
  end
@@ -8,6 +8,8 @@ module DiasporaFederation
8
8
  end
9
9
  end
10
10
 
11
+ require "diaspora_federation/entities/related_entity"
12
+
11
13
  # abstract types
12
14
  require "diaspora_federation/entities/post"
13
15
  require "diaspora_federation/entities/relayable"
@@ -13,6 +13,11 @@ module DiasporaFederation
13
13
  # @see AccountDeletion#author
14
14
  # @return [String] diaspora ID
15
15
  property :author, alias: :diaspora_id, xml_name: :diaspora_handle
16
+
17
+ # @return [String] string representation of this object
18
+ def to_s
19
+ "AccountDeletion:#{author}"
20
+ end
16
21
  end
17
22
  end
18
23
  end
@@ -8,6 +8,9 @@ module DiasporaFederation
8
8
  # @deprecated
9
9
  LEGACY_SIGNATURE_ORDER = %i(guid parent_guid text author).freeze
10
10
 
11
+ # The {Comment} parent is a {Post}
12
+ PARENT_TYPE = "Post".freeze
13
+
11
14
  include Relayable
12
15
 
13
16
  # @!attribute [r] text
@@ -18,12 +21,6 @@ module DiasporaFederation
18
21
  # comment entity creation time
19
22
  # @return [Time] creation time
20
23
  property :created_at, default: -> { Time.now.utc }
21
-
22
- # The {Comment} parent is a Post
23
- # @return [String] parent type
24
- def parent_type
25
- "Post"
26
- end
27
24
  end
28
25
  end
29
26
  end
@@ -24,6 +24,11 @@ module DiasporaFederation
24
24
  # @!attribute [r] sharing
25
25
  # @return [Boolean] if the author is sharing with the person
26
26
  property :sharing, default: true
27
+
28
+ # @return [String] string representation of this object
29
+ def to_s
30
+ "Contact:#{author}:#{recipient}"
31
+ end
27
32
  end
28
33
  end
29
34
  end
@@ -20,7 +20,7 @@ module DiasporaFederation
20
20
 
21
21
  # @!attribute [r] messages
22
22
  # @return [[Entities::Message]] Messages of this conversation
23
- entity :messages, [Entities::Message]
23
+ entity :messages, [Entities::Message], default: []
24
24
 
25
25
  # @!attribute [r] author
26
26
  # The diaspora ID of the person initiated the conversation.
@@ -32,6 +32,15 @@ module DiasporaFederation
32
32
  # The diaspora IDs of the persons participating the conversation separated by ";".
33
33
  # @return [String] participants diaspora IDs
34
34
  property :participants, xml_name: :participant_handles
35
+
36
+ private
37
+
38
+ def validate
39
+ super
40
+ messages.each do |message|
41
+ raise ValidationError, "nested #{message} has different author: author=#{author}" if message.author != author
42
+ end
43
+ end
35
44
  end
36
45
  end
37
46
  end