Skip to content

Commit b185180

Browse files
author
Ben Elam
committed
Add global default authorizers for core-internal workflows
1 parent eee770b commit b185180

File tree

7 files changed

+73
-6
lines changed

7 files changed

+73
-6
lines changed

orchestrator/settings.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
from oauth2_lib.settings import oauth2lib_settings
2323
from orchestrator.services.settings_env_variables import expose_settings
24+
from orchestrator.utils.auth import Authorizer
2425
from orchestrator.utils.expose_settings import SecretStr as OrchSecretStr
2526
from pydantic_forms.types import strEnum
2627

@@ -111,3 +112,28 @@ class AppSettings(BaseSettings):
111112
expose_settings("app_settings", app_settings) # type: ignore
112113
if app_settings.EXPOSE_OAUTH_SETTINGS:
113114
expose_settings("oauth2lib_settings", oauth2lib_settings) # type: ignore
115+
116+
117+
class Authorizers:
118+
# Callbacks specifically for orchestrator-core callbacks.
119+
# Separate from defaults for user-defined workflows and steps.
120+
internal_authorize_callback: Authorizer | None
121+
internal_retry_auth_callback: Authorizer | None
122+
123+
124+
_authorizers = Authorizers()
125+
126+
127+
def get_authorizers() -> Authorizers:
128+
"""Acquire singleton of app authorizers to assign these callbacks at app setup.
129+
130+
Ensures downstream users can acquire singleton without being tempted to do
131+
from orchestrator.settings import authorizers
132+
authorizers = my_authorizers
133+
or
134+
from orchestrator import settings
135+
settings.authorizers = my_authorizers
136+
137+
...each of which goes wrong in its own way.
138+
"""
139+
return _authorizers

orchestrator/workflows/modify_note.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from orchestrator.db import db
1414
from orchestrator.forms import SubmitFormPage
1515
from orchestrator.services import subscriptions
16+
from orchestrator.settings import get_authorizers
1617
from orchestrator.targets import Target
1718
from orchestrator.utils.json import to_serializable
1819
from orchestrator.workflow import StepList, done, init, step, workflow
@@ -21,6 +22,8 @@
2122
from pydantic_forms.types import FormGenerator, State, UUIDstr
2223
from pydantic_forms.validators import LongText
2324

25+
authorizers = get_authorizers()
26+
2427

2528
def initial_input_form(subscription_id: UUIDstr) -> FormGenerator:
2629
subscription = subscriptions.get_subscription(subscription_id)
@@ -51,6 +54,12 @@ def store_subscription_note(subscription_id: UUIDstr, note: str) -> State:
5154
}
5255

5356

54-
@workflow("Modify Note", initial_input_form=wrap_modify_initial_input_form(initial_input_form), target=Target.MODIFY)
57+
@workflow(
58+
"Modify Note",
59+
initial_input_form=wrap_modify_initial_input_form(initial_input_form),
60+
target=Target.MODIFY,
61+
authorize_callback=authorizers.internal_authorize_callback,
62+
retry_auth_callback=authorizers.internal_retry_auth_callback,
63+
)
5564
def modify_note() -> StepList:
5665
return init >> store_process_subscription() >> store_subscription_note >> done

orchestrator/workflows/removed_workflow.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@
1212
# limitations under the License.
1313

1414

15+
from orchestrator.settings import get_authorizers
1516
from orchestrator.workflow import StepList, workflow
1617

18+
authorizers = get_authorizers()
19+
1720

1821
# This workflow has been made to create the initial import process for a SN7 subscription
1922
# it does not do anything but is needed for the correct showing in the GUI.
20-
@workflow("Dummy workflow to replace removed workflows")
23+
@workflow(
24+
"Dummy workflow to replace removed workflows",
25+
authorize_callback=authorizers.internal_authorize_callback,
26+
retry_auth_callback=authorizers.internal_retry_auth_callback,
27+
)
2128
def removed_workflow() -> StepList:
2229
return StepList()

orchestrator/workflows/tasks/cleanup_tasks_log.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
from sqlalchemy import select
1818

1919
from orchestrator.db import ProcessTable, db
20-
from orchestrator.settings import app_settings
20+
from orchestrator.settings import app_settings, get_authorizers
2121
from orchestrator.targets import Target
2222
from orchestrator.utils.datetime import nowtz
2323
from orchestrator.workflow import ProcessStatus, StepList, done, init, step, workflow
2424
from pydantic_forms.types import State
2525

