Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
12c20ec
feat: plugin OAuth with stateful
Mairuis Jun 20, 2025
b3a8dbe
fix: typo
Mairuis Jun 23, 2025
7f292dc
fix: remove debugging flags
Mairuis Jun 23, 2025
5e7c586
refactor(tool oauth): update api implementation
Mairuis Jun 23, 2025
7979e05
Merge branch 'main' into feat/tool-plugin-oauth
Mairuis Jun 24, 2025
fcfaa7c
feat(oauth): plugin oauth service
Mairuis Jun 25, 2025
8bd05ae
Merge branch 'feat/plugin-oauth' into feat/tool-plugin-oauth
Mairuis Jun 25, 2025
a58e99c
Merge branch 'main' into feat/tool-plugin-oauth
Mairuis Jun 25, 2025
1a2dfd9
Merge branch 'main' into feat/tool-plugin-oauth
Mairuis Jun 25, 2025
ce4cc54
feat(oauth): merge tool oauth and remove sequence number branches
Mairuis Jun 25, 2025
6c9e99b
Merge branch 'main' into feat/tool-plugin-oauth
Mairuis Jun 25, 2025
ba843c2
feat(oauth): update api
Mairuis Jun 26, 2025
f4f6e41
feat(oauth): add oauth redirect_uri parameters
Mairuis Jun 26, 2025
8a954c0
Merge branch 'main' into feat/tool-plugin-oauth
Mairuis Jun 26, 2025
daec82b
feat(oauth): refactor tool provider methods and enhance credential ha…
Mairuis Jun 27, 2025
7951a1c
refactor(tool): implement multi provider credentials support
Mairuis Jul 2, 2025
6ef1e01
feat(oauth): add support for retrieving credential info and OAuth cli…
Mairuis Jul 2, 2025
988a760
feat(oauth): enhance OAuth client handling and add custom client support
Mairuis Jul 2, 2025
b316867
Merge remote-tracking branch 'origin/main' into feat/tool-plugin-oauth
Mairuis Jul 2, 2025
c53d5c1
feat: tool oauth
zxhlyh Jul 3, 2025
26b46b8
feat(oauth): add multi credentials support
Mairuis Jul 4, 2025
9f053f3
feat(oauth): rename ToolProviderCredentialType to CredentialType for …
Mairuis Jul 4, 2025
eaefa1b
feat(oauth): refactor encryption
Mairuis Jul 4, 2025
0dc5bfb
feat(oauth): refactor tool encryption utils
Mairuis Jul 4, 2025
0f1be60
tool oauth
zxhlyh Jul 8, 2025
ce8bf7b
Merge branch 'main' into feat/tool-oauth
zxhlyh Jul 8, 2025
ef330fe
feat(oauth): add credential validation for providers
Mairuis Jul 9, 2025
f35b8d6
feat(oauth): refactor session management in tool provider operations
Mairuis Jul 9, 2025
8968a3e
tool oauth
zxhlyh Jul 9, 2025
bda7608
Merge branch 'main' into feat/tool-oauth
zxhlyh Jul 9, 2025
bdf5af7
tool oauth
zxhlyh Jul 10, 2025
18699f8
tool oauth
zxhlyh Jul 10, 2025
5869d6a
tool oauth
zxhlyh Jul 10, 2025
90f8004
merge main
zxhlyh Jul 10, 2025
f3bbab0
Merge remote-tracking branch 'origin/main' into feat/tool-plugin-oauth
Mairuis Jul 11, 2025
545c21b
feat(oauth): clean up imports and streamline OAuth client parameter r…
Mairuis Jul 11, 2025
cb0082c
tool oauth
zxhlyh Jul 11, 2025
119d410
Merge branch 'main' into feat/tool-oauth
zxhlyh Jul 11, 2025
fb9e4a4
feat(oauth): migrations
Mairuis Jul 11, 2025
adc39f7
feat(oauth): enhance OAuth client management and validation
Mairuis Jul 11, 2025
0532135
Merge remote-tracking branch 'origin/main' into feat/tool-plugin-oauth
Mairuis Jul 11, 2025
ab6ae1f
feat(oauth): improve credential schema validation in provider
Mairuis Jul 11, 2025
7ba09df
fix(migrations): update down_revision references in migration files
Mairuis Jul 11, 2025
83ab69d
tool oauth
zxhlyh Jul 11, 2025
580c9a6
fix
zxhlyh Jul 11, 2025
ace6e11
feat(oauth): implement AES encryption and decryption for system OAuth…
Mairuis Jul 11, 2025
31e1261
fix(oauth): improve name validation logic for tool providers
Mairuis Jul 11, 2025
5090f63
feat(tool): update tool provider methods to handle optional credentia…
Mairuis Jul 11, 2025
8fc5cca
fix(oauth): add error handling for OAuth parameter decryption
Mairuis Jul 11, 2025
7de3436
feat(oauth): add credential handling and context support for tool inv…
Mairuis Jul 12, 2025
6cb4a6f
feat(dsl): filter out credential IDs from workflow and model configur…
Mairuis Jul 13, 2025
f9c4897
feat(oauth): replace HIDDEN_VALUE with UNKNOWN_VALUE for better crede…
Mairuis Jul 13, 2025
458e441
feat(oauth): enhance tool provider updates with name validation and i…
Mairuis Jul 13, 2025
3b7df2f
fix: provider
zxhlyh Jul 14, 2025
06802af
Merge branch 'main' into feat/tool-plugin-oauth
Mairuis Jul 14, 2025
f68201a
feat(oauth): implement name length validation
Mairuis Jul 14, 2025
37be099
feat(oauth): update client parameters handling and improve oauth_para…
Mairuis Jul 14, 2025
29035d3
fix: validate
zxhlyh Jul 14, 2025
fd0a8d5
Merge branch 'main' into feat/tool-oauth
zxhlyh Jul 14, 2025
2572e99
form
zxhlyh Jul 14, 2025
d0ba7ad
form
zxhlyh Jul 14, 2025
964e29b
fix: loading
zxhlyh Jul 14, 2025
22297d0
feat(oauth): add functionality to delete custom OAuth client paramete…
Mairuis Jul 14, 2025
3f273ca
fix
zxhlyh Jul 15, 2025
a923087
Merge branch 'main' into feat/tool-oauth
zxhlyh Jul 15, 2025
498d8ab
fix
zxhlyh Jul 15, 2025
6a085fa
Merge remote-tracking branch 'origin/main' into feat/tool-plugin-oauth
Mairuis Jul 15, 2025
e4cf6a4
fix
zxhlyh Jul 15, 2025
67b5d73
fix
zxhlyh Jul 15, 2025
e1bb6c0
fix
zxhlyh Jul 15, 2025
0dcdfd6
refactor: improve OAuth client configuration logic and logging in add…
Yeuoly Jul 15, 2025
9cdbf30
feat(env): update localhost URLs in .env.example
Mairuis Jul 15, 2025
fd2651f
refactor: simplify error handling by removing specific exceptions in …
Mairuis Jul 15, 2025
d162905
feat(oauth): enhance error handling for authorization URL and credent…
Mairuis Jul 16, 2025
3f65117
fix: style
zxhlyh Jul 16, 2025
2bafcd5
feat(oauth): add setup command for system tool OAuth client
Mairuis Jul 16, 2025
686b4b8
fix: style
zxhlyh Jul 16, 2025
52e7bb1
fix
zxhlyh Jul 16, 2025
75d8cb4
fix
zxhlyh Jul 16, 2025
f9f3c20
feat(oauth): add UUID validation and enhance error handling for crede…
Mairuis Jul 16, 2025
5db3887
feat(uuid): enhance UUID validation to check for empty strings
Mairuis Jul 16, 2025
25e0013
fix
zxhlyh Jul 16, 2025
71c89b3
Merge branch 'feat/tool-plugin-oauth' into feat/oauth
Mairuis Jul 16, 2025
fd1f911
Merge remote-tracking branch 'origin/feat/tool-oauth' into feat/oauth
Mairuis Jul 16, 2025
3811fde
fix: migrations
Mairuis Jul 16, 2025
ed186f0
feat: build-push.yml
Mairuis Jul 16, 2025
364e0f1
fix: update OAuth button logic to improve configuration handling
Mairuis Jul 16, 2025
c914d07
Merge branch 'feat/tool-oauth' into feat/oauth
Mairuis Jul 16, 2025
c238b88
feat(oauth): improve error handling for provider retrieval and clarif…
Mairuis Jul 17, 2025
c9bb3e6
Merge branch 'feat/tool-plugin-oauth' into feat/oauth
Mairuis Jul 17, 2025
ff03ae1
Merge remote-tracking branch 'origin/main' into feat/oauth
Mairuis Jul 17, 2025
b8f79a7
fix: apply ruff
Mairuis Jul 17, 2025
1ee69f8
refactor: update OAuth parameter handling to use Pydantic TypeAdapter…
Yeuoly Jul 17, 2025
e589d63
test: add comprehensive unit tests for SystemOAuthEncrypter, covering…
Mairuis Jul 17, 2025
36e76be
test: add comprehensive tests for SystemOAuthEncrypter and related fu…
Mairuis Jul 17, 2025
32fc208
Merge remote-tracking branch 'origin/main' into feat/oauth
Mairuis Jul 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(oauth): add multi credentials support
  • Loading branch information
