mirror of https://github.com/cbeuw/Cloak
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
2.8 KiB
Go
116 lines
2.8 KiB
Go
5 years ago
|
package server
|
||
|
|
||
|
import (
|
||
|
"encoding/binary"
|
||
|
"log"
|
||
|
"time"
|
||
|
|
||
|
"github.com/boltdb/bolt"
|
||
|
)
|
||
|
|
||
|
var Uint32 = binary.BigEndian.Uint32
|
||
|
var Uint64 = binary.BigEndian.Uint64
|
||
|
var PutUint32 = binary.BigEndian.PutUint32
|
||
|
var PutUint64 = binary.BigEndian.PutUint64
|
||
|
|
||
|
type localManager struct {
|
||
|
db *bolt.DB
|
||
|
}
|
||
|
|
||
|
func MakeLocalManager(dbPath string) (*localManager, error) {
|
||
|
db, err := bolt.Open(dbPath, 0600, nil)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return &localManager{db}, nil
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
if bucket == nil {
|
||
|
return ErrUserNotFound
|
||
|
}
|
||
|
upRate = int64(Uint64(bucket.Get([]byte("UpRate"))))
|
||
|
downRate = int64(Uint64(bucket.Get([]byte("DownRate"))))
|
||
|
upCredit = int64(Uint64(bucket.Get([]byte("UpCredit"))))
|
||
|
downCredit = int64(Uint64(bucket.Get([]byte("DownCredit"))))
|
||
|
expiryTime = int64(Uint64(bucket.Get([]byte("ExpiryTime"))))
|
||
|
return nil
|
||
|
})
|
||
|
if err != nil {
|
||
|
return 0, 0, err
|
||
|
}
|
||
|
if upCredit <= 0 {
|
||
|
return 0, 0, ErrNoUpCredit
|
||
|
}
|
||
|
if downCredit <= 0 {
|
||
|
return 0, 0, ErrNoDownCredit
|
||
|
}
|
||
|
if expiryTime < time.Now().Unix() {
|
||
|
return 0, 0, ErrUserExpired
|
||
|
}
|
||
|
|
||
|
return upRate, downRate, nil
|
||
|
}
|
||
|
|
||
|
func (manager *localManager) authoriseNewSession(user *ActiveUser) error {
|
||
|
var sessionsCap int
|
||
|
var upCredit, downCredit, expiryTime int64
|
||
|
err := manager.db.View(func(tx *bolt.Tx) error {
|
||
|
bucket := tx.Bucket(user.arrUID[:])
|
||
|
if bucket == nil {
|
||
|
return ErrUserNotFound
|
||
|
}
|
||
|
sessionsCap = int(Uint32(bucket.Get([]byte("SessionsCap"))))
|
||
|
upCredit = int64(Uint64(bucket.Get([]byte("UpCredit"))))
|
||
|
downCredit = int64(Uint64(bucket.Get([]byte("DownCredit"))))
|
||
|
expiryTime = int64(Uint64(bucket.Get([]byte("ExpiryTime"))))
|
||
|
return nil
|
||
|
})
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if upCredit <= 0 {
|
||
|
return ErrNoUpCredit
|
||
|
}
|
||
|
if downCredit <= 0 {
|
||
|
return ErrNoDownCredit
|
||
|
}
|
||
|
if expiryTime < time.Now().Unix() {
|
||
|
return ErrUserExpired
|
||
|
}
|
||
|
//user.sessionsM.RLock()
|
||
|
if len(user.sessions) >= sessionsCap {
|
||
|
//user.sessionsM.RUnlock()
|
||
|
return ErrSessionsCapReached
|
||
|
}
|
||
|
//user.sessionsM.RUnlock()
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func i64ToB(value int64) []byte {
|
||
|
oct := make([]byte, 8)
|
||
|
PutUint64(oct, uint64(value))
|
||
|
return oct
|
||
|
}
|
||
|
|
||
|
func (manager *localManager) uploadStatus(uploads []statusUpdate) error {
|
||
|
err := manager.db.Update(func(tx *bolt.Tx) error {
|
||
|
for _, status := range uploads {
|
||
|
bucket := tx.Bucket(status.UID)
|
||
|
if bucket == nil {
|
||
|
log.Printf("%x doesn't exist\n", status.UID)
|
||
|
continue
|
||
|
}
|
||
|
oldUp := int64(Uint64(bucket.Get([]byte("UpCredit"))))
|
||
|
bucket.Put([]byte("UpCredit"), i64ToB(oldUp-status.upUsage))
|
||
|
oldDown := int64(Uint64(bucket.Get([]byte("DownCredit"))))
|
||
|
bucket.Put([]byte("DownCredit"), i64ToB(oldDown-status.downUsage))
|
||
|
}
|
||
|
return nil
|
||
|
})
|
||
|
return err
|
||
|
}
|