Xray-core/proxy/vless/validator.go
yuhan6665 85a1c33709
API: Add new Get Inbound User (#3644)
* Add GetInboundUser in proto

* Add get user logic for all existing inbounds

* Add inbounduser command

* Add option to get all users

* Fix shadowsocks2022 config

* Fix init users in shadowsocks2022

* Fix copy

* Add inbound user count command

This api costs much less than get inbound user, could be useful in some case

* Update from latest main
2024-11-03 00:25:23 -04:00

91 lines
2.2 KiB
Go

package vless
import (
"strings"
"sync"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/uuid"
)
type Validator interface {
Get(id uuid.UUID) *protocol.MemoryUser
Add(u *protocol.MemoryUser) error
Del(email string) error
GetByEmail(email string) *protocol.MemoryUser
GetAll() []*protocol.MemoryUser
GetCount() int64
}
// MemoryValidator stores valid VLESS users.
type MemoryValidator struct {
// Considering email's usage here, map + sync.Mutex/RWMutex may have better performance.
email sync.Map
users sync.Map
}
// Add a VLESS user, Email must be empty or unique.
func (v *MemoryValidator) Add(u *protocol.MemoryUser) error {
if u.Email != "" {
_, loaded := v.email.LoadOrStore(strings.ToLower(u.Email), u)
if loaded {
return errors.New("User ", u.Email, " already exists.")
}
}
v.users.Store(u.Account.(*MemoryAccount).ID.UUID(), u)
return nil
}
// Del a VLESS user with a non-empty Email.
func (v *MemoryValidator) Del(e string) error {
if e == "" {
return errors.New("Email must not be empty.")
}
le := strings.ToLower(e)
u, _ := v.email.Load(le)
if u == nil {
return errors.New("User ", e, " not found.")
}
v.email.Delete(le)
v.users.Delete(u.(*protocol.MemoryUser).Account.(*MemoryAccount).ID.UUID())
return nil
}
// Get a VLESS user with UUID, nil if user doesn't exist.
func (v *MemoryValidator) Get(id uuid.UUID) *protocol.MemoryUser {
u, _ := v.users.Load(id)
if u != nil {
return u.(*protocol.MemoryUser)
}
return nil
}
// Get a VLESS user with email, nil if user doesn't exist.
func (v *MemoryValidator) GetByEmail(email string) *protocol.MemoryUser {
u, _ := v.email.Load(email)
if u != nil {
return u.(*protocol.MemoryUser)
}
return nil
}
// Get all users
func (v *MemoryValidator) GetAll() []*protocol.MemoryUser {
var u = make([]*protocol.MemoryUser, 0, 100)
v.email.Range(func(key, value interface{}) bool {
u = append(u, value.(*protocol.MemoryUser))
return true
})
return u
}
// Get users count
func (v *MemoryValidator) GetCount() int64 {
var c int64 = 0
v.email.Range(func(key, value interface{}) bool {
c++
return true
})
return c
}