diaspora_federation 0.2.8 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +14 -2
  3. data/lib/diaspora_federation/callbacks.rb +2 -0
  4. data/lib/diaspora_federation/discovery/discovery.rb +11 -20
  5. data/lib/diaspora_federation/discovery/exceptions.rb +2 -0
  6. data/lib/diaspora_federation/discovery/h_card.rb +3 -12
  7. data/lib/diaspora_federation/discovery/web_finger.rb +33 -36
  8. data/lib/diaspora_federation/discovery/xrd_document.rb +15 -13
  9. data/lib/diaspora_federation/discovery.rb +2 -1
  10. data/lib/diaspora_federation/entities/account_deletion.rb +3 -1
  11. data/lib/diaspora_federation/entities/account_migration/signable.rb +2 -0
  12. data/lib/diaspora_federation/entities/account_migration.rb +5 -1
  13. data/lib/diaspora_federation/entities/comment.rb +3 -1
  14. data/lib/diaspora_federation/entities/contact.rb +2 -0
  15. data/lib/diaspora_federation/entities/conversation.rb +4 -2
  16. data/lib/diaspora_federation/entities/embed.rb +2 -0
  17. data/lib/diaspora_federation/entities/event.rb +2 -0
  18. data/lib/diaspora_federation/entities/event_participation.rb +3 -1
  19. data/lib/diaspora_federation/entities/like.rb +3 -1
  20. data/lib/diaspora_federation/entities/location.rb +2 -0
  21. data/lib/diaspora_federation/entities/message.rb +3 -1
  22. data/lib/diaspora_federation/entities/participation.rb +5 -3
  23. data/lib/diaspora_federation/entities/person.rb +3 -1
  24. data/lib/diaspora_federation/entities/photo.rb +3 -1
  25. data/lib/diaspora_federation/entities/poll.rb +2 -0
  26. data/lib/diaspora_federation/entities/poll_answer.rb +2 -0
  27. data/lib/diaspora_federation/entities/poll_participation.rb +3 -1
  28. data/lib/diaspora_federation/entities/post.rb +3 -1
  29. data/lib/diaspora_federation/entities/profile.rb +3 -1
  30. data/lib/diaspora_federation/entities/related_entity.rb +3 -1
  31. data/lib/diaspora_federation/entities/relayable.rb +17 -30
  32. data/lib/diaspora_federation/entities/reshare.rb +4 -2
  33. data/lib/diaspora_federation/entities/retraction.rb +6 -4
  34. data/lib/diaspora_federation/entities/signable.rb +3 -1
  35. data/lib/diaspora_federation/entities/status_message.rb +3 -1
  36. data/lib/diaspora_federation/entities.rb +2 -5
  37. data/lib/diaspora_federation/entity.rb +12 -8
  38. data/lib/diaspora_federation/federation/diaspora_url_parser.rb +4 -1
  39. data/lib/diaspora_federation/federation/fetcher.rb +3 -0
  40. data/lib/diaspora_federation/federation/receiver/abstract_receiver.rb +2 -0
  41. data/lib/diaspora_federation/federation/receiver/exceptions.rb +2 -0
  42. data/lib/diaspora_federation/federation/receiver/private.rb +3 -0
  43. data/lib/diaspora_federation/federation/receiver/public.rb +2 -0
  44. data/lib/diaspora_federation/federation/receiver.rb +9 -16
  45. data/lib/diaspora_federation/federation/sender/hydra_wrapper.rb +2 -0
  46. data/lib/diaspora_federation/federation/sender.rb +2 -0
  47. data/lib/diaspora_federation/federation.rb +2 -0
  48. data/lib/diaspora_federation/http_client.rb +4 -2
  49. data/lib/diaspora_federation/logging.rb +8 -6
  50. data/lib/diaspora_federation/parsers/base_parser.rb +4 -0
  51. data/lib/diaspora_federation/parsers/json_parser.rb +6 -1
  52. data/lib/diaspora_federation/parsers/relayable_json_parser.rb +3 -0
  53. data/lib/diaspora_federation/parsers/relayable_xml_parser.rb +2 -0
  54. data/lib/diaspora_federation/parsers/xml_parser.rb +18 -6
  55. data/lib/diaspora_federation/parsers.rb +2 -0
  56. data/lib/diaspora_federation/properties_dsl.rb +6 -39
  57. data/lib/diaspora_federation/salmon/aes.rb +5 -3
  58. data/lib/diaspora_federation/salmon/encrypted_magic_envelope.rb +4 -2
  59. data/lib/diaspora_federation/salmon/exceptions.rb +2 -20
  60. data/lib/diaspora_federation/salmon/magic_envelope.rb +13 -10
  61. data/lib/diaspora_federation/salmon.rb +3 -4
  62. data/lib/diaspora_federation/validators/account_deletion_validator.rb +2 -0
  63. data/lib/diaspora_federation/validators/account_migration_validator.rb +2 -0
  64. data/lib/diaspora_federation/validators/comment_validator.rb +2 -0
  65. data/lib/diaspora_federation/validators/contact_validator.rb +2 -0
  66. data/lib/diaspora_federation/validators/conversation_validator.rb +2 -0
  67. data/lib/diaspora_federation/validators/embed_validator.rb +2 -0
  68. data/lib/diaspora_federation/validators/event_participation_validator.rb +2 -0
  69. data/lib/diaspora_federation/validators/event_validator.rb +2 -0
  70. data/lib/diaspora_federation/validators/h_card_validator.rb +2 -0
  71. data/lib/diaspora_federation/validators/like_validator.rb +2 -0
  72. data/lib/diaspora_federation/validators/location_validator.rb +2 -0
  73. data/lib/diaspora_federation/validators/message_validator.rb +2 -0
  74. data/lib/diaspora_federation/validators/optional_aware_validator.rb +3 -0
  75. data/lib/diaspora_federation/validators/participation_validator.rb +2 -0
  76. data/lib/diaspora_federation/validators/person_validator.rb +2 -0
  77. data/lib/diaspora_federation/validators/photo_validator.rb +2 -0
  78. data/lib/diaspora_federation/validators/poll_answer_validator.rb +2 -0
  79. data/lib/diaspora_federation/validators/poll_participation_validator.rb +2 -0
  80. data/lib/diaspora_federation/validators/poll_validator.rb +2 -0
  81. data/lib/diaspora_federation/validators/profile_validator.rb +2 -0
  82. data/lib/diaspora_federation/validators/related_entity_validator.rb +2 -0
  83. data/lib/diaspora_federation/validators/relayable_validator.rb +2 -0
  84. data/lib/diaspora_federation/validators/reshare_validator.rb +2 -0
  85. data/lib/diaspora_federation/validators/retraction_validator.rb +2 -0
  86. data/lib/diaspora_federation/validators/rules/birthday.rb +3 -1
  87. data/lib/diaspora_federation/validators/rules/boolean.rb +6 -5
  88. data/lib/diaspora_federation/validators/rules/diaspora_id.rb +3 -1
  89. data/lib/diaspora_federation/validators/rules/diaspora_id_list.rb +3 -0
  90. data/lib/diaspora_federation/validators/rules/guid.rb +3 -1
  91. data/lib/diaspora_federation/validators/rules/not_nil.rb +2 -0
  92. data/lib/diaspora_federation/validators/rules/public_key.rb +2 -0
  93. data/lib/diaspora_federation/validators/rules/tag_count.rb +2 -0
  94. data/lib/diaspora_federation/validators/status_message_validator.rb +2 -0
  95. data/lib/diaspora_federation/validators/web_finger_validator.rb +2 -0
  96. data/lib/diaspora_federation/validators.rb +2 -0
  97. data/lib/diaspora_federation/version.rb +3 -1
  98. data/lib/diaspora_federation.rb +3 -2
  99. metadata +9 -28
  100. data/lib/diaspora_federation/discovery/host_meta.rb +0 -90
  101. data/lib/diaspora_federation/entities/relayable_retraction.rb +0 -66
  102. data/lib/diaspora_federation/entities/request.rb +0 -31
  103. data/lib/diaspora_federation/entities/signed_retraction.rb +0 -43
  104. data/lib/diaspora_federation/salmon/encrypted_slap.rb +0 -109
  105. data/lib/diaspora_federation/salmon/slap.rb +0 -55
  106. data/lib/diaspora_federation/salmon/xml_payload.rb +0 -41
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "nokogiri"
2
4
  require "openssl"
