2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 12:40:25 +08:00

feat: 安全入口及应用安装检查中间件

This commit is contained in:
耗子
2024-10-12 03:40:20 +08:00
parent 119183971d
commit 09698f7cd3
13 changed files with 176 additions and 29 deletions

View File

@@ -0,0 +1,46 @@
package middleware
import (
"net/http"
"strings"
"github.com/go-rat/chix"
"github.com/spf13/cast"
"github.com/TheTNB/panel/internal/app"
)
// Entrance 确保通过正确的入口访问
func Entrance(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
sess, err := app.Session.GetSession(r)
if err != nil {
render := chix.NewRender(w)
render.Status(http.StatusInternalServerError)
render.JSON(chix.M{
"message": err.Error(),
})
}
entrance := app.Conf.String("http.entrance")
if strings.TrimSuffix(r.URL.Path, "/") == strings.TrimSuffix(entrance, "/") {
sess.Put("verify_entrance", true)
render := chix.NewRender(w, r)
render.Redirect("/login")
return
}
if !app.Conf.Bool("app.debug") &&
!cast.ToBool(sess.Get("verify_entrance", false)) &&
r.URL.Path != "/robots.txt" {
render := chix.NewRender(w)
render.Status(http.StatusTeapot)
render.JSON(chix.M{
"message": "请通过正确的入口访问",
})
return
}
next.ServeHTTP(w, r)
})
}

View File

@@ -19,5 +19,8 @@ func GlobalMiddleware() []func(http.Handler) http.Handler {
middleware.Logger,
middleware.Recoverer,
middleware.Compress(5),
Entrance,
Status,
MustInstall,
}
}

View File

@@ -0,0 +1,52 @@
package middleware
import (
"fmt"
"net/http"
"strings"
"github.com/go-rat/chix"
"github.com/TheTNB/panel/internal/data"
)
// MustInstall 确保已安装应用
func MustInstall(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var slugs []string
if strings.HasPrefix(r.URL.Path, "/api/website") {
slugs = append(slugs, "openresty")
} else if strings.HasPrefix(r.URL.Path, "/api/container") {
slugs = append(slugs, "podman", "docker")
} else if strings.HasPrefix(r.URL.Path, "/api/apps/") {
pathArr := strings.Split(r.URL.Path, "/")
if len(pathArr) < 4 {
render := chix.NewRender(w)
render.Status(http.StatusForbidden)
render.JSON(chix.M{
"message": "应用不存在",
})
return
}
slugs = append(slugs, pathArr[3])
}
flag := false
for _, s := range slugs {
if installed, _ := data.NewAppRepo().IsInstalled("slug = ?", s); installed {
flag = true
break
}
}
if !flag && len(slugs) > 0 {
render := chix.NewRender(w)
render.Status(http.StatusForbidden)
render.JSON(chix.M{
"message": fmt.Sprintf("应用 %s 未安装", slugs),
})
return
}
next.ServeHTTP(w, r)
})
}

View File

@@ -13,7 +13,7 @@ import (
// MustLogin 确保已登录
func MustLogin(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session, err := app.Session.GetSession(r)
sess, err := app.Session.GetSession(r)
if err != nil {
render := chix.NewRender(w)
render.Status(http.StatusInternalServerError)
@@ -22,7 +22,7 @@ func MustLogin(next http.Handler) http.Handler {
})
}
if session.Missing("user_id") {
if sess.Missing("user_id") {
render := chix.NewRender(w)
render.Status(http.StatusUnauthorized)
render.JSON(chix.M{
@@ -31,7 +31,7 @@ func MustLogin(next http.Handler) http.Handler {
return
}
userID := cast.ToUint(session.Get("user_id"))
userID := cast.ToUint(sess.Get("user_id"))
if userID == 0 {
render := chix.NewRender(w)
render.Status(http.StatusUnauthorized)

View File

@@ -0,0 +1,47 @@
package middleware
import (
"net/http"
"github.com/go-rat/chix"
"github.com/TheTNB/panel/pkg/types"
)
// Status 检查程序状态
func Status(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch types.Status {
case types.StatusUpgrade:
render := chix.NewRender(w)
render.Status(http.StatusServiceUnavailable)
render.JSON(chix.M{
"message": "面板升级中,请稍后刷新",
})
return
case types.StatusMaintain:
render := chix.NewRender(w)
render.Status(http.StatusServiceUnavailable)
render.JSON(chix.M{
"message": "面板正在运行维护任务,请稍后刷新",
})
return
case types.StatusClosed:
render := chix.NewRender(w)
render.Status(http.StatusForbidden)
render.JSON(chix.M{
"message": "面板已关闭",
})
return
case types.StatusFailed:
render := chix.NewRender(w)
render.Status(http.StatusInternalServerError)
render.JSON(chix.M{
"message": "面板运行出错,请检查排除或联系支持",
})
return
default:
next.ServeHTTP(w, r)
}
})
}