feat(permissions): allow users to deploy workflows in all workspaces they are an admin in (#1463)

* feat(permissions): allow admin workspace users to deploy workflows in workspaces they don't own

* fixed failing test

* added additional routes

* remove overly complex, unecessary test and fixed docs formatting

* follow DRY
This commit is contained in:
Waleed
2025-09-26 19:58:11 -07:00
committed by GitHub
parent 448e9ea835
commit bcc75376e5
10 changed files with 143 additions and 332 deletions

View File

@@ -2,8 +2,10 @@ import { db } from '@sim/db'
import { apiKey, userStats, workflow as workflowTable } from '@sim/db/schema'
import { eq } from 'drizzle-orm'
import { NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { getEnv } from '@/lib/env'
import { createLogger } from '@/lib/logs/console/logger'
import { hasWorkspaceAdminAccess } from '@/lib/permissions/utils'
import type { ExecutionResult } from '@/executor/types'
import type { WorkflowState } from '@/stores/workflows/workflow/types'
@@ -399,3 +401,64 @@ export const createHttpResponseFromBlock = (executionResult: ExecutionResult): N
headers: responseHeaders,
})
}
/**
* Validates that the current user has permission to access/modify a workflow
* Returns session and workflow info if authorized, or error response if not
*/
export async function validateWorkflowPermissions(
workflowId: string,
requestId: string,
action: 'read' | 'write' | 'admin' = 'read'
) {
const session = await getSession()
if (!session?.user?.id) {
logger.warn(`[${requestId}] No authenticated user session for workflow ${action}`)
return {
error: { message: 'Unauthorized', status: 401 },
session: null,
workflow: null,
}
}
const workflow = await getWorkflowById(workflowId)
if (!workflow) {
logger.warn(`[${requestId}] Workflow ${workflowId} not found`)
return {
error: { message: 'Workflow not found', status: 404 },
session: null,
workflow: null,
}
}
if (workflow.workspaceId) {
const hasAccess = await hasWorkspaceAdminAccess(session.user.id, workflow.workspaceId)
if (!hasAccess) {
logger.warn(
`[${requestId}] User ${session.user.id} unauthorized to ${action} workflow ${workflowId} in workspace ${workflow.workspaceId}`
)
return {
error: { message: `Unauthorized: Access denied to ${action} this workflow`, status: 403 },
session: null,
workflow: null,
}
}
} else {
if (workflow.userId !== session.user.id) {
logger.warn(
`[${requestId}] User ${session.user.id} unauthorized to ${action} workflow ${workflowId} owned by ${workflow.userId}`
)
return {
error: { message: `Unauthorized: Access denied to ${action} this workflow`, status: 403 },
session: null,
workflow: null,
}
}
}
return {
error: null,
session,
workflow,
}
}