mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-20 16:03:21 +00:00
* feat(datatables): add an ACL editor for data table roles Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: take every pooled connection before the ACL apply locks Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRoYE5ZeAVvrDYdfhDAYXb * fix: refresh grant options only after the ACL apply validates its plan Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRoYE5ZeAVvrDYdfhDAYXb * fix: add only missing grant options before an ACL apply, never default privileges Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRoYE5ZeAVvrDYdfhDAYXb * fix: run one data table ACL apply at a time per server before it connects Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRoYE5ZeAVvrDYdfhDAYXb * fix: hold the ACL connection to the database that was authorized Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRoYE5ZeAVvrDYdfhDAYXb * fix: build the ACL connection from the authorized data table entry Resolving the settings again could land on a resource with the same database name on another server, which the later entry checks never see. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRoYE5ZeAVvrDYdfhDAYXb * fix: check ACL read reach against the entry it connects from Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRoYE5ZeAVvrDYdfhDAYXb * chore: update ee-repo-ref to 7e338e4dabf91689bfd7fb0333c6534040b17b59 This commit updates the EE repository reference after PR #787 was merged in windmill-ee-private. Previous ee-repo-ref: 0edd40979cf36bfba59323f3f6a0811ae1369cf5 New ee-repo-ref: 7e338e4dabf91689bfd7fb0333c6534040b17b59 Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
113 lines
3.6 KiB
Rust
113 lines
3.6 KiB
Rust
/*
|
|
* Author: Ruben Fiszel
|
|
* Copyright: Windmill Labs, Inc 2022
|
|
* This file and its contents are licensed under the AGPLv3 License.
|
|
* Please see the included NOTICE for copyright information and
|
|
* LICENSE-AGPL for a copy of the license.
|
|
*/
|
|
|
|
//! Where the data table permissions endpoints and their gates come from: the enterprise
|
|
//! implementation, or a refusal. Roles are an Enterprise Edition feature; see
|
|
//! `windmill_common::datatable_roles_oss`.
|
|
|
|
#[cfg(all(feature = "private", feature = "enterprise"))]
|
|
pub(crate) use crate::datatable_permissions_ee::{
|
|
ensure_governs_datatable, ensure_reaches_datatable, ensure_reaches_governing_datatable,
|
|
get_datatable_permissions, list_usable_datatable_roles, set_datatable_permissions,
|
|
usable_datatable_roles,
|
|
};
|
|
|
|
#[cfg(not(all(feature = "private", feature = "enterprise")))]
|
|
pub(crate) use ce::*;
|
|
|
|
#[cfg(not(all(feature = "private", feature = "enterprise")))]
|
|
mod ce {
|
|
use windmill_api_auth::ApiAuthed;
|
|
use windmill_common::{
|
|
datatable_roles_oss::datatable_roles_unavailable as unavailable,
|
|
error::Result,
|
|
workspaces::{resolve_governing_datatable, GoverningDatatable},
|
|
DB,
|
|
};
|
|
|
|
/// Nobody administers a data table's roles without them.
|
|
#[allow(dead_code)]
|
|
pub(crate) async fn ensure_governs_datatable(
|
|
_db: &DB,
|
|
_authed: &ApiAuthed,
|
|
_w_id: &str,
|
|
_governing: &GoverningDatatable,
|
|
) -> Result<()> {
|
|
Err(unavailable())
|
|
}
|
|
|
|
/// A data table not under roles is reached as it was before roles existed. One under roles is
|
|
/// refused: no role of it can be connected as.
|
|
pub(crate) async fn ensure_reaches_datatable(
|
|
db: &DB,
|
|
w_id: &str,
|
|
datatable_name: &str,
|
|
_authed: &ApiAuthed,
|
|
) -> Result<()> {
|
|
let governing = resolve_governing_datatable(db, w_id, datatable_name).await?;
|
|
if governing.datatable.permissions.is_none() {
|
|
Ok(())
|
|
} else {
|
|
Err(unavailable())
|
|
}
|
|
}
|
|
|
|
pub(crate) async fn ensure_reaches_governing_datatable(
|
|
_db: &DB,
|
|
_w_id: &str,
|
|
_datatable_name: &str,
|
|
governing: &GoverningDatatable,
|
|
_authed: &ApiAuthed,
|
|
) -> Result<()> {
|
|
if governing.datatable.permissions.is_none() {
|
|
Ok(())
|
|
} else {
|
|
Err(unavailable())
|
|
}
|
|
}
|
|
|
|
// The routes stay registered so the API has one shape; each answers after authentication,
|
|
// before anything is read.
|
|
|
|
pub(crate) async fn get_datatable_permissions(_authed: ApiAuthed) -> Result<String> {
|
|
Err(unavailable())
|
|
}
|
|
|
|
pub(crate) async fn set_datatable_permissions(_authed: ApiAuthed) -> Result<String> {
|
|
Err(unavailable())
|
|
}
|
|
|
|
pub(crate) async fn list_usable_datatable_roles(_authed: ApiAuthed) -> Result<String> {
|
|
Err(unavailable())
|
|
}
|
|
|
|
pub(crate) struct UsableDatatableRoles {
|
|
pub(crate) permissioned: bool,
|
|
pub(crate) roles: Vec<String>,
|
|
pub(crate) default_role: String,
|
|
}
|
|
|
|
/// A data table not under roles is used as `admin`, as before roles existed. One under roles
|
|
/// is refused: no role of it can be connected as.
|
|
pub(crate) async fn usable_datatable_roles(
|
|
_db: &DB,
|
|
_authed: &ApiAuthed,
|
|
_w_id: &str,
|
|
governing: &GoverningDatatable,
|
|
) -> Result<UsableDatatableRoles> {
|
|
if governing.datatable.permissions.is_some() {
|
|
return Err(unavailable());
|
|
}
|
|
Ok(UsableDatatableRoles {
|
|
permissioned: false,
|
|
roles: vec![],
|
|
default_role: windmill_common::datatable_roles::ADMIN_DATATABLE_ROLE.to_string(),
|
|
})
|
|
}
|
|
}
|