Refactor usermanager

pull/71/head
Qian Wang 5 years ago
parent 67521efbd6
commit 08cb5d8462

@ -36,7 +36,7 @@ func (u *ActiveUser) GetSession(sessionID uint32, obfuscator *mux.Obfuscator, un
if sesh = u.sessions[sessionID]; sesh != nil {
return sesh, true, nil
} else {
err := u.panel.Manager.authoriseNewSession(u)
err := u.panel.Manager.AuthoriseNewSession(u.arrUID[:], len(u.sessions))
if err != nil {
return nil, false, err
}

@ -5,6 +5,7 @@ import (
"encoding/base64"
"encoding/json"
"errors"
"github.com/cbeuw/Cloak/internal/server/usermanager"
"io/ioutil"
"sync"
"time"
@ -74,7 +75,7 @@ func (sta *State) ParseConfig(conf string) (err error) {
//TODO: implement command & control mode
} else {
manager, err := MakeLocalManager(preParse.DatabasePath)
manager, err := usermanager.MakeLocalManager(preParse.DatabasePath)
if err != nil {
return err
}

@ -1,4 +1,4 @@
package server
package usermanager
import (
"encoding/binary"
@ -63,7 +63,7 @@ func (manager *localManager) registerMux() *gmux.Router {
return r
}
func (manager *localManager) authenticateUser(UID []byte) (int64, int64, error) {
func (manager *localManager) AuthenticateUser(UID []byte) (int64, int64, error) {
var upRate, downRate, upCredit, downCredit, expiryTime int64
err := manager.db.View(func(tx *bolt.Tx) error {
bucket := tx.Bucket(UID)
@ -93,11 +93,13 @@ func (manager *localManager) authenticateUser(UID []byte) (int64, int64, error)
return upRate, downRate, nil
}
func (manager *localManager) authoriseNewSession(user *ActiveUser) error {
func (manager *localManager) AuthoriseNewSession(UID []byte, numExistingSessions int) error {
var arrUID [16]byte
copy(arrUID[:], UID)
var sessionsCap int
var upCredit, downCredit, expiryTime int64
err := manager.db.View(func(tx *bolt.Tx) error {
bucket := tx.Bucket(user.arrUID[:])
bucket := tx.Bucket(arrUID[:])
if bucket == nil {
return ErrUserNotFound
}
@ -120,7 +122,7 @@ func (manager *localManager) authoriseNewSession(user *ActiveUser) error {
return ErrUserExpired
}
//user.sessionsM.RLock()
if len(user.sessions) >= sessionsCap {
if numExistingSessions >= sessionsCap {
//user.sessionsM.RUnlock()
return ErrSessionsCapReached
}
@ -128,14 +130,14 @@ func (manager *localManager) authoriseNewSession(user *ActiveUser) error {
return nil
}
func (manager *localManager) uploadStatus(uploads []statusUpdate) ([]statusResponse, error) {
var responses []statusResponse
func (manager *localManager) UploadStatus(uploads []StatusUpdate) ([]StatusResponse, error) {
var responses []StatusResponse
err := manager.db.Update(func(tx *bolt.Tx) error {
for _, status := range uploads {
var resp statusResponse
var resp StatusResponse
bucket := tx.Bucket(status.UID)
if bucket == nil {
resp = statusResponse{
resp = StatusResponse{
status.UID,
TERMINATE,
"User no longer exists",
@ -145,9 +147,9 @@ func (manager *localManager) uploadStatus(uploads []statusUpdate) ([]statusRespo
}
oldUp := int64(Uint64(bucket.Get([]byte("UpCredit"))))
newUp := oldUp - status.upUsage
newUp := oldUp - status.UpUsage
if newUp <= 0 {
resp = statusResponse{
resp = StatusResponse{
status.UID,
TERMINATE,
"No upload credit left",
@ -162,9 +164,9 @@ func (manager *localManager) uploadStatus(uploads []statusUpdate) ([]statusRespo
}
oldDown := int64(Uint64(bucket.Get([]byte("DownCredit"))))
newDown := oldDown - status.downUsage
newDown := oldDown - status.DownUsage
if newDown <= 0 {
resp = statusResponse{
resp = StatusResponse{
status.UID,
TERMINATE,
"No download credit left",
@ -180,7 +182,7 @@ func (manager *localManager) uploadStatus(uploads []statusUpdate) ([]statusRespo
expiry := int64(Uint64(bucket.Get([]byte("ExpiryTime"))))
if time.Now().Unix() > expiry {
resp = statusResponse{
resp = StatusResponse{
status.UID,
TERMINATE,
"User has expired",

@ -1,4 +1,4 @@
package server
package usermanager
import (
"bytes"

@ -1,23 +1,23 @@
package server
package usermanager
import (
"errors"
)
type statusUpdate struct {
type StatusUpdate struct {
UID []byte
active bool
numSession int
Active bool
NumSession int
upUsage int64
downUsage int64
timestamp int64
UpUsage int64
DownUsage int64
Timestamp int64
}
type statusResponse struct {
type StatusResponse struct {
UID []byte
action int
message string
Action int
Message string
}
const (
@ -32,7 +32,7 @@ var ErrNoDownCredit = errors.New("No download credit left")
var ErrUserExpired = errors.New("User has expired")
type UserManager interface {
authenticateUser([]byte) (int64, int64, error)
authoriseNewSession(*ActiveUser) error
uploadStatus([]statusUpdate) ([]statusResponse, error)
AuthenticateUser([]byte) (int64, int64, error)
AuthoriseNewSession([]byte, int) error
UploadStatus([]StatusUpdate) ([]StatusResponse, error)
}

@ -1,6 +1,7 @@
package server
import (
"github.com/cbeuw/Cloak/internal/server/usermanager"
"sync"
"sync/atomic"
"time"
@ -10,7 +11,7 @@ import (
)
type userPanel struct {
Manager UserManager
Manager usermanager.UserManager
activeUsersM sync.RWMutex
activeUsers map[[16]byte]*ActiveUser
@ -18,7 +19,7 @@ type userPanel struct {
usageUpdateQueue map[[16]byte]*usagePair
}
func MakeUserPanel(manager UserManager) *userPanel {
func MakeUserPanel(manager usermanager.UserManager) *userPanel {
ret := &userPanel{
Manager: manager,
activeUsers: make(map[[16]byte]*ActiveUser),
@ -37,7 +38,7 @@ func (panel *userPanel) GetUser(UID []byte) (*ActiveUser, error) {
return user, nil
}
upRate, downRate, err := panel.Manager.authenticateUser(UID)
upRate, downRate, err := panel.Manager.AuthenticateUser(UID)
if err != nil {
panel.activeUsersM.Unlock()
return nil, err
@ -103,7 +104,7 @@ func (panel *userPanel) updateUsageQueueForOne(user *ActiveUser) {
func (panel *userPanel) commitUpdate() error {
panel.usageUpdateQueueM.Lock()
statuses := make([]statusUpdate, 0, len(panel.usageUpdateQueue))
statuses := make([]usermanager.StatusUpdate, 0, len(panel.usageUpdateQueue))
for arrUID, usage := range panel.usageUpdateQueue {
panel.activeUsersM.RLock()
user := panel.activeUsers[arrUID]
@ -112,31 +113,31 @@ func (panel *userPanel) commitUpdate() error {
if user != nil {
numSession = user.NumSession()
}
status := statusUpdate{
status := usermanager.StatusUpdate{
UID: arrUID[:],
active: panel.isActive(arrUID[:]),
numSession: numSession,
upUsage: *usage.up,
downUsage: *usage.down,
timestamp: time.Now().Unix(),
Active: panel.isActive(arrUID[:]),
NumSession: numSession,
UpUsage: *usage.up,
DownUsage: *usage.down,
Timestamp: time.Now().Unix(),
}
statuses = append(statuses, status)
}
responses, err := panel.Manager.uploadStatus(statuses)
responses, err := panel.Manager.UploadStatus(statuses)
if err != nil {
return err
}
for _, resp := range responses {
var arrUID [16]byte
copy(arrUID[:], resp.UID)
switch resp.action {
case TERMINATE:
switch resp.Action {
case usermanager.TERMINATE:
panel.activeUsersM.RLock()
user := panel.activeUsers[arrUID]
panel.activeUsersM.RUnlock()
if user != nil {
user.Terminate(resp.message)
user.Terminate(resp.Message)
}
}
}

Loading…
Cancel
Save