Files
1Panel/core/middleware/demo_handle.go
CityFun d2dbb6486e feat: add enterprise demo handle (#13592)
* feat: add enterprise demo handle

* feat: add enterprise demo handle
2026-08-20 15:01:04 +08:00

126 lines
5.1 KiB
Go

package middleware
import (
"net/http"
"strings"
"github.com/1Panel-dev/1Panel/core/app/dto"
"github.com/1Panel-dev/1Panel/core/buserr"
"github.com/gin-gonic/gin"
)
type demoRoute struct {
method string
path string
}
var demoAllowedRoutes = map[demoRoute]struct{}{
{http.MethodPost, "/api/v2/dashboard/app/launcher/option"}: {},
{http.MethodPost, "/api/v2/websites/config"}: {},
{http.MethodPost, "/api/v2/files/size"}: {},
{http.MethodPost, "/api/v2/files/ai-search"}: {},
{http.MethodPost, "/api/v2/runtimes/sync"}: {},
{http.MethodPost, "/api/v2/toolbox/device/base"}: {},
{http.MethodPost, "/api/v2/files/user/group"}: {},
{http.MethodPost, "/api/v2/files/mount"}: {},
{http.MethodPost, "/api/v2/hosts/ssh/log"}: {},
{http.MethodPost, "/api/v2/toolbox/clam/base"}: {},
{http.MethodPost, "/api/v2/backups/record/size"}: {},
{http.MethodPost, "/api/v2/core/auth/login"}: {},
{http.MethodPost, "/api/v2/core/logs/login"}: {},
{http.MethodPost, "/api/v2/core/logs/operation"}: {},
{http.MethodPost, "/api/v2/core/auth/logout"}: {},
{http.MethodPost, "/api/v2/apps/installed/loadport"}: {},
{http.MethodPost, "/api/v2/apps/installed/check"}: {},
{http.MethodPost, "/api/v2/apps/installed/conninfo"}: {},
{http.MethodPost, "/api/v2/databases/common/info"}: {},
{http.MethodPost, "/api/v2/databases/common/load/file"}: {},
{http.MethodPost, "/api/v2/databases/variables"}: {},
{http.MethodPost, "/api/v2/databases/status"}: {},
{http.MethodPost, "/api/v2/ai/accounts/counts"}: {},
{http.MethodPost, "/api/v2/ai/accounts/models"}: {},
{http.MethodPost, "/api/v2/ai/agents/overview"}: {},
{http.MethodPost, "/api/v2/ai/agents/hermes/chat/sessions"}: {},
{http.MethodPost, "/api/v2/ai/agents/agent/list"}: {},
{http.MethodPost, "/api/v2/ai/agents/agent/channels"}: {},
{http.MethodPost, "/api/v2/ai/agents/agent/md/list"}: {},
{http.MethodPost, "/api/v2/ai/agents/plugins/list"}: {},
{http.MethodPost, "/api/v2/ai/agents/skills/list"}: {},
{http.MethodPost, "/api/v2/alert/cronjob/list"}: {},
{http.MethodPost, "/api/v2/xpack/cluster/replica/status"}: {},
{http.MethodPost, "/api/v2/xpack/cluster/ipport/healthy"}: {},
{http.MethodPost, "/api/v2/xpack/tampers/template/list"}: {},
{http.MethodPost, "/api/v2/xpack/vllm/command-template/list"}: {},
{http.MethodPost, "/api/v2/core/enterprise/skills-hub/published"}: {},
{http.MethodPost, "/api/v2/core/enterprise/skills-hub/versions"}: {},
{http.MethodPost, "/api/v2/core/enterprise/ai-proxy/smart-route/statistics"}: {},
{http.MethodPost, "/api/v2/core/enterprise/ai-proxy/usage/attempts"}: {},
{http.MethodPost, "/api/v2/core/enterprise/ai-proxy/usage/statistics"}: {},
{http.MethodPost, "/api/v2/xpack/waf/attack/stat"}: {},
{http.MethodPost, "/api/v2/xpack/waf/config/website"}: {},
{http.MethodPost, "/api/v2/xpack/waf/relation/stat"}: {},
{http.MethodPost, "/api/v2/xpack/monitor/stat"}: {},
{http.MethodPost, "/api/v2/xpack/monitor/visitors"}: {},
{http.MethodPost, "/api/v2/xpack/monitor/visitors/loc"}: {},
{http.MethodPost, "/api/v2/xpack/monitor/qps"}: {},
{http.MethodPost, "/api/v2/xpack/monitor/logs/stat"}: {},
{http.MethodPost, "/api/v2/xpack/monitor/websites"}: {},
{http.MethodPost, "/api/v2/xpack/monitor/trend"}: {},
{http.MethodPost, "/api/v2/xpack/monitor/rank"}: {},
{http.MethodPost, "/api/v2/xpack/waf/cdn"}: {},
{http.MethodPost, "/api/v2/core/nodes/list"}: {},
}
var demoDeniedRoutes = map[demoRoute]struct{}{
{http.MethodGet, "/api/v2/containers/exec"}: {},
{http.MethodGet, "/api/v2/hosts/terminal/local"}: {},
{http.MethodGet, "/api/v2/hosts/terminal/ssh"}: {},
{http.MethodGet, "/api/v2/hosts/terminal/container"}: {},
{http.MethodGet, "/api/v2/core/enterprise/vms/console/ws"}: {},
}
func DemoHandle() gin.HandlerFunc {
return func(c *gin.Context) {
if isDemoRequestAllowed(c.Request.Method, c.Request.URL.Path) {
c.Next()
return
}
c.JSON(http.StatusForbidden, dto.Response{
Code: http.StatusForbidden,
Message: buserr.New("ErrDemoEnvironment").Error(),
})
c.Abort()
}
}
func isDemoRequestAllowed(method, path string) bool {
route := demoRoute{method: method, path: path}
if _, denied := demoDeniedRoutes[route]; denied {
return false
}
if method == http.MethodGet {
return true
}
if method == http.MethodPost && hasPathSegment(path, "search") {
return true
}
_, allowed := demoAllowedRoutes[route]
return allowed
}
func hasPathSegment(path, segment string) bool {
for _, item := range strings.Split(strings.Trim(path, "/"), "/") {
if item == segment {
return true
}
}
return false
}