//! Postgres-trigger ancillary handlers (slot / publication / version management) //! must reject a path-mismatched scoped token before opening any connection — //! the route-level middleware only checks the scope domain, so per-path //! enforcement lives in the handlers. Rejecting pre-connection is why these tests //! need no real Postgres resource. use axum::{extract::Path, Extension, Json}; use sqlx::{Pool, Postgres}; use windmill_api_auth::ApiAuthed; use windmill_common::{db::UserDB, error::Error}; use windmill_trigger_postgres::{handler, Slot}; fn scoped_authed(scopes: Vec<&str>) -> ApiAuthed { ApiAuthed { email: "alice@windmill.dev".to_string(), username: "alice".to_string(), is_admin: false, is_operator: false, groups: vec![], folders: vec![], scopes: Some(scopes.into_iter().map(str::to_string).collect()), username_override: None, username_override_is_token_label: false, is_session_token: false, token_prefix: None, read_only: false, } } // A token scoped to `u/alice/db` must not reach a read handler for `u/bob/db`. #[sqlx::test] async fn read_handler_rejects_path_mismatched_scope(db: Pool) -> anyhow::Result<()> { let authed = scoped_authed(vec!["postgres_triggers:read:u/alice/db"]); let user_db = UserDB::new(db.clone()); let res = handler::get_postgres_version( authed, Extension(db), Extension(user_db), Path(("test-workspace".to_string(), "u/bob/db".to_string())), ) .await; assert!( matches!(res, Err(Error::PermissionDenied(_))), "expected PermissionDenied, got {res:?}" ); Ok(()) } // The destructive slot-drop handler must reject a write token scoped to another path. #[sqlx::test] async fn drop_slot_rejects_path_mismatched_scope(db: Pool) -> anyhow::Result<()> { let authed = scoped_authed(vec!["postgres_triggers:write:u/alice/db"]); let user_db = UserDB::new(db.clone()); let res = handler::drop_slot_name( authed, Extension(user_db), Extension(db), Path(("test-workspace".to_string(), "u/bob/db".to_string())), Json(Slot { name: "some_slot".to_string() }), ) .await; assert!( matches!(res, Err(Error::PermissionDenied(_))), "expected PermissionDenied, got {res:?}" ); Ok(()) }