install_plugin.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package service
  2. import (
  3. "errors"
  4. "fmt"
  5. "io"
  6. "mime/multipart"
  7. "github.com/gin-gonic/gin"
  8. "github.com/langgenius/dify-plugin-daemon/internal/core/plugin_manager"
  9. "github.com/langgenius/dify-plugin-daemon/internal/core/plugin_packager/decoder"
  10. "github.com/langgenius/dify-plugin-daemon/internal/core/plugin_packager/verifier"
  11. "github.com/langgenius/dify-plugin-daemon/internal/db"
  12. "github.com/langgenius/dify-plugin-daemon/internal/types/app"
  13. "github.com/langgenius/dify-plugin-daemon/internal/types/entities"
  14. "github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
  15. "github.com/langgenius/dify-plugin-daemon/internal/types/models"
  16. "github.com/langgenius/dify-plugin-daemon/internal/types/models/curd"
  17. "github.com/langgenius/dify-plugin-daemon/internal/utils/stream"
  18. )
  19. func InstallPluginFromPkg(
  20. config *app.Config,
  21. c *gin.Context,
  22. tenant_id string,
  23. dify_pkg_file multipart.File,
  24. verify_signature bool,
  25. source string,
  26. meta map[string]any,
  27. ) {
  28. manager := plugin_manager.Manager()
  29. plugin_file, err := io.ReadAll(dify_pkg_file)
  30. if err != nil {
  31. c.JSON(200, entities.NewErrorResponse(-500, err.Error()))
  32. return
  33. }
  34. decoder, err := decoder.NewZipPluginDecoder(plugin_file)
  35. if err != nil {
  36. c.JSON(200, entities.NewErrorResponse(-500, err.Error()))
  37. return
  38. }
  39. if config.ForceVerifyingSignature || verify_signature {
  40. err := verifier.VerifyPlugin(decoder)
  41. if err != nil {
  42. c.JSON(200, entities.NewErrorResponse(-500, errors.Join(err, errors.New(
  43. "plugin verification has been enabled, and the plugin you want to install has a bad signature",
  44. )).Error()))
  45. return
  46. }
  47. }
  48. baseSSEService(
  49. func() (*stream.Stream[plugin_manager.PluginInstallResponse], error) {
  50. return manager.Install(tenant_id, decoder, source, meta)
  51. },
  52. c,
  53. 3600,
  54. )
  55. }
  56. func InstallPluginFromIdentifier(
  57. tenant_id string,
  58. plugin_unique_identifier plugin_entities.PluginUniqueIdentifier,
  59. source string,
  60. meta map[string]any,
  61. ) *entities.Response {
  62. // check if identifier exists
  63. plugin, err := db.GetOne[models.Plugin](
  64. db.Equal("plugin_unique_identifier", plugin_unique_identifier.String()),
  65. )
  66. if err == db.ErrDatabaseNotFound {
  67. return entities.NewErrorResponse(-404, "Plugin not found")
  68. }
  69. if err != nil {
  70. return entities.NewErrorResponse(-500, err.Error())
  71. }
  72. if plugin.InstallType == plugin_entities.PLUGIN_RUNTIME_TYPE_REMOTE {
  73. return entities.NewErrorResponse(-500, "remote plugin not supported")
  74. }
  75. declaration := plugin.Declaration
  76. // install to this workspace
  77. if _, _, err := curd.InstallPlugin(tenant_id, plugin_unique_identifier, plugin.InstallType, &declaration, source, meta); err != nil {
  78. return entities.NewErrorResponse(-500, err.Error())
  79. }
  80. return entities.NewSuccessResponse(true)
  81. }
  82. func FetchPluginFromIdentifier(
  83. plugin_unique_identifier plugin_entities.PluginUniqueIdentifier,
  84. ) *entities.Response {
  85. _, err := db.GetOne[models.Plugin](
  86. db.Equal("plugin_unique_identifier", plugin_unique_identifier.String()),
  87. )
  88. if err == db.ErrDatabaseNotFound {
  89. return entities.NewSuccessResponse(false)
  90. }
  91. if err != nil {
  92. return entities.NewErrorResponse(-500, err.Error())
  93. }
  94. return entities.NewSuccessResponse(true)
  95. }
  96. func UninstallPlugin(
  97. tenant_id string,
  98. plugin_installation_id string,
  99. ) *entities.Response {
  100. // Check if the plugin exists for the tenant
  101. installation, err := db.GetOne[models.PluginInstallation](
  102. db.Equal("tenant_id", tenant_id),
  103. db.Equal("id", plugin_installation_id),
  104. )
  105. if err == db.ErrDatabaseNotFound {
  106. return entities.NewErrorResponse(-404, "Plugin installation not found for this tenant")
  107. }
  108. if err != nil {
  109. return entities.NewErrorResponse(-500, err.Error())
  110. }
  111. // Uninstall the plugin
  112. _, err = curd.UninstallPlugin(
  113. tenant_id,
  114. plugin_entities.PluginUniqueIdentifier(installation.PluginUniqueIdentifier),
  115. installation.ID,
  116. )
  117. if err != nil {
  118. return entities.NewErrorResponse(-500, fmt.Sprintf("Failed to uninstall plugin: %s", err.Error()))
  119. }
  120. return entities.NewSuccessResponse(true)
  121. }