| 397 | } |
| 398 | |
| 399 | fn check_value(val: &PredicateValue, known: &[&str]) -> crate::Result<()> { |
| 400 | match val { |
| 401 | PredicateValue::AuthRef(field) => { |
| 402 | let base = field.split('.').next().unwrap_or(field); |
| 403 | // Allow metadata.* sub-fields |
| 404 | if base == "metadata" { |
| 405 | return Ok(()); |
| 406 | } |
| 407 | if !known.contains(&base) { |
| 408 | return Err(crate::Error::BadRequest { |
| 409 | detail: format!( |
| 410 | "unknown $auth field: '{field}'. Valid fields: {}", |
| 411 | known.join(", ") |
| 412 | ), |
| 413 | }); |
| 414 | } |
| 415 | } |
| 416 | PredicateValue::AuthFunc { func, .. } => { |
| 417 | const KNOWN_FUNCS: &[&str] = &[ |
| 418 | "scope_status", |
| 419 | "scope_expires_at", |
| 420 | "quota_remaining", |
| 421 | "quota_pct", |
| 422 | ]; |
| 423 | if !KNOWN_FUNCS.contains(&func.as_str()) { |
| 424 | return Err(crate::Error::BadRequest { |
| 425 | detail: format!( |
| 426 | "unknown $auth function: '{func}'. Valid functions: {}", |
| 427 | KNOWN_FUNCS.join(", ") |
| 428 | ), |
| 429 | }); |
| 430 | } |
| 431 | } |
| 432 | _ => {} |
| 433 | } |
| 434 | Ok(()) |
| 435 | } |
| 436 | |
| 437 | check(predicate, &known_fields) |
| 438 | } |