jspg masking system installed

This commit is contained in:
2026-02-18 13:45:40 -05:00
parent 944675d669
commit 29c5160b49
8 changed files with 789 additions and 325 deletions

View File

@ -110,6 +110,65 @@ fn cache_json_schemas(enums: JsonB, types: JsonB, puncs: JsonB) -> JsonB {
JsonB(json!({ "response": "success" }))
}
#[pg_extern(strict, parallel_safe)]
fn mask_json_schema(schema_id: &str, instance: JsonB) -> JsonB {
// 1. Acquire Snapshot
let validator_arc = {
let lock = GLOBAL_VALIDATOR.read().unwrap();
lock.clone()
};
// 2. Validate (Lock-Free)
if let Some(validator) = validator_arc {
// We need a mutable copy of the value to mask it
let mut mutable_instance = instance.0.clone();
match validator.mask(schema_id, &mut mutable_instance) {
Ok(result) => {
// If valid, return the MASKED instance
if result.is_valid() {
let drop = crate::drop::Drop::success_with_val(mutable_instance);
JsonB(serde_json::to_value(drop).unwrap())
} else {
// If invalid, return errors (Schema Validation Errors)
let errors: Vec<crate::drop::Error> = result
.errors
.into_iter()
.map(|e| crate::drop::Error {
punc: None,
code: e.code,
message: e.message,
details: crate::drop::ErrorDetails { path: e.path },
})
.collect();
let drop = crate::drop::Drop::with_errors(errors);
JsonB(serde_json::to_value(drop).unwrap())
}
}
Err(e) => {
// Schema Not Found or other fatal error
let error = crate::drop::Error {
punc: None,
code: e.code,
message: e.message,
details: crate::drop::ErrorDetails { path: e.path },
};
let drop = crate::drop::Drop::with_errors(vec![error]);
JsonB(serde_json::to_value(drop).unwrap())
}
}
} else {
JsonB(json!({
"punc": null,
"errors": [{
"code": "VALIDATOR_NOT_INITIALIZED",
"message": "JSON Schemas have not been cached yet. Run cache_json_schemas()",
"details": { "path": "" }
}]
}))
}
}
#[pg_extern(strict, parallel_safe)]
fn validate_json_schema(schema_id: &str, instance: JsonB) -> JsonB {
// 1. Acquire Snapshot
@ -120,8 +179,37 @@ fn validate_json_schema(schema_id: &str, instance: JsonB) -> JsonB {
// 2. Validate (Lock-Free)
if let Some(validator) = validator_arc {
let drop = validator.validate(schema_id, &instance.0);
JsonB(serde_json::to_value(drop).unwrap())
match validator.validate(schema_id, &instance.0) {
Ok(result) => {
if result.is_valid() {
let drop = crate::drop::Drop::success();
JsonB(serde_json::to_value(drop).unwrap())
} else {
let errors: Vec<crate::drop::Error> = result
.errors
.into_iter()
.map(|e| crate::drop::Error {
punc: None,
code: e.code,
message: e.message,
details: crate::drop::ErrorDetails { path: e.path },
})
.collect();
let drop = crate::drop::Drop::with_errors(errors);
JsonB(serde_json::to_value(drop).unwrap())
}
}
Err(e) => {
let error = crate::drop::Error {
punc: None,
code: e.code,
message: e.message,
details: crate::drop::ErrorDetails { path: e.path },
};
let drop = crate::drop::Drop::with_errors(vec![error]);
JsonB(serde_json::to_value(drop).unwrap())
}
}
} else {
JsonB(json!({
"punc": null,
@ -136,34 +224,11 @@ fn validate_json_schema(schema_id: &str, instance: JsonB) -> JsonB {
#[pg_extern(strict, parallel_safe)]
fn json_schema_cached(schema_id: &str) -> bool {
// Acquire Snapshot for safe read
if let Some(validator) = GLOBAL_VALIDATOR.read().unwrap().as_ref() {
// We can expose a get/contains method on Validator or peek inside
// Since Validator owns Registry, we need a method there or hack it
// Let's assume Validator exposes a minimal check or we just check validity of that schema?
// Actually, registry access is private inside Validator now.
// We should add `has_schema` to Validator.
// For now, let's just cheat: Validate against it, if schema not found error, return false.
// Or better: Add `has_schema` to Validator.
// Let's do that in a follow up if needed, but for now we need a way.
// I'll add `has_schema` to Validator via a quick task or assume it exists?
// No, I just overwrote Validator without it.
// Better Logic: Try to validate "null" against it?
// No, simpler: Update Validator to expose has_schema.
// But I cannot call replace_validator now.
// Wait, I can try to access the public underlying registry if I expose it?
// Validator struct: `pub struct Validator { registry: Registry }`?
// No, keeping it opaque is better.
// Let's execute validate and check if error code is SCHEMA_NOT_FOUND.
let drop = validator.validate(schema_id, &serde_json::Value::Null); // Minimal payload
if !drop.errors.is_empty() {
for e in drop.errors {
if e.code == "SCHEMA_NOT_FOUND" {
return false;
}
}
match validator.validate(schema_id, &serde_json::Value::Null) {
Err(e) if e.code == "SCHEMA_NOT_FOUND" => false,
_ => true,
}
true
} else {
false
}
@ -178,13 +243,8 @@ fn clear_json_schemas() -> JsonB {
#[pg_extern(strict, parallel_safe)]
fn show_json_schemas() -> JsonB {
// Use _validator to suppress warning
if let Some(_validator) = GLOBAL_VALIDATOR.read().unwrap().as_ref() {
// Debug dump
// We need Validator to expose len() or debug info?
// Or just return success for now as in original code.
JsonB(json!({ "response": "success", "status": "active" }))
// Ideally: validator.registry_len()
} else {
JsonB(json!({ "response": "success", "status": "empty" }))
}