WIP
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
"vppn/hub/api/db"
|
||||
"vppn/hub/errs"
|
||||
"vppn/m"
|
||||
|
||||
"git.crumpington.com/lib/go/idgen"
|
||||
@@ -64,31 +65,32 @@ func (a *API) ensurePassword() error {
|
||||
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Printf("Failed to generate password: %v", err)
|
||||
return errs.ErrUnexpected
|
||||
}
|
||||
|
||||
conf := &Config{ConfigID: 1, Password: hashed}
|
||||
return db.Config_Insert(a.db, conf)
|
||||
return errs.DB(db.Config_Insert(a.db, conf))
|
||||
}
|
||||
|
||||
func (a *API) Config_Get() (*Config, error) {
|
||||
return db.Config_Get(a.db, 1)
|
||||
conf, err := db.Config_Get(a.db, 1)
|
||||
return conf, errs.DB(err)
|
||||
}
|
||||
|
||||
func (a *API) Config_Update(conf *Config) error {
|
||||
return db.Config_Update(a.db, conf)
|
||||
return errs.DB(db.Config_Update(a.db, conf))
|
||||
}
|
||||
|
||||
func (a *API) Session_Delete(sessionID string) error {
|
||||
func (a *API) Session_Delete(sessionID string) {
|
||||
a.sessionsMu.Lock()
|
||||
defer a.sessionsMu.Unlock()
|
||||
delete(a.sessions, sessionID)
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
sessionTTLSecs = 86400 * 21 // sessions expire 21 days after last use
|
||||
sessionSweepEvery = time.Hour // cadence of expired-session eviction
|
||||
sessionTTLSecs = 24 * 21 * time.Hour // sessions expire 21 days after last use
|
||||
sessionSweepEvery = time.Hour // cadence of expired-session eviction
|
||||
)
|
||||
|
||||
// Session_Get returns a snapshot copy of the signed-in session for sessionID,
|
||||
@@ -96,23 +98,23 @@ const (
|
||||
// creates a session, so anonymous requests cost no memory — a session is minted
|
||||
// only by Session_SignIn. Returning a value (not the stored pointer) keeps
|
||||
// callers from racing on the shared struct.
|
||||
func (a *API) Session_Get(sessionID string) (Session, error) {
|
||||
func (a *API) Session_Get(sessionID string) Session {
|
||||
a.sessionsMu.Lock()
|
||||
defer a.sessionsMu.Unlock()
|
||||
|
||||
s, ok := a.sessions[sessionID]
|
||||
|
||||
if sessionID == "" || !ok {
|
||||
return Session{}, nil
|
||||
return Session{}
|
||||
}
|
||||
|
||||
if timeSince(s.LastSeenAt) > sessionTTLSecs {
|
||||
if time.Since(s.LastSeenAt) > sessionTTLSecs {
|
||||
delete(a.sessions, sessionID)
|
||||
return Session{}, nil
|
||||
return Session{}
|
||||
}
|
||||
|
||||
s.LastSeenAt = time.Now().Unix()
|
||||
return *s, nil
|
||||
s.LastSeenAt = time.Now()
|
||||
return *s
|
||||
}
|
||||
|
||||
// Session_SignIn verifies pwd and, on success, mints a fresh signed-in session,
|
||||
@@ -121,10 +123,11 @@ func (a *API) Session_Get(sessionID string) (Session, error) {
|
||||
func (a *API) Session_SignIn(pwd string) (Session, error) {
|
||||
conf, err := a.Config_Get()
|
||||
if err != nil {
|
||||
return Session{}, err
|
||||
log.Printf("Failed to get config: %v", err)
|
||||
return Session{}, errs.ErrUnexpected
|
||||
}
|
||||
if err := bcrypt.CompareHashAndPassword(conf.Password, []byte(pwd)); err != nil {
|
||||
return Session{}, ErrNotAuthorized
|
||||
return Session{}, errs.NotAuthorized.WithMsg("Not authorized.")
|
||||
}
|
||||
|
||||
a.sessionsMu.Lock()
|
||||
@@ -132,8 +135,8 @@ func (a *API) Session_SignIn(pwd string) (Session, error) {
|
||||
s := &Session{
|
||||
SessionID: idgen.NewToken(),
|
||||
SignedIn: true,
|
||||
CreatedAt: time.Now().Unix(),
|
||||
LastSeenAt: time.Now().Unix(),
|
||||
CreatedAt: time.Now(),
|
||||
LastSeenAt: time.Now(),
|
||||
}
|
||||
a.sessions[s.SessionID] = s
|
||||
return *s, nil
|
||||
@@ -146,7 +149,7 @@ func (a *API) sweepSessions() {
|
||||
for range time.Tick(sessionSweepEvery) {
|
||||
a.sessionsMu.Lock()
|
||||
for id, s := range a.sessions {
|
||||
if timeSince(s.LastSeenAt) > sessionTTLSecs {
|
||||
if time.Since(s.LastSeenAt) > sessionTTLSecs {
|
||||
delete(a.sessions, id)
|
||||
}
|
||||
}
|
||||
@@ -156,20 +159,22 @@ func (a *API) sweepSessions() {
|
||||
|
||||
func (a *API) Network_Create(n *Network) error {
|
||||
n.NetworkID = idgen.NextID(0)
|
||||
return db.Network_Insert(a.db, n)
|
||||
return errs.DB(db.Network_Insert(a.db, n))
|
||||
}
|
||||
|
||||
func (a *API) Network_Delete(n *Network) error {
|
||||
return db.Network_Delete(a.db, n.NetworkID)
|
||||
return errs.DB(db.Network_Delete(a.db, n.NetworkID))
|
||||
}
|
||||
|
||||
func (a *API) Network_Get(id int64) (*Network, error) {
|
||||
return db.Network_Get(a.db, id)
|
||||
n, err := db.Network_Get(a.db, id)
|
||||
return n, errs.DB(err)
|
||||
}
|
||||
|
||||
func (a *API) Network_List() ([]*Network, error) {
|
||||
const query = db.Network_SelectQuery + ` ORDER BY LocalDomain ASC`
|
||||
return db.Network_List(a.db, query)
|
||||
n, err := db.Network_List(a.db, query)
|
||||
return n, errs.DB(err)
|
||||
}
|
||||
|
||||
func (a *API) Peer_CreateNew(p *Peer) error {
|
||||
@@ -177,7 +182,7 @@ func (a *API) Peer_CreateNew(p *Peer) error {
|
||||
p.SignPubKey = []byte{}
|
||||
p.APIKey = idgen.NewToken()
|
||||
|
||||
return db.Peer_Insert(a.db, p)
|
||||
return errs.DB(db.Peer_Insert(a.db, p))
|
||||
}
|
||||
|
||||
func (a *API) Peer_Init(peer *Peer, args m.PeerInitArgs) error {
|
||||
@@ -191,27 +196,30 @@ func (a *API) Peer_Init(peer *Peer, args m.PeerInitArgs) error {
|
||||
return err
|
||||
}
|
||||
if len(current.WGPubKey) != 0 {
|
||||
return errors.New("peer already initialized")
|
||||
return errs.ErrAlreadyExists
|
||||
}
|
||||
|
||||
peer.WGPubKey = args.WGPubKey
|
||||
peer.SignPubKey = args.SignPubKey
|
||||
|
||||
return db.Peer_UpdateFull(a.db, peer)
|
||||
return errs.DB(db.Peer_UpdateFull(a.db, peer))
|
||||
}
|
||||
|
||||
func (a *API) Peer_Delete(networkID int64, peerIP byte) error {
|
||||
return db.Peer_Delete(a.db, networkID, peerIP)
|
||||
return errs.DB(db.Peer_Delete(a.db, networkID, peerIP))
|
||||
}
|
||||
|
||||
func (a *API) Peer_List(networkID int64) ([]*Peer, error) {
|
||||
return db.Peer_ListAll(a.db, networkID)
|
||||
p, err := db.Peer_ListAll(a.db, networkID)
|
||||
return p, errs.DB(err)
|
||||
}
|
||||
|
||||
func (a *API) Peer_Get(networkID int64, ip byte) (*Peer, error) {
|
||||
return db.Peer_Get(a.db, networkID, ip)
|
||||
p, err := db.Peer_Get(a.db, networkID, ip)
|
||||
return p, errs.DB(err)
|
||||
}
|
||||
|
||||
func (a *API) Peer_GetByAPIKey(key string) (*Peer, error) {
|
||||
return db.Peer_GetByAPIKey(a.db, key)
|
||||
p, err := db.Peer_GetByAPIKey(a.db, key)
|
||||
return p, errs.DB(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user