mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-28 00:02:42 +00:00
* feat: configurable workspace roles with per-workspace overrides Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: close role review gaps in pickers, declarative sync and removal Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: keep resolve_role_name doc on its function Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: validate overrides on instance role changes and bill admins fully Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: allow pipeline drafts and keep role checks on one connection Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: list data pipelines in operator_can_draft Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: expect a 403 role refusal when an operator resolves jobs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: require a valid license for custom workspace roles Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: freeze workspace roles when the license lapses Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: pin the ee companion for workspace roles Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor: broadcast role override changes from the write path, not a trigger Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: update ee-repo-ref to b5294d38db082bdd104d5358a47695390694c05d This commit updates the EE repository reference after PR #891 was merged in windmill-ee-private. Previous ee-repo-ref: 688e00c5982865b14098f530d54280e2311994c0 New ee-repo-ref: b5294d38db082bdd104d5358a47695390694c05d Automated by sync-ee-ref workflow. * fix: let an admin row that kept the operator flag hold full rights everywhere Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: treat superadmin members as admins and return role names from get user Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
81 lines
2.7 KiB
Rust
81 lines
2.7 KiB
Rust
#![cfg(feature = "enterprise")]
|
|
|
|
use std::collections::BTreeMap;
|
|
|
|
use sqlx::{Pool, Postgres};
|
|
use windmill_common::global_settings::WORKSPACE_ROLES_SETTING;
|
|
use windmill_common::instance_config::sync_global_settings_declarative;
|
|
|
|
/// The declarative config sync writes `workspace_roles` without the HTTP settings handler, so it
|
|
/// must validate the value and rebuild `role_seat` itself, or billing misprices the new roles.
|
|
#[sqlx::test(migrations = "../migrations", fixtures("base"))]
|
|
async fn declarative_workspace_roles_validates_and_rebuilds_seats(db: Pool<Postgres>) {
|
|
windmill_common::roles::invalidate_all_roles_cache();
|
|
let desired =
|
|
|roles: serde_json::Value| BTreeMap::from([(WORKSPACE_ROLES_SETTING.to_string(), roles)]);
|
|
|
|
sync_global_settings_declarative(
|
|
&db,
|
|
&BTreeMap::new(),
|
|
&desired(serde_json::json!([{"name": "x", "capabilities": {"flows": "full"}}])),
|
|
&(),
|
|
)
|
|
.await
|
|
.expect_err("full flows without code must be refused");
|
|
|
|
sync_global_settings_declarative(
|
|
&db,
|
|
&BTreeMap::new(),
|
|
&desired(serde_json::json!([
|
|
{"name": "developer"},
|
|
{"name": "builder", "capabilities": {"flows": "compose"}},
|
|
{"name": "operator"}
|
|
])),
|
|
&(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
let author: bool = sqlx::query_scalar(
|
|
"SELECT author FROM role_seat WHERE workspace_id = '' AND role = 'builder'",
|
|
)
|
|
.fetch_one(&db)
|
|
.await
|
|
.unwrap();
|
|
assert!(author, "a role that composes flows costs a full seat");
|
|
|
|
// A workspace grants `builder` full flows on top of an instance definition that codes; the
|
|
// instance then withdrawing `code` would leave that workspace with inline code and no code.
|
|
sync_global_settings_declarative(
|
|
&db,
|
|
&BTreeMap::new(),
|
|
&desired(serde_json::json!([
|
|
{"name": "developer"},
|
|
{"name": "builder", "capabilities": {"code": true, "flows": "compose"}},
|
|
{"name": "operator"}
|
|
])),
|
|
&(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
sqlx::query(
|
|
"UPDATE workspace_settings SET role_overrides =
|
|
'{\"builder\": {\"capabilities\": {\"flows\": \"full\"}}}'
|
|
WHERE workspace_id = 'test-workspace'",
|
|
)
|
|
.execute(&db)
|
|
.await
|
|
.unwrap();
|
|
sync_global_settings_declarative(
|
|
&db,
|
|
&BTreeMap::new(),
|
|
&desired(serde_json::json!([
|
|
{"name": "developer"},
|
|
{"name": "builder", "capabilities": {"code": false, "flows": "compose"}},
|
|
{"name": "operator"}
|
|
])),
|
|
&(),
|
|
)
|
|
.await
|
|
.expect_err("an instance change that invalidates a workspace override must be refused");
|
|
}
|