v0.324.0: the database password comes back with the data (R-1106, R-127b, R-926); restic 0.19.1 (R-1107); R-1108, R-1065, R-1017; dashboard hardening (R-983, R-976)
gates / gates (push) Successful in 44s
gates / gates (push) Successful in 44s
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
// Package family is the household's family list for the permanent family gate (`09` §3 decisions 63, 64; R-780).
|
||||
//
|
||||
// Each family member has their OWN name and password (never the dashboard's); the household's dashboard admin adds,
|
||||
// resets and removes them. A member who signs in gets a SESSION (30 days). Every app cookie the gate mints names the
|
||||
// session, so the gate asks this store on every request: a removed member, a reset password (the member's generation
|
||||
// resets and removes them. A member who signs in gets a SESSION (30 days). Every app cookie the gate mints carries a
|
||||
// token derived from the session for that app (never the session id itself, R-976), so the gate asks this store on
|
||||
// every request (Find): a removed member, a reset password (the member's generation
|
||||
// moves on) or a logout (the session is deleted) ends every app's access at the next request.
|
||||
//
|
||||
// A session with Member "" is the HOUSEHOLD's: minted when the dashboard's own session vouched for the browser (the
|
||||
@@ -312,6 +313,50 @@ func (s *Store) Valid(id string) (Session, bool) {
|
||||
return se, true
|
||||
}
|
||||
|
||||
// Find returns the first session that match accepts and that still holds (the same test as Valid). It lets a caller
|
||||
// look a session up by something DERIVED from its id — the per-app token the family gate puts in an app's cookie
|
||||
// (R-976) — without that id ever leaving the dashboard host.
|
||||
func (s *Store) Find(match func(id string) bool) (Session, bool) {
|
||||
if s == nil || match == nil {
|
||||
return Session{}, false
|
||||
}
|
||||
s.mu.Lock()
|
||||
var found string
|
||||
for id := range s.sessions {
|
||||
if match(id) {
|
||||
found = id
|
||||
break
|
||||
}
|
||||
}
|
||||
s.mu.Unlock()
|
||||
if found == "" {
|
||||
return Session{}, false
|
||||
}
|
||||
return s.Valid(found)
|
||||
}
|
||||
|
||||
// EndAll deletes every session — every member's and the household's — and keeps the members (R-976: a dashboard
|
||||
// password change or reset ends every way into the family apps; members sign in again with their own passwords).
|
||||
// It returns how many sessions it ended.
|
||||
func (s *Store) EndAll() (int, error) {
|
||||
if s == nil {
|
||||
return 0, nil
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
n := len(s.sessions)
|
||||
if n == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
// Ended in memory even when the save fails: an ending is never undone because a disk write failed (the caller
|
||||
// logs the error; the sessions stay ended until a restart would read the old file back).
|
||||
s.sessions = map[string]Session{}
|
||||
if err := s.saveLocked(); err != nil {
|
||||
return n, err
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// EndSession deletes a session (logout). Unknown ids are not an error.
|
||||
func (s *Store) EndSession(id string) error {
|
||||
if s == nil {
|
||||
|
||||
Reference in New Issue
Block a user