From ccac73bb5458ffe5f3a0ff8ecdb64b33c72403d9 Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 19 Dec 2022 11:15:05 -0500 Subject: [PATCH 1/4] set the auth header when calling git commit w/ burnettk --- .../bin/git_commit_bpmn_models_repo | 42 +++++++++++++------ .../services/git_service.py | 1 + 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/spiffworkflow-backend/bin/git_commit_bpmn_models_repo b/spiffworkflow-backend/bin/git_commit_bpmn_models_repo index 62fc0cab0..0ba512021 100755 --- a/spiffworkflow-backend/bin/git_commit_bpmn_models_repo +++ b/spiffworkflow-backend/bin/git_commit_bpmn_models_repo @@ -14,21 +14,39 @@ git_commit_message="$2" git_branch="$3" git_commit_username="$4" git_commit_email="$5" +git_commit_password="$6" -if [[ -z "${5:-}" ]]; then +if [[ -z "${6:-}" ]]; then >&2 echo "usage: $(basename "$0") [bpmn_models_absolute_dir] [git_commit_message] [git_branch] [git_commit_username] [git_commit_email]" exit 1 fi -cd "$bpmn_models_absolute_dir" -git add . +function failed_to_get_lock() { + >&2 echo "ERROR: Failed to get lock." + exit 1 +} -# https://unix.stackexchange.com/a/155077/456630 -if [ -z "$(git status --porcelain)" ]; then - echo "No changes to commit" -else - git config --local user.name "$git_commit_username" - git config --local user.email "$git_commit_email" - git commit -m "$git_commit_message" - git push --set-upstream origin "$git_branch" -fi +function run() { + cd "$bpmn_models_absolute_dir" + git add . + + # https://unix.stackexchange.com/a/155077/456630 + if [ -z "$(git status --porcelain)" ]; then + echo "No changes to commit" + else + PAT="${git_commit_username}:${git_commit_password}" + AUTH=$(echo -n "$PAT" | openssl base64 | tr -d '\n') + + git config --local user.name "$git_commit_username" + git config --local user.email "$git_commit_email" + git config --local http.extraHeader "Authorization: Basic $AUTH" + git commit -m "$git_commit_message" + git push --set-upstream origin "$git_branch" + git config --unset --local http.extraHeader + fi +} + +exec {lock_fd}>/var/lock/mylockfile || failed_to_get_lock +flock --timeout 60 "$lock_fd" || failed_to_get_lock +run +flock -u "$lock_fd" diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py index 8ef952c3c..d94423a33 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py @@ -100,6 +100,7 @@ class GitService: branch_name_to_use, git_username, git_email, + current_app.config['GIT_USER_PASSWORD'] ] return cls.run_shell_command_to_get_stdout(shell_command) From bb5a4add1ff5bf700c88ba439bf596d5d4757009 Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 19 Dec 2022 11:25:21 -0500 Subject: [PATCH 2/4] added updated and created at columns on user w/ burnettk --- spiffworkflow-backend/migrations/env.py | 2 ++ .../versions/{4d75421c0af0_.py => e284612a9778_.py} | 8 +++++--- .../src/spiffworkflow_backend/models/user.py | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) rename spiffworkflow-backend/migrations/versions/{4d75421c0af0_.py => e284612a9778_.py} (98%) diff --git a/spiffworkflow-backend/migrations/env.py b/spiffworkflow-backend/migrations/env.py index 630e381ad..68feded2a 100644 --- a/spiffworkflow-backend/migrations/env.py +++ b/spiffworkflow-backend/migrations/env.py @@ -1,3 +1,5 @@ +from __future__ import with_statement + import logging from logging.config import fileConfig diff --git a/spiffworkflow-backend/migrations/versions/4d75421c0af0_.py b/spiffworkflow-backend/migrations/versions/e284612a9778_.py similarity index 98% rename from spiffworkflow-backend/migrations/versions/4d75421c0af0_.py rename to spiffworkflow-backend/migrations/versions/e284612a9778_.py index 34fa1e974..5ce586adb 100644 --- a/spiffworkflow-backend/migrations/versions/4d75421c0af0_.py +++ b/spiffworkflow-backend/migrations/versions/e284612a9778_.py @@ -1,8 +1,8 @@ """empty message -Revision ID: 4d75421c0af0 +Revision ID: e284612a9778 Revises: -Create Date: 2022-12-06 17:42:56.417673 +Create Date: 2022-12-19 11:23:10.567440 """ from alembic import op @@ -10,7 +10,7 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = '4d75421c0af0' +revision = 'e284612a9778' down_revision = None branch_labels = None depends_on = None @@ -77,6 +77,8 @@ def upgrade(): sa.Column('service_id', sa.String(length=255), nullable=False), sa.Column('name', sa.String(length=255), nullable=True), sa.Column('email', sa.String(length=255), nullable=True), + sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('created_at_in_seconds', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('service', 'service_id', name='service_key'), sa.UniqueConstraint('uid') diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/user.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/user.py index b8c83d0f7..5fa09896d 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/user.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/user.py @@ -37,6 +37,8 @@ class UserModel(SpiffworkflowBaseDBModel): service_id = db.Column(db.String(255), nullable=False, unique=False) name = db.Column(db.String(255)) email = db.Column(db.String(255)) + updated_at_in_seconds: int = db.Column(db.Integer) + created_at_in_seconds: int = db.Column(db.Integer) user_group_assignments = relationship("UserGroupAssignmentModel", cascade="delete") # type: ignore groups = relationship( # type: ignore From aec0416eed1416b5ae3a57b13bd83e059353391e Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 19 Dec 2022 11:54:22 -0500 Subject: [PATCH 3/4] do not allow editing task data for process instances that are not suspended and some code cleanup w/ burnettk --- spiffworkflow-backend/migrations/env.py | 2 - .../models/process_instance.py | 4 + .../routes/process_api_blueprint.py | 8 ++ .../services/git_service.py | 2 +- spiffworkflow-frontend/src/interfaces.ts | 4 + .../src/routes/ProcessInstanceShow.tsx | 122 +++++++++--------- 6 files changed, 78 insertions(+), 64 deletions(-) diff --git a/spiffworkflow-backend/migrations/env.py b/spiffworkflow-backend/migrations/env.py index 68feded2a..630e381ad 100644 --- a/spiffworkflow-backend/migrations/env.py +++ b/spiffworkflow-backend/migrations/env.py @@ -1,5 +1,3 @@ -from __future__ import with_statement - import logging from logging.config import fileConfig diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py index c89f457b0..935eb2094 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py @@ -26,6 +26,10 @@ class ProcessInstanceNotFoundError(Exception): """ProcessInstanceNotFoundError.""" +class ProcessInstanceTaskDataCannotBeUpdatedError(Exception): + """ProcessInstanceTaskDataCannotBeUpdatedError.""" + + class NavigationItemSchema(Schema): """NavigationItemSchema.""" diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py index 294a65247..f5a070b76 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -56,6 +56,9 @@ from spiffworkflow_backend.models.process_instance import ProcessInstanceApiSche from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus +from spiffworkflow_backend.models.process_instance import ( + ProcessInstanceTaskDataCannotBeUpdatedError, +) from spiffworkflow_backend.models.process_instance_metadata import ( ProcessInstanceMetadataModel, ) @@ -2110,6 +2113,11 @@ def update_task_data( ProcessInstanceModel.id == int(process_instance_id) ).first() if process_instance: + if process_instance.status != "suspended": + raise ProcessInstanceTaskDataCannotBeUpdatedError( + f"The process instance needs to be suspended to udpate the task-data. It is currently: {process_instance.status}" + ) + process_instance_bpmn_json_dict = json.loads(process_instance.bpmn_json) if "new_task_data" in body: new_task_data_str: str = body["new_task_data"] diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py index d94423a33..495603cf0 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/git_service.py @@ -100,7 +100,7 @@ class GitService: branch_name_to_use, git_username, git_email, - current_app.config['GIT_USER_PASSWORD'] + current_app.config["GIT_USER_PASSWORD"], ] return cls.run_shell_command_to_get_stdout(shell_command) diff --git a/spiffworkflow-frontend/src/interfaces.ts b/spiffworkflow-frontend/src/interfaces.ts index b0ab6208a..7805249be 100644 --- a/spiffworkflow-frontend/src/interfaces.ts +++ b/spiffworkflow-frontend/src/interfaces.ts @@ -52,6 +52,10 @@ export interface ProcessInstance { id: number; process_model_identifier: string; process_model_display_name: string; + status: string; + start_in_seconds: number | null; + end_in_seconds: number | null; + bpmn_xml_file_contents?: string; spiff_step?: number; } diff --git a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx index 88e5e3bb7..119f79646 100644 --- a/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessInstanceShow.tsx @@ -183,29 +183,23 @@ export default function ProcessInstanceShow() { return taskIds; }; - const currentSpiffStep = (processInstanceToUse: any) => { - if (typeof params.spiff_step === 'undefined') { - return processInstanceToUse.spiff_step; + const currentSpiffStep = () => { + if (processInstance && typeof params.spiff_step === 'undefined') { + return processInstance.spiff_step || 0; } return Number(params.spiff_step); }; - const showingFirstSpiffStep = (processInstanceToUse: any) => { - return currentSpiffStep(processInstanceToUse) === 1; + const showingFirstSpiffStep = () => { + return currentSpiffStep() === 1; }; - const showingLastSpiffStep = (processInstanceToUse: any) => { - return ( - currentSpiffStep(processInstanceToUse) === processInstanceToUse.spiff_step - ); + const showingLastSpiffStep = () => { + return processInstance && currentSpiffStep() === processInstance.spiff_step; }; - const spiffStepLink = ( - processInstanceToUse: any, - label: any, - distance: number - ) => { + const spiffStepLink = (label: any, distance: number) => { const processIdentifier = searchParams.get('process_identifier'); let queryParams = ''; if (processIdentifier) { @@ -217,32 +211,35 @@ export default function ProcessInstanceShow() { data-qa="process-instance-step-link" to={`/admin/process-instances/${params.process_model_id}/${ params.process_instance_id - }/${currentSpiffStep(processInstanceToUse) + distance}${queryParams}`} + }/${currentSpiffStep() + distance}${queryParams}`} > {label} ); }; - const previousStepLink = (processInstanceToUse: any) => { - if (showingFirstSpiffStep(processInstanceToUse)) { + const previousStepLink = () => { + if (showingFirstSpiffStep()) { return null; } - return spiffStepLink(processInstanceToUse, , -1); + return spiffStepLink(, -1); }; - const nextStepLink = (processInstanceToUse: any) => { - if (showingLastSpiffStep(processInstanceToUse)) { + const nextStepLink = () => { + if (showingLastSpiffStep()) { return null; } - return spiffStepLink(processInstanceToUse, , 1); + return spiffStepLink(, 1); }; - const getInfoTag = (processInstanceToUse: any) => { + const getInfoTag = () => { + if (!processInstance) { + return null; + } const currentEndDate = convertSecondsToFormattedDateTime( - processInstanceToUse.end_in_seconds + processInstance.end_in_seconds || 0 ); let currentEndDateTag; if (currentEndDate) { @@ -253,7 +250,7 @@ export default function ProcessInstanceShow() { {convertSecondsToFormattedDateTime( - processInstanceToUse.end_in_seconds + processInstance.end_in_seconds || 0 ) || 'N/A'} @@ -261,13 +258,13 @@ export default function ProcessInstanceShow() { } let statusIcon = ; - if (processInstanceToUse.status === 'suspended') { + if (processInstance.status === 'suspended') { statusIcon = ; - } else if (processInstanceToUse.status === 'complete') { + } else if (processInstance.status === 'complete') { statusIcon = ; - } else if (processInstanceToUse.status === 'terminated') { + } else if (processInstance.status === 'terminated') { statusIcon = ; - } else if (processInstanceToUse.status === 'error') { + } else if (processInstance.status === 'error') { statusIcon = ; } @@ -279,7 +276,7 @@ export default function ProcessInstanceShow() { {convertSecondsToFormattedDateTime( - processInstanceToUse.start_in_seconds + processInstance.start_in_seconds || 0 )} @@ -290,7 +287,7 @@ export default function ProcessInstanceShow() { - {processInstanceToUse.status} {statusIcon} + {processInstance.status} {statusIcon} @@ -333,11 +330,10 @@ export default function ProcessInstanceShow() { ); }; - const terminateButton = (processInstanceToUse: any) => { + const terminateButton = () => { if ( - ['complete', 'terminated', 'error'].indexOf( - processInstanceToUse.status - ) === -1 + processInstance && + !['complete', 'terminated', 'error'].includes(processInstance.status) ) { return ( @@ -354,11 +350,12 @@ export default function ProcessInstanceShow() { return
; }; - const suspendButton = (processInstanceToUse: any) => { + const suspendButton = () => { if ( - ['complete', 'terminated', 'error', 'suspended'].indexOf( - processInstanceToUse.status - ) === -1 + processInstance && + !['complete', 'terminated', 'error', 'suspended'].includes( + processInstance.status + ) ) { return (