added new api endpoint to get task-info so users with access to process instances can see the tasks but not the data
This commit is contained in:
parent
e3fe09490b
commit
662a1ec5d6
|
@ -170,15 +170,17 @@ def set_user_sentry_context() -> None:
|
||||||
def handle_exception(exception: Exception) -> flask.wrappers.Response:
|
def handle_exception(exception: Exception) -> flask.wrappers.Response:
|
||||||
"""Handles unexpected exceptions."""
|
"""Handles unexpected exceptions."""
|
||||||
set_user_sentry_context()
|
set_user_sentry_context()
|
||||||
id = capture_exception(exception)
|
|
||||||
|
|
||||||
organization_slug = current_app.config.get("SENTRY_ORGANIZATION_SLUG")
|
|
||||||
project_slug = current_app.config.get("SENTRY_PROJECT_SLUG")
|
|
||||||
sentry_link = None
|
sentry_link = None
|
||||||
if organization_slug and project_slug:
|
if not isinstance(exception, ApiError) or exception.error_code != "invalid_token":
|
||||||
sentry_link = (
|
id = capture_exception(exception)
|
||||||
f"https://sentry.io/{organization_slug}/{project_slug}/events/{id}"
|
|
||||||
)
|
organization_slug = current_app.config.get("SENTRY_ORGANIZATION_SLUG")
|
||||||
|
project_slug = current_app.config.get("SENTRY_PROJECT_SLUG")
|
||||||
|
if organization_slug and project_slug:
|
||||||
|
sentry_link = (
|
||||||
|
f"https://sentry.io/{organization_slug}/{project_slug}/events/{id}"
|
||||||
|
)
|
||||||
|
|
||||||
# !!!NOTE!!!: do this after sentry stuff since calling logger.exception
|
# !!!NOTE!!!: do this after sentry stuff since calling logger.exception
|
||||||
# seems to break the sentry sdk context where we no longer get back
|
# seems to break the sentry sdk context where we no longer get back
|
||||||
|
|
|
@ -673,6 +673,53 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Workflow"
|
$ref: "#/components/schemas/Workflow"
|
||||||
|
|
||||||
|
/process-instances/{modified_process_model_identifier}/{process_instance_id}/task-info:
|
||||||
|
parameters:
|
||||||
|
- name: modified_process_model_identifier
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: The unique id of an existing process model
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: process_instance_id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: The unique id of an existing process instance.
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
- name: process_identifier
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: The identifier of the process to use for the diagram. Useful for displaying the diagram for a call activity.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: all_tasks
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: If true, this wil return all tasks associated with the process instance and not just user tasks.
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
- name: spiff_step
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: If set will return the tasks as they were during a specific step of execution.
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Process Instances
|
||||||
|
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_task_list_without_task_data
|
||||||
|
summary: returns the list of all user tasks associated with process instance without the task data
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: list of tasks
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Task"
|
||||||
|
|
||||||
/process-instances/{modified_process_model_identifier}/{process_instance_id}:
|
/process-instances/{modified_process_model_identifier}/{process_instance_id}:
|
||||||
parameters:
|
parameters:
|
||||||
- name: modified_process_model_identifier
|
- name: modified_process_model_identifier
|
||||||
|
@ -1132,8 +1179,8 @@ paths:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- Process Instances
|
- Process Instances
|
||||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_task_list
|
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_task_list_with_task_data
|
||||||
summary: returns the list of all user tasks associated with process instance
|
summary: returns the list of all user tasks associated with process instance with the task data
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: list of tasks
|
description: list of tasks
|
||||||
|
|
|
@ -123,12 +123,12 @@ permissions:
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [read]
|
allowed_permissions: [read]
|
||||||
uri: /v1.0/processes
|
uri: /v1.0/processes
|
||||||
|
#
|
||||||
task-data-read:
|
# task-data-read:
|
||||||
groups: [demo]
|
# groups: [demo]
|
||||||
users: []
|
# users: []
|
||||||
allowed_permissions: [read]
|
# allowed_permissions: [read]
|
||||||
uri: /v1.0/task-data/*
|
# uri: /v1.0/task-data/*
|
||||||
|
|
||||||
|
|
||||||
manage-procurement-admin:
|
manage-procurement-admin:
|
||||||
|
|
|
@ -8,7 +8,7 @@ from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class SpiffLoggingModel(SpiffworkflowBaseDBModel):
|
class SpiffLoggingModel(SpiffworkflowBaseDBModel):
|
||||||
"""LoggingModel."""
|
"""SpiffLoggingModel."""
|
||||||
|
|
||||||
__tablename__ = "spiff_logging"
|
__tablename__ = "spiff_logging"
|
||||||
id: int = db.Column(db.Integer, primary_key=True)
|
id: int = db.Column(db.Integer, primary_key=True)
|
||||||
|
|
|
@ -1440,11 +1440,44 @@ def get_tasks(
|
||||||
return make_response(jsonify(response_json), 200)
|
return make_response(jsonify(response_json), 200)
|
||||||
|
|
||||||
|
|
||||||
def process_instance_task_list(
|
def process_instance_task_list_without_task_data(
|
||||||
modified_process_model_identifier: str,
|
modified_process_model_identifier: str,
|
||||||
process_instance_id: int,
|
process_instance_id: int,
|
||||||
all_tasks: bool = False,
|
all_tasks: bool = False,
|
||||||
spiff_step: int = 0,
|
spiff_step: int = 0,
|
||||||
|
) -> flask.wrappers.Response:
|
||||||
|
"""Process_instance_task_list_without_task_data."""
|
||||||
|
return process_instance_task_list(
|
||||||
|
modified_process_model_identifier,
|
||||||
|
process_instance_id,
|
||||||
|
all_tasks,
|
||||||
|
spiff_step,
|
||||||
|
get_task_data=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def process_instance_task_list_with_task_data(
|
||||||
|
modified_process_model_identifier: str,
|
||||||
|
process_instance_id: int,
|
||||||
|
all_tasks: bool = False,
|
||||||
|
spiff_step: int = 0,
|
||||||
|
) -> flask.wrappers.Response:
|
||||||
|
"""Process_instance_task_list_with_task_data."""
|
||||||
|
return process_instance_task_list(
|
||||||
|
modified_process_model_identifier,
|
||||||
|
process_instance_id,
|
||||||
|
all_tasks,
|
||||||
|
spiff_step,
|
||||||
|
get_task_data=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def process_instance_task_list(
|
||||||
|
_modified_process_model_identifier: str,
|
||||||
|
process_instance_id: int,
|
||||||
|
all_tasks: bool = False,
|
||||||
|
spiff_step: int = 0,
|
||||||
|
get_task_data: bool = False,
|
||||||
) -> flask.wrappers.Response:
|
) -> flask.wrappers.Response:
|
||||||
"""Process_instance_task_list."""
|
"""Process_instance_task_list."""
|
||||||
process_instance = find_process_instance_by_id_or_raise(process_instance_id)
|
process_instance = find_process_instance_by_id_or_raise(process_instance_id)
|
||||||
|
@ -1475,7 +1508,8 @@ def process_instance_task_list(
|
||||||
tasks = []
|
tasks = []
|
||||||
for spiff_task in spiff_tasks:
|
for spiff_task in spiff_tasks:
|
||||||
task = ProcessInstanceService.spiff_task_to_api_task(spiff_task)
|
task = ProcessInstanceService.spiff_task_to_api_task(spiff_task)
|
||||||
task.data = spiff_task.data
|
if get_task_data:
|
||||||
|
task.data = spiff_task.data
|
||||||
tasks.append(task)
|
tasks.append(task)
|
||||||
|
|
||||||
return make_response(jsonify(tasks), 200)
|
return make_response(jsonify(tasks), 200)
|
||||||
|
|
|
@ -14,7 +14,8 @@ export const useUriListForPermissions = () => {
|
||||||
processInstanceListPath: '/v1.0/process-instances',
|
processInstanceListPath: '/v1.0/process-instances',
|
||||||
processInstanceLogListPath: `/v1.0/logs/${params.process_model_id}/${params.process_instance_id}`,
|
processInstanceLogListPath: `/v1.0/logs/${params.process_model_id}/${params.process_instance_id}`,
|
||||||
processInstanceReportListPath: '/v1.0/process-instances/reports',
|
processInstanceReportListPath: '/v1.0/process-instances/reports',
|
||||||
processInstanceTaskListPath: `/v1.0/task-data/${params.process_model_id}/${params.process_instance_id}`,
|
processInstanceTaskListPath: `/v1.0/process-instances/${params.process_model_id}/${params.process_instance_id}/task-info`,
|
||||||
|
processInstanceTaskListDataPath: `/v1.0/task-data/${params.process_model_id}/${params.process_instance_id}`,
|
||||||
processModelCreatePath: `/v1.0/process-models/${params.process_group_id}`,
|
processModelCreatePath: `/v1.0/process-models/${params.process_group_id}`,
|
||||||
processModelFileCreatePath: `/v1.0/process-models/${params.process_model_id}/files`,
|
processModelFileCreatePath: `/v1.0/process-models/${params.process_model_id}/files`,
|
||||||
processModelFileShowPath: `/v1.0/process-models/${params.process_model_id}/files/${params.file_name}`,
|
processModelFileShowPath: `/v1.0/process-models/${params.process_model_id}/files/${params.file_name}`,
|
||||||
|
|
|
@ -70,8 +70,10 @@ export default function ProcessInstanceShow() {
|
||||||
const permissionRequestData: PermissionsToCheck = {
|
const permissionRequestData: PermissionsToCheck = {
|
||||||
[targetUris.messageInstanceListPath]: ['GET'],
|
[targetUris.messageInstanceListPath]: ['GET'],
|
||||||
[targetUris.processInstanceTaskListPath]: ['GET'],
|
[targetUris.processInstanceTaskListPath]: ['GET'],
|
||||||
|
[targetUris.processInstanceTaskListDataPath]: ['GET', 'PUT'],
|
||||||
[targetUris.processInstanceActionPath]: ['DELETE'],
|
[targetUris.processInstanceActionPath]: ['DELETE'],
|
||||||
[targetUris.processInstanceLogListPath]: ['GET'],
|
[targetUris.processInstanceLogListPath]: ['GET'],
|
||||||
|
[targetUris.processModelShowPath]: ['PUT'],
|
||||||
[`${targetUris.processInstanceActionPath}/suspend`]: ['PUT'],
|
[`${targetUris.processInstanceActionPath}/suspend`]: ['PUT'],
|
||||||
[`${targetUris.processInstanceActionPath}/terminate`]: ['PUT'],
|
[`${targetUris.processInstanceActionPath}/terminate`]: ['PUT'],
|
||||||
[`${targetUris.processInstanceActionPath}/resume`]: ['PUT'],
|
[`${targetUris.processInstanceActionPath}/resume`]: ['PUT'],
|
||||||
|
@ -104,9 +106,15 @@ export default function ProcessInstanceShow() {
|
||||||
if (typeof params.spiff_step !== 'undefined') {
|
if (typeof params.spiff_step !== 'undefined') {
|
||||||
taskParams = `${taskParams}&spiff_step=${params.spiff_step}`;
|
taskParams = `${taskParams}&spiff_step=${params.spiff_step}`;
|
||||||
}
|
}
|
||||||
if (ability.can('GET', targetUris.processInstanceTaskListPath)) {
|
let taskPath = '';
|
||||||
|
if (ability.can('GET', targetUris.processInstanceTaskListDataPath)) {
|
||||||
|
taskPath = `${targetUris.processInstanceTaskListDataPath}${taskParams}`;
|
||||||
|
} else if (ability.can('GET', targetUris.processInstanceTaskListPath)) {
|
||||||
|
taskPath = `${targetUris.processInstanceTaskListPath}${taskParams}`;
|
||||||
|
}
|
||||||
|
if (taskPath) {
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
path: `${targetUris.processInstanceTaskListPath}${taskParams}`,
|
path: taskPath,
|
||||||
successCallback: setTasks,
|
successCallback: setTasks,
|
||||||
failureCallback: processTaskFailure,
|
failureCallback: processTaskFailure,
|
||||||
});
|
});
|
||||||
|
@ -442,7 +450,9 @@ export default function ProcessInstanceShow() {
|
||||||
|
|
||||||
const canEditTaskData = (task: any) => {
|
const canEditTaskData = (task: any) => {
|
||||||
return (
|
return (
|
||||||
task.state === 'READY' && showingLastSpiffStep(processInstance as any)
|
ability.can('PUT', targetUris.processInstanceTaskListDataPath) &&
|
||||||
|
task.state === 'READY' &&
|
||||||
|
showingLastSpiffStep(processInstance as any)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -491,7 +501,10 @@ export default function ProcessInstanceShow() {
|
||||||
const taskDataButtons = (task: any) => {
|
const taskDataButtons = (task: any) => {
|
||||||
const buttons = [];
|
const buttons = [];
|
||||||
|
|
||||||
if (task.type === 'Script Task') {
|
if (
|
||||||
|
task.type === 'Script Task' &&
|
||||||
|
ability.can('PUT', targetUris.processModelShowPath)
|
||||||
|
) {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
<Button
|
<Button
|
||||||
data-qa="create-script-unit-test-button"
|
data-qa="create-script-unit-test-button"
|
||||||
|
|
|
@ -40,7 +40,7 @@ export default function TaskShow() {
|
||||||
|
|
||||||
const { targetUris } = useUriListForPermissions();
|
const { targetUris } = useUriListForPermissions();
|
||||||
const permissionRequestData: PermissionsToCheck = {
|
const permissionRequestData: PermissionsToCheck = {
|
||||||
[targetUris.processInstanceTaskListPath]: ['GET'],
|
[targetUris.processInstanceTaskListDataPath]: ['GET'],
|
||||||
};
|
};
|
||||||
const { ability, permissionsLoaded } = usePermissionFetcher(
|
const { ability, permissionsLoaded } = usePermissionFetcher(
|
||||||
permissionRequestData
|
permissionRequestData
|
||||||
|
@ -50,7 +50,7 @@ export default function TaskShow() {
|
||||||
if (permissionsLoaded) {
|
if (permissionsLoaded) {
|
||||||
const processResult = (result: any) => {
|
const processResult = (result: any) => {
|
||||||
setTask(result);
|
setTask(result);
|
||||||
if (ability.can('GET', targetUris.processInstanceTaskListPath)) {
|
if (ability.can('GET', targetUris.processInstanceTaskListDataPath)) {
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
path: `/task-data/${modifyProcessIdentifierForPathParam(
|
path: `/task-data/${modifyProcessIdentifierForPathParam(
|
||||||
result.process_model_identifier
|
result.process_model_identifier
|
||||||
|
|
Loading…
Reference in New Issue