3
5
 
@@ -182,13 +184,11 @@ module DiasporaFederation
182
184
  # queue_public_receive
183
185
  # Queue a public salmon xml to process in background
184
186
  # @param [String] data salmon slap xml or magic envelope xml
185
- # @param [Boolean] legacy true if it is a legacy salmon slap, false if it is a magic envelope xml
186
187
  #
187
188
  # queue_private_receive
188
189
  # Queue a private salmon xml to process in background
189
190
  # @param [String] guid guid of the receiver person
190
191
  # @param [String] data salmon slap xml or encrypted magic envelope json
191
- # @param [Boolean] legacy true if it is a legacy salmon slap, false if it is a encrypted magic envelope json
192
192
  # @return [Boolean] true if successful, false if the user was not found
193
193
  #
194
194
  # receive_entity
@@ -256,6 +256,7 @@ module DiasporaFederation
256
256
  configuration_error "http_timeout: please configure a number" unless @http_timeout.is_a?(Integer)
257
257
 
258
258
  return unless !@http_verbose.is_a?(TrueClass) && !@http_verbose.is_a?(FalseClass)
259
+
259
260
  configuration_error "http_verbose: please configure a boolean"
260
261
  end
261
262
 
metadata CHANGED
@@ -1,53 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diaspora_federation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Neff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-17 00:00:00.000000000 Z
11
+ date: 2022-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 0.9.0
20
- - - "<"
17
+ - - "~>"
21
18
  - !ruby/object:Gem::Version
