Module: Sidetree::Validator

Defined in:
lib/sidetree/validator.rb

Class Method Summary collapse

Class Method Details

.valid_base64_encoding?(base64) ⇒ Boolean

Returns:

  • (Boolean)


179
180
181
# File 'lib/sidetree/validator.rb', line 179

def valid_base64_encoding?(base64)
  /^[A-Za-z0-9_-]+$/.match?(base64)
end

.validate_add_public_keys_patch!(patch) ⇒ Object



62
63
64
65
66
67
# File 'lib/sidetree/validator.rb', line 62

def validate_add_public_keys_patch!(patch)
  unless patch.keys.length == 2
    raise Error, "Patch missing or unknown property."
  end
  validate_public_keys!(patch[:publicKeys])
end

.validate_add_services_patch!(patch) ⇒ Object



82
83
84
85
86
87
88
89
90
# File 'lib/sidetree/validator.rb', line 82

def validate_add_services_patch!(patch)
  unless patch.keys.length == 2
    raise Error, "Patch missing or unknown property."
  end
  unless patch[:services].instance_of?(Array)
    raise Error, "Patch services not an array."
  end
  validate_services!(patch[:services])
end

.validate_canonicalize_object_hash!(content, multihash, target) ⇒ Object

Verify that the Multihash of content matches that of multihash.

Parameters:

  • content (String)

    content to be hashed

  • multihash (String)

    Hash value to be checked

  • target (String)

    Name of the target object to include in the error message

Raises:



223
224
225
226
227
228
# File 'lib/sidetree/validator.rb', line 223

def validate_canonicalize_object_hash!(content, multihash, target)
  unless Sidetree.to_hash(content) == multihash
    raise Sidetree::Error,
          "Canonicalized #{target} object hash does not match expected hash '#{multihash}'"
  end
end

.validate_cas_file_uri!(uri, target) ⇒ Object



261
262
263
264
265
266
267
268
269
270
# File 'lib/sidetree/validator.rb', line 261

def validate_cas_file_uri!(uri, target)
  unless uri.is_a?(String)
    raise Sidetree::Error,
          "Input #{target} CAS file URI '#{uri}' needs to be of string type"
  end
  if uri.bytesize > Sidetree::Params::MAX_CAS_URI_LENGTH
    raise Sidetree::Error,
          "Input #{target} CAS file URI byte size cannot exceed #{Sidetree::Params::MAX_CAS_URI_LENGTH}"
  end
end

.validate_delta!(delta) ⇒ Sidetree::Error

Parameters:

  • delta (Hash)

    delta object.

Returns:

Raises:



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/sidetree/validator.rb', line 7

def validate_delta!(delta)
  raise Error, "Delta does not defined." unless delta
  delta_size = delta.to_json_c14n.bytesize
  if delta_size > Sidetree::Params::MAX_DELTA_SIZE
    raise Error,
          "#{delta_size} bytes of 'delta' exceeded limit of #{Sidetree::Params::MAX_DELTA_SIZE} bytes."
  end

  if delta.instance_of?(Array)
    raise Error, "Delta object cannot be an array."
  end
  delta.keys.each do |k|
    unless %w[patches updateCommitment].include?(k.to_s)
      raise Error, "Property '#{k}' is not allowed in delta object."
    end
  end

  unless delta[:patches].instance_of?(Array)
    raise Error, "Patches object in delta must be an array."
  end
  delta[:patches].each { |p| validate_patch!(p) }

  validate_encoded_multi_hash!(delta[:updateCommitment], "updateCommitment")
end

.validate_did_type!(type) ⇒ Object

Raises:



230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/sidetree/validator.rb', line 230

def validate_did_type!(type)
  return unless type
  raise Error, "DID type must be a string." unless type.instance_of?(String)
  if type.length > 4
    raise Error,
          "DID type string '#{type}' cannot be longer than 4 characters."
  end
  unless valid_base64_encoding?(type)
    raise Error,
          "DID type string '#{type}' contains a non-Base64URL character."
  end
end

.validate_document!(document) ⇒ Object

Raises:



51
52
53
54
55
56
57
58
59
60
# File 'lib/sidetree/validator.rb', line 51

def validate_document!(document)
  raise Error, "Document object missing in patch object" unless document
  document.keys.each do |k|
    unless %w[publicKeys services].include?(k.to_s)
      raise Error, "Property '#{k}' is not allowed in document object."
    end
  end
  validate_public_keys!(document[:publicKeys]) if document[:publicKeys]
  validate_services!(document[:services]) if document[:services]
end

.validate_encoded_multi_hash!(multi_hash, target) ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/sidetree/validator.rb', line 205

def validate_encoded_multi_hash!(multi_hash, target)
  begin
    decoded = Multihashes.decode(Base64.urlsafe_decode64(multi_hash))
    unless Params::HASH_ALGORITHM.include?(decoded[:code])
      raise Error,
            "Given #{target} uses unsupported multihash algorithm with code #{decoded[:code]}."
    end
  rescue StandardError
    raise Error,
          "Given #{target} string '#{multi_hash}' is not a multihash."
  end
end

.validate_id!(id) ⇒ Object

Raises:



197
198
199
200
201
202
203
# File 'lib/sidetree/validator.rb', line 197

def validate_id!(id)
  raise Error, "id does not string." unless id.instance_of?(String)
  raise Error, "id is too long." if id.length > 50
  unless valid_base64_encoding?(id)
    raise Error, "id does not use base64url character set."
  end