26+
authorizers = get_authorizers()
27+
2628

2729
@step("Clean up completed tasks older than TASK_LOG_RETENTION_DAYS")
2830
def remove_tasks() -> State:
@@ -41,6 +43,11 @@ def remove_tasks() -> State:
4143
return {"tasks_removed": count}
4244

4345

44-
@workflow("Clean up old tasks", target=Target.SYSTEM)
46+
@workflow(
47+
"Clean up old tasks",
48+
target=Target.SYSTEM,
49+
authorize_callback=authorizers.internal_authorize_callback,
50+
retry_auth_callback=authorizers.internal_retry_auth_callback,
51+
)
4552
def task_clean_up_tasks() -> StepList:
4653
return init >> remove_tasks >> done

orchestrator/workflows/tasks/resume_workflows.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717

1818
from orchestrator.db import ProcessTable, db
1919
from orchestrator.services import processes
20+
from orchestrator.settings import get_authorizers
2021
from orchestrator.targets import Target
2122
from orchestrator.workflow import ProcessStatus, StepList, done, init, step, workflow
2223
from pydantic_forms.types import State, UUIDstr
2324

25+
authorizers = get_authorizers()
2426
logger = structlog.get_logger(__name__)
2527

2628

@@ -110,6 +112,8 @@ def restart_created_workflows(created_state_process_ids: list[UUIDstr]) -> State
110112
@workflow(
111113
"Resume all workflows that are stuck on tasks with the status 'waiting', 'created' or 'resumed'",
112114
target=Target.SYSTEM,
115+
authorize_callback=authorizers.internal_authorize_callback,
116+
retry_auth_callback=authorizers.internal_retry_auth_callback,
113117
)
114118
def task_resume_workflows() -> StepList:
115119
return init >> find_waiting_workflows >> resume_found_workflows >> restart_created_workflows >> done

orchestrator/workflows/tasks/validate_product_type.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
get_validation_product_workflows_for_subscription,
2626
start_validation_workflow_for_workflows,
2727
)
28+
from orchestrator.settings import get_authorizers
2829
from orchestrator.targets import Target
2930
from orchestrator.workflow import StepList, done, init, step, workflow
3031
from pydantic_forms.types import FormGenerator, State
3132

33+
authorizers = get_authorizers()
3234
logger = structlog.get_logger(__name__)
3335

3436

@@ -86,7 +88,11 @@ def validate_product_type(product_type: str) -> State:
8688

8789

8890
@workflow(
89-
"Validate all subscriptions of Product Type", target=Target.SYSTEM, initial_input_form=initial_input_form_generator
91+
"Validate all subscriptions of Product Type",
92+
target=Target.SYSTEM,
93+
initial_input_form=initial_input_form_generator,
94+
authorize_callback=authorizers.internal_authorize_callback,
95+
retry_auth_callback=authorizers.internal_retry_auth_callback,
9096
)
9197
def task_validate_product_type() -> StepList:
9298
return init >> validate_product_type >> done

orchestrator/workflows/tasks/validate_products.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,15 @@
2626
from orchestrator.services.products import get_products
2727
from orchestrator.services.translations import generate_translations
2828
from orchestrator.services.workflows import get_workflow_by_name, get_workflows
29+
from orchestrator.settings import get_authorizers
2930
from orchestrator.targets import Target
3031
from orchestrator.utils.errors import ProcessFailureError
3132
from orchestrator.utils.fixed_inputs import fixed_input_configuration as fi_configuration
3233
from orchestrator.workflow import StepList, done, init, step, workflow
3334
from pydantic_forms.types import State
3435

36+
authorizers = get_authorizers()
37+
3538
# Since these errors are probably programming failures we should not throw AssertionErrors
3639

3740

@@ -187,7 +190,12 @@ def check_subscription_models() -> State:
187190
return {"check_subscription_models": True}
188191

189192

190-
@workflow("Validate products", target=Target.SYSTEM)
193+
@workflow(
194+
"Validate products",
195+
target=Target.SYSTEM,
196+
authorize_callback=authorizers.internal_authorize_callback,
197+
retry_auth_callback=authorizers.internal_retry_auth_callback,
198+
)
191199
def task_validate_products() -> StepList:
192200
return (
193201
init

0 commit comments

Comments
 (0)