2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 03:07:20 +08:00

fix: 优化访问入口检查,fix #760

This commit is contained in:
2025-05-24 14:57:53 +08:00
parent 7d9b84c746
commit 07881311b3
6 changed files with 41 additions and 111 deletions

View File

@@ -57,7 +57,7 @@ upx:
archives:
- id: panel
builds:
ids:
- web
- cli
formats: ["zip"]

View File

@@ -22,19 +22,11 @@ func Entrance(t *gotext.Locale, conf *koanf.Koanf, session *sessions.Manager) fu
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
sess, err := session.GetSession(r)
if err != nil {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusInternalServerError)
render.JSON(chix.M{
"msg": err.Error(),
})
Abort(w, http.StatusInternalServerError, "%v", err)
return
}
entrance := strings.TrimSuffix(conf.String("http.entrance"), "/")
if entrance == "" {
entrance = "/"
}
entrance := conf.String("http.entrance")
if !strings.HasPrefix(entrance, "/") {
entrance = "/" + entrance
}
@@ -50,12 +42,7 @@ func Entrance(t *gotext.Locale, conf *koanf.Koanf, session *sessions.Manager) fu
}
}
if len(conf.Strings("http.bind_domain")) > 0 && !slices.Contains(conf.Strings("http.bind_domain"), host) {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusTeapot)
render.JSON(chix.M{
"msg": t.Get("invalid request domain: %s", r.Host),
})
Abort(w, http.StatusTeapot, t.Get("invalid request domain: %s", r.Host))
return
}
ip, _, err := net.SplitHostPort(r.RemoteAddr)
@@ -63,26 +50,16 @@ func Entrance(t *gotext.Locale, conf *koanf.Koanf, session *sessions.Manager) fu
ip = r.RemoteAddr
}
if len(conf.Strings("http.bind_ip")) > 0 && !slices.Contains(conf.Strings("http.bind_ip"), ip) {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusTeapot)
render.JSON(chix.M{
"msg": t.Get("invalid request ip: %s", ip),
})
Abort(w, http.StatusTeapot, t.Get("invalid request ip: %s", ip))
return
}
if len(conf.Strings("http.bind_ua")) > 0 && !slices.Contains(conf.Strings("http.bind_ua"), r.UserAgent()) {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusTeapot)
render.JSON(chix.M{
"msg": t.Get("invalid request user agent: %s", r.UserAgent()),
})
Abort(w, http.StatusTeapot, t.Get("invalid request user agent: %s", r.UserAgent()))
return
}
// 情况二:请求路径与入口路径相同,标记通过验证并重定向到登录页面
if strings.TrimSuffix(r.URL.Path, "/") == entrance {
if strings.TrimSuffix(r.URL.Path, "/") == strings.TrimSuffix(entrance, "/") {
sess.Put("verify_entrance", true)
render := chix.NewRender(w, r)
defer render.Release()
@@ -107,12 +84,7 @@ func Entrance(t *gotext.Locale, conf *koanf.Koanf, session *sessions.Manager) fu
if !conf.Bool("app.debug") &&
!cast.ToBool(sess.Get("verify_entrance", false)) &&
r.URL.Path != "/robots.txt" {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusTeapot)
render.JSON(chix.M{
"msg": t.Get("invalid access entrance"),
})
Abort(w, http.StatusTeapot, t.Get("invalid access entrance"))
return
}

View File

@@ -0,0 +1,21 @@
package middleware
import (
"fmt"
"net/http"
"github.com/go-rat/chix"
)
func Abort(w http.ResponseWriter, code int, format string, args ...any) {
render := chix.NewRender(w)
defer render.Release()
render.Header(chix.HeaderContentType, chix.MIMEApplicationJSONCharsetUTF8) // must before Status()
render.Status(code)
if len(args) > 0 {
format = fmt.Sprintf(format, args...)
}
render.JSON(chix.M{
"msg": format,
})
}

View File

@@ -4,7 +4,6 @@ import (
"net/http"
"strings"
"github.com/go-rat/chix"
"github.com/leonelquinteros/gotext"
"github.com/tnb-labs/panel/internal/biz"
@@ -22,12 +21,7 @@ func MustInstall(t *gotext.Locale, app biz.AppRepo) func(next http.Handler) http
} else if strings.HasPrefix(r.URL.Path, "/api/apps/") {
pathArr := strings.Split(r.URL.Path, "/")
if len(pathArr) < 4 {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusForbidden)
render.JSON(chix.M{
"msg": t.Get("app not found"),
})
Abort(w, http.StatusForbidden, t.Get("app not found"))
return
}
slugs = append(slugs, pathArr[3])
@@ -41,12 +35,7 @@ func MustInstall(t *gotext.Locale, app biz.AppRepo) func(next http.Handler) http
}
}
if !flag && len(slugs) > 0 {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusForbidden)
render.JSON(chix.M{
"msg": t.Get("app %s not installed", slugs),
})
Abort(w, http.StatusForbidden, t.Get("app %s not installed", slugs))
return
}

