mirror of
https://github.com/langgenius/dify.git
synced 2026-05-27 12:26:15 +08:00
Replace the single mutable-context Pipeline with a two-phase, condition-driven system dispatched by token type. New architecture: - TokenType(StrEnum) replaces source: str on AuthContext / TokenKind - AuthPipeline: pure prepare→auth step runner; no guard() - PipelineRoute: binds AuthPipeline to an optional required_edition gate - PipelineRouter: single guard() entry point; runs edition/license/token-type pre-gates then dispatches to the registered pipeline for the token type - Cond / When: composable predicates for conditional step dispatch - AuthData: frozen Pydantic model produced by the prepare phase; carries token_id so endpoints don't need to call get_auth_ctx() for identity fields - Edition enum + current_edition(): CE / EE / SAAS discriminator Two pipelines in composition.py: - account_pipeline — OAUTH_ACCOUNT tokens - external_sso_pipeline — OAUTH_EXTERNAL_SSO tokens (EE enforced at route level) All /openapi/v1 endpoints migrated to auth_router.guard(). Old context.py, steps.py, strategies.py, surface_gate.py deleted. WORKSPACE_READ scope added; cached_verdicts renamed to membership_cache.
65 lines
2.1 KiB
Python
65 lines
2.1 KiB
Python
from __future__ import annotations
|
|
|
|
from controllers.openapi.auth.conditions import (
|
|
EDITION_CE,
|
|
EDITION_EE,
|
|
LOADED_APP_IS_PRIVATE,
|
|
PATH_HAS_APP_ID,
|
|
WEBAPP_AUTH_ENABLED,
|
|
)
|
|
from controllers.openapi.auth.data import Edition
|
|
from controllers.openapi.auth.flow import When
|
|
from controllers.openapi.auth.pipeline import AuthPipeline, PipelineRoute, PipelineRouter
|
|
from controllers.openapi.auth.prepare import (
|
|
build_external_identity,
|
|
load_account,
|
|
load_app,
|
|
load_app_access_mode,
|
|
load_tenant,
|
|
resolve_external_user,
|
|
)
|
|
from controllers.openapi.auth.verify import (
|
|
check_acl,
|
|
check_app_access,
|
|
check_membership,
|
|
check_private_app_permission,
|
|
check_scope,
|
|
)
|
|
from libs.oauth_bearer import TokenType
|
|
|
|
account_pipeline = AuthPipeline(
|
|
prepare=[
|
|
When(PATH_HAS_APP_ID, then=load_app),
|
|
When(PATH_HAS_APP_ID, then=load_tenant),
|
|
load_account, # unconditional — this IS the account pipeline
|
|
When(PATH_HAS_APP_ID & EDITION_EE, then=load_app_access_mode),
|
|
],
|
|
auth=[
|
|
check_scope,
|
|
When(EDITION_CE & PATH_HAS_APP_ID, then=check_membership),
|
|
When(EDITION_EE & PATH_HAS_APP_ID & ~WEBAPP_AUTH_ENABLED, then=check_app_access),
|
|
When(PATH_HAS_APP_ID & EDITION_EE & WEBAPP_AUTH_ENABLED, then=check_acl),
|
|
When(EDITION_EE & LOADED_APP_IS_PRIVATE, then=check_private_app_permission),
|
|
],
|
|
)
|
|
|
|
external_sso_pipeline = AuthPipeline(
|
|
prepare=[
|
|
build_external_identity,
|
|
When(PATH_HAS_APP_ID, then=load_app),
|
|
When(PATH_HAS_APP_ID, then=load_tenant),
|
|
When(PATH_HAS_APP_ID, then=resolve_external_user),
|
|
When(PATH_HAS_APP_ID, then=load_app_access_mode),
|
|
],
|
|
auth=[
|
|
check_scope,
|
|
When(PATH_HAS_APP_ID & WEBAPP_AUTH_ENABLED, then=check_acl),
|
|
When(LOADED_APP_IS_PRIVATE, then=check_private_app_permission),
|
|
],
|
|
)
|
|
|
|
auth_router = PipelineRouter({
|
|
TokenType.OAUTH_ACCOUNT: PipelineRoute(account_pipeline),
|
|
TokenType.OAUTH_EXTERNAL_SSO: PipelineRoute(external_sso_pipeline, required_edition=frozenset({Edition.EE})),
|
|
})
|