Merge remote-tracking branch 'origin/main' into feature/remove_spif_step_details
This commit is contained in:
commit
0567251192
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/*")
|
||||
)
|
||||
|
|
|
@ -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,6 +102,8 @@ class ProcessInstanceService:
|
|||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.lock_process_instance(process_instance_lock_prefix)
|
||||
locked = True
|
||||
db.session.refresh(process_instance)
|
||||
if process_instance.status == status_value:
|
||||
execution_strategy_name = current_app.config[
|
||||
"SPIFFWORKFLOW_BACKEND_ENGINE_STEP_DEFAULT_STRATEGY_BACKGROUND"
|
||||
]
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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 = (
|
||||
let refilterTextComponent = null;
|
||||
if (requiresRefilter) {
|
||||
refilterTextComponent = (
|
||||
<h2>
|
||||
Please press the filter button when you have completed updating the
|
||||
filters.
|
||||
</h2>
|
||||
);
|
||||
if (!requiresRefilter) {
|
||||
resultsTable = (
|
||||
}
|
||||
const resultsTable = (
|
||||
<>
|
||||
{refilterTextComponent}
|
||||
<PaginationForTable
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
|
@ -1467,8 +1499,8 @@ export default function ProcessInstanceListTable({
|
|||
perPageOptions={perPageOptions}
|
||||
paginationClassName={paginationClassName}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{reportColumnForm()}
|
||||
|
|
|
@ -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]);
|
||||
|
||||
|
|
Loading…
Reference in New Issue