mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-17 00:02:59 +00:00
AllowOperatorForking now grants a fork to build in: the creator row copies only is_admin, so the operator is a developer there. Deploying back still runs with their parent role, where operator write checks refuse it. On self-hosted EE this makes them a full seat, which the ruleset toggle says. "Edit in fork" is shown to an operator when they may fork and the workspace has no canonical dev workspace. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
64 lines
2.1 KiB
Rust
64 lines
2.1 KiB
Rust
//! Its own test binary: the protection-rules cache is process-wide and keyed by workspace id, so a
|
|
//! sibling test forking its own `test-workspace` can cache an empty ruleset list over this one's.
|
|
use serde_json::json;
|
|
use sqlx::{Pool, Postgres};
|
|
|
|
use windmill_test_utils::*;
|
|
|
|
/// Operators cannot fork until a ruleset carries `AllowOperatorForking`, and the fork they then
|
|
/// create makes them a developer, not an operator.
|
|
#[sqlx::test(migrations = "../migrations", fixtures("base"))]
|
|
async fn test_operator_fork_needs_ruleset_and_develops_in_fork(
|
|
db: Pool<Postgres>,
|
|
) -> anyhow::Result<()> {
|
|
initialize_tracing().await;
|
|
let server = ApiServer::start(db.clone()).await?;
|
|
let base_url = format!(
|
|
"http://localhost:{}/api/w/test-workspace/workspaces",
|
|
server.addr.port()
|
|
);
|
|
let client = reqwest::Client::new();
|
|
|
|
sqlx::query(
|
|
"UPDATE usr SET operator = true WHERE workspace_id = 'test-workspace' AND username = 'test-user-3'",
|
|
)
|
|
.execute(&db)
|
|
.await?;
|
|
|
|
let fork = || {
|
|
client
|
|
.post(format!("{base_url}/create_fork"))
|
|
.header("Authorization", "Bearer SECRET_TOKEN_3")
|
|
.json(&json!({ "id": "wm-fork-op", "name": "Operator fork" }))
|
|
.send()
|
|
};
|
|
|
|
let resp = fork().await?;
|
|
assert_eq!(resp.status(), 403, "{}", resp.text().await?);
|
|
|
|
let resp = client
|
|
.post(format!("{base_url}/protection_rules"))
|
|
.header("Authorization", "Bearer SECRET_TOKEN")
|
|
.json(&json!({
|
|
"name": "ops-can-fork",
|
|
"rules": ["AllowOperatorForking"],
|
|
"bypass_groups": [],
|
|
"bypass_users": []
|
|
}))
|
|
.send()
|
|
.await?;
|
|
assert!(resp.status().is_success(), "{}", resp.text().await?);
|
|
|
|
let resp = fork().await?;
|
|
assert!(resp.status().is_success(), "{}", resp.text().await?);
|
|
|
|
let (operator, is_admin): (bool, bool) = sqlx::query_as(
|
|
"SELECT operator, is_admin FROM usr WHERE workspace_id = 'wm-fork-op' AND username = 'test-user-3'",
|
|
)
|
|
.fetch_one(&db)
|
|
.await?;
|
|
assert!(!operator && !is_admin);
|
|
|
|
Ok(())
|
|
}
|