accounts/internal/xrayconfig/source_gorm.go

66 lines
1.5 KiB
Go

package xrayconfig
import (
"context"
"errors"
"log/slog"
"strings"
"gorm.io/gorm"
)
// GormClientSource reads Xray client credentials from the users table using GORM.
type GormClientSource struct {
DB *gorm.DB
Logger *slog.Logger
}
// NewGormClientSource constructs a ClientSource backed by the provided GORM instance.
func NewGormClientSource(db *gorm.DB) (*GormClientSource, error) {
if db == nil {
return nil, errors.New("gorm db is required")
}
return &GormClientSource{
DB: db,
Logger: slog.Default().With("component", "xray-gorm-source"),
}, nil
}
// ListClients returns all users ordered by creation time.
func (s *GormClientSource) ListClients(ctx context.Context) ([]Client, error) {
if s == nil || s.DB == nil {
return nil, errors.New("gorm client source is not configured")
}
type row struct {
ProxyUUID string `gorm:"column:proxy_uuid"`
Email *string `gorm:"column:email"`
}
var rows []row
if err := s.DB.WithContext(ctx).
Table("users").
Select("proxy_uuid, email").
Order("created_at ASC, proxy_uuid ASC").
Find(&rows).Error; err != nil {
if s.Logger != nil {
s.Logger.Error("failed to list clients from users table", "err", err)
}
return nil, err
}
clients := make([]Client, 0, len(rows))
for _, r := range rows {
id := strings.TrimSpace(r.ProxyUUID)
if id == "" {
continue
}
client := Client{ID: id}
if r.Email != nil {
client.Email = strings.TrimSpace(*r.Email)
}
clients = append(clients, client)
}
return clients, nil
}