[feature/backend] implement /users handler + switch to username + add display name + user management cli

This commit is contained in:
CDN 2025-02-21 04:30:07 +08:00
parent 1d712d4e6c
commit 86ab334bc9
Signed by: CDN
GPG key ID: 0C656827F9F80080
38 changed files with 1851 additions and 506 deletions

View file

@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"time"
"github.com/gin-gonic/gin"
@ -78,26 +79,41 @@ func newAccessLogger(config *types.AccessLogConfig) (*accessLogger, error) {
// 配置文件日志
if config.EnableFile {
// 确保日志目录存在
if err := os.MkdirAll(filepath.Dir(config.FilePath), 0755); err != nil {
// 验证文件路径
if config.FilePath == "" {
return nil, fmt.Errorf("file path cannot be empty")
}
// 验证路径是否包含无效字符
if strings.ContainsAny(config.FilePath, "\x00") {
return nil, fmt.Errorf("file path contains invalid characters")
}
dir := filepath.Dir(config.FilePath)
// 检查目录是否存在或是否可以创建
if err := os.MkdirAll(dir, 0755); err != nil {
return nil, fmt.Errorf("failed to create log directory: %w", err)
}
// 配置日志轮转
// 尝试打开或创建文件,验证路径是否有效且有写入权限
file, err := os.OpenFile(config.FilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
return nil, fmt.Errorf("failed to open or create log file: %w", err)
}
file.Close()
// 配置文件日志
logWriter = &lumberjack.Logger{
Filename: config.FilePath,
MaxSize: config.Rotation.MaxSize, // MB
MaxAge: config.Rotation.MaxAge, // days
MaxBackups: config.Rotation.MaxBackups, // files
MaxBackups: config.Rotation.MaxBackups, // 文件个数
MaxAge: config.Rotation.MaxAge, // 天数
Compress: config.Rotation.Compress, // 是否压缩
LocalTime: config.Rotation.LocalTime, // 使用本地时间
}
logger := zerolog.New(logWriter).
With().
Timestamp().
Logger()
logger := zerolog.New(logWriter).With().Timestamp().Logger()
fileLogger = &logger
}

View file

@ -219,7 +219,7 @@ func TestAccessLogInvalidConfig(t *testing.T) {
name: "Invalid file path",
config: &types.AccessLogConfig{
EnableFile: true,
FilePath: "/dev/null/nonexistent/test.log", // 在所有操作系统上都无效的路径
FilePath: "\x00invalid\x00path", // 使用空字符的路径在所有操作系统上都是无效的
},
expectedError: true,
},