This commit is contained in:
Sakurasan
2025-04-17 02:17:19 +08:00
parent d4cbc27a77
commit b0d68ba338
7 changed files with 55 additions and 35 deletions

View File

@@ -147,7 +147,7 @@ func main() {
r.GET("/assets/*filepath", gin.WrapH(http.StripPrefix("/assets/", http.FileServer(http.FS(assetsFS))))) r.GET("/assets/*filepath", gin.WrapH(http.StripPrefix("/assets/", http.FileServer(http.FS(assetsFS)))))
srv := &http.Server{ srv := &http.Server{
Addr: ":8080", Addr: fmt.Sprintf(":%d", cfg.Port),
Handler: r, Handler: r,
} }

View File

@@ -11,7 +11,7 @@ WORKDIR /build
COPY . . COPY . .
COPY --from=frontend /frontend-build/dist /build/cmd/openteam/dist COPY --from=frontend /frontend-build/dist /build/cmd/openteam/dist
ENV GO111MODULE=on ENV GO111MODULE=on
# ENV GOPROXY=https://goproxy.cn,direct ENV GOPROXY=https://goproxy.cn,direct
CMD [ "go mod tidy","go mod download" ] CMD [ "go mod tidy","go mod download" ]
RUN make build RUN make build
@@ -24,5 +24,5 @@ WORKDIR /app
COPY --from=backend /build/bin/openteam /app/openteam COPY --from=backend /build/bin/openteam /app/openteam
ENV GIN_MODE=release ENV GIN_MODE=release
ENV PATH=$PATH:/app ENV PATH=$PATH:/app
EXPOSE 80 EXPOSE 80 443
ENTRYPOINT ["/app/openteam"] ENTRYPOINT ["/app/openteam"]

View File

@@ -2,11 +2,13 @@ package controller
import ( import (
"opencatd-open/internal/service" "opencatd-open/internal/service"
"opencatd-open/pkg/config"
"gorm.io/gorm" "gorm.io/gorm"
) )
type Api struct { type Api struct {
cfg *config.Config
db *gorm.DB db *gorm.DB
userService *service.UserServiceImpl userService *service.UserServiceImpl
tokenService *service.TokenServiceImpl tokenService *service.TokenServiceImpl
@@ -15,8 +17,9 @@ type Api struct {
usageService *service.UsageService usageService *service.UsageService
} }
func NewApi(db *gorm.DB, userService *service.UserServiceImpl, tokenService *service.TokenServiceImpl, keyService *service.ApiKeyServiceImpl, webAuthService *service.WebAuthnService, usageService *service.UsageService) *Api { func NewApi(cfg *config.Config, db *gorm.DB, userService *service.UserServiceImpl, tokenService *service.TokenServiceImpl, keyService *service.ApiKeyServiceImpl, webAuthService *service.WebAuthnService, usageService *service.UsageService) *Api {
return &Api{ return &Api{
cfg: cfg,
db: db, db: db,
userService: userService, userService: userService,
tokenService: tokenService, tokenService: tokenService,

View File

@@ -9,6 +9,7 @@ import (
"opencatd-open/internal/dto" "opencatd-open/internal/dto"
"opencatd-open/internal/model" "opencatd-open/internal/model"
"opencatd-open/internal/utils" "opencatd-open/internal/utils"
"opencatd-open/pkg/config"
"strings" "strings"
"time" "time"
@@ -17,12 +18,14 @@ import (
) )
type UserServiceImpl struct { type UserServiceImpl struct {
cfg *config.Config
db *gorm.DB db *gorm.DB
userRepo dao.UserRepository userRepo dao.UserRepository
} }
func NewUserService(db *gorm.DB, userRepo dao.UserRepository) *UserServiceImpl { func NewUserService(cfg *config.Config, db *gorm.DB, userRepo dao.UserRepository) *UserServiceImpl {
return &UserServiceImpl{ return &UserServiceImpl{
cfg: cfg,
db: db, db: db,
userRepo: userRepo, userRepo: userRepo,
} }
@@ -40,11 +43,19 @@ func (s *UserServiceImpl) Register(ctx context.Context, req *model.User) error {
_user.Role = utils.ToPtr(consts.RoleRoot) _user.Role = utils.ToPtr(consts.RoleRoot)
_user.Active = utils.ToPtr(true) _user.Active = utils.ToPtr(true)
_user.UnlimitedQuota = utils.ToPtr(true) _user.UnlimitedQuota = utils.ToPtr(true)
} else {
if !s.cfg.AllowRegister {
return fmt.Errorf("register is not allowed")
}
} }
_user.Password, err = utils.HashPassword(req.Password) _user.Password, err = utils.HashPassword(req.Password)
if err != nil { if err != nil {
return err return err
} }
_user.Active = &s.cfg.DefaultActive
_user.UnlimitedQuota = &s.cfg.UnlimitedQuota
_user.Username = req.Username _user.Username = req.Username
_user.Email = req.Email _user.Email = req.Email
_user.Tokens = []model.Token{ _user.Tokens = []model.Token{

View File

@@ -62,6 +62,7 @@ func (u *WebAuthnUser) WebAuthnCredentialDescriptors() (descriptors []protocol.C
// WebAuthnService 提供WebAuthn相关功能 // WebAuthnService 提供WebAuthn相关功能
type WebAuthnService struct { type WebAuthnService struct {
cfg *config.Config
DB *gorm.DB DB *gorm.DB
WebAuthn *webauthn.WebAuthn WebAuthn *webauthn.WebAuthn
// Sessions map[string]webauthn.SessionData // 用于存储注册和认证过程中的会话数据 // Sessions map[string]webauthn.SessionData // 用于存储注册和认证过程中的会话数据
@@ -69,12 +70,12 @@ type WebAuthnService struct {
} }
// NewWebAuthnService 创建新的WebAuthn服务 // NewWebAuthnService 创建新的WebAuthn服务
func NewWebAuthnService(db *gorm.DB, cfg *config.Config) (*WebAuthnService, error) { func NewWebAuthnService(cfg *config.Config, db *gorm.DB) (*WebAuthnService, error) {
// 创建WebAuthn配置 // 创建WebAuthn配置
wconfig := &webauthn.Config{ wconfig := &webauthn.Config{
RPDisplayName: config.Cfg.AppName, // 依赖方(Relying Party)显示名称 RPDisplayName: cfg.AppName, // 依赖方(Relying Party)显示名称
RPID: config.Cfg.Domain, // 依赖方ID(通常为域名) RPID: cfg.RPID, // 依赖方ID(通常为域名)
RPOrigins: []string{config.Cfg.AppURL}, // 依赖方源(URL) RPOrigins: cfg.RPOrigins, // 依赖方源(URL)
AuthenticatorSelection: protocol.AuthenticatorSelection{ AuthenticatorSelection: protocol.AuthenticatorSelection{
RequireResidentKey: protocol.ResidentKeyRequired(), // 要求认证器存储用户 ID (resident key) RequireResidentKey: protocol.ResidentKeyRequired(), // 要求认证器存储用户 ID (resident key)
ResidentKey: protocol.ResidentKeyRequirementRequired, // 使用 Discoverable 模式 ResidentKey: protocol.ResidentKeyRequirementRequired, // 使用 Discoverable 模式
@@ -90,6 +91,7 @@ func NewWebAuthnService(db *gorm.DB, cfg *config.Config) (*WebAuthnService, erro
} }
return &WebAuthnService{ return &WebAuthnService{
cfg: cfg,
DB: db, DB: db,
WebAuthn: wa, WebAuthn: wa,
// Sessions: make(map[string]webauthn.SessionData), // Sessions: make(map[string]webauthn.SessionData),

View File

@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"os" "os"
"strconv" "strconv"
"strings"
"time" "time"
_ "github.com/joho/godotenv/autoload" _ "github.com/joho/godotenv/autoload"
@@ -14,15 +15,14 @@ var Cfg *Config
// Config 结构体存储应用配置 // Config 结构体存储应用配置
type Config struct { type Config struct {
// 服务器配置 // 服务器配置
ServerPort int Port int
ServerHost string
ReadTimeout time.Duration ReadTimeout time.Duration
WriteTimeout time.Duration WriteTimeout time.Duration
// PassKey配置 // PassKey配置
AppName string AppName string // 依赖方(Relying Party)显示名称
Domain string RPID string // 依赖方ID(通常为域名)
AppURL string RPOrigins []string // 依赖方源(URL)
WebAuthnTimeout time.Duration WebAuthnTimeout time.Duration
ChallengeExpiration time.Duration ChallengeExpiration time.Duration
@@ -70,12 +70,12 @@ func init() {
// LoadConfig 从环境变量加载配置 // LoadConfig 从环境变量加载配置
func LoadConfig() (*Config, error) { func LoadConfig() (*Config, error) {
cfg := &Config{ cfg := &Config{
AppName: "OpenTeam", AppName: "OpenTeam",
Domain: "localhost", RPID: "localhost", // 域名
AppURL: "https://localhost:5173", RPOrigins: []string{"https://localhost:5173"},
// 默认值设置 // 默认值设置
ServerPort: 8080, Port: 80,
ServerHost: "0.0.0.0",
ReadTimeout: 10 * time.Second, ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second,
@@ -91,8 +91,8 @@ func LoadConfig() (*Config, error) {
// 系统设置 // 系统设置
AllowRegister: false, AllowRegister: false,
UnlimitedQuota: false, UnlimitedQuota: true,
DefaultActive: false, DefaultActive: true,
UsageWorker: 1, UsageWorker: 1,
UsageChanSize: 1000, UsageChanSize: 1000,
@@ -103,26 +103,30 @@ func LoadConfig() (*Config, error) {
if appName := os.Getenv("APP_NAME"); appName != "" { if appName := os.Getenv("APP_NAME"); appName != "" {
cfg.AppName = appName cfg.AppName = appName
} }
if domain := os.Getenv("DOMAIN"); domain != "" { if domain := os.Getenv("RPID"); domain != "" {
cfg.Domain = domain cfg.RPID = domain
} }
if appURL := os.Getenv("APP_URL"); appURL != "" { if origin := os.Getenv("RPORIGINS"); origin != "" {
cfg.AppURL = appURL var rpos []string
list := strings.Split(origin, ",")
for _, l := range list {
trimmedl := strings.TrimSpace(l)
if trimmedl != "" {
rpos = append(rpos, trimmedl)
}
}
cfg.RPOrigins = rpos
} }
// 服务器配置 // 服务器配置
if port := os.Getenv("SERVER_PORT"); port != "" { if port := os.Getenv("PORT"); port != "" {
if p, err := strconv.Atoi(port); err == nil { if p, err := strconv.Atoi(port); err == nil {
cfg.ServerPort = p cfg.Port = p
} else { } else {
return nil, fmt.Errorf("无效的SERVER_PORT: %s", port) return nil, fmt.Errorf("PORT: %s", port)
} }
} }
if host := os.Getenv("SERVER_HOST"); host != "" {
cfg.ServerHost = host
}
if timeout := os.Getenv("READ_TIMEOUT"); timeout != "" { if timeout := os.Getenv("READ_TIMEOUT"); timeout != "" {
if t, err := strconv.Atoi(timeout); err == nil { if t, err := strconv.Atoi(timeout); err == nil {
cfg.ReadTimeout = time.Duration(t) * time.Second cfg.ReadTimeout = time.Duration(t) * time.Second

View File

@@ -38,17 +38,17 @@ func InitTeamHandler(ctx context.Context, cfg *config.Config, db *gorm.DB) (*con
func InitAPIHandler(ctx context.Context, cfg *config.Config, db *gorm.DB) (*controller2.Api, error) { func InitAPIHandler(ctx context.Context, cfg *config.Config, db *gorm.DB) (*controller2.Api, error) {
userDAO := dao.NewUserDAO(db) userDAO := dao.NewUserDAO(db)
userServiceImpl := service2.NewUserService(db, userDAO) userServiceImpl := service2.NewUserService(cfg, db, userDAO)
tokenDAO := dao.NewTokenDAO(db) tokenDAO := dao.NewTokenDAO(db)
tokenServiceImpl := service2.NewTokenService(db, tokenDAO) tokenServiceImpl := service2.NewTokenService(db, tokenDAO)
apiKeyDAO := dao.NewApiKeyDAO(db) apiKeyDAO := dao.NewApiKeyDAO(db)
apiKeyServiceImpl := service2.NewApiKeyService(db, apiKeyDAO) apiKeyServiceImpl := service2.NewApiKeyService(db, apiKeyDAO)
webAuthnService, err := service2.NewWebAuthnService(db, cfg) webAuthnService, err := service2.NewWebAuthnService(cfg, db)
if err != nil { if err != nil {
return nil, err return nil, err
} }
usageService := service2.NewUsageService(ctx, cfg, db) usageService := service2.NewUsageService(ctx, cfg, db)
api := controller2.NewApi(db, userServiceImpl, tokenServiceImpl, apiKeyServiceImpl, webAuthnService, usageService) api := controller2.NewApi(cfg, db, userServiceImpl, tokenServiceImpl, apiKeyServiceImpl, webAuthnService, usageService)
return api, nil return api, nil
} }