From 0be4ce9891b97f4cd6ea7d5c6532293eb9837e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Tue, 18 Jun 2024 00:48:48 +0800 Subject: [PATCH] =?UTF-8?q?revert:=20=E5=8A=A0=E5=9B=9Emust=5Finstall?= =?UTF-8?q?=E4=B8=AD=E9=97=B4=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/http/middleware/must_install.go | 93 +++++++++++++++++++++++++++++ lang/en.json | 8 ++- lang/zh_CN.json | 8 ++- routes/api.go | 6 +- routes/plugin.go | 2 +- 5 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 app/http/middleware/must_install.go diff --git a/app/http/middleware/must_install.go b/app/http/middleware/must_install.go new file mode 100644 index 00000000..cc6b94cd --- /dev/null +++ b/app/http/middleware/must_install.go @@ -0,0 +1,93 @@ +package middleware + +import ( + "strings" + + "github.com/goravel/framework/contracts/http" + "github.com/goravel/framework/contracts/translation" + "github.com/goravel/framework/facades" + + "github.com/TheTNB/panel/internal/services" +) + +// MustInstall 确保已安装插件 +func MustInstall() http.Middleware { + return func(ctx http.Context) { + path := ctx.Request().Path() + translate := facades.Lang(ctx) + var slug string + if strings.HasPrefix(path, "/api/panel/website") { + slug = "openresty" + } else if strings.HasPrefix(path, "/api/panel/container") { + slug = "podman" + } else { + pathArr := strings.Split(path, "/") + if len(pathArr) < 4 { + ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{ + "message": translate.Get("errors.plugin.notExist"), + }) + return + } + slug = pathArr[3] + } + + plugin := services.NewPluginImpl().GetBySlug(slug) + installedPlugin := services.NewPluginImpl().GetInstalledBySlug(slug) + installedPlugins, err := services.NewPluginImpl().AllInstalled() + if err != nil { + ctx.Request().AbortWithStatusJson(http.StatusInternalServerError, http.Json{ + "message": translate.Get("errors.internal"), + }) + return + } + + if installedPlugin.Slug != plugin.Slug { + ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{ + "message": translate.Get("errors.plugin.notInstalled", translation.Option{ + Replace: map[string]string{ + "slug": slug, + }, + }), + }) + return + } + + pluginsMap := make(map[string]bool) + + for _, p := range installedPlugins { + pluginsMap[p.Slug] = true + } + + for _, require := range plugin.Requires { + _, requireFound := pluginsMap[require] + if !requireFound { + ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{ + "message": translate.Get("errors.plugin.dependent", translation.Option{ + Replace: map[string]string{ + "slug": slug, + "dependency": require, + }, + }), + }) + return + } + } + + for _, exclude := range plugin.Excludes { + _, excludeFound := pluginsMap[exclude] + if excludeFound { + ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{ + "message": translate.Get("errors.plugin.incompatible", translation.Option{ + Replace: map[string]string{ + "slug": slug, + "exclude": exclude, + }, + }), + }) + return + } + } + + ctx.Request().Next() + } +} diff --git a/lang/en.json b/lang/en.json index 7e979017..70a65eac 100644 --- a/lang/en.json +++ b/lang/en.json @@ -186,7 +186,13 @@ } }, "errors": { - "internal": "internal system error" + "internal": "internal system error", + "plugin": { + "notExist": "plugin does not exist", + "notInstalled": "plugin :slug is not installed", + "dependent": "plugin :slug requires dependency :dependency", + "incompatible": "plugin :slug is incompatible with :exclude plugin" + } }, "messages": { "mistake": "mistake" diff --git a/lang/zh_CN.json b/lang/zh_CN.json index 16e17d2b..0d1d32b6 100644 --- a/lang/zh_CN.json +++ b/lang/zh_CN.json @@ -186,7 +186,13 @@ } }, "errors": { - "internal": "系统内部错误" + "internal": "系统内部错误", + "plugin": { + "notExist": "插件不存在", + "notInstalled": "插件 :slug 未安装", + "dependent": "插件 :slug 需要依赖 :dependency 插件", + "incompatible": "插件 :slug 不兼容 :exclude 插件" + } }, "messages": { "mistake": "错误" diff --git a/routes/api.go b/routes/api.go index 26bb6366..ff654e57 100644 --- a/routes/api.go +++ b/routes/api.go @@ -35,7 +35,7 @@ func Api() { r.Get("log", taskController.Log) r.Post("delete", taskController.Delete) }) - r.Prefix("website").Middleware(middleware.Jwt()).Group(func(r route.Router) { + r.Prefix("website").Middleware(middleware.Jwt(), middleware.MustInstall()).Group(func(r route.Router) { websiteController := controllers.NewWebsiteController() r.Get("defaultConfig", websiteController.GetDefaultConfig) r.Post("defaultConfig", websiteController.SaveDefaultConfig) @@ -43,7 +43,7 @@ func Api() { r.Put("uploadBackup", websiteController.UploadBackup) r.Delete("deleteBackup", websiteController.DeleteBackup) }) - r.Prefix("websites").Middleware(middleware.Jwt()).Group(func(r route.Router) { + r.Prefix("websites").Middleware(middleware.Jwt(), middleware.MustInstall()).Group(func(r route.Router) { websiteController := controllers.NewWebsiteController() r.Get("/", websiteController.List) r.Post("/", websiteController.Add) @@ -115,7 +115,7 @@ func Api() { r.Get("pingStatus", safeController.GetPingStatus) r.Post("pingStatus", safeController.SetPingStatus) }) - r.Prefix("container").Middleware(middleware.Jwt()).Group(func(r route.Router) { + r.Prefix("container").Middleware(middleware.Jwt(), middleware.MustInstall()).Group(func(r route.Router) { containerController := controllers.NewContainerController() r.Get("list", containerController.ContainerList) r.Get("search", containerController.ContainerSearch) diff --git a/routes/plugin.go b/routes/plugin.go index 9e1306bc..a5b20506 100644 --- a/routes/plugin.go +++ b/routes/plugin.go @@ -10,7 +10,7 @@ import ( // Plugin 加载插件路由 func Plugin() { - facades.Route().Prefix("api/plugins").Middleware(middleware.Jwt()).Group(func(r route.Router) { + facades.Route().Prefix("api/plugins").Middleware(middleware.Jwt(), middleware.MustInstall()).Group(func(r route.Router) { r.Prefix("openresty").Group(func(route route.Router) { openRestyController := plugins.NewOpenrestyController() route.Get("load", openRestyController.Load)