217 lines
8.1 KiB
Python
Raw Normal View History

2025-07-04 18:05:58 +08:00
import random
2025-05-27 00:01:23 +08:00
from flask import redirect, request
from flask_login import current_user # type: ignore
from flask_restful import ( # type: ignore
Resource, # type: ignore
reqparse,
)
from werkzeug.exceptions import Forbidden, NotFound
from configs import dify_config
from controllers.console import api
from controllers.console.wraps import (
account_initialization_required,
setup_required,
)
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.plugin.impl.oauth import OAuthHandler
from extensions.ext_database import db
from libs.login import login_required
from models.oauth import DatasourceOauthParamConfig, DatasourceProvider
from services.datasource_provider_service import DatasourceProviderService
class DatasourcePluginOauthApi(Resource):
@setup_required
@login_required
@account_initialization_required
2025-06-04 15:12:05 +08:00
def get(self):
parser = reqparse.RequestParser()
parser.add_argument("provider", type=str, required=True, nullable=False, location="args")
parser.add_argument("plugin_id", type=str, required=True, nullable=False, location="args")
args = parser.parse_args()
provider = args["provider"]
plugin_id = args["plugin_id"]
2025-05-27 00:01:23 +08:00
# Check user role first
if not current_user.is_editor:
raise Forbidden()
# get all plugin oauth configs
2025-06-03 19:02:57 +08:00
plugin_oauth_config = (
db.session.query(DatasourceOauthParamConfig).filter_by(provider=provider, plugin_id=plugin_id).first()
)
2025-05-27 00:01:23 +08:00
if not plugin_oauth_config:
raise NotFound()
oauth_handler = OAuthHandler()
2025-06-17 19:06:17 +08:00
redirect_url = (
f"{dify_config.CONSOLE_WEB_URL}/oauth/datasource/callback?provider={provider}&plugin_id={plugin_id}"
)
2025-05-27 00:01:23 +08:00
system_credentials = plugin_oauth_config.system_credentials
if system_credentials:
system_credentials["redirect_url"] = redirect_url
response = oauth_handler.get_authorization_url(
2025-06-03 19:02:57 +08:00
current_user.current_tenant.id, current_user.id, plugin_id, provider, system_credentials=system_credentials
2025-05-27 00:01:23 +08:00
)
return response.model_dump()
2025-06-03 19:02:57 +08:00
2025-05-27 00:01:23 +08:00
class DatasourceOauthCallback(Resource):
@setup_required
@login_required
@account_initialization_required
2025-06-04 15:12:05 +08:00
def get(self):
parser = reqparse.RequestParser()
parser.add_argument("provider", type=str, required=True, nullable=False, location="args")
parser.add_argument("plugin_id", type=str, required=True, nullable=False, location="args")
args = parser.parse_args()
provider = args["provider"]
plugin_id = args["plugin_id"]
2025-05-27 00:01:23 +08:00
oauth_handler = OAuthHandler()
2025-06-03 19:02:57 +08:00
plugin_oauth_config = (
db.session.query(DatasourceOauthParamConfig).filter_by(provider=provider, plugin_id=plugin_id).first()
)
2025-05-27 00:01:23 +08:00
if not plugin_oauth_config:
raise NotFound()
credentials = oauth_handler.get_credentials(
current_user.current_tenant.id,
current_user.id,
plugin_id,
provider,
system_credentials=plugin_oauth_config.system_credentials,
2025-06-03 19:02:57 +08:00
request=request,
2025-05-27 00:01:23 +08:00
)
datasource_provider = DatasourceProvider(
2025-06-03 19:02:57 +08:00
plugin_id=plugin_id, provider=provider, auth_type="oauth", encrypted_credentials=credentials
2025-05-27 00:01:23 +08:00
)
db.session.add(datasource_provider)
db.session.commit()
return redirect(f"{dify_config.CONSOLE_WEB_URL}")
2025-06-03 19:02:57 +08:00
2025-05-27 00:01:23 +08:00
class DatasourceAuth(Resource):
@setup_required
@login_required
@account_initialization_required
2025-06-04 15:12:05 +08:00
def post(self):
2025-05-27 00:01:23 +08:00
if not current_user.is_editor:
raise Forbidden()
parser = reqparse.RequestParser()
2025-06-04 15:12:05 +08:00
parser.add_argument("provider", type=str, required=True, nullable=False, location="json")
2025-07-02 18:15:23 +08:00
parser.add_argument("name", type=str, required=False, nullable=False, location="json", default="test")
2025-06-04 15:12:05 +08:00
parser.add_argument("plugin_id", type=str, required=True, nullable=False, location="json")
2025-05-27 00:01:23 +08:00
parser.add_argument("credentials", type=dict, required=True, nullable=False, location="json")
args = parser.parse_args()
datasource_provider_service = DatasourceProviderService()
try:
datasource_provider_service.datasource_provider_credentials_validate(
2025-06-03 19:02:57 +08:00
tenant_id=current_user.current_tenant_id,
2025-06-04 15:12:05 +08:00
provider=args["provider"],
plugin_id=args["plugin_id"],
2025-06-03 19:02:57 +08:00
credentials=args["credentials"],
2025-07-09 15:48:08 +08:00
name="test" + str(random.randint(1, 1000000)), # noqa: S311
2025-05-27 00:01:23 +08:00
)
except CredentialsValidateFailedError as ex:
raise ValueError(str(ex))
return {"result": "success"}, 201
2025-06-03 19:02:57 +08:00
2025-05-30 00:37:27 +08:00
@setup_required
@login_required
@account_initialization_required
2025-06-04 15:12:05 +08:00
def get(self):
parser = reqparse.RequestParser()
parser.add_argument("provider", type=str, required=True, nullable=False, location="args")
parser.add_argument("plugin_id", type=str, required=True, nullable=False, location="args")
args = parser.parse_args()
2025-05-30 00:37:27 +08:00
datasource_provider_service = DatasourceProviderService()
datasources = datasource_provider_service.get_datasource_credentials(
2025-06-17 19:06:17 +08:00
tenant_id=current_user.current_tenant_id, provider=args["provider"], plugin_id=args["plugin_id"]
2025-05-30 00:37:27 +08:00
)
return {"result": datasources}, 200
2025-06-03 19:02:57 +08:00
2025-06-04 17:29:39 +08:00
class DatasourceAuthUpdateDeleteApi(Resource):
2025-05-27 00:01:23 +08:00
@setup_required
@login_required
@account_initialization_required
2025-06-04 17:29:39 +08:00
def delete(self, auth_id: str):
2025-06-04 15:12:05 +08:00
parser = reqparse.RequestParser()
parser.add_argument("provider", type=str, required=True, nullable=False, location="args")
parser.add_argument("plugin_id", type=str, required=True, nullable=False, location="args")
args = parser.parse_args()
2025-05-27 00:01:23 +08:00
if not current_user.is_editor:
raise Forbidden()
datasource_provider_service = DatasourceProviderService()
datasource_provider_service.remove_datasource_credentials(
2025-06-04 17:29:39 +08:00
tenant_id=current_user.current_tenant_id,
auth_id=auth_id,
provider=args["provider"],
2025-06-17 19:06:17 +08:00
plugin_id=args["plugin_id"],
2025-05-27 00:01:23 +08:00
)
return {"result": "success"}, 200
2025-06-04 17:29:39 +08:00
@setup_required
@login_required
@account_initialization_required
def patch(self, auth_id: str):
parser = reqparse.RequestParser()
parser.add_argument("provider", type=str, required=True, nullable=False, location="args")
parser.add_argument("plugin_id", type=str, required=True, nullable=False, location="args")
parser.add_argument("credentials", type=dict, required=True, nullable=False, location="json")
args = parser.parse_args()
if not current_user.is_editor:
raise Forbidden()
try:
datasource_provider_service = DatasourceProviderService()
datasource_provider_service.update_datasource_credentials(
tenant_id=current_user.current_tenant_id,
auth_id=auth_id,
provider=args["provider"],
plugin_id=args["plugin_id"],
credentials=args["credentials"],
)
except CredentialsValidateFailedError as ex:
raise ValueError(str(ex))
return {"result": "success"}, 201
2025-07-09 14:27:49 +08:00
2025-07-08 17:16:10 +08:00
class DatasourceAuthListApi(Resource):
@setup_required
@login_required
@account_initialization_required
def get(self):
datasource_provider_service = DatasourceProviderService()
datasources = datasource_provider_service.get_all_datasource_credentials(
tenant_id=current_user.current_tenant_id
)
return {"result": datasources}, 200
2025-06-03 19:02:57 +08:00
2025-07-09 14:27:49 +08:00
2025-05-27 00:01:23 +08:00
# Import Rag Pipeline
api.add_resource(
DatasourcePluginOauthApi,
2025-06-04 15:12:05 +08:00
"/oauth/plugin/datasource",
2025-05-27 00:01:23 +08:00
)
api.add_resource(
DatasourceOauthCallback,
2025-06-04 15:12:05 +08:00
"/oauth/plugin/datasource/callback",
2025-05-27 00:01:23 +08:00
)
api.add_resource(
DatasourceAuth,
2025-06-04 15:12:05 +08:00
"/auth/plugin/datasource",
2025-05-27 00:01:23 +08:00
)
2025-06-04 17:29:39 +08:00
api.add_resource(
2025-06-04 17:39:31 +08:00
DatasourceAuthUpdateDeleteApi,
2025-06-04 17:29:39 +08:00
"/auth/plugin/datasource/<string:auth_id>",
)
2025-07-08 17:16:10 +08:00
api.add_resource(
DatasourceAuthListApi,
"/auth/plugin/datasource/list",
2025-07-09 14:27:49 +08:00
)