Merge pull request #143 from yokowu/feat-readonly

feat: 只读模型
This commit is contained in:
Yoko
2025-07-24 19:07:29 +08:00
committed by GitHub
8 changed files with 45 additions and 4 deletions

View File

@@ -73,7 +73,8 @@ func newServer() (*Server, error) {
modelUsecase := usecase3.NewModelUsecase(slogLogger, modelRepo, configConfig)
sessionSession := session.NewSession(configConfig)
authMiddleware := middleware.NewAuthMiddleware(sessionSession, slogLogger)
modelHandler := v1_2.NewModelHandler(web, modelUsecase, authMiddleware, activeMiddleware, slogLogger)
readOnlyMiddleware := middleware.NewReadOnlyMiddleware(configConfig)
modelHandler := v1_2.NewModelHandler(web, modelUsecase, authMiddleware, activeMiddleware, readOnlyMiddleware, slogLogger)
ipdbIPDB, err := ipdb.NewIPDB(slogLogger)
if err != nil {
return nil, err
@@ -84,7 +85,7 @@ func newServer() (*Server, error) {
dashboardUsecase := usecase5.NewDashboardUsecase(dashboardRepo)
billingRepo := repo7.NewBillingRepo(client)
billingUsecase := usecase6.NewBillingUsecase(billingRepo)
userHandler := v1_3.NewUserHandler(web, userUsecase, extensionUsecase, dashboardUsecase, billingUsecase, authMiddleware, activeMiddleware, sessionSession, slogLogger, configConfig)
userHandler := v1_3.NewUserHandler(web, userUsecase, extensionUsecase, dashboardUsecase, billingUsecase, authMiddleware, activeMiddleware, readOnlyMiddleware, sessionSession, slogLogger, configConfig)
dashboardHandler := v1_4.NewDashboardHandler(web, dashboardUsecase, authMiddleware, activeMiddleware)
billingHandler := v1_5.NewBillingHandler(web, billingUsecase, authMiddleware, activeMiddleware)
versionInfo := version.NewVersionInfo()

View File

@@ -17,6 +17,8 @@ var ConfigTmpl []byte
type Config struct {
Debug bool `mapstructure:"debug"`
ReadOnly bool `mapstructure:"read_only"`
Logger *logger.Config `mapstructure:"logger"`
Server struct {
@@ -97,6 +99,7 @@ func Init() (*Config, error) {
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
v.SetDefault("debug", false)
v.SetDefault("read_only", false)
v.SetDefault("logger.level", "info")
v.SetDefault("server.addr", ":8888")
v.SetDefault("server.port", "")

View File

@@ -12,6 +12,7 @@ var LocalFS embed.FS
var (
ErrPermission = web.NewBadRequestErr("err-permission")
ErrUserNotFound = web.NewBadRequestErr("err-user-not-found")
ErrReadOnly = web.NewBadRequestErr("err-read-only")
ErrPassword = web.NewBadRequestErr("err-password")
ErrInviteCodeInvalid = web.NewBadRequestErr("err-invite-code-invalid")
ErrEmailInvalid = web.NewBadRequestErr("err-email-invalid")

View File

@@ -1,6 +1,9 @@
[err-permission]
other = "无权操作"
[err-read-only]
other = "只读模式"
[err-user-not-found]
other = "用户不存在"

View File

@@ -0,0 +1,29 @@
package middleware
import (
"net/http"
"github.com/labstack/echo/v4"
"github.com/chaitin/MonkeyCode/backend/config"
"github.com/chaitin/MonkeyCode/backend/errcode"
)
type ReadOnlyMiddleware struct {
cfg *config.Config
}
func NewReadOnlyMiddleware(cfg *config.Config) *ReadOnlyMiddleware {
return &ReadOnlyMiddleware{cfg: cfg}
}
func (m *ReadOnlyMiddleware) Guard() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
if m.cfg.ReadOnly && c.Request().Method != http.MethodGet {
return errcode.ErrReadOnly
}
return next(c)
}
}
}

View File

@@ -20,12 +20,13 @@ func NewModelHandler(
usecase domain.ModelUsecase,
auth *middleware.AuthMiddleware,
active *middleware.ActiveMiddleware,
readonly *middleware.ReadOnlyMiddleware,
logger *slog.Logger,
) *ModelHandler {
m := &ModelHandler{usecase: usecase, logger: logger.With("handler", "model")}
g := w.Group("/api/v1/model")
g.Use(auth.Auth(), active.Active("admin"))
g.Use(auth.Auth(), active.Active("admin"), readonly.Guard())
g.GET("", web.BaseHandler(m.List))
g.GET("/provider/supported", web.BindHandler(m.GetProviderModelList))

View File

@@ -45,6 +45,7 @@ var Provider = wire.NewSet(
middleware.NewProxyMiddleware,
middleware.NewAuthMiddleware,
middleware.NewActiveMiddleware,
middleware.NewReadOnlyMiddleware,
userV1.NewUserHandler,
userrepo.NewUserRepo,
userusecase.NewUserUsecase,

View File

@@ -49,6 +49,7 @@ func NewUserHandler(
buse domain.BillingUsecase,
auth *middleware.AuthMiddleware,
active *middleware.ActiveMiddleware,
readonly *middleware.ReadOnlyMiddleware,
session *session.Session,
logger *slog.Logger,
cfg *config.Config,
@@ -74,7 +75,7 @@ func NewUserHandler(
admin.POST("/login", web.BindHandler(u.AdminLogin))
admin.GET("/setting", web.BaseHandler(u.GetSetting))
admin.Use(auth.Auth(), active.Active("admin"))
admin.Use(auth.Auth(), active.Active("admin"), readonly.Guard())
admin.GET("/profile", web.BaseHandler(u.AdminProfile))
admin.GET("/list", web.BaseHandler(u.AdminList, web.WithPage()))
admin.GET("/login-history", web.BaseHandler(u.AdminLoginHistory, web.WithPage()))
@@ -91,6 +92,7 @@ func NewUserHandler(
g.POST("/register", web.BindHandler(u.Register))
g.POST("/login", web.BindHandler(u.Login))
g.Use(readonly.Guard())
g.GET("/profile", web.BaseHandler(u.Profile), auth.UserAuth())
g.PUT("/profile", web.BindHandler(u.UpdateProfile), auth.UserAuth())
g.POST("/logout", web.BaseHandler(u.Logout), auth.UserAuth())