added method to add permissions based on macros w/ burnettk

This commit is contained in:
jasquat 2022-12-21 17:14:11 -05:00
parent db3bbc7603
commit 2f2dc6f98c
5 changed files with 150 additions and 100 deletions

View File

@ -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: []

View File

@ -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: []

View File

@ -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."""

View File

@ -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,

View File

@ -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) => {