mirror of
https://github.com/langgenius/dify.git
synced 2026-09-19 10:11:30 +08:00
refactor: replace manual model_validate with @model_validate in workspace remaining controllers (#40239)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
autofix-ci[bot]
parent
5ebb389d26
commit
b692ddd80c
@@ -41,6 +41,7 @@ from controllers.console.wraps import (
|
||||
cloud_edition_billing_enabled,
|
||||
enable_change_email,
|
||||
enterprise_license_required,
|
||||
model_validate,
|
||||
only_edition_cloud,
|
||||
setup_required,
|
||||
with_current_user,
|
||||
@@ -332,9 +333,9 @@ class AccountAvatarApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
def get(self, current_user: Account):
|
||||
args = AccountAvatarQuery.model_validate(request.args.to_dict(flat=True))
|
||||
avatar = args.avatar
|
||||
@model_validate(AccountAvatarQuery)
|
||||
def get(self, req_data: AccountAvatarQuery, current_user: Account):
|
||||
avatar = req_data.avatar
|
||||
|
||||
if avatar.startswith(("http://", "https://")):
|
||||
return AvatarUrlResponse(avatar_url=avatar).model_dump(mode="json")
|
||||
|
||||
@@ -11,7 +11,6 @@ from enum import StrEnum
|
||||
from http import HTTPStatus
|
||||
from typing import Any
|
||||
|
||||
from flask import request
|
||||
from flask_restx import Resource
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
@@ -294,14 +293,14 @@ class EndpointListApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user_id
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str, user_id: str):
|
||||
args = EndpointListQuery.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(EndpointListQuery)
|
||||
def get(self, req_data: EndpointListQuery, tenant_id: str, user_id: str):
|
||||
|
||||
endpoints = EndpointService.list_endpoints(
|
||||
tenant_id=tenant_id,
|
||||
user_id=user_id,
|
||||
page=args.page,
|
||||
page_size=args.page_size,
|
||||
page=req_data.page,
|
||||
page_size=req_data.page_size,
|
||||
)
|
||||
|
||||
return EndpointListResponse(endpoints=endpoints).model_dump(mode="json")
|
||||
@@ -322,15 +321,15 @@ class EndpointListForSinglePluginApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user_id
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str, user_id: str):
|
||||
args = EndpointListForPluginQuery.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(EndpointListForPluginQuery)
|
||||
def get(self, req_data: EndpointListForPluginQuery, tenant_id: str, user_id: str):
|
||||
|
||||
endpoints = EndpointService.list_endpoints_for_single_plugin(
|
||||
tenant_id=tenant_id,
|
||||
user_id=user_id,
|
||||
plugin_id=args.plugin_id,
|
||||
page=args.page,
|
||||
page_size=args.page_size,
|
||||
plugin_id=req_data.plugin_id,
|
||||
page=req_data.page,
|
||||
page_size=req_data.page_size,
|
||||
)
|
||||
|
||||
return EndpointListResponse(endpoints=endpoints).model_dump(mode="json")
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import logging
|
||||
from typing import Any, cast
|
||||
|
||||
from flask import request
|
||||
from flask_restx import Resource
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
|
||||
@@ -18,6 +17,7 @@ from controllers.console.wraps import (
|
||||
RBACResourceScope,
|
||||
account_initialization_required,
|
||||
is_admin_or_owner_required,
|
||||
model_validate,
|
||||
rbac_permission_required,
|
||||
setup_required,
|
||||
with_current_tenant_id,
|
||||
@@ -212,12 +212,12 @@ class DefaultModelApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str):
|
||||
args = ParserGetDefault.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(ParserGetDefault)
|
||||
def get(self, req_data: ParserGetDefault, tenant_id: str):
|
||||
|
||||
model_provider_service = ModelProviderService()
|
||||
default_model_entity = model_provider_service.get_default_model_of_model_type(
|
||||
tenant_id=tenant_id, model_type=args.model_type
|
||||
tenant_id=tenant_id, model_type=req_data.model_type
|
||||
)
|
||||
|
||||
return DefaultModelDataResponse(data=default_model_entity).model_dump(mode="json")
|
||||
@@ -230,10 +230,10 @@ class DefaultModelApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str):
|
||||
args = ParserPostDefault.model_validate(console_ns.payload)
|
||||
@model_validate(ParserPostDefault)
|
||||
def post(self, req_data: ParserPostDefault, tenant_id: str):
|
||||
model_provider_service = ModelProviderService()
|
||||
model_settings = args.model_settings
|
||||
model_settings = req_data.model_settings
|
||||
for model_setting in model_settings:
|
||||
if model_setting.provider is None:
|
||||
continue
|
||||
@@ -279,43 +279,43 @@ class ModelProviderModelApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, provider: str):
|
||||
@model_validate(ParserPostModels)
|
||||
def post(self, req_data: ParserPostModels, tenant_id: str, provider: str):
|
||||
# To save the model's load balance configs
|
||||
args = ParserPostModels.model_validate(console_ns.payload)
|
||||
|
||||
if args.config_from == "custom-model":
|
||||
if not args.credential_id:
|
||||
if req_data.config_from == "custom-model":
|
||||
if not req_data.credential_id:
|
||||
raise ValueError("credential_id is required when configuring a custom-model")
|
||||
service = ModelProviderService()
|
||||
service.switch_active_custom_model_credential(
|
||||
tenant_id=tenant_id,
|
||||
provider=provider,
|
||||
model_type=args.model_type,
|
||||
model=args.model,
|
||||
credential_id=args.credential_id,
|
||||
model_type=req_data.model_type,
|
||||
model=req_data.model,
|
||||
credential_id=req_data.credential_id,
|
||||
)
|
||||
|
||||
model_load_balancing_service = ModelLoadBalancingService()
|
||||
|
||||
if args.load_balancing and args.load_balancing.configs:
|
||||
if req_data.load_balancing and req_data.load_balancing.configs:
|
||||
# save load balancing configs
|
||||
model_load_balancing_service.update_load_balancing_configs(
|
||||
tenant_id=tenant_id,
|
||||
provider=provider,
|
||||
model=args.model,
|
||||
model_type=args.model_type,
|
||||
configs=args.load_balancing.configs,
|
||||
config_from=args.config_from or "",
|
||||
model=req_data.model,
|
||||
model_type=req_data.model_type,
|
||||
configs=req_data.load_balancing.configs,
|
||||
config_from=req_data.config_from or "",
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
if args.load_balancing.enabled:
|
||||
if req_data.load_balancing.enabled:
|
||||
model_load_balancing_service.enable_model_load_balancing(
|
||||
tenant_id=tenant_id, provider=provider, model=args.model, model_type=args.model_type
|
||||
tenant_id=tenant_id, provider=provider, model=req_data.model, model_type=req_data.model_type
|
||||
)
|
||||
else:
|
||||
model_load_balancing_service.disable_model_load_balancing(
|
||||
tenant_id=tenant_id, provider=provider, model=args.model, model_type=args.model_type
|
||||
tenant_id=tenant_id, provider=provider, model=req_data.model, model_type=req_data.model_type
|
||||
)
|
||||
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json"), 200
|
||||
@@ -328,12 +328,12 @@ class ModelProviderModelApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def delete(self, tenant_id: str, provider: str):
|
||||
args = ParserDeleteModels.model_validate(console_ns.payload)
|
||||
@model_validate(ParserDeleteModels)
|
||||
def delete(self, req_data: ParserDeleteModels, tenant_id: str, provider: str):
|
||||
|
||||
model_provider_service = ModelProviderService()
|
||||
model_provider_service.remove_model(
|
||||
tenant_id=tenant_id, provider=provider, model=args.model, model_type=args.model_type
|
||||
tenant_id=tenant_id, provider=provider, model=req_data.model, model_type=req_data.model_type
|
||||
)
|
||||
|
||||
return "", 204
|
||||
@@ -352,29 +352,29 @@ class ModelProviderModelCredentialApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str, user: Account, provider: str):
|
||||
args = ParserGetCredentials.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(ParserGetCredentials)
|
||||
def get(self, req_data: ParserGetCredentials, tenant_id: str, user: Account, provider: str):
|
||||
|
||||
model_provider_service = ModelProviderService()
|
||||
current_credential = model_provider_service.get_model_credential(
|
||||
tenant_id=tenant_id,
|
||||
provider=provider,
|
||||
model_type=args.model_type,
|
||||
model=args.model,
|
||||
credential_id=args.credential_id,
|
||||
model_type=req_data.model_type,
|
||||
model=req_data.model,
|
||||
credential_id=req_data.credential_id,
|
||||
)
|
||||
|
||||
model_load_balancing_service = ModelLoadBalancingService()
|
||||
is_load_balancing_enabled, load_balancing_configs = model_load_balancing_service.get_load_balancing_configs(
|
||||
tenant_id=tenant_id,
|
||||
provider=provider,
|
||||
model=args.model,
|
||||
model_type=args.model_type,
|
||||
model=req_data.model,
|
||||
model_type=req_data.model_type,
|
||||
session=db.session(),
|
||||
config_from=args.config_from or "",
|
||||
config_from=req_data.config_from or "",
|
||||
)
|
||||
|
||||
if args.config_from == "predefined-model":
|
||||
if req_data.config_from == "predefined-model":
|
||||
# Only the predefined-model branch needs visibility filtering by user.
|
||||
# The account is injected once by the handler and only passed into the
|
||||
# service branch that needs user-scoped credential visibility.
|
||||
@@ -387,8 +387,8 @@ class ModelProviderModelCredentialApi(Resource):
|
||||
available_credentials = model_provider_service.get_provider_model_available_credentials(
|
||||
tenant_id=tenant_id,
|
||||
provider=provider,
|
||||
model_type=args.model_type,
|
||||
model=args.model,
|
||||
model_type=req_data.model_type,
|
||||
model=req_data.model,
|
||||
)
|
||||
|
||||
credentials: dict[str, Any] = {}
|
||||
@@ -414,8 +414,8 @@ class ModelProviderModelCredentialApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_CREATE, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, provider: str):
|
||||
args = ParserCreateCredential.model_validate(console_ns.payload)
|
||||
@model_validate(ParserCreateCredential)
|
||||
def post(self, req_data: ParserCreateCredential, tenant_id: str, provider: str):
|
||||
|
||||
model_provider_service = ModelProviderService()
|
||||
|
||||
@@ -423,17 +423,17 @@ class ModelProviderModelCredentialApi(Resource):
|
||||
model_provider_service.create_model_credential(
|
||||
tenant_id=tenant_id,
|
||||
provider=provider,
|
||||
model=args.model,
|
||||
model_type=args.model_type,
|
||||
credentials=args.credentials,
|
||||
credential_name=args.name,
|
||||
model=req_data.model,
|
||||
model_type=req_data.model_type,
|
||||
credentials=req_data.credentials,
|
||||
credential_name=req_data.name,
|
||||
)
|
||||
except CredentialsValidateFailedError as ex:
|
||||
logger.exception(
|
||||
"Failed to save model credentials, tenant_id: %s, model: %s, model_type: %s",
|
||||
tenant_id,
|
||||
args.model,
|
||||
args.model_type,
|
||||
req_data.model,
|
||||
req_data.model_type,
|
||||
)
|
||||
raise ValueError(str(ex))
|
||||
|
||||
@@ -447,8 +447,8 @@ class ModelProviderModelCredentialApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def put(self, current_tenant_id: str, provider: str):
|
||||
args = ParserUpdateCredential.model_validate(console_ns.payload)
|
||||
@model_validate(ParserUpdateCredential)
|
||||
def put(self, req_data: ParserUpdateCredential, current_tenant_id: str, provider: str):
|
||||
|
||||
model_provider_service = ModelProviderService()
|
||||
|
||||
@@ -456,11 +456,11 @@ class ModelProviderModelCredentialApi(Resource):
|
||||
model_provider_service.update_model_credential(
|
||||
tenant_id=current_tenant_id,
|
||||
provider=provider,
|
||||
model_type=args.model_type,
|
||||
model=args.model,
|
||||
credentials=args.credentials,
|
||||
credential_id=args.credential_id,
|
||||
credential_name=args.name,
|
||||
model_type=req_data.model_type,
|
||||
model=req_data.model,
|
||||
credentials=req_data.credentials,
|
||||
credential_id=req_data.credential_id,
|
||||
credential_name=req_data.name,
|
||||
)
|
||||
except CredentialsValidateFailedError as ex:
|
||||
raise ValueError(str(ex))
|
||||
@@ -475,16 +475,16 @@ class ModelProviderModelCredentialApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def delete(self, current_tenant_id: str, provider: str):
|
||||
args = ParserDeleteCredential.model_validate(console_ns.payload)
|
||||
@model_validate(ParserDeleteCredential)
|
||||
def delete(self, req_data: ParserDeleteCredential, current_tenant_id: str, provider: str):
|
||||
|
||||
model_provider_service = ModelProviderService()
|
||||
model_provider_service.remove_model_credential(
|
||||
tenant_id=current_tenant_id,
|
||||
provider=provider,
|
||||
model_type=args.model_type,
|
||||
model=args.model,
|
||||
credential_id=args.credential_id,
|
||||
model_type=req_data.model_type,
|
||||
model=req_data.model,
|
||||
credential_id=req_data.credential_id,
|
||||
)
|
||||
|
||||
return "", 204
|
||||
@@ -500,16 +500,16 @@ class ModelProviderModelCredentialSwitchApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_USE, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, current_tenant_id: str, provider: str):
|
||||
args = ParserSwitch.model_validate(console_ns.payload)
|
||||
@model_validate(ParserSwitch)
|
||||
def post(self, req_data: ParserSwitch, current_tenant_id: str, provider: str):
|
||||
|
||||
service = ModelProviderService()
|
||||
service.add_model_credential_to_model_list(
|
||||
tenant_id=current_tenant_id,
|
||||
provider=provider,
|
||||
model_type=args.model_type,
|
||||
model=args.model,
|
||||
credential_id=args.credential_id,
|
||||
model_type=req_data.model_type,
|
||||
model=req_data.model,
|
||||
credential_id=req_data.credential_id,
|
||||
)
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||
|
||||
@@ -525,12 +525,12 @@ class ModelProviderModelEnableApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
|
||||
def patch(self, tenant_id: str, provider: str):
|
||||
args = ParserDeleteModels.model_validate(console_ns.payload)
|
||||
@model_validate(ParserDeleteModels)
|
||||
def patch(self, req_data: ParserDeleteModels, tenant_id: str, provider: str):
|
||||
|
||||
model_provider_service = ModelProviderService()
|
||||
model_provider_service.enable_model(
|
||||
tenant_id=tenant_id, provider=provider, model=args.model, model_type=args.model_type
|
||||
tenant_id=tenant_id, provider=provider, model=req_data.model, model_type=req_data.model_type
|
||||
)
|
||||
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||
@@ -547,12 +547,12 @@ class ModelProviderModelDisableApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
|
||||
def patch(self, tenant_id: str, provider: str):
|
||||
args = ParserDeleteModels.model_validate(console_ns.payload)
|
||||
@model_validate(ParserDeleteModels)
|
||||
def patch(self, req_data: ParserDeleteModels, tenant_id: str, provider: str):
|
||||
|
||||
model_provider_service = ModelProviderService()
|
||||
model_provider_service.disable_model(
|
||||
tenant_id=tenant_id, provider=provider, model=args.model, model_type=args.model_type
|
||||
tenant_id=tenant_id, provider=provider, model=req_data.model, model_type=req_data.model_type
|
||||
)
|
||||
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||
@@ -579,8 +579,8 @@ class ModelProviderModelValidateApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, provider: str):
|
||||
args = ParserValidate.model_validate(console_ns.payload)
|
||||
@model_validate(ParserValidate)
|
||||
def post(self, req_data: ParserValidate, tenant_id: str, provider: str):
|
||||
|
||||
model_provider_service = ModelProviderService()
|
||||
|
||||
@@ -591,9 +591,9 @@ class ModelProviderModelValidateApi(Resource):
|
||||
model_provider_service.validate_model_credentials(
|
||||
tenant_id=tenant_id,
|
||||
provider=provider,
|
||||
model=args.model,
|
||||
model_type=args.model_type,
|
||||
credentials=args.credentials,
|
||||
model=req_data.model,
|
||||
model_type=req_data.model_type,
|
||||
credentials=req_data.credentials,
|
||||
)
|
||||
except CredentialsValidateFailedError as ex:
|
||||
result = False
|
||||
@@ -617,12 +617,12 @@ class ModelProviderModelParameterRuleApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str, provider: str):
|
||||
args = ParserParameter.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(ParserParameter)
|
||||
def get(self, req_data: ParserParameter, tenant_id: str, provider: str):
|
||||
|
||||
model_provider_service = ModelProviderService()
|
||||
parameter_rules = model_provider_service.get_model_parameter_rules(
|
||||
tenant_id=tenant_id, provider=provider, model=args.model
|
||||
tenant_id=tenant_id, provider=provider, model=req_data.model
|
||||
)
|
||||
|
||||
return ModelParameterRuleListResponse(data=parameter_rules).model_dump(mode="json")
|
||||
|
||||
@@ -11,7 +11,7 @@ from werkzeug.exceptions import NotFound
|
||||
from configs import dify_config
|
||||
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
|
||||
from controllers.console import console_ns
|
||||
from controllers.console.wraps import RBACPermission, RBACResourceScope, rbac_permission_required
|
||||
from controllers.console.wraps import RBACPermission, RBACResourceScope, model_validate, rbac_permission_required
|
||||
from core.db.session_factory import session_factory
|
||||
from core.rbac import RBACResourceWhitelistScope
|
||||
from extensions.ext_database import db
|
||||
@@ -310,19 +310,19 @@ class RBACRolesApi(Resource):
|
||||
RBACResourceScope.WORKSPACE, RBACPermission.WORKSPACE_ROLE_MANAGE, resource_required=False
|
||||
)
|
||||
@console_ns.response(200, "Success", console_ns.models[_RBACRoleList.__name__])
|
||||
def get(self):
|
||||
@model_validate(_RolesListQuery)
|
||||
def get(self, req_data: _RolesListQuery):
|
||||
tenant_id, account_id = _current_ids()
|
||||
query = _RolesListQuery.model_validate(request.args.to_dict(flat=True))
|
||||
options = query.to_inner_options()
|
||||
options = req_data.to_inner_options()
|
||||
if not dify_config.RBAC_ENABLED:
|
||||
result = _legacy_workspace_roles(
|
||||
options, include_owner=query.include_owner, billing_enabled=dify_config.BILLING_ENABLED
|
||||
options, include_owner=req_data.include_owner, billing_enabled=dify_config.BILLING_ENABLED
|
||||
)
|
||||
else:
|
||||
result = svc.RBACService.Roles.list(
|
||||
tenant_id,
|
||||
account_id,
|
||||
include_owner=query.include_owner,
|
||||
include_owner=req_data.include_owner,
|
||||
biiling_enabled=dify_config.BILLING_ENABLED,
|
||||
options=options,
|
||||
)
|
||||
|
||||
@@ -39,6 +39,7 @@ from ..wraps import (
|
||||
account_initialization_required,
|
||||
edit_permission_required,
|
||||
is_admin_or_owner_required,
|
||||
model_validate,
|
||||
rbac_permission_required,
|
||||
setup_required,
|
||||
with_current_tenant_id,
|
||||
@@ -233,13 +234,12 @@ class TriggerSubscriptionBuilderCreateApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account, provider: str):
|
||||
@model_validate(TriggerSubscriptionBuilderCreatePayload)
|
||||
def post(self, req_data: TriggerSubscriptionBuilderCreatePayload, tenant_id: str, user: Account, provider: str):
|
||||
"""Add a new subscription instance for a trigger provider"""
|
||||
|
||||
payload = TriggerSubscriptionBuilderCreatePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
try:
|
||||
credential_type = CredentialType.of(payload.credential_type)
|
||||
credential_type = CredentialType.of(req_data.credential_type)
|
||||
subscription_builder = TriggerSubscriptionBuilderService.create_trigger_subscription_builder(
|
||||
tenant_id=tenant_id,
|
||||
user_id=user.id,
|
||||
@@ -298,11 +298,17 @@ class TriggerSubscriptionBuilderVerifyApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account, provider: str, subscription_builder_id: str):
|
||||
@model_validate(TriggerSubscriptionBuilderVerifyPayload)
|
||||
def post(
|
||||
self,
|
||||
req_data: TriggerSubscriptionBuilderVerifyPayload,
|
||||
tenant_id: str,
|
||||
user: Account,
|
||||
provider: str,
|
||||
subscription_builder_id: str,
|
||||
):
|
||||
"""Verify and update a subscription instance for a trigger provider"""
|
||||
|
||||
payload = TriggerSubscriptionBuilderVerifyPayload.model_validate(console_ns.payload or {})
|
||||
|
||||
try:
|
||||
# Use atomic update_and_verify to prevent race conditions
|
||||
result = TriggerSubscriptionBuilderService.update_and_verify_builder(
|
||||
@@ -311,7 +317,7 @@ class TriggerSubscriptionBuilderVerifyApi(Resource):
|
||||
provider_id=TriggerProviderID(provider),
|
||||
subscription_builder_id=subscription_builder_id,
|
||||
subscription_builder_updater=SubscriptionBuilderUpdater(
|
||||
credentials=payload.credentials,
|
||||
credentials=req_data.credentials,
|
||||
),
|
||||
)
|
||||
return dump_response(TriggerVerificationResponse, result)
|
||||
@@ -337,10 +343,17 @@ class TriggerSubscriptionBuilderUpdateApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account, provider: str, subscription_builder_id: str):
|
||||
@model_validate(TriggerSubscriptionBuilderUpdatePayload)
|
||||
def post(
|
||||
self,
|
||||
req_data: TriggerSubscriptionBuilderUpdatePayload,
|
||||
tenant_id: str,
|
||||
user: Account,
|
||||
provider: str,
|
||||
subscription_builder_id: str,
|
||||
):
|
||||
"""Update a subscription instance for a trigger provider"""
|
||||
|
||||
payload = TriggerSubscriptionBuilderUpdatePayload.model_validate(console_ns.payload or {})
|
||||
try:
|
||||
return TriggerSubscriptionBuilderService.update_trigger_subscription_builder(
|
||||
tenant_id=tenant_id,
|
||||
@@ -348,10 +361,10 @@ class TriggerSubscriptionBuilderUpdateApi(Resource):
|
||||
provider_id=TriggerProviderID(provider),
|
||||
subscription_builder_id=subscription_builder_id,
|
||||
subscription_builder_updater=SubscriptionBuilderUpdater(
|
||||
name=payload.name,
|
||||
parameters=payload.parameters,
|
||||
properties=payload.properties,
|
||||
credentials=payload.credentials,
|
||||
name=req_data.name,
|
||||
parameters=req_data.parameters,
|
||||
properties=req_data.properties,
|
||||
credentials=req_data.credentials,
|
||||
),
|
||||
).model_dump(mode="json")
|
||||
except Exception as e:
|
||||
@@ -406,9 +419,16 @@ class TriggerSubscriptionBuilderBuildApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account, provider: str, subscription_builder_id: str):
|
||||
@model_validate(TriggerSubscriptionBuilderUpdatePayload)
|
||||
def post(
|
||||
self,
|
||||
req_data: TriggerSubscriptionBuilderUpdatePayload,
|
||||
tenant_id: str,
|
||||
user: Account,
|
||||
provider: str,
|
||||
subscription_builder_id: str,
|
||||
):
|
||||
"""Build a subscription instance for a trigger provider"""
|
||||
payload = TriggerSubscriptionBuilderUpdatePayload.model_validate(console_ns.payload or {})
|
||||
try:
|
||||
# Use atomic update_and_build to prevent race conditions
|
||||
TriggerSubscriptionBuilderService.update_and_build_builder(
|
||||
@@ -417,9 +437,9 @@ class TriggerSubscriptionBuilderBuildApi(Resource):
|
||||
provider_id=TriggerProviderID(provider),
|
||||
subscription_builder_id=subscription_builder_id,
|
||||
subscription_builder_updater=SubscriptionBuilderUpdater(
|
||||
name=payload.name,
|
||||
parameters=payload.parameters,
|
||||
properties=payload.properties,
|
||||
name=req_data.name,
|
||||
parameters=req_data.parameters,
|
||||
properties=req_data.properties,
|
||||
),
|
||||
)
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||
@@ -442,11 +462,10 @@ class TriggerSubscriptionUpdateApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, subscription_id: str):
|
||||
@model_validate(TriggerSubscriptionBuilderUpdatePayload)
|
||||
def post(self, req_data: TriggerSubscriptionBuilderUpdatePayload, tenant_id: str, subscription_id: str):
|
||||
"""Update a subscription instance"""
|
||||
|
||||
request = TriggerSubscriptionBuilderUpdatePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
subscription = TriggerProviderService.get_subscription_by_id(
|
||||
tenant_id=tenant_id,
|
||||
subscription_id=subscription_id,
|
||||
@@ -458,7 +477,9 @@ class TriggerSubscriptionUpdateApi(Resource):
|
||||
|
||||
try:
|
||||
# For rename only, just update the name
|
||||
rename = request.name is not None and not any((request.credentials, request.parameters, request.properties))
|
||||
rename = req_data.name is not None and not any(
|
||||
(req_data.credentials, req_data.parameters, req_data.properties)
|
||||
)
|
||||
# When credential type is UNAUTHORIZED, it indicates the subscription was manually created
|
||||
# For Manually created subscription, they dont have credentials, parameters
|
||||
# They only have name and properties(which is input by user)
|
||||
@@ -467,8 +488,8 @@ class TriggerSubscriptionUpdateApi(Resource):
|
||||
TriggerProviderService.update_trigger_subscription(
|
||||
tenant_id=tenant_id,
|
||||
subscription_id=subscription_id,
|
||||
name=request.name,
|
||||
properties=request.properties,
|
||||
name=req_data.name,
|
||||
properties=req_data.properties,
|
||||
)
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||
|
||||
@@ -476,11 +497,11 @@ class TriggerSubscriptionUpdateApi(Resource):
|
||||
# we need to call third party provider(e.g. GitHub) to rebuild the subscription
|
||||
TriggerProviderService.rebuild_trigger_subscription(
|
||||
tenant_id=tenant_id,
|
||||
name=request.name,
|
||||
name=req_data.name,
|
||||
provider_id=provider_id,
|
||||
subscription_id=subscription_id,
|
||||
credentials=request.credentials or subscription.credentials,
|
||||
parameters=request.parameters or subscription.parameters,
|
||||
credentials=req_data.credentials or subscription.credentials,
|
||||
parameters=req_data.parameters or subscription.parameters,
|
||||
)
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||
except ValueError as e:
|
||||
@@ -740,18 +761,17 @@ class TriggerOAuthClientManageApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, provider: str):
|
||||
@model_validate(TriggerOAuthClientPayload)
|
||||
def post(self, req_data: TriggerOAuthClientPayload, tenant_id: str, provider: str):
|
||||
"""Configure custom OAuth client for a provider"""
|
||||
|
||||
payload = TriggerOAuthClientPayload.model_validate(console_ns.payload or {})
|
||||
|
||||
try:
|
||||
provider_id = TriggerProviderID(provider)
|
||||
result = TriggerProviderService.save_custom_oauth_client_params(
|
||||
tenant_id=tenant_id,
|
||||
provider_id=provider_id,
|
||||
client_params=payload.client_params,
|
||||
enabled=payload.enabled,
|
||||
client_params=req_data.client_params,
|
||||
enabled=req_data.enabled,
|
||||
)
|
||||
return dump_response(SimpleResultResponse, result)
|
||||
|
||||
@@ -805,18 +825,24 @@ class TriggerSubscriptionVerifyApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account, provider: str, subscription_id: str):
|
||||
@model_validate(TriggerSubscriptionBuilderVerifyPayload)
|
||||
def post(
|
||||
self,
|
||||
req_data: TriggerSubscriptionBuilderVerifyPayload,
|
||||
tenant_id: str,
|
||||
user: Account,
|
||||
provider: str,
|
||||
subscription_id: str,
|
||||
):
|
||||
"""Verify credentials for an existing subscription (edit mode only)"""
|
||||
|
||||
verify_request = TriggerSubscriptionBuilderVerifyPayload.model_validate(console_ns.payload or {})
|
||||
|
||||
try:
|
||||
result = TriggerProviderService.verify_subscription_credentials(
|
||||
tenant_id=tenant_id,
|
||||
user_id=user.id,
|
||||
provider_id=TriggerProviderID(provider),
|
||||
subscription_id=subscription_id,
|
||||
credentials=verify_request.credentials,
|
||||
credentials=req_data.credentials,
|
||||
)
|
||||
return dump_response(TriggerVerificationResponse, result)
|
||||
except ValueError as e:
|
||||
|
||||
@@ -16,6 +16,7 @@ from controllers.console.auth.error import (
|
||||
from controllers.console.error import AccountInFreezeError
|
||||
from controllers.console.workspace.account import (
|
||||
AccountAvatarApi,
|
||||
AccountAvatarQuery,
|
||||
AccountDeleteApi,
|
||||
AccountDeleteVerifyApi,
|
||||
AccountInitApi,
|
||||
@@ -216,7 +217,7 @@ class TestAccountAvatarApiGet:
|
||||
return_value="https://signed/example",
|
||||
) as sign_mock,
|
||||
):
|
||||
result = method(api, user)
|
||||
result = method(api, AccountAvatarQuery(avatar=file_id), user)
|
||||
|
||||
assert result == {"avatar_url": "https://signed/example"}
|
||||
sign_mock.assert_called_once_with(upload_file_id=file_id)
|
||||
@@ -256,7 +257,7 @@ class TestAccountAvatarApiGet:
|
||||
) as sign_mock,
|
||||
):
|
||||
with pytest.raises(NotFound):
|
||||
method(api, user)
|
||||
method(api, AccountAvatarQuery(avatar=file_id), user)
|
||||
|
||||
sign_mock.assert_not_called()
|
||||
|
||||
@@ -289,7 +290,7 @@ class TestAccountAvatarApiGet:
|
||||
return_value="https://signed/example",
|
||||
) as sign_mock,
|
||||
):
|
||||
result = method(api, user)
|
||||
result = method(api, AccountAvatarQuery(avatar=file_id), user)
|
||||
|
||||
assert result == {"avatar_url": "https://signed/example"}
|
||||
sign_mock.assert_called_once_with(upload_file_id=file_id)
|
||||
@@ -308,7 +309,7 @@ class TestAccountAvatarApiGet:
|
||||
return_value="https://signed/should-not-use",
|
||||
) as sign_mock,
|
||||
):
|
||||
result = method(api, user)
|
||||
result = method(api, AccountAvatarQuery(avatar=external), user)
|
||||
|
||||
assert result == {"avatar_url": external}
|
||||
sign_mock.assert_not_called()
|
||||
|
||||
@@ -17,7 +17,9 @@ from controllers.console.workspace.endpoint import (
|
||||
EndpointIdPayload,
|
||||
EndpointItemApi,
|
||||
EndpointListApi,
|
||||
EndpointListForPluginQuery,
|
||||
EndpointListForSinglePluginApi,
|
||||
EndpointListQuery,
|
||||
EndpointUpdatePayload,
|
||||
LegacyEndpointUpdatePayload,
|
||||
)
|
||||
@@ -146,7 +148,7 @@ class TestEndpointListApi:
|
||||
return_value=[endpoint_entity],
|
||||
),
|
||||
):
|
||||
result = method(api, "t1", "u1")
|
||||
result = method(api, EndpointListQuery(page=1, page_size=10), "t1", "u1")
|
||||
|
||||
endpoint = result["endpoints"][0]
|
||||
assert endpoint["id"] == "e1"
|
||||
@@ -180,7 +182,7 @@ class TestEndpointListApi:
|
||||
app.test_request_context("/?page=0&page_size=10"),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api, "t1", "u1")
|
||||
method(api, EndpointListQuery(page=0, page_size=10), "t1", "u1")
|
||||
|
||||
|
||||
class TestEndpointListForSinglePluginApi:
|
||||
@@ -195,7 +197,7 @@ class TestEndpointListForSinglePluginApi:
|
||||
return_value=[_endpoint_entity()],
|
||||
),
|
||||
):
|
||||
result = method(api, "t1", "u1")
|
||||
result = method(api, EndpointListForPluginQuery(page=1, page_size=10, plugin_id="p1"), "t1", "u1")
|
||||
|
||||
assert result["endpoints"][0]["id"] == "e1"
|
||||
assert result["endpoints"][0]["settings"]["api_key"] == "pl********et"
|
||||
@@ -209,7 +211,7 @@ class TestEndpointListForSinglePluginApi:
|
||||
app.test_request_context("/?page=1&page_size=10"),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api, "t1", "u1")
|
||||
method(api, EndpointListForPluginQuery(page=1, page_size=10), "t1", "u1")
|
||||
|
||||
|
||||
class TestEndpointItemApi:
|
||||
|
||||
@@ -15,6 +15,16 @@ from controllers.console.workspace.models import (
|
||||
ModelProviderModelEnableApi,
|
||||
ModelProviderModelParameterRuleApi,
|
||||
ModelProviderModelValidateApi,
|
||||
ParserCreateCredential,
|
||||
ParserDeleteCredential,
|
||||
ParserDeleteModels,
|
||||
ParserGetCredentials,
|
||||
ParserGetDefault,
|
||||
ParserParameter,
|
||||
ParserPostDefault,
|
||||
ParserPostModels,
|
||||
ParserSwitch,
|
||||
ParserValidate,
|
||||
)
|
||||
from graphon.model_runtime.entities.model_entities import ModelType
|
||||
from graphon.model_runtime.errors.validate import CredentialsValidateFailedError
|
||||
@@ -43,7 +53,7 @@ class TestDefaultModelApi:
|
||||
},
|
||||
}
|
||||
|
||||
result = method(api, "tenant1")
|
||||
result = method(api, ParserGetDefault(model_type=ModelType.LLM), "tenant1")
|
||||
|
||||
assert "data" in result
|
||||
|
||||
@@ -65,7 +75,7 @@ class TestDefaultModelApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.models.ModelProviderService"),
|
||||
):
|
||||
result = method(api, "tenant1")
|
||||
result = method(api, ParserPostDefault.model_validate(payload), "tenant1")
|
||||
|
||||
assert result["result"] == "success"
|
||||
|
||||
@@ -79,7 +89,7 @@ class TestDefaultModelApi:
|
||||
):
|
||||
service.return_value.get_default_model_of_model_type.return_value = None
|
||||
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserGetDefault(model_type=ModelType.LLM), "t1")
|
||||
|
||||
assert "data" in result
|
||||
|
||||
@@ -117,7 +127,7 @@ class TestModelProviderModelApi:
|
||||
patch("controllers.console.workspace.models.ModelProviderService"),
|
||||
patch("controllers.console.workspace.models.ModelLoadBalancingService"),
|
||||
):
|
||||
result, status = method(api, "tenant1", "openai")
|
||||
result, status = method(api, ParserPostModels.model_validate(payload), "tenant1", "openai")
|
||||
|
||||
assert status == 200
|
||||
|
||||
@@ -134,7 +144,7 @@ class TestModelProviderModelApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.models.ModelProviderService"),
|
||||
):
|
||||
result, status = method(api, "tenant1", "openai")
|
||||
result, status = method(api, ParserDeleteModels.model_validate(payload), "tenant1", "openai")
|
||||
|
||||
assert status == 204
|
||||
|
||||
@@ -177,7 +187,13 @@ class TestModelProviderModelCredentialApi:
|
||||
provider_service.return_value.provider_manager.get_provider_model_available_credentials.return_value = []
|
||||
lb_service.return_value.get_load_balancing_configs.return_value = (False, [])
|
||||
|
||||
result = method(api, "tenant1", SimpleNamespace(id="u1"), "openai")
|
||||
result = method(
|
||||
api,
|
||||
ParserGetCredentials(model="gpt-4", model_type=ModelType.LLM),
|
||||
"tenant1",
|
||||
SimpleNamespace(id="u1"),
|
||||
"openai",
|
||||
)
|
||||
|
||||
assert "credentials" in result
|
||||
|
||||
@@ -195,7 +211,7 @@ class TestModelProviderModelCredentialApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.models.ModelProviderService"),
|
||||
):
|
||||
result, status = method(api, "tenant1", "openai")
|
||||
result, status = method(api, ParserCreateCredential.model_validate(payload), "tenant1", "openai")
|
||||
|
||||
assert status == 201
|
||||
|
||||
@@ -212,7 +228,13 @@ class TestModelProviderModelCredentialApi:
|
||||
service.return_value.provider_manager.get_provider_model_available_credentials.return_value = []
|
||||
lb.return_value.get_load_balancing_configs.return_value = (False, [])
|
||||
|
||||
result = method(api, "t1", SimpleNamespace(id="u1"), "openai")
|
||||
result = method(
|
||||
api,
|
||||
ParserGetCredentials(model="gpt", model_type=ModelType.LLM),
|
||||
"t1",
|
||||
SimpleNamespace(id="u1"),
|
||||
"openai",
|
||||
)
|
||||
|
||||
assert result["credentials"] == {}
|
||||
|
||||
@@ -230,7 +252,7 @@ class TestModelProviderModelCredentialApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.models.ModelProviderService"),
|
||||
):
|
||||
result, status = method(api, "t1", "openai")
|
||||
result, status = method(api, ParserDeleteCredential.model_validate(payload), "t1", "openai")
|
||||
|
||||
assert status == 204
|
||||
|
||||
@@ -250,7 +272,7 @@ class TestModelProviderModelCredentialSwitchApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.models.ModelProviderService"),
|
||||
):
|
||||
result = method(api, "tenant1", "openai")
|
||||
result = method(api, ParserSwitch.model_validate(payload), "tenant1", "openai")
|
||||
|
||||
assert result["result"] == "success"
|
||||
|
||||
@@ -269,7 +291,7 @@ class TestModelEnableDisableApis:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.models.ModelProviderService"),
|
||||
):
|
||||
result = method(api, "tenant1", "openai")
|
||||
result = method(api, ParserDeleteModels.model_validate(payload), "tenant1", "openai")
|
||||
|
||||
assert result["result"] == "success"
|
||||
|
||||
@@ -286,7 +308,7 @@ class TestModelEnableDisableApis:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.models.ModelProviderService"),
|
||||
):
|
||||
result = method(api, "tenant1", "openai")
|
||||
result = method(api, ParserDeleteModels.model_validate(payload), "tenant1", "openai")
|
||||
|
||||
assert result["result"] == "success"
|
||||
|
||||
@@ -306,7 +328,7 @@ class TestModelProviderModelValidateApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.models.ModelProviderService"),
|
||||
):
|
||||
result = method(api, "tenant1", "openai")
|
||||
result = method(api, ParserValidate.model_validate(payload), "tenant1", "openai")
|
||||
|
||||
assert result["result"] == "success"
|
||||
|
||||
@@ -327,7 +349,7 @@ class TestModelProviderModelValidateApi:
|
||||
):
|
||||
service_mock.return_value.validate_model_credentials.side_effect = CredentialsValidateFailedError("invalid")
|
||||
|
||||
result = method(api, "tenant1", "openai")
|
||||
result = method(api, ParserValidate.model_validate(payload), "tenant1", "openai")
|
||||
|
||||
assert result["result"] == "error"
|
||||
|
||||
@@ -343,7 +365,7 @@ class TestParameterAndAvailableModels:
|
||||
):
|
||||
service_mock.return_value.get_model_parameter_rules.return_value = []
|
||||
|
||||
result = method(api, "tenant1", "openai")
|
||||
result = method(api, ParserParameter(model="gpt-4"), "tenant1", "openai")
|
||||
|
||||
assert "data" in result
|
||||
|
||||
@@ -371,7 +393,7 @@ class TestParameterAndAvailableModels:
|
||||
):
|
||||
service.return_value.get_model_parameter_rules.return_value = []
|
||||
|
||||
result = method(api, "t1", "openai")
|
||||
result = method(api, ParserParameter(model="gpt"), "t1", "openai")
|
||||
|
||||
assert result["data"] == []
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ from werkzeug.exceptions import Forbidden, NotFound
|
||||
|
||||
from configs import dify_config
|
||||
from controllers.console.workspace import rbac as rbac_mod
|
||||
from controllers.console.workspace.rbac import _RolesListQuery
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -175,7 +176,10 @@ class TestPaginationMapping:
|
||||
patch("controllers.console.workspace.rbac._current_ids", return_value=("tenant-1", "acct-1")),
|
||||
patch("controllers.console.workspace.rbac.svc.RBACService.Roles.list") as mock_list,
|
||||
):
|
||||
response = inspect.unwrap(rbac_mod.RBACRolesApi.get)(rbac_mod.RBACRolesApi())
|
||||
response = inspect.unwrap(rbac_mod.RBACRolesApi.get)(
|
||||
rbac_mod.RBACRolesApi(),
|
||||
_RolesListQuery.model_validate({"page": 1, "limit": 2, "include_owner": 1}),
|
||||
)
|
||||
|
||||
owner_permission_keys = rbac_mod._LEGACY_ROLE_PERMISSION_KEYS["owner"]
|
||||
valid_owner_permission_keys = []
|
||||
@@ -230,7 +234,7 @@ class TestPaginationMapping:
|
||||
patch("controllers.console.workspace.rbac._current_ids", return_value=("tenant-1", "acct-1")),
|
||||
patch("controllers.console.workspace.rbac.svc.RBACService.Roles.list"),
|
||||
):
|
||||
response = inspect.unwrap(rbac_mod.RBACRolesApi.get)(rbac_mod.RBACRolesApi())
|
||||
response = inspect.unwrap(rbac_mod.RBACRolesApi.get)(rbac_mod.RBACRolesApi(), _RolesListQuery())
|
||||
|
||||
names = [r["name"] for r in response["data"]]
|
||||
assert "owner" not in names
|
||||
@@ -242,7 +246,10 @@ class TestPaginationMapping:
|
||||
patch("controllers.console.workspace.rbac._current_ids", return_value=("tenant-1", "acct-1")),
|
||||
patch("controllers.console.workspace.rbac.svc.RBACService.Roles.list"),
|
||||
):
|
||||
response = inspect.unwrap(rbac_mod.RBACRolesApi.get)(rbac_mod.RBACRolesApi())
|
||||
response = inspect.unwrap(rbac_mod.RBACRolesApi.get)(
|
||||
rbac_mod.RBACRolesApi(),
|
||||
_RolesListQuery.model_validate({"include_owner": 1}),
|
||||
)
|
||||
|
||||
names = [r["name"] for r in response["data"]]
|
||||
assert "owner" in names
|
||||
@@ -254,7 +261,7 @@ class TestPaginationMapping:
|
||||
patch("controllers.console.workspace.rbac._current_ids", return_value=("tenant-1", "acct-1")),
|
||||
patch("controllers.console.workspace.rbac.svc.RBACService.Roles.list"),
|
||||
):
|
||||
response = inspect.unwrap(rbac_mod.RBACRolesApi.get)(rbac_mod.RBACRolesApi())
|
||||
response = inspect.unwrap(rbac_mod.RBACRolesApi.get)(rbac_mod.RBACRolesApi(), _RolesListQuery())
|
||||
|
||||
names = [r["name"] for r in response["data"]]
|
||||
assert "owner" not in names
|
||||
@@ -267,7 +274,10 @@ class TestPaginationMapping:
|
||||
patch("controllers.console.workspace.rbac.svc.RBACService.Roles.list") as mock_list,
|
||||
patch("controllers.console.workspace.rbac._dump", return_value={}),
|
||||
):
|
||||
inspect.unwrap(rbac_mod.RBACRolesApi.get)(rbac_mod.RBACRolesApi())
|
||||
inspect.unwrap(rbac_mod.RBACRolesApi.get)(
|
||||
rbac_mod.RBACRolesApi(),
|
||||
_RolesListQuery.model_validate({"page": 2, "limit": 50, "reverse": True, "include_owner": 1}),
|
||||
)
|
||||
|
||||
_, kwargs = mock_list.call_args
|
||||
options = kwargs["options"]
|
||||
|
||||
@@ -15,15 +15,19 @@ from controllers.console.workspace.trigger_providers import (
|
||||
TriggerOAuthAuthorizeApi,
|
||||
TriggerOAuthCallbackApi,
|
||||
TriggerOAuthClientManageApi,
|
||||
TriggerOAuthClientPayload,
|
||||
TriggerProviderIconApi,
|
||||
TriggerProviderInfoApi,
|
||||
TriggerProviderListApi,
|
||||
TriggerSubscriptionBuilderBuildApi,
|
||||
TriggerSubscriptionBuilderCreateApi,
|
||||
TriggerSubscriptionBuilderCreatePayload,
|
||||
TriggerSubscriptionBuilderGetApi,
|
||||
TriggerSubscriptionBuilderLogsApi,
|
||||
TriggerSubscriptionBuilderUpdateApi,
|
||||
TriggerSubscriptionBuilderUpdatePayload,
|
||||
TriggerSubscriptionBuilderVerifyApi,
|
||||
TriggerSubscriptionBuilderVerifyPayload,
|
||||
TriggerSubscriptionListApi,
|
||||
TriggerSubscriptionUpdateApi,
|
||||
TriggerSubscriptionVerifyApi,
|
||||
@@ -163,7 +167,13 @@ class TestTriggerSubscriptionBuilderApis:
|
||||
return_value=subscription_builder(),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1", mock_user(), "github")
|
||||
result = method(
|
||||
api,
|
||||
TriggerSubscriptionBuilderCreatePayload(credential_type="UNAUTHORIZED"),
|
||||
"t1",
|
||||
mock_user(),
|
||||
"github",
|
||||
)
|
||||
assert result["subscription_builder"]["id"] == "b1"
|
||||
|
||||
def test_get_builder(self, app: Flask) -> None:
|
||||
@@ -196,7 +206,14 @@ class TestTriggerSubscriptionBuilderApis:
|
||||
return_value={"verified": True},
|
||||
),
|
||||
):
|
||||
assert method(api, "t1", mock_user(), "github", "b1") == {"verified": True}
|
||||
assert method(
|
||||
api,
|
||||
TriggerSubscriptionBuilderVerifyPayload(credentials={"a": 1}),
|
||||
"t1",
|
||||
mock_user(),
|
||||
"github",
|
||||
"b1",
|
||||
) == {"verified": True}
|
||||
|
||||
def test_verify_builder_error(self, app: Flask) -> None:
|
||||
api = TriggerSubscriptionBuilderVerifyApi()
|
||||
@@ -210,7 +227,14 @@ class TestTriggerSubscriptionBuilderApis:
|
||||
),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api, "t1", mock_user(), "github", "b1")
|
||||
method(
|
||||
api,
|
||||
TriggerSubscriptionBuilderVerifyPayload(credentials={}),
|
||||
"t1",
|
||||
mock_user(),
|
||||
"github",
|
||||
"b1",
|
||||
)
|
||||
|
||||
def test_update_builder(self, app: Flask) -> None:
|
||||
api = TriggerSubscriptionBuilderUpdateApi()
|
||||
@@ -223,7 +247,17 @@ class TestTriggerSubscriptionBuilderApis:
|
||||
return_value=subscription_builder(),
|
||||
) as mock_update_builder,
|
||||
):
|
||||
assert method(api, "t1", mock_user(), "github", "b1")["id"] == "b1"
|
||||
assert (
|
||||
method(
|
||||
api,
|
||||
TriggerSubscriptionBuilderUpdatePayload(name="n"),
|
||||
"t1",
|
||||
mock_user(),
|
||||
"github",
|
||||
"b1",
|
||||
)["id"]
|
||||
== "b1"
|
||||
)
|
||||
mock_update_builder.assert_called_once_with(
|
||||
tenant_id="t1",
|
||||
user_id="u1",
|
||||
@@ -263,7 +297,14 @@ class TestTriggerSubscriptionBuilderApis:
|
||||
return_value=None,
|
||||
),
|
||||
):
|
||||
assert method(api, "t1", mock_user(), "github", "b1") == {"result": "success"}
|
||||
assert method(
|
||||
api,
|
||||
TriggerSubscriptionBuilderUpdatePayload(name="x"),
|
||||
"t1",
|
||||
mock_user(),
|
||||
"github",
|
||||
"b1",
|
||||
) == {"result": "success"}
|
||||
|
||||
|
||||
class TestTriggerSubscriptionCrud:
|
||||
@@ -283,7 +324,12 @@ class TestTriggerSubscriptionCrud:
|
||||
),
|
||||
patch("controllers.console.workspace.trigger_providers.TriggerProviderService.update_trigger_subscription"),
|
||||
):
|
||||
assert method(api, "t1", "s1") == {"result": "success"}
|
||||
assert method(
|
||||
api,
|
||||
TriggerSubscriptionBuilderUpdatePayload(name="x"),
|
||||
"t1",
|
||||
"s1",
|
||||
) == {"result": "success"}
|
||||
|
||||
def test_update_not_found(self, app: Flask) -> None:
|
||||
api = TriggerSubscriptionUpdateApi()
|
||||
@@ -297,7 +343,7 @@ class TestTriggerSubscriptionCrud:
|
||||
),
|
||||
):
|
||||
with pytest.raises(NotFoundError):
|
||||
method(api, "t1", "x")
|
||||
method(api, TriggerSubscriptionBuilderUpdatePayload(name="x"), "t1", "x")
|
||||
|
||||
def test_update_rebuild(self, app: Flask) -> None:
|
||||
api = TriggerSubscriptionUpdateApi()
|
||||
@@ -319,7 +365,12 @@ class TestTriggerSubscriptionCrud:
|
||||
"controllers.console.workspace.trigger_providers.TriggerProviderService.rebuild_trigger_subscription"
|
||||
),
|
||||
):
|
||||
assert method(api, "t1", "s1") == {"result": "success"}
|
||||
assert method(
|
||||
api,
|
||||
TriggerSubscriptionBuilderUpdatePayload(credentials={}),
|
||||
"t1",
|
||||
"s1",
|
||||
) == {"result": "success"}
|
||||
|
||||
|
||||
class TestTriggerOAuthApis:
|
||||
@@ -499,7 +550,12 @@ class TestTriggerOAuthClientManageApi:
|
||||
return_value={"result": "success"},
|
||||
),
|
||||
):
|
||||
assert method(api, "t1", "github") == {"result": "success"}
|
||||
assert method(
|
||||
api,
|
||||
TriggerOAuthClientPayload(enabled=True),
|
||||
"t1",
|
||||
"github",
|
||||
) == {"result": "success"}
|
||||
|
||||
def test_delete_client(self, app: Flask) -> None:
|
||||
api = TriggerOAuthClientManageApi()
|
||||
@@ -526,7 +582,7 @@ class TestTriggerOAuthClientManageApi:
|
||||
),
|
||||
):
|
||||
with pytest.raises(BadRequest):
|
||||
method(api, "t1", "github")
|
||||
method(api, TriggerOAuthClientPayload(enabled=True), "t1", "github")
|
||||
|
||||
|
||||
class TestTriggerSubscriptionVerifyApi:
|
||||
@@ -541,7 +597,14 @@ class TestTriggerSubscriptionVerifyApi:
|
||||
return_value={"verified": True},
|
||||
),
|
||||
):
|
||||
assert method(api, "t1", mock_user(), "github", "s1") == {"verified": True}
|
||||
assert method(
|
||||
api,
|
||||
TriggerSubscriptionBuilderVerifyPayload(credentials={}),
|
||||
"t1",
|
||||
mock_user(),
|
||||
"github",
|
||||
"s1",
|
||||
) == {"verified": True}
|
||||
|
||||
@pytest.mark.parametrize("raised_exception", [ValueError("bad"), Exception("boom")])
|
||||
def test_verify_errors(self, app: Flask, raised_exception: Exception) -> None:
|
||||
@@ -556,4 +619,11 @@ class TestTriggerSubscriptionVerifyApi:
|
||||
),
|
||||
):
|
||||
with pytest.raises(BadRequest):
|
||||
method(api, "t1", mock_user(), "github", "s1")
|
||||
method(
|
||||
api,
|
||||
TriggerSubscriptionBuilderVerifyPayload(credentials={}),
|
||||
"t1",
|
||||
mock_user(),
|
||||
"github",
|
||||
"s1",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user