added method to add permissions based on macros w/ burnettk
This commit is contained in:
parent
4b7de2cc6d
commit
6171eef87b
|
@ -129,37 +129,6 @@ permissions:
|
||||||
uri: /processes
|
uri: /processes
|
||||||
|
|
||||||
|
|
||||||
manage-procurement-admin:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-groups/manage-procurement:*
|
|
||||||
manage-procurement-admin-slash:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-groups/manage-procurement/*
|
|
||||||
manage-procurement-admin-models:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-models/manage-procurement:*
|
|
||||||
manage-procurement-admin-models-slash:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-models/manage-procurement/*
|
|
||||||
manage-procurement-admin-instances:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-instances/manage-procurement:*
|
|
||||||
manage-procurement-admin-instances-slash:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-instances/manage-procurement/*
|
|
||||||
|
|
||||||
finance-admin:
|
finance-admin:
|
||||||
groups: ["Finance Team"]
|
groups: ["Finance Team"]
|
||||||
users: []
|
users: []
|
||||||
|
|
|
@ -48,12 +48,6 @@ groups:
|
||||||
lead1
|
lead1
|
||||||
]
|
]
|
||||||
|
|
||||||
core-contributor:
|
|
||||||
users:
|
|
||||||
[
|
|
||||||
core,
|
|
||||||
harmeet,
|
|
||||||
]
|
|
||||||
test:
|
test:
|
||||||
users: [natalia]
|
users: [natalia]
|
||||||
|
|
||||||
|
@ -64,25 +58,7 @@ permissions:
|
||||||
allowed_permissions: [create, read, update, delete]
|
allowed_permissions: [create, read, update, delete]
|
||||||
uri: /*
|
uri: /*
|
||||||
|
|
||||||
tasks-crud:
|
# open system defaults for everybody
|
||||||
groups: [everybody]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /tasks/*
|
|
||||||
|
|
||||||
service-tasks:
|
|
||||||
groups: [everybody]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [read]
|
|
||||||
uri: /service-tasks
|
|
||||||
user-groups-for-current-user:
|
|
||||||
groups: [everybody]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [read]
|
|
||||||
uri: /user-groups/for-current-user
|
|
||||||
|
|
||||||
|
|
||||||
# read all for everybody
|
|
||||||
read-all-process-groups:
|
read-all-process-groups:
|
||||||
groups: [everybody]
|
groups: [everybody]
|
||||||
users: []
|
users: []
|
||||||
|
@ -93,6 +69,8 @@ permissions:
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [read]
|
allowed_permissions: [read]
|
||||||
uri: /process-models/*
|
uri: /process-models/*
|
||||||
|
|
||||||
|
# basic perms for everybody
|
||||||
read-all-process-instances-for-me:
|
read-all-process-instances-for-me:
|
||||||
groups: [everybody]
|
groups: [everybody]
|
||||||
users: []
|
users: []
|
||||||
|
@ -108,39 +86,23 @@ permissions:
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [read]
|
allowed_permissions: [read]
|
||||||
uri: /processes
|
uri: /processes
|
||||||
|
service-tasks:
|
||||||
|
groups: [everybody]
|
||||||
|
users: []
|
||||||
|
allowed_permissions: [read]
|
||||||
|
uri: /service-tasks
|
||||||
|
tasks-crud:
|
||||||
|
groups: [everybody]
|
||||||
|
users: []
|
||||||
|
allowed_permissions: [create, read, update, delete]
|
||||||
|
uri: /tasks/*
|
||||||
|
user-groups-for-current-user:
|
||||||
|
groups: [everybody]
|
||||||
|
users: []
|
||||||
|
allowed_permissions: [read]
|
||||||
|
uri: /user-groups/for-current-user
|
||||||
|
|
||||||
|
|
||||||
manage-procurement-admin:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-groups/manage-procurement:*
|
|
||||||
manage-procurement-admin-slash:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-groups/manage-procurement/*
|
|
||||||
manage-procurement-admin-models:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-models/manage-procurement:*
|
|
||||||
manage-procurement-admin-models-slash:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-models/manage-procurement/*
|
|
||||||
manage-procurement-admin-instances:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-instances/manage-procurement:*
|
|
||||||
manage-procurement-admin-instances-slash:
|
|
||||||
groups: ["Project Lead"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create, read, update, delete]
|
|
||||||
uri: /process-instances/manage-procurement/*
|
|
||||||
|
|
||||||
finance-admin:
|
finance-admin:
|
||||||
groups: ["Finance Team"]
|
groups: ["Finance Team"]
|
||||||
users: []
|
users: []
|
||||||
|
@ -148,23 +110,37 @@ permissions:
|
||||||
uri: /process-groups/manage-procurement:procurement:*
|
uri: /process-groups/manage-procurement:procurement:*
|
||||||
|
|
||||||
manage-revenue-streams-instances:
|
manage-revenue-streams-instances:
|
||||||
groups: ["core-contributor", "demo"]
|
groups: ["demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create, read]
|
allowed_permissions: [create]
|
||||||
uri: /process-instances/manage-revenue-streams:product-revenue-streams:customer-contracts-trade-terms/*
|
uri: /process-instances/manage-revenue-streams:product-revenue-streams:customer-contracts-trade-terms/*
|
||||||
|
|
||||||
manage-procurement-invoice-instances:
|
manage-procurement-invoice-instances:
|
||||||
groups: ["core-contributor", "demo"]
|
groups: ["demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create, read]
|
allowed_permissions: [create]
|
||||||
uri: /process-instances/manage-procurement:procurement:core-contributor-invoice-management:*
|
uri: /process-instances/manage-procurement:procurement:core-contributor-invoice-management:*
|
||||||
|
|
||||||
manage-procurement-instances:
|
manage-procurement-instances:
|
||||||
groups: ["core-contributor", "demo"]
|
groups: ["demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create, read]
|
allowed_permissions: [create]
|
||||||
uri: /process-instances/manage-procurement:vendor-lifecycle-management:*
|
uri: /process-instances/manage-procurement:vendor-lifecycle-management:*
|
||||||
|
|
||||||
|
manage-revenue-streams-instances-for-me:
|
||||||
|
groups: ["demo"]
|
||||||
|
users: []
|
||||||
|
allowed_permissions: [read]
|
||||||
|
uri: /process-instances/for-me/manage-revenue-streams:product-revenue-streams:customer-contracts-trade-terms/*
|
||||||
|
manage-procurement-invoice-instances-for-me:
|
||||||
|
groups: ["demo"]
|
||||||
|
users: []
|
||||||
|
allowed_permissions: [read]
|
||||||
|
uri: /process-instances/for-me/manage-procurement:procurement:core-contributor-invoice-management:*
|
||||||
|
manage-procurement-instances-for-me:
|
||||||
|
groups: ["demo"]
|
||||||
|
users: []
|
||||||
|
allowed_permissions: [read]
|
||||||
|
uri: /process-instances/for-me/manage-procurement:vendor-lifecycle-management:*
|
||||||
|
|
||||||
create-test-instances:
|
create-test-instances:
|
||||||
groups: ["test"]
|
groups: ["test"]
|
||||||
users: []
|
users: []
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""Authorization_service."""
|
"""Authorization_service."""
|
||||||
|
from dataclasses import dataclass
|
||||||
import inspect
|
import inspect
|
||||||
import re
|
import re
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
|
@ -46,6 +47,21 @@ class UserDoesNotHaveAccessToTaskError(Exception):
|
||||||
"""UserDoesNotHaveAccessToTaskError."""
|
"""UserDoesNotHaveAccessToTaskError."""
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PermissionToAssign:
|
||||||
|
permission: str
|
||||||
|
target_uri: str
|
||||||
|
|
||||||
|
|
||||||
|
PATH_SEGMENTS_FOR_PERMISSION_ALL = [
|
||||||
|
'/logs',
|
||||||
|
'/process-instances',
|
||||||
|
'/process-instance-suspend',
|
||||||
|
'/process-instance-terminate',
|
||||||
|
'/task-data',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class AuthorizationService:
|
class AuthorizationService:
|
||||||
"""Determine whether a user has permission to perform their request."""
|
"""Determine whether a user has permission to perform their request."""
|
||||||
|
|
||||||
|
@ -514,6 +530,93 @@ class AuthorizationService:
|
||||||
# this cannot be None so ignore mypy
|
# this cannot be None so ignore mypy
|
||||||
return user_model # type: ignore
|
return user_model # type: ignore
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_permissions_to_assign(cls, permission: str, process_related_path_segment: str, target_uris: list[str]) -> list[PermissionToAssign]:
|
||||||
|
permissions = [permission]
|
||||||
|
if permission == "all":
|
||||||
|
permissions = ['create', 'read', 'update', 'delete']
|
||||||
|
|
||||||
|
permissions_to_assign: list[PermissionToAssign] = []
|
||||||
|
|
||||||
|
# we were thinking that if you can start an instance, you ought to be able to view your own instances.
|
||||||
|
if permission == "start":
|
||||||
|
target_uri = f"/process-instances/{process_related_path_segment}"
|
||||||
|
permissions_to_assign.append(PermissionToAssign(permission='create', target_uri=target_uri))
|
||||||
|
target_uri = f"/process-instances/for-me/{process_related_path_segment}"
|
||||||
|
permissions_to_assign.append(PermissionToAssign(permission='read', target_uri=target_uri))
|
||||||
|
|
||||||
|
else:
|
||||||
|
if permission == 'all':
|
||||||
|
for path_segment in PATH_SEGMENTS_FOR_PERMISSION_ALL:
|
||||||
|
target_uris.append(f"{path_segment}/{process_related_path_segment}")
|
||||||
|
|
||||||
|
for target_uri in target_uris:
|
||||||
|
for permission in permissions:
|
||||||
|
permissions_to_assign.append(PermissionToAssign(permission=permission, target_uri=target_uri))
|
||||||
|
|
||||||
|
return permissions_to_assign
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def explode_permissions(cls, permission: str, target: str) -> list[PermissionToAssign]:
|
||||||
|
"""Explodes given permissions to and returns list of PermissionToAssign objects.
|
||||||
|
|
||||||
|
These can be used to then iterate through and inserted into the database.
|
||||||
|
Target Macros:
|
||||||
|
PG:[process_group_identifier]
|
||||||
|
* affects given process-group and all sub process-groups and process-models
|
||||||
|
PM:[process_model_identifier]
|
||||||
|
* affects given process-model
|
||||||
|
BASIC
|
||||||
|
* Basic access to complete tasks and use the site
|
||||||
|
|
||||||
|
Permission Macros:
|
||||||
|
all - create, read, update, delete
|
||||||
|
start - create process-instances (aka instantiate or start a process-model)
|
||||||
|
"""
|
||||||
|
permissions_to_assign: list[PermissionToAssign] = []
|
||||||
|
if target.startswith("PG:"):
|
||||||
|
process_group_identifier = target.removeprefix("PG:").replace(":", "/")
|
||||||
|
process_related_path_segment = f"{process_group_identifier}/*"
|
||||||
|
target_uris = []
|
||||||
|
if process_group_identifier == "ALL":
|
||||||
|
process_related_path_segment = "*"
|
||||||
|
target_uris = [f"/process-groups/{process_related_path_segment}", f"/process-models/{process_related_path_segment}"]
|
||||||
|
permissions_to_assign = permissions_to_assign + cls.get_permissions_to_assign(permission, process_related_path_segment, target_uris)
|
||||||
|
|
||||||
|
elif target.startswith("PM:"):
|
||||||
|
process_model_identifier = target.removeprefix("PM:").replace(":", "/")
|
||||||
|
process_related_path_segment = f"{process_model_identifier}/*"
|
||||||
|
target_uris = []
|
||||||
|
if process_model_identifier == "ALL":
|
||||||
|
process_related_path_segment = "*"
|
||||||
|
target_uris = [f"/process-models/{process_related_path_segment}"]
|
||||||
|
permissions_to_assign = permissions_to_assign + cls.get_permissions_to_assign(permission, process_related_path_segment, target_uris)
|
||||||
|
|
||||||
|
elif target.startswith("BASIC"):
|
||||||
|
permissions_to_assign.append(PermissionToAssign(permission='read', target_uri="/process-instances/for-me"))
|
||||||
|
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"))
|
||||||
|
|
||||||
|
for permission in ['create', 'read', 'update', 'delete']:
|
||||||
|
permissions_to_assign.append(PermissionToAssign(permission=permission, target_uri="/process-instances/reports/*"))
|
||||||
|
permissions_to_assign.append(PermissionToAssign(permission=permission, target_uri="/tasks/*"))
|
||||||
|
else:
|
||||||
|
permissions_to_assign.append(PermissionToAssign(permission=permission, target_uri=target))
|
||||||
|
|
||||||
|
return permissions_to_assign
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_permission_from_uri_or_macro(cls, group_identifier: str, permission: str, target: str) -> None:
|
||||||
|
"""Add_permission_from_uri_or_macro."""
|
||||||
|
group = GroupService.find_or_create_group(group_identifier)
|
||||||
|
permissions_to_assign = cls.explode_permissions(permission, target)
|
||||||
|
for permission_to_assign in permissions_to_assign:
|
||||||
|
permission_target = AuthorizationService.find_or_create_permission_target(permission_to_assign.target_uri)
|
||||||
|
AuthorizationService.create_permission_for_principal(
|
||||||
|
group.principal, permission_target, permission_to_assign.permission
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class KeycloakAuthorization:
|
class KeycloakAuthorization:
|
||||||
"""Interface with Keycloak server."""
|
"""Interface with Keycloak server."""
|
||||||
|
|
|
@ -17,7 +17,8 @@ from spiffworkflow_backend.models.task import MultiInstanceType
|
||||||
from spiffworkflow_backend.models.task import Task
|
from spiffworkflow_backend.models.task import Task
|
||||||
from spiffworkflow_backend.models.user import UserModel
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
from spiffworkflow_backend.services.authorization_service import AuthorizationService
|
from spiffworkflow_backend.services.authorization_service import AuthorizationService
|
||||||
from spiffworkflow_backend.services.git_service import GitService, GitCommandError
|
from spiffworkflow_backend.services.git_service import GitCommandError
|
||||||
|
from spiffworkflow_backend.services.git_service import GitService
|
||||||
from spiffworkflow_backend.services.process_instance_processor import (
|
from spiffworkflow_backend.services.process_instance_processor import (
|
||||||
ProcessInstanceProcessor,
|
ProcessInstanceProcessor,
|
||||||
)
|
)
|
||||||
|
@ -38,7 +39,7 @@ class ProcessInstanceService:
|
||||||
"""Get_process_instance_from_spec."""
|
"""Get_process_instance_from_spec."""
|
||||||
try:
|
try:
|
||||||
current_git_revision = GitService.get_current_revision()
|
current_git_revision = GitService.get_current_revision()
|
||||||
except GitCommandError as ge:
|
except GitCommandError:
|
||||||
current_git_revision = ""
|
current_git_revision = ""
|
||||||
process_instance_model = ProcessInstanceModel(
|
process_instance_model = ProcessInstanceModel(
|
||||||
status=ProcessInstanceStatus.not_started.value,
|
status=ProcessInstanceStatus.not_started.value,
|
||||||
|
|
|
@ -56,6 +56,8 @@ export default function ProcessModelEditDiagram() {
|
||||||
const [processSearchEventBus, setProcessSearchEventBus] = useState<any>(null);
|
const [processSearchEventBus, setProcessSearchEventBus] = useState<any>(null);
|
||||||
const [processSearchElement, setProcessSearchElement] = useState<any>(null);
|
const [processSearchElement, setProcessSearchElement] = useState<any>(null);
|
||||||
const [processes, setProcesses] = useState<ProcessReference[]>([]);
|
const [processes, setProcesses] = useState<ProcessReference[]>([]);
|
||||||
|
const [displaySaveFileMessage, setDisplaySaveFileMessage] =
|
||||||
|
useState<boolean>(false);
|
||||||
|
|
||||||
const handleShowMarkdownEditor = () => setShowMarkdownEditor(true);
|
const handleShowMarkdownEditor = () => setShowMarkdownEditor(true);
|
||||||
|
|
||||||
|
@ -157,6 +159,7 @@ export default function ProcessModelEditDiagram() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const navigateToProcessModelFile = (_result: any) => {
|
const navigateToProcessModelFile = (_result: any) => {
|
||||||
|
setDisplaySaveFileMessage(true);
|
||||||
if (!params.file_name) {
|
if (!params.file_name) {
|
||||||
const fileNameWithExtension = `${newFileName}.${searchParams.get(
|
const fileNameWithExtension = `${newFileName}.${searchParams.get(
|
||||||
'file_type'
|
'file_type'
|
||||||
|
@ -167,9 +170,8 @@ export default function ProcessModelEditDiagram() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const [displaySaveFileMessage, setDisplaySaveFileMessage] =
|
|
||||||
useState<boolean>(false);
|
|
||||||
const saveDiagram = (bpmnXML: any, fileName = params.file_name) => {
|
const saveDiagram = (bpmnXML: any, fileName = params.file_name) => {
|
||||||
|
setDisplaySaveFileMessage(false);
|
||||||
setErrorMessage(null);
|
setErrorMessage(null);
|
||||||
setBpmnXmlForDiagramRendering(bpmnXML);
|
setBpmnXmlForDiagramRendering(bpmnXML);
|
||||||
|
|
||||||
|
@ -204,7 +206,6 @@ export default function ProcessModelEditDiagram() {
|
||||||
// after saving the file, make sure we null out newFileName
|
// after saving the file, make sure we null out newFileName
|
||||||
// so it does not get used over the params
|
// so it does not get used over the params
|
||||||
setNewFileName('');
|
setNewFileName('');
|
||||||
setDisplaySaveFileMessage(true);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDeleteFile = (fileName = params.file_name) => {
|
const onDeleteFile = (fileName = params.file_name) => {
|
||||||
|
|
Loading…
Reference in New Issue