From 9e856dbdf4f076c5d10e6e9e75d6c3b1052cfdc0 Mon Sep 17 00:00:00 2001 From: Arnaud Morin Date: Mon, 8 Sep 2025 15:55:11 +0200 Subject: [PATCH] Allow admin to retrieve everything Since an admin may need to retrieve information about any task, action, workflow, etc., we want insecure flag to be set based on admin context. Signed-off-by: Arnaud Morin Change-Id: I411525df6432d489699235e30b9d09050651ea3d --- mistral/db/v2/sqlalchemy/api.py | 88 +++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 15 deletions(-) diff --git a/mistral/db/v2/sqlalchemy/api.py b/mistral/db/v2/sqlalchemy/api.py index 659875db0..148b62462 100644 --- a/mistral/db/v2/sqlalchemy/api.py +++ b/mistral/db/v2/sqlalchemy/api.py @@ -269,6 +269,10 @@ def _delete_all(model, **kwargs): def _get_collection(model, insecure=False, limit=None, marker=None, sort_keys=None, sort_dirs=None, fields=None, **filters): + # Allow admin to retrieve all objects by overwriting insecure + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure + columns = ( tuple([getattr(model, f) for f in fields if hasattr(model, f)]) if fields else () @@ -291,6 +295,10 @@ def _get_collection(model, insecure=False, limit=None, marker=None, def get_db_objects(model, insecure=False, **filters): + # Allow admin to retrieve all objects by overwriting insecure + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure + query = b.model_query(model) if insecure else _secure_query(model) query = db_filters.apply_filters(query, model, **filters) @@ -298,6 +306,10 @@ def get_db_objects(model, insecure=False, **filters): def _get_count(model, insecure=False, **filters): + # Allow admin to retrieve all objects by overwriting insecure + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure + query = b.model_query(model) if insecure else _secure_query(model) query = db_filters.apply_filters(query, model, **filters) @@ -312,6 +324,10 @@ def _get_db_object_by_name(model, name, columns=()): def _get_db_object_by_id(model, id, insecure=False, columns=()): + # Allow admin to retrieve all objects by overwriting insecure + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure + columns = ( tuple([getattr(model, f) for f in columns if hasattr(model, f)]) if columns and isinstance(columns, list) else columns @@ -329,6 +345,10 @@ def _get_db_object_by_id(model, id, insecure=False, columns=()): def _get_db_object_by_name_and_namespace_or_id(model, identifier, namespace=None, insecure=False, columns=()): + # Allow admin to retrieve all objects by overwriting insecure + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure + columns = ( tuple([getattr(model, f) for f in columns if hasattr(model, f)]) if columns and isinstance(columns, list) else columns @@ -359,6 +379,10 @@ def _get_db_object_by_name_and_namespace_or_id(model, identifier, def _get_db_object_by_name_and_namespace(model, name, namespace='', insecure=False, columns=()): + # Allow admin to retrieve all objects by overwriting insecure + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure + query = ( b.model_query(model, columns=columns) if insecure @@ -484,13 +508,16 @@ def get_workflow_definition(identifier, namespace='', fields=(), session=None): (WorkflowDefinition.name,) :return: Workflow definition. """ - ctx = context.ctx() + # Allow admin to retrieve all objects by overwriting insecure + insecure = False + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure wf_def = _get_db_object_by_name_and_namespace_or_id( models.WorkflowDefinition, identifier, namespace=namespace, - insecure=ctx.is_admin, + insecure=insecure, columns=fields ) @@ -936,8 +963,8 @@ def delete_action_definitions(session=None, **kwargs): @b.session_aware() def get_action_execution(id, insecure=False, fields=(), session=None): # Allow admin to retrieve action execution by overwriting insecure - ctx = context.ctx() - insecure = ctx.is_admin or insecure + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure a_ex = _get_db_object_by_id(models.ActionExecution, id, insecure=insecure, columns=fields) @@ -978,6 +1005,10 @@ def create_action_execution(values, session=None): @b.session_aware() def update_action_execution(id, values, insecure=False, session=None): + # Allow admin to retrieve all objects by overwriting insecure + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure + a_ex = get_action_execution(id, insecure) a_ex.update(values.copy()) @@ -1028,12 +1059,15 @@ def _get_action_executions(**kwargs): @b.session_aware() def get_workflow_execution(id, fields=(), session=None): - ctx = context.ctx() + # Allow admin to retrieve all objects by overwriting insecure + insecure = False + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure wf_ex = _get_db_object_by_id( models.WorkflowExecution, id, - insecure=ctx.is_admin, + insecure=insecure, columns=fields ) @@ -1095,7 +1129,10 @@ def create_or_update_workflow_execution(id, values, session=None): @b.session_aware() def delete_workflow_execution(id, session=None): model = models.WorkflowExecution - insecure = context.ctx().is_admin + # Allow admin to retrieve all objects by overwriting insecure + insecure = False + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure query = b.model_query(model) if insecure else _secure_query(model) try: @@ -1138,7 +1175,11 @@ def delete_workflow_execution_recurse(wf_ex_id): def _get_all_direct_subworkflows(wf_ex_id): model = models.WorkflowExecution - insecure = context.ctx().is_admin + # Allow admin to retrieve all objects by overwriting insecure + insecure = False + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure + if insecure: query = b.model_query(model, [model.id]) else: @@ -1168,11 +1209,13 @@ def update_workflow_execution_state(id, cur_state, state): @b.session_aware() def get_task_execution(id, fields=(), session=None): - # Allow admin to retrieve all tasks - ctx = context.ctx() + # Allow admin to retrieve all objects by overwriting insecure + insecure = False + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure task_ex = _get_db_object_by_id(models.TaskExecution, id, - insecure=ctx.is_admin, columns=fields) + insecure=insecure, columns=fields) if not task_ex: raise exc.DBEntityNotFoundError( @@ -1623,12 +1666,15 @@ def _get_completed_root_executions_query(columns): @b.session_aware() def get_cron_trigger(identifier, session=None, fields=()): - ctx = context.ctx() + # Allow admin to retrieve all objects by overwriting insecure + insecure = False + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure cron_trigger = _get_db_object_by_name_and_namespace_or_id( models.CronTrigger, identifier, - insecure=ctx.is_admin, + insecure=insecure, columns=fields, ) @@ -1642,9 +1688,13 @@ def get_cron_trigger(identifier, session=None, fields=()): @b.session_aware() def get_cron_trigger_by_id(id, session=None, fields=()): - ctx = context.ctx() + # Allow admin to retrieve all objects by overwriting insecure + insecure = False + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure + cron_trigger = _get_db_object_by_id(models.CronTrigger, id, - insecure=ctx.is_admin, + insecure=insecure, columns=fields) if not cron_trigger: raise exc.DBEntityNotFoundError( @@ -2009,6 +2059,10 @@ def _get_accepted_resources(res_type): @b.session_aware() def get_event_trigger(id, insecure=False, session=None, fields=()): + # Allow admin to retrieve all objects by overwriting insecure + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure + event_trigger = _get_db_object_by_id(models.EventTrigger, id, insecure, columns=fields) @@ -2022,6 +2076,10 @@ def get_event_trigger(id, insecure=False, session=None, fields=()): @b.session_aware() def load_event_trigger(id, insecure=False, session=None, fields=()): + # Allow admin to retrieve all objects by overwriting insecure + if context.has_ctx(): + insecure = context.ctx().is_admin or insecure + return _get_db_object_by_id(models.EventTrigger, id, insecure, columns=fields)