mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-30 18:49:08 +02:00
session: clear stale SSO deadline on teardown and after expiry
The session deadline lived in two sinks kept in sync by hand: ApplySessionDeadline wrote both the (engine-scoped) sessionwatch.Watcher and the (server-scoped) peer.Status recorder. The clear paths only touched the watcher, so the recorder — which is what the Status RPC / SubscribeStatus snapshot the UI reads from — kept reporting a deadline that had gone stale, surfacing as a frozen "expires in …" countdown. Two cases were leaking: - Profile switch / Down: the watcher is recreated per engine but the recorder outlives it, so a switch to a profile whose server sends no deadline left the previous profile's value in place. - In-place expiry: the watcher arms warning timers at T-WarningLead and T-FinalWarningLead but nothing at the deadline itself, so once the moment passed the recorder kept the now-past value indefinitely. Make the watcher the single writer of the recorder deadline (Update / clearLocked / Close all route through SetSessionExpiresAt) so teardown clears it, and guard GetSessionExpiresAt to report a past deadline as none so in-place expiry stops painting a stale countdown.
This commit is contained in:
@@ -36,19 +36,21 @@ func (e *Engine) ApplySessionDeadline(ts *timestamppb.Timestamp) {
|
||||
var deadline time.Time
|
||||
// Explicit zero (seconds=0 AND nanos=0) is the sentinel for "disabled".
|
||||
// Everything else flows through Watcher.Update, whose sanity-checks
|
||||
// reject out-of-range / pre-epoch / far-future / too-stale values; the
|
||||
// catch-block below converts any rejection into a clear.
|
||||
// reject out-of-range / pre-epoch / far-future / too-stale values and
|
||||
// clear on rejection.
|
||||
if ts.GetSeconds() != 0 || ts.GetNanos() != 0 {
|
||||
deadline = ts.AsTime().UTC()
|
||||
}
|
||||
if e.sessionWatcher != nil {
|
||||
if err := e.sessionWatcher.Update(deadline); err != nil {
|
||||
log.Errorf("auth session deadline rejected: %v, clearing", err)
|
||||
deadline = time.Time{}
|
||||
}
|
||||
if e.sessionWatcher == nil {
|
||||
return
|
||||
}
|
||||
if e.statusRecorder != nil {
|
||||
e.statusRecorder.SetSessionExpiresAt(deadline)
|
||||
// Watcher.Update owns the propagation to the status recorder (the
|
||||
// SubscribeStatus / Status snapshot the UI reads): a set writes the
|
||||
// deadline, a clear or a sanity-check rejection writes the zero value.
|
||||
// Keeping a single writer is what stops the recorder from drifting out
|
||||
// of sync with the warning timers.
|
||||
if err := e.sessionWatcher.Update(deadline); err != nil {
|
||||
log.Errorf("auth session deadline rejected: %v, clearing", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user