From 5d986c2cdf4ff6614b306f6b38bbf78cf9123c60 Mon Sep 17 00:00:00 2001 From: Harry Date: Tue, 22 Jul 2025 00:53:03 +0800 Subject: [PATCH] feat: add expires_at field to OAuth credentials and default value for builtin tool provider --- .../console/workspace/tool_providers.py | 1 + api/core/plugin/entities/plugin_daemon.py | 4 +++ ...2_0019-375fe79ead14_oauth_refresh_token.py | 34 +++++++++++++++++++ api/models/tools.py | 1 + .../tools/builtin_tools_manage_service.py | 5 +++ 5 files changed, 45 insertions(+) create mode 100644 api/migrations/versions/2025_07_22_0019-375fe79ead14_oauth_refresh_token.py diff --git a/api/controllers/console/workspace/tool_providers.py b/api/controllers/console/workspace/tool_providers.py index c70bf84d2a..71a6b43c8b 100644 --- a/api/controllers/console/workspace/tool_providers.py +++ b/api/controllers/console/workspace/tool_providers.py @@ -759,6 +759,7 @@ class ToolOAuthCallback(Resource): provider=provider, credentials=dict(credentials), api_type=CredentialType.OAUTH2, + expires_at=credentials.get("expires_at"), ) return redirect(f"{dify_config.CONSOLE_WEB_URL}/oauth-callback") diff --git a/api/core/plugin/entities/plugin_daemon.py b/api/core/plugin/entities/plugin_daemon.py index 00253b8a11..5c97ebd877 100644 --- a/api/core/plugin/entities/plugin_daemon.py +++ b/api/core/plugin/entities/plugin_daemon.py @@ -182,6 +182,10 @@ class PluginOAuthAuthorizationUrlResponse(BaseModel): class PluginOAuthCredentialsResponse(BaseModel): + metadata: Mapping[str, Any] = Field( + default_factory=dict, description="The metadata of the OAuth, like avatar url, name, etc." + ) + expires_at: int | None = Field(description="The expires at time of the credentials. UTC timestamp.") credentials: Mapping[str, Any] = Field(description="The credentials of the OAuth.") diff --git a/api/migrations/versions/2025_07_22_0019-375fe79ead14_oauth_refresh_token.py b/api/migrations/versions/2025_07_22_0019-375fe79ead14_oauth_refresh_token.py new file mode 100644 index 0000000000..9d15cae1b0 --- /dev/null +++ b/api/migrations/versions/2025_07_22_0019-375fe79ead14_oauth_refresh_token.py @@ -0,0 +1,34 @@ +"""oauth_refresh_token + +Revision ID: 375fe79ead14 +Revises: 1a83934ad6d1 +Create Date: 2025-07-22 00:19:45.599636 + +""" +from alembic import op +import models as models +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '375fe79ead14' +down_revision = '1a83934ad6d1' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_builtin_providers', schema=None) as batch_op: + batch_op.add_column(sa.Column('expires_at', sa.Integer(), server_default=sa.text('2147483647'), nullable=False)) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + + with op.batch_alter_table('tool_builtin_providers', schema=None) as batch_op: + batch_op.drop_column('expires_at') + + # ### end Alembic commands ### diff --git a/api/models/tools.py b/api/models/tools.py index f5fae8b796..83ac26f3d7 100644 --- a/api/models/tools.py +++ b/api/models/tools.py @@ -93,6 +93,7 @@ class BuiltinToolProvider(Base): credential_type: Mapped[str] = mapped_column( db.String(32), nullable=False, server_default=db.text("'api-key'::character varying") ) + expires_at: Mapped[int] = mapped_column(db.Integer, nullable=False, server_default=db.text("2147483647")) @property def credentials(self) -> dict: diff --git a/api/services/tools/builtin_tools_manage_service.py b/api/services/tools/builtin_tools_manage_service.py index 430575b532..f336c69889 100644 --- a/api/services/tools/builtin_tools_manage_service.py +++ b/api/services/tools/builtin_tools_manage_service.py @@ -38,6 +38,7 @@ logger = logging.getLogger(__name__) class BuiltinToolManageService: __MAX_BUILTIN_TOOL_PROVIDER_COUNT__ = 100 + __DEFAULT_EXPIRES_AT__ = 2147483647 @staticmethod def delete_custom_oauth_client_params(tenant_id: str, provider: str): @@ -213,6 +214,7 @@ class BuiltinToolManageService: provider: str, credentials: dict, name: str | None = None, + expires_at: int | None = None, ): """ add builtin tool provider @@ -269,6 +271,9 @@ class BuiltinToolManageService: encrypted_credentials=json.dumps(encrypter.encrypt(credentials)), credential_type=api_type.value, name=name, + expires_at=expires_at + if expires_at is not None + else BuiltinToolManageService.__DEFAULT_EXPIRES_AT__, ) session.add(db_provider)