Validate that all `$auth.*` references in a predicate are known fields. Called at policy creation time to reject typos like `$auth.usrname`.
(predicate: &RlsPredicate)
| 358 | /// |
| 359 | /// Called at policy creation time to reject typos like `$auth.usrname`. |
| 360 | pub fn validate_auth_refs(predicate: &RlsPredicate) -> crate::Result<()> { |
| 361 | let known_fields = [ |
| 362 | "id", |
| 363 | "username", |
| 364 | "email", |
| 365 | "tenant_id", |
| 366 | "org_id", |
| 367 | "org_ids", |
| 368 | "roles", |
| 369 | "groups", |
| 370 | "permissions", |
| 371 | "status", |
| 372 | "auth_method", |
| 373 | "auth_time", |
| 374 | "session_id", |
| 375 | ]; |
| 376 | |
| 377 | fn check(pred: &RlsPredicate, known: &[&str]) -> crate::Result<()> { |
| 378 | match pred { |
| 379 | RlsPredicate::Compare { value, .. } => check_value(value, known), |
| 380 | RlsPredicate::Contains { set, element } => { |
| 381 | check_value(set, known)?; |
| 382 | check_value(element, known) |
| 383 | } |
| 384 | RlsPredicate::Intersects { left, right } => { |
| 385 | check_value(left, known)?; |
| 386 | check_value(right, known) |
| 387 | } |
| 388 | RlsPredicate::And(children) | RlsPredicate::Or(children) => { |
| 389 | for child in children { |
| 390 | check(child, known)?; |
| 391 | } |
| 392 | Ok(()) |
| 393 | } |
| 394 | RlsPredicate::Not(inner) => check(inner, known), |
| 395 | RlsPredicate::AlwaysTrue | RlsPredicate::AlwaysFalse => Ok(()), |
| 396 | } |
| 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] = &[ |
no test coverage detected