22
19
  version: '1.0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 0.9.0
30
- - - "<"
24
+ - - "~>"
31
25
  - !ruby/object:Gem::Version
32
26
  version: '1.0'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: faraday_middleware
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: 0.10.0
40
- - - "<"
31
+ - - "~>"
41
32
  - !ruby/object:Gem::Version
42
33
  version: '1.0'
43
34
  type: :runtime
44
35
  prerelease: false
45
36
  version_requirements: !ruby/object:Gem::Requirement
46
37
  requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: 0.10.0
50
- - - "<"
38
+ - - "~>"
51
39
  - !ruby/object:Gem::Version
52
40
  version: '1.0'
53
41
  - !ruby/object:Gem::Dependency
@@ -116,7 +104,6 @@ files:
116
104
  - lib/diaspora_federation/discovery/discovery.rb
117
105
  - lib/diaspora_federation/discovery/exceptions.rb
118
106
  - lib/diaspora_federation/discovery/h_card.rb
119
- - lib/diaspora_federation/discovery/host_meta.rb
120
107
  - lib/diaspora_federation/discovery/web_finger.rb
121
108
  - lib/diaspora_federation/discovery/xrd_document.rb
122
109
  - lib/diaspora_federation/entities.rb
@@ -142,12 +129,9 @@ files:
142
129
  - lib/diaspora_federation/entities/profile.rb
143
130
  - lib/diaspora_federation/entities/related_entity.rb
144
131
  - lib/diaspora_federation/entities/relayable.rb
145
- - lib/diaspora_federation/entities/relayable_retraction.rb
146
- - lib/diaspora_federation/entities/request.rb
147
132
  - lib/diaspora_federation/entities/reshare.rb
148
133
  - lib/diaspora_federation/entities/retraction.rb
149
134
  - lib/diaspora_federation/entities/signable.rb
150
- - lib/diaspora_federation/entities/signed_retraction.rb
151
135
  - lib/diaspora_federation/entities/status_message.rb
152
136
  - lib/diaspora_federation/entity.rb
153
137
  - lib/diaspora_federation/federation.rb
@@ -172,11 +156,8 @@ files:
172
156
  - lib/diaspora_federation/salmon.rb
