Removed peer editing, cleanup

This commit is contained in:
jdl
2026-06-12 14:49:40 +02:00
parent 4d2aa5c8c7
commit 3e7d34a92a
17 changed files with 99 additions and 203 deletions

View File

@@ -40,7 +40,13 @@ func New(dbPath string) (*API, error) {
sessions: make(map[string]*Session),
}
return a, a.ensurePassword()
if err := a.ensurePassword(); err != nil {
return nil, err
}
go a.sweepSessions()
return a, nil
}
func (a *API) ensurePassword() error {
@@ -80,58 +86,72 @@ func (a *API) Session_Delete(sessionID string) error {
return nil
}
// Session_Get returns a snapshot copy of the session for sessionID (creating a
// fresh one if absent/expired). Returning a value rather than the stored
// pointer prevents callers from racing on the shared struct; mutations go
// through Session_SignIn / Session_Delete under the lock.
const (
sessionTTLSecs = 86400 * 21 // 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,
// or the zero Session if the cookie is missing/unknown/expired. It never
// 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) {
a.sessionsMu.Lock()
defer a.sessionsMu.Unlock()
if sessionID != "" {
s, ok := a.sessions[sessionID]
if ok {
if timeSince(s.LastSeenAt) <= 86400*21 {
if timeSince(s.LastSeenAt) > 86400*7 {
s.LastSeenAt = time.Now().Unix()
}
return *s, nil
}
delete(a.sessions, sessionID)
}
s, ok := a.sessions[sessionID]
if sessionID == "" || !ok {
return Session{}, nil
}
return *a.session_Create(), nil
if timeSince(s.LastSeenAt) > sessionTTLSecs {
delete(a.sessions, sessionID)
return Session{}, nil
}
s.LastSeenAt = time.Now().Unix()
return *s, nil
}
// caller must hold sessionsMu
func (a *API) session_Create() *Session {
// Session_SignIn verifies pwd and, on success, mints a fresh signed-in session,
// returning it so the caller can set the cookie. A new ID per sign-in rotates
// the session at the privilege boundary (session-fixation resistance).
func (a *API) Session_SignIn(pwd string) (Session, error) {
conf, err := a.Config_Get()
if err != nil {
return Session{}, err
}
if err := bcrypt.CompareHashAndPassword(conf.Password, []byte(pwd)); err != nil {
return Session{}, ErrNotAuthorized
}
a.sessionsMu.Lock()
defer a.sessionsMu.Unlock()
s := &Session{
SessionID: idgen.NewToken(),
SignedIn: true,
CreatedAt: time.Now().Unix(),
LastSeenAt: time.Now().Unix(),
}
a.sessions[s.SessionID] = s
return s
return *s, nil
}
func (a *API) Session_SignIn(sessionID, pwd string) error {
conf, err := a.Config_Get()
if err != nil {
return err
// sweepSessions periodically evicts sessions past their TTL. Without it, a
// signed-in session whose ID is never presented again would linger forever
// (Session_Get only evicts on a lookup of that same ID).
func (a *API) sweepSessions() {
for range time.Tick(sessionSweepEvery) {
a.sessionsMu.Lock()
for id, s := range a.sessions {
if timeSince(s.LastSeenAt) > sessionTTLSecs {
delete(a.sessions, id)
}
}
a.sessionsMu.Unlock()
}
if err := bcrypt.CompareHashAndPassword(conf.Password, []byte(pwd)); err != nil {
return ErrNotAuthorized
}
a.sessionsMu.Lock()
defer a.sessionsMu.Unlock()
s, ok := a.sessions[sessionID]
if !ok {
// Session expired or was evicted between fetch and sign-in.
return ErrNotAuthorized
}
s.SignedIn = true
return nil
}
func (a *API) Network_Create(n *Network) error {
@@ -153,7 +173,6 @@ func (a *API) Network_List() ([]*Network, error) {
}
func (a *API) Peer_CreateNew(p *Peer) error {
p.Version = idgen.NextID(0)
p.WGPubKey = []byte{}
p.SignPubKey = []byte{}
p.APIKey = idgen.NewToken()
@@ -175,21 +194,12 @@ func (a *API) Peer_Init(peer *Peer, args m.PeerInitArgs) error {
return errors.New("peer already initialized")
}
peer.Version = idgen.NextID(0)
peer.WGPubKey = args.WGPubKey
peer.SignPubKey = args.SignPubKey
return db.Peer_UpdateFull(a.db, peer)
}
func (a *API) Peer_Update(p *Peer) error {
a.lock.Lock()
defer a.lock.Unlock()
p.Version = idgen.NextID(0)
return db.Peer_Update(a.db, p)
}
func (a *API) Peer_Delete(networkID int64, peerIP byte) error {
return db.Peer_Delete(a.db, networkID, peerIP)
}