mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-12 00:06:14 +00:00
Merge remote-tracking branch 'origin/main' into di/data-tables
This commit is contained in:
-24
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT flow.path FROM flow\n LEFT JOIN flow_version\n ON flow_version.path = flow.path AND flow_version.workspace_id = flow.workspace_id\n WHERE flow.path = $1 AND flow.workspace_id = $2 AND flow_version.id = $3",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "path",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "79464d5ef46a05ff9c05a4f1f4419ffac7e82c985d59a2e20e5c616461dbfe7b"
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
5e950542fed5ce5d6154932b3bc6b2172cb32c73
|
||||
5e950542fed5ce5d6154932b3bc6b2172cb32c73
|
||||
|
||||
@@ -6796,7 +6796,7 @@ paths:
|
||||
items:
|
||||
type: string
|
||||
|
||||
/w/{workspace}/flows/get/v/{version}/p/{path}:
|
||||
/w/{workspace}/flows/get/v/{version}:
|
||||
get:
|
||||
summary: get flow version
|
||||
operationId: getFlowVersion
|
||||
@@ -6807,7 +6807,6 @@ paths:
|
||||
required: true
|
||||
schema:
|
||||
type: number
|
||||
- $ref: "#/components/parameters/ScriptPath"
|
||||
tags:
|
||||
- flow
|
||||
responses:
|
||||
@@ -6818,7 +6817,7 @@ paths:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Flow"
|
||||
|
||||
/w/{workspace}/flows/history_update/v/{version}/p/{path}:
|
||||
/w/{workspace}/flows/history_update/v/{version}:
|
||||
post:
|
||||
summary: update flow history
|
||||
operationId: updateFlowHistory
|
||||
@@ -6829,7 +6828,6 @@ paths:
|
||||
required: true
|
||||
schema:
|
||||
type: number
|
||||
- $ref: "#/components/parameters/ScriptPath"
|
||||
requestBody:
|
||||
description: Flow deployment message
|
||||
required: true
|
||||
|
||||
@@ -69,10 +69,8 @@ pub fn workspaced_service() -> Router {
|
||||
"/list_paths_from_workspace_runnable/:runnable_kind/*path",
|
||||
get(list_paths_from_workspace_runnable),
|
||||
)
|
||||
.route(
|
||||
"/history_update/v/:version/p/*path",
|
||||
post(update_flow_history),
|
||||
)
|
||||
.route("/history_update/v/:version", post(update_flow_history))
|
||||
.route("/get/v/:version", get(get_flow_version_by_id))
|
||||
.route("/get/v/:version/p/*path", get(get_flow_version))
|
||||
.route(
|
||||
"/toggle_workspace_error_handler/*path",
|
||||
@@ -709,6 +707,73 @@ async fn get_flow_version(
|
||||
Ok(Json(flow))
|
||||
}
|
||||
|
||||
async fn get_flow_version_by_id(
|
||||
authed: ApiAuthed,
|
||||
Extension(user_db): Extension<UserDB>,
|
||||
Path((w_id, version)): Path<(String, i64)>,
|
||||
) -> JsonResult<Flow> {
|
||||
let mut tx = user_db.begin(&authed).await?;
|
||||
|
||||
// First, fetch the path to perform authorization check early
|
||||
let path: Option<String> = sqlx::query_scalar(
|
||||
"SELECT path FROM flow_version WHERE id = $1 AND workspace_id = $2",
|
||||
)
|
||||
.bind(version)
|
||||
.bind(&w_id)
|
||||
.fetch_optional(&mut *tx)
|
||||
.await?;
|
||||
|
||||
let path = not_found_if_none(
|
||||
path,
|
||||
"Flow version",
|
||||
format!("{} in workspace {}", version, w_id),
|
||||
)?;
|
||||
|
||||
// Perform authorization check before fetching full data
|
||||
check_scopes(&authed, || format!("flows:read:{}", path))?;
|
||||
|
||||
// Now fetch the full flow data with INNER JOIN to ensure flow exists
|
||||
let flow = sqlx::query_as::<_, Flow>(
|
||||
"SELECT
|
||||
flow.workspace_id,
|
||||
flow.path,
|
||||
flow.summary,
|
||||
flow.description,
|
||||
flow.archived,
|
||||
flow.extra_perms,
|
||||
flow.draft_only,
|
||||
flow.dedicated_worker,
|
||||
flow.tag,
|
||||
flow.ws_error_handler_muted,
|
||||
flow.timeout,
|
||||
flow.visible_to_runner_only,
|
||||
flow.on_behalf_of_email,
|
||||
flow_version.schema,
|
||||
flow_version.value,
|
||||
flow_version.created_at as edited_at,
|
||||
flow_version.created_by as edited_by
|
||||
FROM flow
|
||||
INNER JOIN flow_version
|
||||
ON flow_version.path = flow.path
|
||||
AND flow_version.workspace_id = flow.workspace_id
|
||||
WHERE flow_version.id = $1 AND flow.workspace_id = $2",
|
||||
)
|
||||
.bind(version)
|
||||
.bind(&w_id)
|
||||
.fetch_optional(&mut *tx)
|
||||
.await?;
|
||||
|
||||
tx.commit().await?;
|
||||
|
||||
let flow = not_found_if_none(
|
||||
flow,
|
||||
"Flow",
|
||||
format!("for version {} (flow may have been deleted)", version),
|
||||
)?;
|
||||
|
||||
Ok(Json(flow))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct FlowHistoryUpdate {
|
||||
pub deployment_msg: String,
|
||||
@@ -717,42 +782,42 @@ pub struct FlowHistoryUpdate {
|
||||
async fn update_flow_history(
|
||||
authed: ApiAuthed,
|
||||
Extension(user_db): Extension<UserDB>,
|
||||
Path((w_id, version, path)): Path<(String, i64, StripPath)>,
|
||||
Path((w_id, version)): Path<(String, i64)>,
|
||||
Json(history_update): Json<FlowHistoryUpdate>,
|
||||
) -> Result<()> {
|
||||
let path = path.to_path();
|
||||
check_scopes(&authed, || format!("flows:write:{}", path))?;
|
||||
let mut tx = user_db.begin(&authed).await?;
|
||||
let path_o = sqlx::query_scalar!(
|
||||
"SELECT flow.path FROM flow
|
||||
LEFT JOIN flow_version
|
||||
ON flow_version.path = flow.path AND flow_version.workspace_id = flow.workspace_id
|
||||
WHERE flow.path = $1 AND flow.workspace_id = $2 AND flow_version.id = $3",
|
||||
path,
|
||||
w_id,
|
||||
version
|
||||
|
||||
// Fetch path and perform authorization check early
|
||||
let path: Option<String> = sqlx::query_scalar(
|
||||
"SELECT path FROM flow_version WHERE workspace_id = $1 AND id = $2",
|
||||
)
|
||||
.bind(&w_id)
|
||||
.bind(version)
|
||||
.fetch_optional(&mut *tx)
|
||||
.await?;
|
||||
|
||||
if path_o.is_none() {
|
||||
tx.commit().await?;
|
||||
return Err(Error::NotFound(
|
||||
format!("Flow version {version} for path {path} not found").to_string(),
|
||||
));
|
||||
}
|
||||
let path = not_found_if_none(
|
||||
path,
|
||||
"Flow version",
|
||||
format!("{} in workspace {}", version, w_id),
|
||||
)?;
|
||||
|
||||
// Perform authorization check before any modifications
|
||||
check_scopes(&authed, || format!("flows:write:{}", path))?;
|
||||
|
||||
// Insert or update deployment metadata
|
||||
sqlx::query!(
|
||||
"INSERT INTO deployment_metadata (workspace_id, path, flow_version, deployment_msg) VALUES ($1, $2, $3, $4) ON CONFLICT (workspace_id, path, flow_version) WHERE flow_version IS NOT NULL DO UPDATE SET deployment_msg = EXCLUDED.deployment_msg",
|
||||
w_id,
|
||||
path_o.unwrap(),
|
||||
&w_id,
|
||||
path,
|
||||
version,
|
||||
history_update.deployment_msg,
|
||||
)
|
||||
.fetch_optional(&mut *tx)
|
||||
.await?;
|
||||
|
||||
tx.commit().await?;
|
||||
return Ok(());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_flow(
|
||||
|
||||
Generated
+9
-9
@@ -20,11 +20,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1753694789,
|
||||
"narHash": "sha256-cKgvtz6fKuK1Xr5LQW/zOUiAC0oSQoA9nOISB0pJZqM=",
|
||||
"lastModified": 1764517877,
|
||||
"narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "dc9637876d0dcc8c9e5e22986b857632effeb727",
|
||||
"rev": "2d293cbfa5a793b4c50d17c05ef9e385b90edf6c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -35,11 +35,11 @@
|
||||
},
|
||||
"nixpkgs-claude": {
|
||||
"locked": {
|
||||
"lastModified": 1763421233,
|
||||
"narHash": "sha256-Stk9ZYRkGrnnpyJ4eqt9eQtdFWRRIvMxpNRf4sIegnw=",
|
||||
"lastModified": 1764517877,
|
||||
"narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648",
|
||||
"rev": "2d293cbfa5a793b4c50d17c05ef9e385b90edf6c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -93,11 +93,11 @@
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1753757591,
|
||||
"narHash": "sha256-3okLvry8fRWZhJZP75pPC9P6U1dcu84VOCPhPLXYozI=",
|
||||
"lastModified": 1764643237,
|
||||
"narHash": "sha256-6Ezx9DqVv5UZ7DBK9rcNwBuQUENFyWPS7M09I+FvNao=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "b372cf71b4125d420d7648cbd898ab8f5c355be2",
|
||||
"rev": "e66d6b924ac59e6c722f69332f6540ea57c69233",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -29,8 +29,7 @@
|
||||
async function loadFlow(version: number) {
|
||||
selected = await FlowService.getFlowVersion({
|
||||
workspace: $workspaceStore!,
|
||||
version,
|
||||
path
|
||||
version
|
||||
})
|
||||
}
|
||||
|
||||
@@ -54,7 +53,6 @@
|
||||
await FlowService.updateFlowHistory({
|
||||
workspace: $workspaceStore!,
|
||||
version,
|
||||
path,
|
||||
requestBody: {
|
||||
deployment_msg: deploymentMsgUpdate!
|
||||
}
|
||||
|
||||
@@ -113,7 +113,6 @@
|
||||
if (templateId) {
|
||||
template = await FlowService.getFlowVersion({
|
||||
workspace: $workspaceStore!,
|
||||
path: templatePath,
|
||||
version: parseInt(templateId)
|
||||
})
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user