173
157
  - lib/diaspora_federation/salmon/aes.rb
174
158
  - lib/diaspora_federation/salmon/encrypted_magic_envelope.rb
175
- - lib/diaspora_federation/salmon/encrypted_slap.rb
176
159
  - lib/diaspora_federation/salmon/exceptions.rb
177
160
  - lib/diaspora_federation/salmon/magic_envelope.rb
178
- - lib/diaspora_federation/salmon/slap.rb
179
- - lib/diaspora_federation/salmon/xml_payload.rb
180
161
  - lib/diaspora_federation/validators.rb
181
162
  - lib/diaspora_federation/validators/account_deletion_validator.rb
182
163
  - lib/diaspora_federation/validators/account_migration_validator.rb
@@ -224,16 +205,16 @@ require_paths:
224
205
  - lib
225
206
  required_ruby_version: !ruby/object:Gem::Requirement
226
207
  requirements:
227
- - - "~>"
208
+ - - ">="
228
209
  - !ruby/object:Gem::Version
229
- version: '2.1'
210
+ version: '2.7'
230
211
  required_rubygems_version: !ruby/object:Gem::Requirement
231
212
  requirements:
232
213
  - - ">="
233
214
  - !ruby/object:Gem::Version
234
215
  version: '0'
235
216
  requirements: []
236
- rubygems_version: 3.0.9
217
+ rubygems_version: 3.3.7
237
218
  signing_key:
238
219
  specification_version: 4
239
220
  summary: diaspora* federation library