View File

@@ -9,7 +9,6 @@ import (
"slices"
"strings"
"github.com/go-rat/chix"
"github.com/go-rat/sessions"
"github.com/leonelquinteros/gotext"
"github.com/spf13/cast"
@@ -32,12 +31,7 @@ func MustLogin(t *gotext.Locale, session *sessions.Manager, userToken biz.UserTo
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
sess, err := session.GetSession(r)
if err != nil {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusInternalServerError)
render.JSON(chix.M{
"msg": err.Error(),
})
Abort(w, http.StatusInternalServerError, "%v", err)
return
}
@@ -51,32 +45,17 @@ func MustLogin(t *gotext.Locale, session *sessions.Manager, userToken biz.UserTo
if r.Header.Get("Authorization") != "" {
// 禁止访问 ws 相关的接口
if strings.HasPrefix(r.URL.Path, "/api/ws") {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusForbidden)
render.JSON(chix.M{
"msg": t.Get("ws not allowed"),
})
Abort(w, http.StatusForbidden, t.Get("ws not allowed"))
return
}
// API 请求验证
if userID, err = userToken.ValidateReq(r); err != nil {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusUnauthorized)
render.JSON(chix.M{
"msg": err.Error(),
})
Abort(w, http.StatusUnauthorized, "%v", err)
return
}
} else {
if sess.Missing("user_id") {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusUnauthorized)
render.JSON(chix.M{
"msg": t.Get("session expired, please login again"),
})
Abort(w, http.StatusUnauthorized, t.Get("session expired, please login again"))
return
}
@@ -86,12 +65,7 @@ func MustLogin(t *gotext.Locale, session *sessions.Manager, userToken biz.UserTo
ip, _, _ := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr))
clientHash := fmt.Sprintf("%x", sha256.Sum256([]byte(ip)))
if safeClientHash != clientHash || safeClientHash == "" {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusUnauthorized)
render.JSON(chix.M{
"msg": t.Get("client ip/ua changed, please login again"),
})
Abort(w, http.StatusUnauthorized, t.Get("client ip/ua changed, please login again"))
return
}
}
@@ -100,12 +74,7 @@ func MustLogin(t *gotext.Locale, session *sessions.Manager, userToken biz.UserTo
}
if userID == 0 {
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusUnauthorized)
render.JSON(chix.M{
"msg": t.Get("invalid user id, please login again"),
})
Abort(w, http.StatusUnauthorized, "%v", t.Get("invalid user id, please login again"))
return
}

View File

@@ -3,7 +3,6 @@ package middleware
import (
"net/http"
"github.com/go-rat/chix"
"github.com/leonelquinteros/gotext"
"github.com/tnb-labs/panel/internal/app"
@@ -15,36 +14,16 @@ func Status(t *gotext.Locale) func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch app.Status {
case app.StatusUpgrade:
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusServiceUnavailable)
render.JSON(chix.M{
"msg": t.Get("panel is upgrading, please refresh later"),
})
Abort(w, http.StatusServiceUnavailable, t.Get("panel is upgrading, please refresh later"))
return
case app.StatusMaintain:
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusServiceUnavailable)
render.JSON(chix.M{
"msg": t.Get("panel is maintaining, please refresh later"),
})
Abort(w, http.StatusServiceUnavailable, t.Get("panel is maintaining, please refresh later"))
return
case app.StatusClosed:
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusForbidden)
render.JSON(chix.M{
"msg": t.Get("panel is closed"),
})
Abort(w, http.StatusServiceUnavailable, t.Get("panel is closed"))
return
case app.StatusFailed:
render := chix.NewRender(w)
defer render.Release()
render.Status(http.StatusInternalServerError)
render.JSON(chix.M{
"msg": t.Get("panel run error, please check or contact support"),
})
Abort(w, http.StatusInternalServerError, t.Get("panel run error, please check or contact support"))
return
default:
next.ServeHTTP(w, r)