diaspora_federation 0.2.2 → 0.2.3

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