Mairuis committed Jul 4, 2025
commit 26b46b88c9acb6ddedd213dee5beaee7d6ddb26b
4 changes: 3 additions & 1 deletion api/core/plugin/impl/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from core.plugin.entities.plugin import GenericProviderID, ToolProviderID
from core.plugin.entities.plugin_daemon import PluginBasicBooleanResponse, PluginToolProviderEntity
from core.plugin.impl.base import BasePluginClient
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParameter
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParameter, ToolProviderCredentialType


class PluginToolManager(BasePluginClient):
Expand Down Expand Up @@ -78,6 +78,7 @@ def invoke(
tool_provider: str,
tool_name: str,
credentials: dict[str, Any],
credential_type: ToolProviderCredentialType,
tool_parameters: dict[str, Any],
conversation_id: Optional[str] = None,
app_id: Optional[str] = None,
Expand All @@ -102,6 +103,7 @@ def invoke(
"provider": tool_provider_id.provider_name,
"tool": tool_name,
"credentials": credentials,
"credential_type": credential_type,
"tool_parameters": tool_parameters,
},
},
Expand Down
3 changes: 2 additions & 1 deletion api/core/tools/__base/tool_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from pydantic import Field

from core.app.entities.app_invoke_entities import InvokeFrom
from core.tools.entities.tool_entities import ToolInvokeFrom
from core.tools.entities.tool_entities import ToolInvokeFrom, ToolProviderCredentialType


