From a7287c9f41a578b10b711a71178f5acd1b10b326 Mon Sep 17 00:00:00 2001 From: yokowu <18836617@qq.com> Date: Thu, 24 Jul 2025 19:04:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8F=AA=E8=AF=BB=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/cmd/server/wire_gen.go | 5 ++-- backend/config/config.go | 3 ++ backend/errcode/errcode.go | 1 + backend/errcode/locale.zh.toml | 3 ++ backend/internal/middleware/readonly.go | 29 +++++++++++++++++++ .../internal/model/handler/http/v1/model.go | 3 +- backend/internal/provider.go | 1 + backend/internal/user/handler/v1/user.go | 4 ++- 8 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 backend/internal/middleware/readonly.go diff --git a/backend/cmd/server/wire_gen.go b/backend/cmd/server/wire_gen.go index e3ecd13..5206542 100644 --- a/backend/cmd/server/wire_gen.go +++ b/backend/cmd/server/wire_gen.go @@ -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() diff --git a/backend/config/config.go b/backend/config/config.go index 00c58ef..8fc1953 100644 --- a/backend/config/config.go +++ b/backend/config/config.go @@ -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", "") diff --git a/backend/errcode/errcode.go b/backend/errcode/errcode.go index 9d168b7..bac6a1d 100644 --- a/backend/errcode/errcode.go +++ b/backend/errcode/errcode.go @@ -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") diff --git a/backend/errcode/locale.zh.toml b/backend/errcode/locale.zh.toml index 536e37b..ac13825 100644 --- a/backend/errcode/locale.zh.toml +++ b/backend/errcode/locale.zh.toml @@ -1,6 +1,9 @@ [err-permission] other = "无权操作" +[err-read-only] +other = "只读模式" + [err-user-not-found] other = "用户不存在" diff --git a/backend/internal/middleware/readonly.go b/backend/internal/middleware/readonly.go new file mode 100644 index 0000000..4ff31d9 --- /dev/null +++ b/backend/internal/middleware/readonly.go @@ -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) + } + } +} diff --git a/backend/internal/model/handler/http/v1/model.go b/backend/internal/model/handler/http/v1/model.go index e8fb9ef..a1717bc 100644 --- a/backend/internal/model/handler/http/v1/model.go +++ b/backend/internal/model/handler/http/v1/model.go @@ -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)) diff --git a/backend/internal/provider.go b/backend/internal/provider.go index c7350c0..b493657 100644 --- a/backend/internal/provider.go +++ b/backend/internal/provider.go @@ -45,6 +45,7 @@ var Provider = wire.NewSet( middleware.NewProxyMiddleware, middleware.NewAuthMiddleware, middleware.NewActiveMiddleware, + middleware.NewReadOnlyMiddleware, userV1.NewUserHandler, userrepo.NewUserRepo, userusecase.NewUserUsecase, diff --git a/backend/internal/user/handler/v1/user.go b/backend/internal/user/handler/v1/user.go index 4a20ba6..daa17b4 100644 --- a/backend/internal/user/handler/v1/user.go +++ b/backend/internal/user/handler/v1/user.go @@ -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())