diaspora_federation 0.2.2 → 0.2.3

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: 79f5ac9d463c824a36b9769994431ac6e66625fd
4
- data.tar.gz: 270ed5a33de71c405bdcd584c620d3f1d97422c9
3
+ metadata.gz: 42c68f5013a4c3f538bdf2d0c304d79b42e09ab5
4
+ data.tar.gz: a3a21dd08bac81bc602fbee8e9ce7f4f726d7413
5
5
  SHA512:
6
- metadata.gz: 14ed9bc7669bf07166bebacfe43bbb0cb78821010964181f94f3f395838ba7836755ebdc913048f7455fa6ca6cf0e78e281190ec1f914591c5233a641d986040
7
- data.tar.gz: 91b6f07218394e0e066aefd973de6ddc4fa7c0d694c4ee25e53504d15f5371036e8b765f1d911f6008464c9f86e23e66a2a9010c32e3fb4f30da8c064099668e
6
+ metadata.gz: d4858c3925cd46cd2adf8097066340445129c7630f6a41c8560edac13cc233c825d7b8ae593f3bc917848003f722f4035dca0bf6716c87edb56f99035ffd4b20
7
+ data.tar.gz: 8bca5a011c3bb00cc128ef5cea489fe1e575bcdb6a3a74cede7fa5336f7c86f6b102ed0e3980b2a370eeba42e14d6c0b7d99b29a40ee7673477645420d9c1bc8
@@ -1,3 +1,20 @@
1
+ # 0.2.3
2
+
3
+ ## Features
4
+
5
+ Add `blocking` flag to `Contact` entity [#80](https://github.com/diaspora/diaspora_federation/pull/80)
6
+ Introduce alternative form for `AccountMigration` entity signature [#89](https://github.com/diaspora/diaspora_federation/pull/89)
7
+
8
+ ## Refactor
9
+
10
+ Extract signing of `AccountMigration` to a different module [#89](https://github.com/diaspora/diaspora_federation/pull/89)
11
+ Remove participants limit for conversations [#91](https://github.com/diaspora/diaspora_federation/pull/91)
12
+
13
+ ## Bug fixes
14
+
15
+ Fix when booleans in relayables are false [#90](https://github.com/diaspora/diaspora_federation/pull/90)
16
+ Fix relayable signatures for messages with invalid XML characters [#95](https://github.com/diaspora/diaspora_federation/pull/95)
17
+
1
18
  # 0.2.2
2
19
 
3
20
  ## Features
@@ -26,7 +26,7 @@ module DiasporaFederation
26
26
  person
27
27
  rescue DiscoveryError
28
28
  raise # simply re-raise DiscoveryError
29
- rescue => e # rubocop:disable Lint/RescueWithoutErrorClass
29
+ rescue => e # rubocop:disable Style/RescueStandardError
30
30
  raise DiscoveryError, "Failed discovery for #{diaspora_id}: #{e.class}: #{e.message}"
31
31
  end
32
32
 
@@ -48,7 +48,7 @@ module DiasporaFederation
48
48
  response = HttpClient.get(url)
49
49
  raise "Failed to fetch #{url}: #{response.status}" unless response.success?
50
50
  response.body
51
- rescue => e # rubocop:disable Lint/RescueWithoutErrorClass
51
+ rescue => e # rubocop:disable Style/RescueStandardError
52
52
  unless http_fallback && url.start_with?("https://")
53
53
  raise DiscoveryError, "Failed to fetch #{url} for #{diaspora_id}: #{e.class}: #{e.message}"
54
54
  end
@@ -78,7 +78,7 @@ module DiasporaFederation
78
78
 
79
79
  # This tries the WebFinger URL with https first, then falls back to http if webfinger_http_fallback is enabled.
80
80
  @webfinger = WebFinger.from_json(get(webfinger_url, DiasporaFederation.webfinger_http_fallback))
81
- rescue => e # rubocop:disable Lint/RescueWithoutErrorClass
81
+ rescue => e # rubocop:disable Style/RescueStandardError
82
82
  logger.warn "WebFinger failed, retrying with legacy WebFinger for #{diaspora_id}: #{e.class}: #{e.message}"
83
83
  @webfinger = WebFinger.from_xml(get(legacy_webfinger_url_from_host_meta))
84
84
  end
@@ -13,6 +13,7 @@ require "diaspora_federation/entities/related_entity"
13
13
  # abstract types
14
14
  require "diaspora_federation/entities/post"
15
15
  require "diaspora_federation/entities/signable"
16
+ require "diaspora_federation/entities/account_migration/signable"
16
17
  require "diaspora_federation/entities/relayable"
17
18
 
18
19
  # types
@@ -5,10 +5,12 @@ module DiasporaFederation
5
5
  #
6
6
  # @see Validators::AccountMigrationValidator
7
7
  class AccountMigration < Entity
8
- include Signable
8
+ include AccountMigration::Signable
9
9
 
10
10
  # @!attribute [r] author
11
- # The old diaspora* ID of the person who changes their ID
11
+ # Sender of the AccountMigration message. Usually it is the old diaspora* ID of the person who changes their ID.
12
+ # This property is also allowed to be the new diaspora* ID, which is equal to the author of the included
13
+ # profile.
12
14
  # @see Person#author
13
15
  # @return [String] author diaspora* ID
14
16
  property :author, :string
@@ -19,20 +21,39 @@ module DiasporaFederation
19
21
  entity :profile, Entities::Profile
20
22
 
21
23
  # @!attribute [r] signature
22
- # Signature that validates original and target diaspora* IDs with the new key of person
24
+ # Signature that validates original and target diaspora* IDs with the private key of the second identity, other
25
+ # than the entity author. So if the author is the old identity then this signature is made with the new identity
26
+ # key, and vice versa.
23
27
  # @return [String] signature
24
28
  property :signature, :string, default: nil
25
29
 
26
- # @return [String] string representation of this object
27
- def to_s
28
- "AccountMigration:#{author}:#{profile.author}"
30
+ # @!attribute [r] old_identity
31
+ # Optional attribute which keeps old diaspora* ID. Must be present when author attribute contains new diaspora*
32
+ # ID.
33
+ # @return [String] old identity
34
+ property :old_identity, :string, default: nil
35
+
36
+ # Returns diaspora* ID of the old person identity.
37
+ # @return [String] diaspora* ID of the old person identity
38
+ def old_identity
39
+ return @old_identity if author_is_new_id?
40
+ author
41
+ end
42
+
43
+ # Returns diaspora* ID of the new person identity.
44
+ # @return [String] diaspora* ID of the new person identity
45
+ def new_identity
46
+ profile.author
29
47
  end
30
48
 
49
+ # @return [String] string representation of this object
50
+ alias to_s unique_migration_descriptor
51
+
31
52
  # Shortcut for calling super method with sensible arguments
32
53
  #
33
54
  # @see DiasporaFederation::Entities::Signable#verify_signature
34
55
  def verify_signature
35
- super(profile.author, :signature)
56
+ super(signer_id, :signature)
36
57
  end
37
58
 
38
59
  # Calls super and additionally does signature verification for the instantiated entity.
@@ -44,30 +65,33 @@ module DiasporaFederation
44
65
 
45
66
  private
46
67
 
47
- # @see DiasporaFederation::Entities::Signable#signature_data
48
- def signature_data
49
- to_s
68
+ def author_is_new_id?
69
+ author == new_identity
70
+ end
71
+
72
+ def signer_id
73
+ author_is_new_id? ? @old_identity : new_identity
50
74
  end
51
75
 
52
76
  def enriched_properties
53
77
  super.tap do |hash|
54
- hash[:signature] = signature || sign_with_new_key
78
+ hash[:signature] = signature || sign_with_respective_key
55
79
  end
56
80
  end
57
81
 
58
- # Sign with new user's key
59
- # @raise [NewPrivateKeyNotFound] if the new user's private key is not found
82
+ # Sign with the key of the #signer_id identity
83
+ # @raise [PrivateKeyNotFound] if the signer's private key is not found
60
84
  # @return [String] A Base64 encoded signature of #signature_data with key
61
- def sign_with_new_key
62
- privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key, profile.author)
63
- raise NewPrivateKeyNotFound, "author=#{profile.author} obj=#{self}" if privkey.nil?
85
+ def sign_with_respective_key
86
+ privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key, signer_id)
87
+ raise PrivateKeyNotFound, "signer=#{signer_id} obj=#{self}" if privkey.nil?
64
88
  sign_with_key(privkey).tap do
65
- logger.info "event=sign status=complete signature=signature author=#{profile.author} obj=#{self}"
89
+ logger.info "event=sign status=complete signature=signature signer=#{signer_id} obj=#{self}"
66
90
  end
67
91
  end
68
92
 
69
93
  # Raised, if creating the signature fails, because the new private key of a user was not found
70
- class NewPrivateKeyNotFound < RuntimeError
94
+ class PrivateKeyNotFound < RuntimeError
71
95
  end
72
96
  end
73
97
  end
@@ -0,0 +1,24 @@
1
+ module DiasporaFederation
2
+ module Entities
3
+ class AccountMigration < Entity
4
+ # AccountMigration::Signable is a module that encapsulates basic signature generation/verification flow for
5
+ # AccountMigration entity.
6
+ #
7
+ # It is possible that implementation of diaspora* protocol requires to compute the signature for the
8
+ # AccountMigration entity without instantiating the entity. In this case this module may be useful.
9
+ module Signable
10
+ include Entities::Signable
11
+
12
+ # @return [String] string which is uniquely represents migration occasion
13
+ def unique_migration_descriptor
14
+ "AccountMigration:#{old_identity}:#{new_identity}"
15
+ end
16
+
17
+ # @see DiasporaFederation::Entities::Signable#signature_data
18
+ def signature_data
19
+ unique_migration_descriptor
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -25,10 +25,25 @@ module DiasporaFederation
25
25
  # @return [Boolean] if the author is sharing with the person
26
26
  property :sharing, :boolean, default: true
27
27
 
28
+ # @!attribute [r] blocking
29
+ # @return [Boolean] if the author is blocking the person
30
+ property :blocking, :boolean, optional: true, default: false
31
+
28
32
  # @return [String] string representation of this object
29
33
  def to_s
30
34
  "Contact:#{author}:#{recipient}"
31
35
  end
36
+
37
+ private
38
+
39
+ def validate
40
+ super
41
+
42
+ return unless (following || sharing) && blocking
43
+
44
+ raise ValidationError,
45
+ "flags invalid: following:#{following}/sharing:#{sharing} and blocking:#{blocking} can't both be true"
46
+ end
32
47
  end
33
48
  end
34
49
  end
@@ -148,7 +148,7 @@ module DiasporaFederation
148
148
  hash[:parent_author_signature] = parent_author_signature || sign_with_parent_author_if_available.to_s
149
149
  end
150
150
  order = signature_order + %i[author_signature parent_author_signature]
151
- order.map {|element| [element, data[element] || ""] }.to_h
151
+ order.map {|element| [element, data[element].to_s] }.to_h
152
152
  end
153
153
 
154
154
  def signature_order=(order)
@@ -277,7 +277,7 @@ module DiasporaFederation
277
277
 
278
278
  case self.class.class_props[name]
279
279
  when :string
280
- value.to_s
280
+ value.to_s.gsub(INVALID_XML_REGEX, "\uFFFD")
281
281
  when :timestamp
282
282
  value.nil? ? "" : value.utc.iso8601
283
283
  else
@@ -310,7 +310,7 @@ module DiasporaFederation
310
310
  # Create simple node, fill it with text and append to root
311
311
  def simple_node(doc, name, value)
312
312
  Nokogiri::XML::Element.new(name.to_s, doc).tap do |node|
313
- node.content = value.gsub(INVALID_XML_REGEX, "\uFFFD") unless value.empty?
313
+ node.content = value unless value.empty?
314
314
  end
315
315
  end
316
316
 
@@ -26,7 +26,7 @@ module DiasporaFederation
26
26
  class_name = Entity.entity_class(type).to_s.rpartition("::").last
27
27
  return if DiasporaFederation.callbacks.trigger(:fetch_related_entity, class_name, guid)
28
28
  Fetcher.fetch_public(author, type, guid)
29
- rescue => e # rubocop:disable Lint/RescueWithoutErrorClass
29
+ rescue => e # rubocop:disable Style/RescueStandardError
30
30
  logger.error "Failed to fetch linked entity #{type}:#{guid}: #{e.class}: #{e.message}"
31
31
  end
32
32
  end
@@ -11,7 +11,7 @@ module DiasporaFederation
11
11
  type = entity_name(entity_type).to_s
12
12
  raise "Already fetching ..." if fetching[type].include?(guid)
13
13
  fetch_from_url(author, type, guid)
14
- rescue => e # rubocop:disable Lint/RescueWithoutErrorClass
14
+ rescue => e # rubocop:disable Style/RescueStandardError
15
15
  raise NotFetchable, "Failed to fetch #{entity_type}:#{guid} from #{author}: #{e.class}: #{e.message}"
16
16
  end
17
17
 
@@ -15,7 +15,7 @@ module DiasporaFederation
15
15
  Salmon::MagicEnvelope.unenvelop(magic_env_xml)
16
16
  end
17
17
  Public.new(magic_env).receive
18
- rescue => e # rubocop:disable Lint/RescueWithoutErrorClass
18
+ rescue => e # rubocop:disable Style/RescueStandardError
19
19
  logger.error "failed to receive public message: #{e.class}: #{e.message}"
20
20
  logger.debug "received data:\n#{data}"
21
21
  raise e
@@ -36,7 +36,7 @@ module DiasporaFederation
36
36
  Salmon::MagicEnvelope.unenvelop(magic_env_xml)
37
37
  end
38
38
  Private.new(magic_env, recipient_id).receive
39
- rescue => e # rubocop:disable Lint/RescueWithoutErrorClass
39
+ rescue => e # rubocop:disable Style/RescueStandardError
40
40
  logger.error "failed to receive private message for #{recipient_id}: #{e.class}: #{e.message}"
41
41
  logger.debug "received data:\n#{data}"
42
42
  raise e
@@ -17,7 +17,7 @@ module DiasporaFederation
17
17
  # Validates and receives the entity
18
18
  def receive
19
19
  validate_and_receive
20
- rescue => e # rubocop:disable Lint/RescueWithoutErrorClass
20
+ rescue => e # rubocop:disable Style/RescueStandardError
21
21
  logger.error "failed to receive #{entity}"
22
22
  raise e
23
23
  end
@@ -19,7 +19,7 @@ end
19
19
  require "diaspora_federation/validators/rules/birthday"
20
20
  require "diaspora_federation/validators/rules/boolean"
21
21
  require "diaspora_federation/validators/rules/diaspora_id"
22
- require "diaspora_federation/validators/rules/diaspora_id_count"
22
+ require "diaspora_federation/validators/rules/diaspora_id_list"
23
23
  require "diaspora_federation/validators/rules/guid"
24
24
  require "diaspora_federation/validators/rules/not_nil"
25
25
  require "diaspora_federation/validators/rules/public_key"
@@ -7,6 +7,8 @@ module DiasporaFederation
7
7
  rule :author, :diaspora_id
8
8
 
9
9
  rule :profile, :not_nil
10
+
11
+ rule :old_identity, :diaspora_id
10
12
  end
11
13
  end
12
14
  end
@@ -8,6 +8,7 @@ module DiasporaFederation
8
8
  rule :recipient, :diaspora_id
9
9
  rule :following, :boolean
10
10
  rule :sharing, :boolean
11
+ rule :blocking, :boolean
11
12
  end
12
13
  end
13
14
  end
@@ -9,7 +9,7 @@ module DiasporaFederation
9
9
 
10
10
  rule :subject, [:not_empty, length: {maximum: 255}]
11
11
 
12
- rule :participants, diaspora_id_count: {maximum: 20}
12
+ rule :participants, diaspora_id_list: {minimum: 2}
13
13
  rule :messages, :not_nil
14
14
  end
15
15
  end
@@ -0,0 +1,41 @@
1
+ module Validation
2
+ module Rule
3
+ # Rule for validating the number of diaspora* IDs in a string.
4
+ # The evaluated string is split at ";".
5
+ class DiasporaIdList
6
+ # This rule can have a +minimum+ or +maximum+ param.
7
+ # @return [Hash] params
8
+ attr_reader :params
9
+
10
+ # Creates a new rule for a diaspora* ID list validation
11
+ # @param [Hash] params
12
+ # @option params [Integer] :minimum minimum allowed id count
13
+ # @option params [Integer] :maximum maximum allowed id count
14
+ def initialize(params={})
15
+ %i[minimum maximum].each do |param|
16
+ if params.include?(param) && !params[param].is_a?(Integer)
17
+ raise ArgumentError, "The :#{param} needs to be an Integer"
18
+ end
19
+ end
20
+
21
+ @params = params
22
+ end
23
+
24
+ # The error key for this rule
25
+ # @return [Symbol] error key
26
+ def error_key
27
+ :diaspora_id_list
28
+ end
29
+
30
+ def valid_value?(value)
31
+ ids = value.split(";")
32
+ return false if params.include?(:maximum) && ids.count > params[:maximum]
33
+ return false if params.include?(:minimum) && ids.count < params[:minimum]
34
+ ids.each do |id|
35
+ return false if DiasporaId::DIASPORA_ID.match(id).nil?
36
+ end
37
+ true
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,4 +1,4 @@
1
1
  module DiasporaFederation
2
2
  # the gem version
3
- VERSION = "0.2.2".freeze
3
+ VERSION = "0.2.3".freeze
4
4
  end
metadata CHANGED
@@ -1,35 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diaspora_federation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Neff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-23 00:00:00.000000000 Z
11
+ date: 2018-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: nokogiri
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.6'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 1.6.8
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
- requirements:
27
- - - "~>"
28
- - !ruby/object:Gem::Version
29
- version: '1.6'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 1.6.8
33
13
  - !ruby/object:Gem::Dependency
34
14
  name: faraday
35
15
  requirement: !ruby/object:Gem::Requirement
@@ -39,7 +19,7 @@ dependencies:
39
19
  version: 0.9.0
40
20
  - - "<"
41
21
  - !ruby/object:Gem::Version
42
- version: 0.14.0
22
+ version: 0.15.0
43
23
  type: :runtime
44
24
  prerelease: false
45
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -49,7 +29,7 @@ dependencies:
49
29
  version: 0.9.0
50
30
  - - "<"
51
31
  - !ruby/object:Gem::Version
52
- version: 0.14.0
32
+ version: 0.15.0
53
33
  - !ruby/object:Gem::Dependency
54
34
  name: faraday_middleware
55
35
  requirement: !ruby/object:Gem::Requirement
@@ -70,6 +50,26 @@ dependencies:
70
50
  - - "<"
71
51
  - !ruby/object:Gem::Version
72
52
  version: 0.13.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: nokogiri
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.6'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 1.6.8
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.6'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 1.6.8
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: typhoeus
75
75
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +122,7 @@ files:
122
122
  - lib/diaspora_federation/entities.rb
123
123
  - lib/diaspora_federation/entities/account_deletion.rb
124
124
  - lib/diaspora_federation/entities/account_migration.rb
125
+ - lib/diaspora_federation/entities/account_migration/signable.rb
125
126
  - lib/diaspora_federation/entities/comment.rb
126
127
  - lib/diaspora_federation/entities/contact.rb
127
128
  - lib/diaspora_federation/entities/conversation.rb
@@ -202,7 +203,7 @@ files:
202
203
  - lib/diaspora_federation/validators/rules/birthday.rb
203
204
  - lib/diaspora_federation/validators/rules/boolean.rb
204
205
  - lib/diaspora_federation/validators/rules/diaspora_id.rb
205
- - lib/diaspora_federation/validators/rules/diaspora_id_count.rb
206
+ - lib/diaspora_federation/validators/rules/diaspora_id_list.rb
206
207
  - lib/diaspora_federation/validators/rules/guid.rb
207
208
  - lib/diaspora_federation/validators/rules/not_nil.rb
208
209
  - lib/diaspora_federation/validators/rules/public_key.rb
@@ -230,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
230
231
  version: '0'
231
232
  requirements: []
232
233
  rubyforge_project:
233
- rubygems_version: 2.6.13
234
+ rubygems_version: 2.6.14
234
235
  signing_key:
235
236
  specification_version: 4
236
237
  summary: diaspora* federation library
@@ -1,37 +0,0 @@
1
- module Validation
2
- module Rule
3
- # Rule for validating the number of diaspora* IDs in a string.
4
- # The evaluated string is split at ";" and the result will be counted.
5
- class DiasporaIdCount
6
- # This rule must have a +maximum+ param.
7
- # @return [Hash] params
8
- attr_reader :params
9
-
10
- # Creates a new rule for a maximum diaspora* ID count validation
11
- # @param [Hash] params
12
- # @option params [Integer] :maximum maximum allowed id count
13
- def initialize(params)
14
- unless params.include?(:maximum) && params[:maximum].is_a?(Integer)
15
- raise ArgumentError, "A number has to be specified for :maximum"
16
- end
17
-
18
- @params = params
19
- end
20
-
21
- # The error key for this rule
22
- # @return [Symbol] error key
23
- def error_key
24
- :diaspora_id_count
25
- end
26
-
27
- def valid_value?(value)
28
- ids = value.split(";")
29
- return false unless ids.count <= params[:maximum]
30
- ids.each do |id|
31
- return false if DiasporaId::DIASPORA_ID.match(id).nil?
32
- end
33
- true
34
- end
35
- end
36
- end
37
- end