package auth import ( "crypto/rand" "cs-bridge/internal/db" "encoding/hex" "errors" "fmt" "time" "gorm.io/gorm" ) var ( ErrTokenNotFound = errors.New("token not found") ErrTokenExpired = errors.New("token expired") ErrTokenUsed = errors.New("token already used") ) // GenerateWorkspaceToken 生成workspace访问token // workspacePath: workspace的路径 // ttl: token有效期 // 返回生成的token字符串和可能的错误 func GenerateWorkspaceToken(workspacePath string, ttl time.Duration) (string, error) { // 生成随机token (32字节 = 64个十六进制字符) tokenBytes := make([]byte, 32) if _, err := rand.Read(tokenBytes); err != nil { return "", err } token := hex.EncodeToString(tokenBytes) // 计算过期时间 expiresAt := time.Now().Add(time.Second * ttl) fmt.Println("GenerateWorkspaceToken: expiresAt: ", expiresAt) // 保存到数据库 workspaceToken := db.WorkspaceToken{ Token: token, WorkspacePath: workspacePath, ExpiresAt: expiresAt, Used: false, } database := db.GetDB() if err := database.Create(&workspaceToken).Error; err != nil { return "", err } return token, nil } // ValidateToken 验证token (可多次使用,直到过期) // token: 要验证的token字符串 // 返回workspace路径和可能的错误 func ValidateAndConsumeToken(token string) (string, error) { database := db.GetDB() var workspaceToken db.WorkspaceToken // 查找token if err := database.Where("token = ?", token).First(&workspaceToken).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return "", ErrTokenNotFound } return "", err } // 检查是否过期 if time.Now().After(workspaceToken.ExpiresAt) { return "", ErrTokenExpired } // Token有效,可以多次使用直到过期 return workspaceToken.WorkspacePath, nil } // CleanExpiredTokens 清理过期的token // 删除所有已过期的token记录 func CleanExpiredTokens() error { database := db.GetDB() // 删除所有过期的token result := database.Where("expires_at < ?", time.Now()).Delete(&db.WorkspaceToken{}) return result.Error }