Merge remote-tracking branch 'origin/main' into feature/remove_spif_step_details

This commit is contained in:
jasquat 2023-03-20 11:06:02 -04:00
commit 50e4d27dbd
7 changed files with 96 additions and 32 deletions

View File

@ -1538,6 +1538,25 @@ paths:
items:
$ref: "#/components/schemas/User"
/users/exists/by-username:
post:
tags:
- Users
operationId: spiffworkflow_backend.routes.users_controller.user_exists_by_username
summary: Returns a true if user exists by username.
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/User"
responses:
"200":
description: true if user exists
content:
application/json:
schema:
$ref: "#/components/schemas/OkTrue"
/user-groups/for-current-user:
get:
tags:

View File

@ -1,13 +1,29 @@
"""Users_controller."""
from typing import Any
from typing import Dict
import flask
from flask import current_app
from flask import g
from flask import jsonify
from flask import make_response
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.user import UserModel
def user_exists_by_username(body: Dict[str, Any]) -> flask.wrappers.Response:
if "username" not in body:
raise ApiError(
error_code="username_not_given",
message="Username could not be found in post body.",
status_code=400,
)
username = body["username"]
found_user = UserModel.query.filter_by(username=username).first()
return make_response(jsonify({"user_found": found_user is not None}), 200)
def user_search(username_prefix: str) -> flask.wrappers.Response:
"""User_search."""
found_users = UserModel.query.filter(UserModel.username.like(f"{username_prefix}%")).all() # type: ignore

View File

@ -565,6 +565,7 @@ class AuthorizationService:
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/processes"))
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/service-tasks"))
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/user-groups/for-current-user"))
permissions_to_assign.append(PermissionToAssign(permission="create", target_uri="/users/exists/by-username"))
permissions_to_assign.append(
PermissionToAssign(permission="read", target_uri="/process-instances/find-by-id/*")
)

View File

@ -25,7 +25,6 @@ from spiffworkflow_backend.models.process_instance_file_data import (
from spiffworkflow_backend.models.process_model import ProcessModelInfo
from spiffworkflow_backend.models.task import Task
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.assertion_service import safe_assertion
from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.git_service import GitCommandError
from spiffworkflow_backend.services.git_service import GitService
@ -96,13 +95,6 @@ class ProcessInstanceService:
)
process_instance_lock_prefix = "Background"
for process_instance in records:
with safe_assertion(process_instance.status == status_value) as false_assumption:
if false_assumption:
raise AssertionError(
f"Queue assumed process instance {process_instance.id} has status of {status_value} "
f"when it really is {process_instance.status}"
)
locked = False
processor = None
try:
@ -110,10 +102,12 @@ class ProcessInstanceService:
processor = ProcessInstanceProcessor(process_instance)
processor.lock_process_instance(process_instance_lock_prefix)
locked = True
execution_strategy_name = current_app.config[
"SPIFFWORKFLOW_BACKEND_ENGINE_STEP_DEFAULT_STRATEGY_BACKGROUND"
]
processor.do_engine_steps(save=True, execution_strategy_name=execution_strategy_name)
db.session.refresh(process_instance)
if process_instance.status == status_value:
execution_strategy_name = current_app.config[
"SPIFFWORKFLOW_BACKEND_ENGINE_STEP_DEFAULT_STRATEGY_BACKGROUND"
]
processor.do_engine_steps(save=True, execution_strategy_name=execution_strategy_name)
except ProcessInstanceIsAlreadyLockedError:
continue
except Exception as e:

View File

@ -288,6 +288,7 @@ class TestAuthorizationService(BaseTest):
("/tasks/*", "read"),
("/tasks/*", "update"),
("/user-groups/for-current-user", "read"),
("/users/exists/by-username", "create"),
]
permissions_to_assign = AuthorizationService.explode_permissions("all", "BASIC")
permissions_to_assign_tuples = sorted([(p.target_uri, p.permission) for p in permissions_to_assign])

View File

