mirror of https://github.com/v2ray/v2ray-core
Introduce user level
parent
d585ec0593
commit
b44098d752
|
@ -10,12 +10,14 @@ import (
|
|||
type ConfigUser struct {
|
||||
Id *config.ID
|
||||
Email string
|
||||
LevelValue config.UserLevel
|
||||
}
|
||||
|
||||
func (u *ConfigUser) UnmarshalJSON(data []byte) error {
|
||||
type rawUser struct {
|
||||
IdString string `json:"id"`
|
||||
EmailString string `json:"email"`
|
||||
LevelInt int `json:"level"`
|
||||
}
|
||||
var rawUserValue rawUser
|
||||
if err := json.Unmarshal(data, &rawUserValue); err != nil {
|
||||
|
@ -27,9 +29,14 @@ func (u *ConfigUser) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
u.Id = id
|
||||
u.Email = rawUserValue.EmailString
|
||||
u.LevelValue = config.UserLevel(rawUserValue.LevelInt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *ConfigUser) ID() *config.ID {
|
||||
return u.Id
|
||||
}
|
||||
|
||||
func (this *ConfigUser) Level() config.UserLevel {
|
||||
return this.LevelValue
|
||||
}
|
|
@ -1,5 +1,27 @@
|
|||
package config
|
||||
|
||||
type UserLevel int
|
||||
|
||||
const (
|
||||
UserLevelAdmin = UserLevel(999)
|
||||
UserLevelUntrusted = UserLevel(0)
|
||||
)
|
||||
|
||||
type User interface {
|
||||
ID() *ID
|
||||
Level() UserLevel
|
||||
}
|
||||
|
||||
type UserSettings struct {
|
||||
PayloadReadTimeout int
|
||||
}
|
||||
|
||||
func GetUserSettings(level UserLevel) UserSettings {
|
||||
settings := UserSettings {
|
||||
PayloadReadTimeout: 120,
|
||||
}
|
||||
if level > 0 {
|
||||
settings.PayloadReadTimeout = 0
|
||||
}
|
||||
return settings
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@ const (
|
|||
|
||||
type UserSet interface {
|
||||
AddUser(user config.User) error
|
||||
GetUser(timeHash []byte) (*config.ID, int64, bool)
|
||||
GetUser(timeHash []byte) (config.User, int64, bool)
|
||||
}
|
||||
|
||||
type TimedUserSet struct {
|
||||
validUserIds []*config.ID
|
||||
validUsers []config.User
|
||||
userHash map[string]indexTimePair
|
||||
userHashDeleteQueue *collect.TimedQueue
|
||||
access sync.RWMutex
|
||||
|
@ -32,7 +32,7 @@ type indexTimePair struct {
|
|||
|
||||
func NewTimedUserSet() UserSet {
|
||||
tus := &TimedUserSet{
|
||||
validUserIds: make([]*config.ID, 0, 16),
|
||||
validUsers: make([]config.User, 0, 16),
|
||||
userHash: make(map[string]indexTimePair, 512),
|
||||
userHashDeleteQueue: collect.NewTimedQueue(updateIntervalSec),
|
||||
access: sync.RWMutex{},
|
||||
|
@ -67,8 +67,8 @@ func (us *TimedUserSet) updateUserHash(tick <-chan time.Time) {
|
|||
|
||||
for now := range tick {
|
||||
nowSec := now.Unix() + cacheDurationSec
|
||||
for idx, id := range us.validUserIds {
|
||||
us.generateNewHashes(lastSec, nowSec, idx, id)
|
||||
for idx, user := range us.validUsers {
|
||||
us.generateNewHashes(lastSec, nowSec, idx, user.ID())
|
||||
}
|
||||
lastSec = nowSec
|
||||
}
|
||||
|
@ -76,8 +76,8 @@ func (us *TimedUserSet) updateUserHash(tick <-chan time.Time) {
|
|||
|
||||
func (us *TimedUserSet) AddUser(user config.User) error {
|
||||
id := user.ID()
|
||||
idx := len(us.validUserIds)
|
||||
us.validUserIds = append(us.validUserIds, id)
|
||||
idx := len(us.validUsers)
|
||||
us.validUsers = append(us.validUsers, user)
|
||||
|
||||
nowSec := time.Now().Unix()
|
||||
lastSec := nowSec - cacheDurationSec
|
||||
|
@ -86,12 +86,12 @@ func (us *TimedUserSet) AddUser(user config.User) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (us TimedUserSet) GetUser(userHash []byte) (*config.ID, int64, bool) {
|
||||
func (us TimedUserSet) GetUser(userHash []byte) (config.User, int64, bool) {
|
||||
defer us.access.RUnlock()
|
||||
us.access.RLock()
|
||||
pair, found := us.userHash[string(userHash)]
|
||||
if found {
|
||||
return us.validUserIds[pair.index], pair.timeSec, true
|
||||
return us.validUsers[pair.index], pair.timeSec, true
|
||||
}
|
||||
return nil, 0, false
|
||||
}
|
||||
|
|
|
@ -75,12 +75,12 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
userId, timeSec, valid := r.vUserSet.GetUser(buffer.Value[:nBytes])
|
||||
userObj, timeSec, valid := r.vUserSet.GetUser(buffer.Value[:nBytes])
|
||||
if !valid {
|
||||
return nil, proxyerrors.InvalidAuthentication
|
||||
}
|
||||
|
||||
aesCipher, err := aes.NewCipher(userId.CmdKey())
|
||||
aesCipher, err := aes.NewCipher(userObj.ID().CmdKey())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
|
|||
bufferLen := nBytes
|
||||
|
||||
request := &VMessRequest{
|
||||
UserId: *userId,
|
||||
UserId: *userObj.ID(),
|
||||
Version: buffer.Value[0],
|
||||
}
|
||||
|
||||
|
|
|
@ -14,12 +14,17 @@ import (
|
|||
|
||||
type TestUser struct {
|
||||
id *config.ID
|
||||
level config.UserLevel
|
||||
}
|
||||
|
||||
func (u *TestUser) ID() *config.ID {
|
||||
return u.id
|
||||
}
|
||||
|
||||
func (this *TestUser) Level() config.UserLevel {
|
||||
return this.level
|
||||
}
|
||||
|
||||
func TestVMessSerialization(t *testing.T) {
|
||||
assert := unit.Assert(t)
|
||||
|
||||
|
@ -28,8 +33,10 @@ func TestVMessSerialization(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
userSet := mocks.MockUserSet{[]*config.ID{}, make(map[string]int), make(map[string]int64)}
|
||||
userSet.AddUser(&TestUser{userId})
|
||||
userSet := mocks.MockUserSet{[]config.User{}, make(map[string]int), make(map[string]int64)}
|
||||
userSet.AddUser(&TestUser{
|
||||
id: userId,
|
||||
})
|
||||
|
||||
request := new(VMessRequest)
|
||||
request.Version = byte(0x01)
|
||||
|
@ -72,8 +79,10 @@ func TestVMessSerialization(t *testing.T) {
|
|||
|
||||
func BenchmarkVMessRequestWriting(b *testing.B) {
|
||||
userId, _ := config.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
|
||||
userSet := mocks.MockUserSet{[]*config.ID{}, make(map[string]int), make(map[string]int64)}
|
||||
userSet.AddUser(&TestUser{userId})
|
||||
userSet := mocks.MockUserSet{[]config.User{}, make(map[string]int), make(map[string]int64)}
|
||||
userSet.AddUser(&TestUser{
|
||||
id: userId,
|
||||
})
|
||||
|
||||
request := new(VMessRequest)
|
||||
request.Version = byte(0x01)
|
||||
|
|
|
@ -5,20 +5,20 @@ import (
|
|||
)
|
||||
|
||||
type MockUserSet struct {
|
||||
UserIds []*config.ID
|
||||
Users []config.User
|
||||
UserHashes map[string]int
|
||||
Timestamps map[string]int64
|
||||
}
|
||||
|
||||
func (us *MockUserSet) AddUser(user config.User) error {
|
||||
us.UserIds = append(us.UserIds, user.ID())
|
||||
us.Users = append(us.Users, user)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (us *MockUserSet) GetUser(userhash []byte) (*config.ID, int64, bool) {
|
||||
func (us *MockUserSet) GetUser(userhash []byte) (config.User, int64, bool) {
|
||||
idx, found := us.UserHashes[string(userhash)]
|
||||
if found {
|
||||
return us.UserIds[idx], us.Timestamps[string(userhash)], true
|
||||
return us.Users[idx], us.Timestamps[string(userhash)], true
|
||||
}
|
||||
return nil, 0, false
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue