123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- package service
- import (
- "errors"
- "io"
- "mime/multipart"
- "github.com/gin-gonic/gin"
- "github.com/langgenius/dify-plugin-daemon/internal/core/bundle_packager"
- "github.com/langgenius/dify-plugin-daemon/internal/core/plugin_manager"
- "github.com/langgenius/dify-plugin-daemon/internal/core/plugin_packager/decoder"
- "github.com/langgenius/dify-plugin-daemon/internal/types/app"
- "github.com/langgenius/dify-plugin-daemon/internal/types/entities"
- "github.com/langgenius/dify-plugin-daemon/internal/types/entities/bundle_entities"
- "github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
- "github.com/langgenius/dify-plugin-daemon/internal/types/exception"
- "github.com/langgenius/dify-plugin-daemon/internal/utils/cache/helper"
- )
- func UploadPluginPkg(
- config *app.Config,
- c *gin.Context,
- tenant_id string,
- dify_pkg_file multipart.File,
- verify_signature bool,
- ) *entities.Response {
- pluginFile, err := io.ReadAll(dify_pkg_file)
- if err != nil {
- return exception.InternalServerError(err).ToResponse()
- }
- decoder, err := decoder.NewZipPluginDecoder(pluginFile)
- if err != nil {
- return exception.BadRequestError(err).ToResponse()
- }
- pluginUniqueIdentifier, err := decoder.UniqueIdentity()
- if err != nil {
- return exception.BadRequestError(err).ToResponse()
- }
- // avoid author to be a uuid
- if pluginUniqueIdentifier.RemoteLike() {
- return exception.BadRequestError(errors.New("author cannot be a uuid")).ToResponse()
- }
- manager := plugin_manager.Manager()
- declaration, err := manager.SavePackage(pluginUniqueIdentifier, pluginFile)
- if err != nil {
- return exception.BadRequestError(errors.Join(err, errors.New("failed to save package"))).ToResponse()
- }
- if config.ForceVerifyingSignature || verify_signature {
- if !declaration.Verified {
- return exception.BadRequestError(errors.Join(err, errors.New(
- "plugin verification has been enabled, and the plugin you want to install has a bad signature",
- ))).ToResponse()
- }
- }
- return entities.NewSuccessResponse(map[string]any{
- "unique_identifier": pluginUniqueIdentifier,
- "manifest": declaration,
- })
- }
- func UploadPluginBundle(
- config *app.Config,
- c *gin.Context,
- tenant_id string,
- dify_bundle_file multipart.File,
- verify_signature bool,
- ) *entities.Response {
- bundleFile, err := io.ReadAll(dify_bundle_file)
- if err != nil {
- return exception.InternalServerError(err).ToResponse()
- }
- packager, err := bundle_packager.NewMemoryZipBundlePackager(bundleFile)
- if err != nil {
- return exception.BadRequestError(errors.Join(err, errors.New("failed to decode bundle"))).ToResponse()
- }
- // load bundle
- bundle, err := packager.Manifest()
- if err != nil {
- return exception.BadRequestError(errors.Join(err, errors.New("failed to load bundle manifest"))).ToResponse()
- }
- manager := plugin_manager.Manager()
- result := []map[string]any{}
- for _, dependency := range bundle.Dependencies {
- if dependency.Type == bundle_entities.DEPENDENCY_TYPE_GITHUB {
- if dep, ok := dependency.Value.(bundle_entities.GithubDependency); ok {
- result = append(result, map[string]any{
- "type": "github",
- "value": map[string]any{
- "repo_address": dep.RepoPattern.Repo(),
- "repo": dep.RepoPattern.GithubRepo(),
- "release": dep.RepoPattern.Release(),
- "packages": dep.RepoPattern.Asset(),
- },
- })
- }
- } else if dependency.Type == bundle_entities.DEPENDENCY_TYPE_MARKETPLACE {
- if dep, ok := dependency.Value.(bundle_entities.MarketplaceDependency); ok {
- result = append(result, map[string]any{
- "type": "marketplace",
- "value": map[string]any{
- "organization": dep.MarketplacePattern.Organization(),
- "plugin": dep.MarketplacePattern.Plugin(),
- "version": dep.MarketplacePattern.Version(),
- },
- })
- }
- } else if dependency.Type == bundle_entities.DEPENDENCY_TYPE_PACKAGE {
- if dep, ok := dependency.Value.(bundle_entities.PackageDependency); ok {
- // fetch package
- path := dep.Path
- if asset, err := packager.FetchAsset(path); err != nil {
- return exception.InternalServerError(errors.Join(errors.New("failed to fetch package from bundle"), err)).ToResponse()
- } else {
- // decode and save
- decoder, err := decoder.NewZipPluginDecoder(asset)
- if err != nil {
- return exception.BadRequestError(errors.Join(errors.New("failed to create package decoder"), err)).ToResponse()
- }
- pluginUniqueIdentifier, err := decoder.UniqueIdentity()
- if err != nil {
- return exception.BadRequestError(errors.Join(errors.New("failed to get package unique identifier"), err)).ToResponse()
- }
- declaration, err := manager.SavePackage(pluginUniqueIdentifier, asset)
- if err != nil {
- return exception.InternalServerError(errors.Join(errors.New("failed to save package"), err)).ToResponse()
- }
- if config.ForceVerifyingSignature || verify_signature {
- if !declaration.Verified {
- return exception.BadRequestError(errors.Join(errors.New(
- "plugin verification has been enabled, and the plugin you want to install has a bad signature",
- ), err)).ToResponse()
- }
- }
- result = append(result, map[string]any{
- "type": "package",
- "value": map[string]any{
- "unique_identifier": pluginUniqueIdentifier,
- "manifest": declaration,
- },
- })
- }
- }
- }
- }
- return entities.NewSuccessResponse(result)
- }
- func FetchPluginManifest(
- tenant_id string,
- pluginUniqueIdentifier plugin_entities.PluginUniqueIdentifier,
- ) *entities.Response {
- runtimeType := plugin_entities.PLUGIN_RUNTIME_TYPE_LOCAL
- if pluginUniqueIdentifier.RemoteLike() {
- runtimeType = plugin_entities.PLUGIN_RUNTIME_TYPE_REMOTE
- }
- pluginManifestCache, err := helper.CombinedGetPluginDeclaration(
- pluginUniqueIdentifier, tenant_id, runtimeType,
- )
- if err == helper.ErrPluginNotFound {
- return exception.BadRequestError(errors.New("plugin not found")).ToResponse()
- }
- if err != nil {
- return exception.InternalServerError(err).ToResponse()
- }
- return entities.NewSuccessResponse(pluginManifestCache)
- }
|