Introduce user level

pull/55/head
V2Ray 2015-10-31 00:38:31 +01:00
parent d585ec0593
commit b44098d752
6 changed files with 58 additions and 20 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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],
}

View File

@ -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)

View File

@ -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
}