class ToolRuntime(BaseModel):
Expand All @@ -17,6 +17,7 @@ class ToolRuntime(BaseModel):
invoke_from: Optional[InvokeFrom] = None
tool_invoke_from: Optional[ToolInvokeFrom] = None
credentials: dict[str, Any] = Field(default_factory=dict)
credential_type: Optional[ToolProviderCredentialType] = ToolProviderCredentialType.API_KEY
runtime_parameters: dict[str, Any] = Field(default_factory=dict)


Expand Down
1 change: 1 addition & 0 deletions api/core/tools/plugin_tool/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def _invoke(
tool_provider=self.entity.identity.provider,
tool_name=self.entity.identity.name,
credentials=self.runtime.credentials,
credential_type=self.runtime.credential_type,
tool_parameters=tool_parameters,
conversation_id=conversation_id,
app_id=app_id,
Expand Down
48 changes: 30 additions & 18 deletions api/core/tools/tool_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from collections.abc import Generator
from os import listdir, path
from threading import Lock
from typing import TYPE_CHECKING, Any, Union, cast
from typing import TYPE_CHECKING, Any, Optional, Union, cast

from yarl import URL

Expand Down Expand Up @@ -39,6 +39,7 @@
ApiProviderAuthType,
ToolInvokeFrom,
ToolParameter,
ToolProviderCredentialType,
ToolProviderType,
)
from core.tools.errors import ToolProviderNotFoundError
Expand Down Expand Up @@ -148,6 +149,7 @@ def get_tool_runtime(
tenant_id: str,
invoke_from: InvokeFrom = InvokeFrom.DEBUGGER,
tool_invoke_from: ToolInvokeFrom = ToolInvokeFrom.AGENT,
credential_id: Optional[str] = None,
) -> Union[BuiltinTool, PluginTool, ApiTool, WorkflowTool]:
"""
get the tool runtime
Expand All @@ -158,6 +160,7 @@ def get_tool_runtime(
:param tenant_id: the tenant id
:param invoke_from: invoke from
:param tool_invoke_from: the tool invoke from
:param credential_id: the credential id

:return: the tool
"""
Expand Down Expand Up @@ -185,19 +188,31 @@ def get_tool_runtime(
if isinstance(provider_controller, PluginToolProviderController):
provider_id_entity = ToolProviderID(provider_id)
# get credentials
builtin_provider: BuiltinToolProvider | None = (
db.session.query(BuiltinToolProvider)
.filter(
BuiltinToolProvider.tenant_id == tenant_id,
(BuiltinToolProvider.provider == str(provider_id_entity))
| (BuiltinToolProvider.provider == provider_id_entity.provider_name),
if credential_id:
builtin_provider = (
db.session.query(BuiltinToolProvider)
.filter(
BuiltinToolProvider.tenant_id == tenant_id,
BuiltinToolProvider.id == credential_id,
)
.first()
)
if builtin_provider is None:
raise ToolProviderNotFoundError(f"builtin provider {credential_id} not found")
else:
builtin_provider = (
db.session.query(BuiltinToolProvider)
.filter(
BuiltinToolProvider.tenant_id == tenant_id,
(BuiltinToolProvider.provider == str(provider_id_entity))
| (BuiltinToolProvider.provider == provider_id_entity.provider_name),
)
.order_by(BuiltinToolProvider.is_default.desc(), BuiltinToolProvider.created_at.asc())
.first()
)
.order_by(BuiltinToolProvider.is_default.desc(), BuiltinToolProvider.created_at.asc())
.first()
)

if builtin_provider is None:
raise ToolProviderNotFoundError(f"builtin provider {provider_id} not found")
if builtin_provider is None:
raise ToolProviderNotFoundError(f"builtin provider {provider_id} not found")
else:
builtin_provider = (
db.session.query(BuiltinToolProvider)
Expand All @@ -209,8 +224,6 @@ def get_tool_runtime(
if builtin_provider is None:
raise ToolProviderNotFoundError(f"builtin provider {provider_id} not found")

# decrypt the credentials
credentials = builtin_provider.credentials
encrypter, _ = create_encrypter(
tenant_id=tenant_id,
config=[
Expand All @@ -221,15 +234,13 @@ def get_tool_runtime(
tenant_id=tenant_id, provider=provider_id, credential_id=builtin_provider.id
),
)

decrypted_credentials = encrypter.decrypt(credentials)

return cast(
BuiltinTool,
builtin_tool.fork_tool_runtime(
runtime=ToolRuntime(
tenant_id=tenant_id,
credentials=decrypted_credentials,
credentials=encrypter.decrypt(builtin_provider.credentials),
credential_type=ToolProviderCredentialType.of(builtin_provider.credential_type),
runtime_parameters={},
invoke_from=invoke_from,
tool_invoke_from=tool_invoke_from,
Expand Down Expand Up @@ -362,6 +373,7 @@ def get_workflow_tool_runtime(
tenant_id=tenant_id,
invoke_from=invoke_from,
tool_invoke_from=ToolInvokeFrom.WORKFLOW,
credential_id=workflow_tool.credential_id,
)
runtime_parameters = {}
parameters = tool_runtime.get_merged_runtime_parameters()
Expand Down
1 change: 1 addition & 0 deletions api/core/workflow/nodes/tool/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class ToolEntity(BaseModel):
tool_name: str
tool_label: str # redundancy
tool_configurations: dict[str, Any]
credential_id: str | None = None
plugin_unique_identifier: str | None = None # redundancy

@field_validator("tool_configurations", mode="before")
Expand Down
5 changes: 5 additions & 0 deletions api/services/app_dsl_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,11 @@ def _append_workflow_export_data(cls, *, export_data: dict, app_model: App, incl
cls.encrypt_dataset_id(dataset_id=dataset_id, tenant_id=app_model.tenant_id)
for dataset_id in dataset_ids
]
# filter credential id from tool node
if node.get("data", {}).get("type", "") == NodeType.TOOL.value:
node["data"]["credential_id"] = None


export_data["workflow"] = workflow_dict
dependencies = cls._extract_dependencies_from_workflow(workflow)
export_data["dependencies"] = [
Expand Down