end

.validate_patch!(patch) ⇒ Object

Parameters:

  • patch (Hash)

    patch object.

Raises:



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/sidetree/validator.rb', line 34

def validate_patch!(patch)
  case patch[:action]
  when OP::PatchAction::REPLACE
    validate_document!(patch[:document])
  when OP::PatchAction::ADD_PUBLIC_KEYS
    validate_add_public_keys_patch!(patch)
  when OP::PatchAction::REMOVE_PUBLIC_KEYS
    validate_remove_public_keys_patch!(patch)
  when OP::PatchAction::ADD_SERVICES
    validate_add_services_patch!(patch)
  when OP::PatchAction::REMOVE_SERVICES
    validate_remove_services_patch!(patch)
  else
    raise Error, "#{patch[:action]} is unknown patch action."
  end
end

.validate_public_keys!(public_keys) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/sidetree/validator.rb', line 105

def validate_public_keys!(public_keys)
  unless public_keys.instance_of?(Array)
    raise Error, "publicKeys must be an array."
  end
  pubkey_ids = []
  public_keys.each do |public_key|
    public_key.keys.each do |k|
      unless %w[id type purposes publicKeyJwk].include?(k.to_s)
        raise Error, "Property '#{k}' is not allowed in publicKeys object."
      end
    end
    if public_key[:publicKeyJwk].instance_of?(Array)
      raise Error, "publicKeyJwk object cannot be an array."
    end
    if public_key[:type] && !public_key[:type].is_a?(String)
      raise Error, "Public key type #{public_key[:type]} is incorrect."
    end

    validate_id!(public_key[:id])

    if pubkey_ids.include?(public_key[:id])
      raise Error, "Public key id is duplicated."
    end
    pubkey_ids << public_key[:id]

    if public_key[:purposes]
      unless public_key[:purposes].instance_of?(Array)
        raise Error, "purposes must be an array."
      end
      unless public_key[:purposes].count == public_key[:purposes].uniq.count
        raise Error, "purpose is duplicated."
      end
      public_key[:purposes].each do |purpose|
        unless OP::PublicKeyPurpose.values.include?(purpose)
          raise Error, "purpose #{} is invalid."
        end
      end
    end
  end
end

.validate_remove_public_keys_patch!(patch) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/sidetree/validator.rb', line 69

def validate_remove_public_keys_patch!(patch)
  patch.keys.each do |k|
    unless %w[action ids].include?(k.to_s)
      raise Error, "Unexpected property '#{k}' in remove-public-keys patch."
    end
  end
  unless patch[:ids].instance_of?(Array)
    raise Error, "Patch public key ids not an array."
  end

  patch[:ids].each { |id| validate_id!(id) }
end

.validate_remove_services_patch!(patch) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/sidetree/validator.rb', line 92

def validate_remove_services_patch!(patch)
  patch.keys.each do |k|
    unless %w[action ids].include?(k.to_s)
      raise Error, "Unexpected property '#{k}' in remove-services patch."
    end
  end
  unless patch[:ids].instance_of?(Array)
    raise Error, "Patch service ids not an array."
  end

  patch[:ids].each { |id| validate_id!(id) }
end

.validate_services!(services) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/sidetree/validator.rb', line 146

def validate_services!(services)
  unless services.instance_of?(Array)
    raise Error, "services must be an array."
  end

  service_ids = []
  services.each do |service|
    unless service.keys.length == 3
      raise Error, "Service has missing or unknown property."
    end

    validate_id!(service[:id])

    if service_ids.include?(service[:id])
      raise Error, "Service id has to be unique."
    end
    service_ids << service[:id]

    unless service[:type].is_a?(String)
      raise Error, "Service type #{service[:type]} is incorrect."
    end
    raise Error, "Service type too long." if service[:type].length > 30

    endpoint = service[:serviceEndpoint]
    if endpoint.instance_of?(String)
      validate_uri!(endpoint)
    elsif endpoint.instance_of?(Hash)
    else
      raise Error, "ServiceEndpoint must be string or object."
    end
  end
end

.validate_suffix_data!(suffix) ⇒ Object



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/sidetree/validator.rb', line 243

def validate_suffix_data!(suffix)
  if suffix.instance_of?(Array)
    raise Error, "Suffix data can not be an array."
  end
  suffix.keys.each do |k|
    unless %w[deltaHash recoveryCommitment type].include?(k.to_s)
      raise Error, "Property '#{k}' is not allowed in publicKeys object."
    end
  end
  validate_encoded_multi_hash!(suffix[:deltaHash], "delta hash")
  validate_encoded_multi_hash!(
    suffix[:recoveryCommitment],
    "recovery commitment"
  )
  validate_encoded_multi_hash!(suffix[:deltaHash], "delta hash")
  validate_did_type!(suffix[:type])
end

.validate_uri!(uri) ⇒ Sidetree::Error

Validate uri

Parameters:

  • uri (String)

    uri

Returns:



186
187
188
189
190
191
192
193
194
195
# File 'lib/sidetree/validator.rb', line 186

def validate_uri!(uri)
  begin
    URI.parse(uri)
    unless uri =~ /\A#{URI.regexp(%w[http https])}\z/
      raise Error, "URI string '#{uri}' is not a valid URI."
    end
  rescue StandardError
    raise Error, "URI string '#{uri}' is not a valid URI."
  end
end