This is an automated email from the ASF dual-hosted git repository. ephraimanierobi pushed a commit to branch v2-3-test in repository https://gitbox.apache.org/repos/asf/airflow.git
commit a51b679c386b5c3f9b95230c7c15556f85cbbfc5 Author: Brent Bovenzi <[email protected]> AuthorDate: Thu Apr 28 13:20:56 2022 -0400 Don't show grid actions if server would reject with permission denied (#23332) * Add edit permission check for grid actions * Remove if wrapper for meta tag * Use dag.can_edit (cherry picked from commit 67e8bdd691ded0e88760b3d59b9c58ba43fa9453) --- airflow/www/static/js/tree/Table.jsx | 33 +++++++++++++--------- .../js/tree/details/content/ConfirmDialog.jsx | 2 +- .../js/tree/details/content/dagRun/ClearRun.jsx | 11 +++++++- .../tree/details/content/dagRun/MarkFailedRun.jsx | 5 +++- .../tree/details/content/dagRun/MarkSuccessRun.jsx | 5 +++- .../js/tree/details/content/dagRun/QueueRun.jsx | 4 +++ .../content/taskInstance/MappedInstances.jsx | 3 +- .../content/taskInstance/taskActions/Clear.jsx | 6 +++- .../taskInstance/taskActions/MarkFailed.jsx | 7 +++-- .../taskInstance/taskActions/MarkSuccess.jsx | 7 +++-- .../content/taskInstance/taskActions/Run.jsx | 7 +++-- airflow/www/templates/airflow/dag.html | 3 +- 12 files changed, 66 insertions(+), 27 deletions(-) diff --git a/airflow/www/static/js/tree/Table.jsx b/airflow/www/static/js/tree/Table.jsx index e500b08966..6f8e351d86 100644 --- a/airflow/www/static/js/tree/Table.jsx +++ b/airflow/www/static/js/tree/Table.jsx @@ -72,6 +72,24 @@ const Table = ({ const lowerCount = (offset || 0) + 1; const upperCount = lowerCount + data.length - 1; + // Don't show row selection if selectRows doesn't exist + const selectProps = selectRows + ? [useRowSelect, + (hooks) => { + hooks.visibleColumns.push((cols) => [ + { + id: 'selection', + Cell: ({ row }) => ( + <div> + <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} /> + </div> + ), + }, + ...cols, + ]); + }] + : []; + const { getTableProps, getTableBodyProps, @@ -98,20 +116,7 @@ const Table = ({ }, useSortBy, usePagination, - useRowSelect, - (hooks) => { - hooks.visibleColumns.push((cols) => [ - { - id: 'selection', - Cell: ({ row }) => ( - <div> - <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} /> - </div> - ), - }, - ...cols, - ]); - }, + ...selectProps, ); const handleNext = () => { diff --git a/airflow/www/static/js/tree/details/content/ConfirmDialog.jsx b/airflow/www/static/js/tree/details/content/ConfirmDialog.jsx index 25d37d1276..823fddc4eb 100644 --- a/airflow/www/static/js/tree/details/content/ConfirmDialog.jsx +++ b/airflow/www/static/js/tree/details/content/ConfirmDialog.jsx @@ -55,7 +55,7 @@ const ConfirmDialog = ({ <AlertDialogBody> <Text mb={2}>{description}</Text> - {body.map((ti) => (<Code key={ti} fontSize="lg">{ti}</Code>))} + {Array.isArray(body) && body.map((ti) => (<Code key={ti} fontSize="lg">{ti}</Code>))} </AlertDialogBody> <AlertDialogFooter> diff --git a/airflow/www/static/js/tree/details/content/dagRun/ClearRun.jsx b/airflow/www/static/js/tree/details/content/dagRun/ClearRun.jsx index c423ba9fca..97c9438184 100644 --- a/airflow/www/static/js/tree/details/content/dagRun/ClearRun.jsx +++ b/airflow/www/static/js/tree/details/content/dagRun/ClearRun.jsx @@ -22,6 +22,9 @@ import { Button, useDisclosure } from '@chakra-ui/react'; import { useClearRun } from '../../../api'; import ConfirmDialog from '../ConfirmDialog'; +import { getMetaValue } from '../../../../utils'; + +const canEdit = getMetaValue('can_edit') === 'True'; const ClearRun = ({ dagId, runId }) => { const [affectedTasks, setAffectedTasks] = useState([]); @@ -42,7 +45,13 @@ const ClearRun = ({ dagId, runId }) => { return ( <> - <Button onClick={onClick} isLoading={isLoading}>Clear existing tasks</Button> + <Button + onClick={onClick} + isLoading={isLoading} + isDisabled={!canEdit} + > + Clear existing tasks + </Button> <ConfirmDialog isOpen={isOpen} onClose={onClose} diff --git a/airflow/www/static/js/tree/details/content/dagRun/MarkFailedRun.jsx b/airflow/www/static/js/tree/details/content/dagRun/MarkFailedRun.jsx index 1d3eb54cb5..3de973fd11 100644 --- a/airflow/www/static/js/tree/details/content/dagRun/MarkFailedRun.jsx +++ b/airflow/www/static/js/tree/details/content/dagRun/MarkFailedRun.jsx @@ -22,6 +22,9 @@ import { Button, useDisclosure } from '@chakra-ui/react'; import { useMarkFailedRun } from '../../../api'; import ConfirmDialog from '../ConfirmDialog'; +import { getMetaValue } from '../../../../utils'; + +const canEdit = getMetaValue('can_edit') === 'True'; const MarkFailedRun = ({ dagId, runId }) => { const [affectedTasks, setAffectedTasks] = useState([]); @@ -42,7 +45,7 @@ const MarkFailedRun = ({ dagId, runId }) => { return ( <> - <Button onClick={onClick} colorScheme="red" isLoading={isLoading}>Mark Failed</Button> + <Button onClick={onClick} colorScheme="red" isLoading={isLoading} isDisabled={!canEdit}>Mark Failed</Button> <ConfirmDialog isOpen={isOpen} onClose={onClose} diff --git a/airflow/www/static/js/tree/details/content/dagRun/MarkSuccessRun.jsx b/airflow/www/static/js/tree/details/content/dagRun/MarkSuccessRun.jsx index fbc49a3461..97ce9d439d 100644 --- a/airflow/www/static/js/tree/details/content/dagRun/MarkSuccessRun.jsx +++ b/airflow/www/static/js/tree/details/content/dagRun/MarkSuccessRun.jsx @@ -22,6 +22,9 @@ import { Button, useDisclosure } from '@chakra-ui/react'; import { useMarkSuccessRun } from '../../../api'; import ConfirmDialog from '../ConfirmDialog'; +import { getMetaValue } from '../../../../utils'; + +const canEdit = getMetaValue('can_edit') === 'True'; const MarkSuccessRun = ({ dagId, runId }) => { const [affectedTasks, setAffectedTasks] = useState([]); @@ -42,7 +45,7 @@ const MarkSuccessRun = ({ dagId, runId }) => { return ( <> - <Button onClick={onClick} colorScheme="green" isLoading={isLoading}>Mark Success</Button> + <Button onClick={onClick} colorScheme="green" isLoading={isLoading} isDisabled={!canEdit}>Mark Success</Button> <ConfirmDialog isOpen={isOpen} onClose={onClose} diff --git a/airflow/www/static/js/tree/details/content/dagRun/QueueRun.jsx b/airflow/www/static/js/tree/details/content/dagRun/QueueRun.jsx index 8eb6552fcf..b974988c33 100644 --- a/airflow/www/static/js/tree/details/content/dagRun/QueueRun.jsx +++ b/airflow/www/static/js/tree/details/content/dagRun/QueueRun.jsx @@ -22,6 +22,9 @@ import { Button, useDisclosure } from '@chakra-ui/react'; import { useQueueRun } from '../../../api'; import ConfirmDialog from '../ConfirmDialog'; +import { getMetaValue } from '../../../../utils'; + +const canEdit = getMetaValue('can_edit') === 'True'; const QueueRun = ({ dagId, runId }) => { const [affectedTasks, setAffectedTasks] = useState([]); @@ -49,6 +52,7 @@ const QueueRun = ({ dagId, runId }) => { isLoading={isLoading} ml="5px" title="Queue up new tasks to make the DAG run up-to-date with any DAG file changes." + isDisabled={!canEdit} > Queue up new tasks </Button> diff --git a/airflow/www/static/js/tree/details/content/taskInstance/MappedInstances.jsx b/airflow/www/static/js/tree/details/content/taskInstance/MappedInstances.jsx index 336b9d1f19..d2f211cd62 100644 --- a/airflow/www/static/js/tree/details/content/taskInstance/MappedInstances.jsx +++ b/airflow/www/static/js/tree/details/content/taskInstance/MappedInstances.jsx @@ -37,6 +37,7 @@ import { SimpleStatus } from '../../../StatusBox'; import Table from '../../../Table'; import Time from '../../../Time'; +const canEdit = getMetaValue('can_edit') === 'True'; const renderedTemplatesUrl = getMetaValue('rendered_templates_url'); const logUrl = getMetaValue('log_url'); const taskUrl = getMetaValue('task_url'); @@ -148,7 +149,7 @@ const MappedInstances = ({ pageSize={limit} setSortBy={setSortBy} isLoading={isLoading} - selectRows={selectRows} + selectRows={canEdit && selectRows} /> </Box> ); diff --git a/airflow/www/static/js/tree/details/content/taskInstance/taskActions/Clear.jsx b/airflow/www/static/js/tree/details/content/taskInstance/taskActions/Clear.jsx index 098cfdb793..3bbfafdcec 100644 --- a/airflow/www/static/js/tree/details/content/taskInstance/taskActions/Clear.jsx +++ b/airflow/www/static/js/tree/details/content/taskInstance/taskActions/Clear.jsx @@ -28,6 +28,9 @@ import { import ActionButton from './ActionButton'; import ConfirmDialog from '../../ConfirmDialog'; import { useClearTask } from '../../../../api'; +import { getMetaValue } from '../../../../../utils'; + +const canEdit = getMetaValue('can_edit') === 'True'; const Run = ({ dagId, @@ -96,7 +99,7 @@ const Run = ({ return ( <Flex justifyContent="space-between" width="100%"> - <ButtonGroup isAttached variant="outline"> + <ButtonGroup isAttached variant="outline" isDisabled={!canEdit}> <ActionButton bg={past && 'gray.100'} onClick={onTogglePast} name="Past" /> <ActionButton bg={future && 'gray.100'} onClick={onToggleFuture} name="Future" /> <ActionButton bg={upstream && 'gray.100'} onClick={onToggleUpstream} name="Upstream" /> @@ -108,6 +111,7 @@ const Run = ({ colorScheme="blue" onClick={onClick} isLoading={isLoading} + isDisabled={!canEdit} title="Clearing deletes the previous state of the task instance, allowing it to get re-triggered by the scheduler or a backfill command" > Clear diff --git a/airflow/www/static/js/tree/details/content/taskInstance/taskActions/MarkFailed.jsx b/airflow/www/static/js/tree/details/content/taskInstance/taskActions/MarkFailed.jsx index ffbaf8e321..6dd0ac13e2 100644 --- a/airflow/www/static/js/tree/details/content/taskInstance/taskActions/MarkFailed.jsx +++ b/airflow/www/static/js/tree/details/content/taskInstance/taskActions/MarkFailed.jsx @@ -28,6 +28,9 @@ import { import ActionButton from './ActionButton'; import { useConfirmMarkTask, useMarkFailedTask } from '../../../../api'; import ConfirmDialog from '../../ConfirmDialog'; +import { getMetaValue } from '../../../../../utils'; + +const canEdit = getMetaValue('can_edit') === 'True'; const MarkFailed = ({ dagId, @@ -90,13 +93,13 @@ const MarkFailed = ({ return ( <Flex justifyContent="space-between" width="100%"> - <ButtonGroup isAttached variant="outline"> + <ButtonGroup isAttached variant="outline" isDisabled={!canEdit}> <ActionButton bg={past && 'gray.100'} onClick={onTogglePast} name="Past" /> <ActionButton bg={future && 'gray.100'} onClick={onToggleFuture} name="Future" /> <ActionButton bg={upstream && 'gray.100'} onClick={onToggleUpstream} name="Upstream" /> <ActionButton bg={downstream && 'gray.100'} onClick={onToggleDownstream} name="Downstream" /> </ButtonGroup> - <Button colorScheme="red" onClick={onClick} isLoading={isLoading}> + <Button colorScheme="red" onClick={onClick} isLoading={isLoading} isDisabled={!canEdit}> Mark Failed </Button> <ConfirmDialog diff --git a/airflow/www/static/js/tree/details/content/taskInstance/taskActions/MarkSuccess.jsx b/airflow/www/static/js/tree/details/content/taskInstance/taskActions/MarkSuccess.jsx index 5f6950c629..56f2b9efe3 100644 --- a/airflow/www/static/js/tree/details/content/taskInstance/taskActions/MarkSuccess.jsx +++ b/airflow/www/static/js/tree/details/content/taskInstance/taskActions/MarkSuccess.jsx @@ -28,6 +28,9 @@ import { import ConfirmDialog from '../../ConfirmDialog'; import ActionButton from './ActionButton'; import { useMarkSuccessTask, useConfirmMarkTask } from '../../../../api'; +import { getMetaValue } from '../../../../../utils'; + +const canEdit = getMetaValue('can_edit') === 'True'; const MarkSuccess = ({ dagId, runId, taskId, mapIndexes, @@ -85,13 +88,13 @@ const MarkSuccess = ({ return ( <Flex justifyContent="space-between" width="100%"> - <ButtonGroup isAttached variant="outline"> + <ButtonGroup isAttached variant="outline" isDisabled={!canEdit}> <ActionButton bg={past && 'gray.100'} onClick={onTogglePast} name="Past" /> <ActionButton bg={future && 'gray.100'} onClick={onToggleFuture} name="Future" /> <ActionButton bg={upstream && 'gray.100'} onClick={onToggleUpstream} name="Upstream" /> <ActionButton bg={downstream && 'gray.100'} onClick={onToggleDownstream} name="Downstream" /> </ButtonGroup> - <Button colorScheme="green" onClick={onClick} isLoading={isLoading}> + <Button colorScheme="green" onClick={onClick} isLoading={isLoading} isDisabled={!canEdit}> Mark Success </Button> <ConfirmDialog diff --git a/airflow/www/static/js/tree/details/content/taskInstance/taskActions/Run.jsx b/airflow/www/static/js/tree/details/content/taskInstance/taskActions/Run.jsx index 85d502aeed..19559a8266 100644 --- a/airflow/www/static/js/tree/details/content/taskInstance/taskActions/Run.jsx +++ b/airflow/www/static/js/tree/details/content/taskInstance/taskActions/Run.jsx @@ -25,6 +25,9 @@ import { } from '@chakra-ui/react'; import { useRunTask } from '../../../../api'; +import { getMetaValue } from '../../../../../utils'; + +const canEdit = getMetaValue('can_edit') === 'True'; const Run = ({ dagId, @@ -54,7 +57,7 @@ const Run = ({ return ( <Flex justifyContent="space-between" width="100%"> - <ButtonGroup isAttached variant="outline"> + <ButtonGroup isAttached variant="outline" isDisabled={!canEdit}> <Button bg={ignoreAllDeps && 'gray.100'} onClick={onToggleAllDeps} @@ -77,7 +80,7 @@ const Run = ({ Ignore Task Deps </Button> </ButtonGroup> - <Button colorScheme="blue" onClick={onClick} isLoading={isLoading}> + <Button colorScheme="blue" onClick={onClick} isLoading={isLoading} isDisabled={!canEdit}> Run </Button> </Flex> diff --git a/airflow/www/templates/airflow/dag.html b/airflow/www/templates/airflow/dag.html index e7afde8af9..70adcf81d1 100644 --- a/airflow/www/templates/airflow/dag.html +++ b/airflow/www/templates/airflow/dag.html @@ -82,7 +82,8 @@ {% endif %} {% if external_log_name is defined %} <meta name="external_log_name" content="{{ external_log_name }}"> -{% endif %} + {% endif %} + <meta name="can_edit" content="{{ dag.can_edit }}"> {% endblock %} {% block content %}