@ -182,6 +182,10 @@ export default function ProcessInstanceListTable({
const [processInitiatorText, setProcessInitiatorText] = useState<
string | null
>(null);
const [
processInitiatorNotFoundErrorText,
setProcessInitiatorNotFoundErrorText,
] = useState<string>('');
const lastRequestedInitatorSearchTerm = useRef<string>();
@ -560,8 +564,17 @@ export default function ProcessInstanceListTable({
return (reportMetadata as any).filter_by;
};
const navigateToNewReport = (queryParamString: string) => {
removeError();
setProcessInstanceReportJustSaved(null);
setProcessInstanceFilters({});
navigate(`${processInstanceListPathPrefix}?${queryParamString}`);
};
const applyFilter = (event: any) => {
event.preventDefault();
setProcessInitiatorNotFoundErrorText('');
const { page, perPage } = getPageInfoFromSearchParams(
searchParams,
undefined,
@ -605,21 +618,33 @@ export default function ProcessInstanceListTable({
queryParamString += `&report_id=${processInstanceReportSelection.id}`;
}
if (processInitiatorSelection) {
queryParamString += `&process_initiator_username=${processInitiatorSelection.username}`;
} else if (processInitiatorText) {
queryParamString += `&process_initiator_username=${processInitiatorText}`;
}
const reportColumnsBase64 = encodeBase64(JSON.stringify(reportColumns()));
queryParamString += `&report_columns=${reportColumnsBase64}`;
const reportFilterByBase64 = encodeBase64(JSON.stringify(reportFilterBy()));
queryParamString += `&report_filter_by=${reportFilterByBase64}`;
removeError();
setProcessInstanceReportJustSaved(null);
setProcessInstanceFilters({});
navigate(`${processInstanceListPathPrefix}?${queryParamString}`);
if (processInitiatorSelection) {
queryParamString += `&process_initiator_username=${processInitiatorSelection.username}`;
navigateToNewReport(queryParamString);
} else if (processInitiatorText) {
HttpService.makeCallToBackend({
path: targetUris.userExists,
httpMethod: 'POST',
postBody: { username: processInitiatorText },
successCallback: (result: any) => {
if (result.user_found) {
queryParamString += `&process_initiator_username=${processInitiatorText}`;
navigateToNewReport(queryParamString);
} else {
setProcessInitiatorNotFoundErrorText(
`The provided username is invalid. Please type the exact username.`
);
}
},
});
} else {
navigateToNewReport(queryParamString);
}
};
const dateComponent = (
@ -683,6 +708,7 @@ export default function ProcessInstanceListTable({
items={processStatusAllOptions}
onChange={(selection: any) => {
setProcessStatusSelection(selection.selectedItems);
setRequiresRefilter(true);
}}
itemToString={(item: any) => {
return item || '';
@ -1142,6 +1168,8 @@ export default function ProcessInstanceListTable({
id="process-instance-initiator-search"
placeholder="Enter username"
labelText="Process Initiator"
invalid={processInitiatorNotFoundErrorText !== ''}
invalidText={processInitiatorNotFoundErrorText}
onChange={(event: any) => {
setProcessInitiatorText(event.target.value);
setRequiresRefilter(true);
@ -1450,14 +1478,18 @@ export default function ProcessInstanceListTable({
// eslint-disable-next-line prefer-destructuring
perPage = perPageOptions[1];
}
let resultsTable = (
<h2>
Please press the filter button when you have completed updating the
filters.
</h2>
);
if (!requiresRefilter) {
resultsTable = (
let refilterTextComponent = null;
if (requiresRefilter) {
refilterTextComponent = (
<h2>
Please press the filter button when you have completed updating the
filters.
</h2>
);
}
const resultsTable = (
<>
{refilterTextComponent}
<PaginationForTable
page={page}
perPage={perPage}
@ -1467,8 +1499,8 @@ export default function ProcessInstanceListTable({
perPageOptions={perPageOptions}
paginationClassName={paginationClassName}
/>
);
}
</>
);
return (
<>
{reportColumnForm()}

View File

@ -30,6 +30,7 @@ export const useUriListForPermissions = () => {
processModelShowPath: `/v1.0/process-models/${params.process_model_id}`,
secretListPath: `/v1.0/secrets`,
userSearch: `/v1.0/users/search`,
userExists: `/v1.0/users/exists/by-username`,
};
}, [params]);