|
3 | 3 | -- uses that; otherwise falls back to the embedded validator below. |
4 | 4 |
|
5 | 5 | local Schema = {} |
6 | | -local USE_PY = os.getenv("SCHEMA_VALIDATOR") == "python" |
| 6 | +local SCHEMA_MODE = os.getenv("SCHEMA_VALIDATOR") or "auto" -- auto|python|embedded |
7 | 7 |
|
8 | 8 | -- Schemas embedded as Lua tables (converted from schemas/*.json) |
9 | 9 | local SCHEMAS = { |
@@ -55,9 +55,27 @@ local SCHEMAS = { |
55 | 55 | type = "object", |
56 | 56 | required = { "subject", "asset" }, |
57 | 57 | properties = { |
58 | | - subject = { type = "string" }, |
59 | | - asset = { type = "string" }, |
60 | | - policy = { type = "string" }, |
| 58 | + subject = { type = "string", minLength = 1, maxLength = 128 }, |
| 59 | + asset = { type = "string", minLength = 1, maxLength = 256 }, |
| 60 | + policy = { type = "string", minLength = 1, maxLength = 128 }, |
| 61 | + }, |
| 62 | + }, |
| 63 | + accessAsset = { |
| 64 | + type = "object", |
| 65 | + required = { "asset", "ref" }, |
| 66 | + properties = { |
| 67 | + asset = { type = "string", minLength = 1, maxLength = 256 }, |
| 68 | + ref = { type = "string", minLength = 1, maxLength = 2048 }, |
| 69 | + visibility = { type = "string", enum = { "protected", "public" } } |
| 70 | + }, |
| 71 | + }, |
| 72 | + registryConfig = { |
| 73 | + type = "object", |
| 74 | + required = {}, |
| 75 | + properties = { |
| 76 | + version = { type = "string", minLength = 1, maxLength = 128 }, |
| 77 | + metadata = { type = "object" }, |
| 78 | + flags = { type = "object" }, |
61 | 79 | }, |
62 | 80 | }, |
63 | 81 | } |
@@ -149,7 +167,7 @@ local function validate_against(schema, value, path, errors) |
149 | 167 | end |
150 | 168 |
|
151 | 169 | function Schema.validate(schema_name, value) |
152 | | - if USE_PY then |
| 170 | + if SCHEMA_MODE ~= "embedded" then |
153 | 171 | local ok, err = Schema.validate_python(schema_name, value) |
154 | 172 | if ok ~= nil then return ok, err end -- nil means fallback to embedded |
155 | 173 | end |
|
167 | 185 |
|
168 | 186 | -- Python/jsonschema validator (optional). Returns nil if not usable. |
169 | 187 | function Schema.validate_python(schema_name, value) |
| 188 | + local has_py = os.execute("python3 -c \"import jsonschema\" >/dev/null 2>&1") |
| 189 | + if has_py ~= true and has_py ~= 0 then |
| 190 | + return nil, "python_jsonschema_missing" |
| 191 | + end |
170 | 192 | local schema_path = "schemas/" .. schema_name .. ".schema.json" |
171 | 193 | local f = io.open(schema_path, "r") |
172 | 194 | if not f then return nil, "schema_not_found" end |
@@ -202,12 +224,15 @@ function Schema.validate_python(schema_name, value) |
202 | 224 | end |
203 | 225 | jf:write(json_encode(value)) |
204 | 226 | jf:close() |
205 | | - local cmd = string.format("python3 - <<'PY'\nimport json,sys\ntry:\n import jsonschema\nexcept ImportError:\n sys.exit(2)\nwith open(%q) as f: schema=json.load(f)\nwith open(%q) as f: inst=json.load(f)\ntry:\n jsonschema.validate(inst, schema)\n sys.exit(0)\nexcept jsonschema.ValidationError as e:\n print(e.message)\n sys.exit(1)\nPY", schema_path, tmp) |
| 227 | + local cmd = string.format("python3 - <<'PY'\nimport json,sys,jsonschema\nwith open(%q) as f: schema=json.load(f)\nwith open(%q) as f: inst=json.load(f)\ntry:\n jsonschema.validate(inst, schema)\n sys.exit(0)\nexcept jsonschema.ValidationError:\n sys.exit(1)\nPY", schema_path, tmp) |
206 | 228 | local ok = os.execute(cmd) |
207 | 229 | os.remove(tmp) |
208 | | - if ok == 0 then return true end |
209 | | - if ok == 2 then return nil, "python_jsonschema_missing" end |
210 | | - return false, { "python_validator_failed" } |
| 230 | + if ok == 0 or ok == true then return true end |
| 231 | + -- If validation fails, treat as schema error; otherwise fallback |
| 232 | + if ok == 256 or ok == false then |
| 233 | + return false, { "python_validator_failed" } |
| 234 | + end |
| 235 | + return nil, "python_validator_unavailable" |
211 | 236 | end |
212 | 237 |
|
213 | 238 | return Schema |
0 commit comments