@@ -1,90 +0,0 @@
1
- module DiasporaFederation
2
- module Discovery
3
- # Generates and parses Host Meta documents.
4
- #
5
- # This is a minimal implementation of the standard, only to the degree of what
6
- # is used for the purposes of the diaspora* protocol. (e.g. WebFinger)
7
- #
8
- # @example Creating a Host Meta document
9
- # doc = HostMeta.from_base_url("https://pod.example.tld/")
10
- # doc.to_xml
11
- #
12
- # @example Parsing a Host Meta document
13
- # doc = HostMeta.from_xml(xml_string)
14
- # webfinger_tpl = doc.webfinger_template_url
15
- #
16
- # @see http://tools.ietf.org/html/rfc6415 RFC 6415: "Web Host Metadata"
17
- # @see XrdDocument
18
- class HostMeta
19
- private_class_method :new
20
-
21
- # Creates a new host-meta instance
22
- # @param [String] webfinger_url the webfinger-url
23
- def initialize(webfinger_url)
24
- @webfinger_url = webfinger_url
25
- end
26
-
27
- # URL fragment to append to the base URL
28
- WEBFINGER_SUFFIX = "/.well-known/webfinger.xml?resource={uri}".freeze
29
-
30
- # Returns the WebFinger URL that was used to build this instance (either from
31
- # xml or by giving a base URL).
32
- # @return [String] WebFinger template URL
33
- def webfinger_template_url
34
- @webfinger_url
35
- end
36
-
37
- # Produces the XML string for the Host Meta instance with a +Link+ element
38
- # containing the +webfinger_url+.
39
- # @return [String] XML string
40
- def to_xml
41
- doc = XrdDocument.new
42
- doc.links << {rel: "lrdd",
43
- type: "application/xrd+xml",
44
- template: @webfinger_url}
45
- doc.to_xml
46
- end
47
-
48
- # Builds a new HostMeta instance and constructs the WebFinger URL from the
49
- # given base URL by appending HostMeta::WEBFINGER_SUFFIX.
50
- # @param [String, URL] base_url the base-url for the webfinger-url
51
- # @return [HostMeta]
52
- # @raise [InvalidData] if the webfinger url is malformed
53
- def self.from_base_url(base_url)
54
- webfinger_url = "#{base_url.to_s.chomp('/')}#{WEBFINGER_SUFFIX}"
55
- raise InvalidData, "invalid webfinger url: #{webfinger_url}" unless webfinger_url_valid?(webfinger_url)
56
-
57
- new(webfinger_url)
58
- end
59
-
60
- # Reads the given Host Meta XML document string and populates the
61
- # +webfinger_url+.
62
- # @param [String] hostmeta_xml Host Meta XML string
63
- # @raise [InvalidData] if the xml or the webfinger url is malformed
64
- def self.from_xml(hostmeta_xml)
65
- data = XrdDocument.xml_data(hostmeta_xml)
66
- raise InvalidData, "received an invalid xml" unless data.key?(:links)
67
-
68
- webfinger_url = webfinger_url_from_xrd(data)
69
- raise InvalidData, "invalid webfinger url: #{webfinger_url}" unless webfinger_url_valid?(webfinger_url)
70
-
71
- new(webfinger_url)
72
- end
73
-
74
- # Applies some basic sanity-checking to the given URL
75
- # @param [String] url validation subject
76
- # @return [Boolean] validation result
77
- private_class_method def self.webfinger_url_valid?(url)
78
- !url.nil? && url.instance_of?(String) && url =~ %r{\Ahttps?:\/\/.*\/.*\{uri\}.*}i
79
- end
80
-
81
- # Gets the webfinger url from an XRD data structure
82
- # @param [Hash] data extracted data
83
- # @return [String] webfinger url
84
- private_class_method def self.webfinger_url_from_xrd(data)
85
- link = data[:links].find {|l| l[:rel] == "lrdd" }
86
- return link[:template] unless link.nil?
87
- end
88
- end
89
- end
90
- end
@@ -1,66 +0,0 @@
1
- module DiasporaFederation
2
- module Entities
3
- # This entity represents a claim of deletion of a previously federated
4
- # relayable entity. ({Entities::Comment}, {Entities::Like})
5
- #
6
- # There are two cases of federation of the RelayableRetraction.
7
- # Retraction from the dowstream object owner is when an author of the
8
- # relayable (e.g. Comment) deletes it themself. In this case only target_author_signature
9
- # is filled and a retraction is sent to the commented post's author. Here
10
- # the upstream object owner signs it with the parent's author key, puts
11
- # the signature in parent_author_signature and sends it to other pods where
12
- # other participating people are present. This is the second case - retraction
13
- # from the upstream object owner.
14
- # Retraction from the upstream object owner can also be performed by the
15
- # upstream object owner themself - they have a right to delete comments on their posts.
16
- # In any case in the retraction by the upstream author target_author_signature
17
- # is not checked, only parent_author_signature is checked.
18
- #
19
- # @see Validators::RelayableRetractionValidator
20
- # @deprecated will be replaced with {Entities::Retraction}
21
- class RelayableRetraction < Entity
22
- # @!attribute [r] parent_author_signature
23
- # Contains a signature of the entity using the private key of the author of a parent post.
24
- # This signature is mandatory only when federating from an upstream author to the subscribers.
25
- # @see Relayable#parent_author_signature
26
- # @return [String] parent author signature
27
- property :parent_author_signature, :string, default: nil
28
-
29
- # @!attribute [r] target_guid
30
- # Guid of a relayable to be deleted
31
- # @see Comment#guid
32
- # @return [String] target guid
33
- property :target_guid, :string
34
-
35
- # @!attribute [r] target_type
36
- # A string describing a type of the target
37
- # @see Retraction#target_type
38
- # @return [String] target type
39
- property :target_type, :string
40
-
41
- # @!attribute [r] author
42
- # The diaspora* ID of the person who deletes a relayable
43
- # @see Person#author
44
- # @return [String] diaspora* ID
45
- property :author, :string, xml_name: :sender_handle
46
-
47
- # @!attribute [r] target_author_signature
48
- # Contains a signature of the entity using the private key of the
49
- # author of a federated relayable entity. ({Entities::Comment}, {Entities::Like})
50
- # This signature is mandatory only when federation from the subscriber to an upstream
51
- # author is done.
52
- # @see Relayable#author_signature
53
- # @return [String] target author signature
54
- property :target_author_signature, :string, default: nil
55
-
56
- def initialize(*)
57
- raise "Sending RelayableRetraction is not supported anymore! Use Retraction instead!"
58
- end
59
-
60
- # @return [Retraction] instance
61
- def self.from_hash(hash)
62
- Retraction.from_hash(hash)
63
- end
64
- end
65
- end
66
- end
@@ -1,31 +0,0 @@
1
- module DiasporaFederation
2
- module Entities
3
- # This entity represents a sharing request for a user. A user issues it
4
- # when they start sharing with another user.
5
- #
6
- # @see Validators::RequestValidator
7
- # @deprecated will be replaced with {Contact}
8
- class Request < Entity
9
- # @!attribute [r] author
10
- # The diaspora* ID of the person who share their profile
11
- # @see Person#author
12
- # @return [String] sender ID
13
- property :author, :string, xml_name: :sender_handle
14
-
15
- # @!attribute [r] recipient
16
- # The diaspora* ID of the person who will be shared with
17
- # @see Validation::Rule::DiasporaId
18
- # @return [String] recipient ID
19
- property :recipient, :string, xml_name: :recipient_handle
20
-
21
- def initialize(*)
22
- raise "Sending Request is not supported anymore! Use Contact instead!"
23
- end
24
-
25
- # @return [Retraction] instance
26
- def self.from_hash(hash)
27
- Contact.new(hash)
28
- end
29
- end
30
- end
31
- end
@@ -1,43 +0,0 @@
1
- module DiasporaFederation
2
- module Entities
3
- # This entity represents a claim of deletion of a previously federated
4
- # entity of post type. ({Entities::StatusMessage})
5
- #
6
- # @see Validators::SignedRetractionValidator
7
- # @deprecated will be replaced with {Entities::Retraction}
8
- class SignedRetraction < Entity
9
- # @!attribute [r] target_guid
10
- # Guid of a post to be deleted
11
- # @see Retraction#target_guid
12
- # @return [String] target guid
13
- property :target_guid, :string
14
-
15
- # @!attribute [r] target_type
16
- # A string describing the type of the target
17
- # @see Retraction#target_type
18
- # @return [String] target type
19
- property :target_type, :string
20
-
21
- # @!attribute [r] author
22
- # The diaspora* ID of the person who deletes a post
23
- # @see Person#author
24
- # @return [String] diaspora* ID
25
- property :author, :string, xml_name: :sender_handle
26
-
27
- # @!attribute [r] author_signature
28
- # Contains a signature of the entity using the private key of the author of a post
29
- # This signature is mandatory.
30
- # @return [String] author signature
31
- property :target_author_signature, :string, default: nil
32
-
33
- def initialize(*)
34
- raise "Sending SignedRetraction is not supported anymore! Use Retraction instead!"
35
- end
36
-
37
- # @return [Retraction] instance
38
- def self.from_hash(hash)
39
- Retraction.from_hash(hash)
40
- end
41
- end
42
- end
43
- end
@@ -1,109 +0,0 @@
1
- require "json"
2
-
3
- module DiasporaFederation
4
- module Salmon
5
- # +EncryptedSlap+ provides class methods for generating and parsing encrypted
6
- # Slaps. (In principle the same as {Slap}, but with encryption.)
7
- #
8
- # The basic encryption mechanism used here is based on the knowledge that
9
- # asymmetrical encryption is slow and symmetrical encryption is fast. Keeping in
10
- # mind that a message we want to de-/encrypt may greatly vary in length,
11
- # performance considerations must play a part of this scheme.
12
- #
13
- # A diaspora*-flavored encrypted magic-enveloped XML message looks like the following:
14
- #
15
- # <?xml version="1.0" encoding="UTF-8"?>
16
- # <diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env">
17
- # <encrypted_header>{encrypted_header}</encrypted_header>
18
- # {magic_envelope with encrypted data}
19
- # </diaspora>
20
- #
21
- # The encrypted header is encoded in JSON like this (when in plain text):
22
- #
23
- # {
24
- # "aes_key" => "...",
25
- # "ciphertext" => "..."
26
- # }
27
- #
28
- # +aes_key+ is encrypted using the recipients public key, and contains the AES
29
- # +key+ and +iv+ used to encrypt the +ciphertext+ also encoded as JSON.
30
- #
31
- # {
32
- # "key" => "...",
33
- # "iv" => "..."
34
- # }
35
- #
36
- # +ciphertext+, once decrypted, contains the +author_id+, +aes_key+ and +iv+
37
- # relevant to the decryption of the data in the magic_envelope and the
38
- # verification of its signature.
39
- #
40
- # The decrypted cyphertext has this XML structure:
41
- #
42
- # <decrypted_header>
43
- # <iv>{iv}</iv>
44
- # <aes_key>{aes_key}</aes_key>
45
- # <author_id>{author_id}</author_id>
46
- # </decrypted_header>
47
- #
48
- # Finally, before decrypting the magic envelope payload, the signature should
49
- # first be verified.
50
- #
51
- # @example Parsing a Salmon Slap
52
- # recipient_privkey = however_you_retrieve_the_recipients_private_key()
53
- # entity = EncryptedSlap.from_xml(slap_xml, recipient_privkey).payload
54
- #
55
- # @deprecated
56
- class EncryptedSlap < Slap
57
- # Creates a {MagicEnvelope} instance from the data within the given XML string
58
- # containing an encrypted payload.
59
- #
60
- # @param [String] slap_xml encrypted Salmon xml
61
- # @param [OpenSSL::PKey::RSA] privkey recipient private_key for decryption
62
- #
63
- # @return [MagicEnvelope] magic envelope instance with payload and sender
64
- #
65
- # @raise [ArgumentError] if any of the arguments is of the wrong type
66
- # @raise [MissingHeader] if the +encrypted_header+ element is missing in the XML
67
- # @raise [MissingMagicEnvelope] if the +me:env+ element is missing in the XML
68
- def self.from_xml(slap_xml, privkey)
69
- raise ArgumentError unless slap_xml.instance_of?(String) && privkey.instance_of?(OpenSSL::PKey::RSA)
70
- doc = Nokogiri::XML(slap_xml)
71
-
72
- header_elem = doc.at_xpath("d:diaspora/d:encrypted_header", Slap::NS)
73
- raise MissingHeader if header_elem.nil?
74
- header = header_data(header_elem.content, privkey)
75
- sender = header[:author_id]
76
- cipher_params = {key: Base64.decode64(header[:aes_key]), iv: Base64.decode64(header[:iv])}
77
-
78
- MagicEnvelope.unenvelop(magic_env_from_doc(doc), sender, cipher_params)
79
- end
80
-
81
- # Decrypts and reads the data from the encrypted XML header
82
- # @param [String] data base64 encoded, encrypted header data
83
- # @param [OpenSSL::PKey::RSA] privkey private key for decryption
84
- # @return [Hash] { iv: "...", aes_key: "...", author_id: "..." }
85
- private_class_method def self.header_data(data, privkey)
86
- header_elem = decrypt_header(data, privkey)
87
- raise InvalidHeader unless header_elem.name == "decrypted_header"
88
-
89
- iv = header_elem.at_xpath("iv").content
90
- key = header_elem.at_xpath("aes_key").content
91
- author_id = header_elem.at_xpath("author_id").content
92
-
93
- {iv: iv, aes_key: key, author_id: author_id}
94
- end
95
-
96
- # Decrypts the xml header
97
- # @param [String] data base64 encoded, encrypted header data
98
- # @param [OpenSSL::PKey::RSA] privkey private key for decryption
99
- # @return [Nokogiri::XML::Element] header xml document
100
- private_class_method def self.decrypt_header(data, privkey)
101
- cipher_header = JSON.parse(Base64.decode64(data))
102
- key = JSON.parse(privkey.private_decrypt(Base64.decode64(cipher_header["aes_key"])))
103
-
104
- xml = AES.decrypt(cipher_header["ciphertext"], Base64.decode64(key["key"]), Base64.decode64(key["iv"]))
105
- Nokogiri::XML(xml).root
106
- end
107
- end
108
- end
109
- end
@@ -1,55 +0,0 @@
1
- module DiasporaFederation
2
- module Salmon
3
- # +Slap+ provides class methods to create unencrypted Slap XML from payload
4
- # data and parse incoming XML into a Slap instance.
5
- #
6
- # A diaspora* flavored magic-enveloped XML message looks like the following:
7
- #
8
- # <?xml version="1.0" encoding="UTF-8"?>
9
- # <diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env">
10
- # <header>
11
- # <author_id>{author}</author_id>
12
- # </header>
13
- # {magic_envelope}
14
- # </diaspora>
15
- #
16
- # @example Parsing a Salmon Slap
17
- # entity = Slap.from_xml(slap_xml).payload
18
- #
19
- # @deprecated
20
- class Slap
21
- # Namespaces
22
- NS = {d: Salmon::XMLNS, me: MagicEnvelope::XMLNS}.freeze
23
-
24
- # Parses an unencrypted Salmon XML string and returns a new instance of
25
- # {MagicEnvelope} with the XML data.
26
- #
27
- # @param [String] slap_xml Salmon XML
28
- #
29
- # @return [MagicEnvelope] magic envelope instance with payload and sender
30
- #
31
- # @raise [ArgumentError] if the argument is not a String
32
- # @raise [MissingAuthor] if the +author_id+ element is missing from the XML
33
- # @raise [MissingMagicEnvelope] if the +me:env+ element is missing from the XML
34
- def self.from_xml(slap_xml)
35
- raise ArgumentError unless slap_xml.instance_of?(String)
36
- doc = Nokogiri::XML(slap_xml)
37
-
38
- author_elem = doc.at_xpath("d:diaspora/d:header/d:author_id", Slap::NS)
39
- raise MissingAuthor if author_elem.nil? || author_elem.content.empty?
40
- sender = author_elem.content
41
-
42
- MagicEnvelope.unenvelop(magic_env_from_doc(doc), sender)
43
- end
44
-
45
- # Parses the magic envelop from the document.
46
- #
47
- # @param [Nokogiri::XML::Document] doc Salmon XML Document
48
- private_class_method def self.magic_env_from_doc(doc)
49
- doc.at_xpath("d:diaspora/me:env", Slap::NS).tap do |env|
50
- raise MissingMagicEnvelope if env.nil?
51
- end
52
- end
53
- end
54
- end
55
- end
@@ -1,41 +0,0 @@
1
- module DiasporaFederation
2
- module Salmon
3
- # +XmlPayload+ provides methods to wrap a XML-serialized {Entity} inside a
4
- # common XML structure that will become the payload for federation messages.
5
- #
6
- # The wrapper looks like so:
7
- # <XML>
8
- # <post>
9
- # {data}
10
- # </post>
11
- # </XML>
12
- #
13
- # (The +post+ element is there for historic reasons...)
14
- # @deprecated
15
- module XmlPayload
16
- # Extracts the Entity XML from the wrapping XML structure, parses the entity
17
- # XML and returns a new instance of the Entity that was packed inside the
18
- # given payload.
19
- #
20
- # @param [Nokogiri::XML::Element] xml payload XML root node
21
- # @return [Entity] re-constructed Entity instance
22
- # @raise [ArgumentError] if the argument is not an
23
- # {http://www.rubydoc.info/gems/nokogiri/Nokogiri/XML/Element Nokogiri::XML::Element}
24
- # @raise [UnknownEntity] if the class for the entity contained inside the
25
- # XML can't be found
26
- def self.unpack(xml)
27
- raise ArgumentError, "only Nokogiri::XML::Element allowed" unless xml.instance_of?(Nokogiri::XML::Element)
28
-
29
- data = xml_wrapped?(xml) ? xml.at_xpath("post/*[1]") : xml
30
-
31
- Entity.entity_class(data.name).from_xml(data)
32
- end
33
-
34
- # @param [Nokogiri::XML::Element] element
35
- private_class_method def self.xml_wrapped?(element)
36
- (element.name == "XML" && !element.at_xpath("post").nil? &&
37
- !element.at_xpath("post").children.empty?)
38
- end
39
- end
40
- end
41
- end