mirror of https://github.com/langgenius/dify.git
fix: Auto-delete API credentials when uninstalling plugin
Automatically remove plugin provider credentials on uninstall to prevent orphaned keys from being restored when plugin is reinstalled. Fixes #27531
This commit is contained in:
parent
ddad2460f3
commit
c1b914ee7c
|
|
@ -826,3 +826,29 @@ class PluginReadmeApi(Resource):
|
|||
return jsonable_encoder(
|
||||
{"readme": PluginService.fetch_plugin_readme(tenant_id, args.plugin_unique_identifier, args.language)}
|
||||
)
|
||||
|
||||
|
||||
class ParserUninstall(BaseModel):
|
||||
plugin_installation_id: str = Field(..., description="Plugin installation ID")
|
||||
|
||||
|
||||
console_ns.schema_model(
|
||||
ParserUninstall.__name__, ParserUninstall.model_json_schema(ref_template=DEFAULT_REF_TEMPLATE_SWAGGER_2_0)
|
||||
)
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/plugin/uninstall")
|
||||
class PluginUninstallApi(Resource):
|
||||
@console_ns.expect(console_ns.models[ParserUninstall.__name__])
|
||||
@setup_required
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@plugin_permission_required(install_required=True)
|
||||
def post(self):
|
||||
_, tenant_id = current_account_with_tenant()
|
||||
args = ParserUninstall.model_validate(console_ns.payload)
|
||||
|
||||
try:
|
||||
return {"success": PluginService.uninstall(tenant_id, args.plugin_installation_id)}
|
||||
except PluginDaemonClientSideError as e:
|
||||
raise ValueError(e)
|
||||
|
|
|
|||
|
|
@ -505,7 +505,38 @@ class PluginService:
|
|||
|
||||
@staticmethod
|
||||
def uninstall(tenant_id: str, plugin_installation_id: str) -> bool:
|
||||
from extensions.ext_database import db
|
||||
from models.provider import ProviderCredential
|
||||
from sqlalchemy import select
|
||||
|
||||
manager = PluginInstaller()
|
||||
|
||||
# Get plugin info before uninstalling to delete associated credentials
|
||||
try:
|
||||
plugins = manager.list_plugins(tenant_id)
|
||||
plugin = next((p for p in plugins if p.installation_id == plugin_installation_id), None)
|
||||
|
||||
if plugin:
|
||||
plugin_id = plugin.plugin_id
|
||||
logger.info(f"Deleting credentials for plugin: {plugin_id}")
|
||||
|
||||
# Delete provider credentials that match this plugin
|
||||
credentials = db.session.scalars(
|
||||
select(ProviderCredential).where(
|
||||
ProviderCredential.tenant_id == tenant_id,
|
||||
ProviderCredential.provider_name.like(f"{plugin_id}/%"),
|
||||
)
|
||||
).all()
|
||||
|
||||
for cred in credentials:
|
||||
db.session.delete(cred)
|
||||
|
||||
db.session.commit()
|
||||
logger.info(f"Deleted {len(credentials)} credentials for plugin: {plugin_id}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to delete credentials: {e}")
|
||||
# Continue with uninstall even if credential deletion fails
|
||||
|
||||
return manager.uninstall(tenant_id, plugin_installation_id)
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
Loading…
Reference in New Issue