diaspora_federation 0.0.13 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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