mirror of
https://github.com/nais/wonderwall.git
synced 2026-08-19 11:06:17 +00:00
refactor(session): clarify token refresh scheduling
Consolidate the refresh schedule into a single NextRefresh function (leeway + inactivity half-life, floored at the cooldown). ShouldRefresh now defers to it, so the explicit cooldown gate is redundant and removed. Add doc comments naming the mechanisms. No behavior change.
This commit is contained in:
+15
-12
@@ -13,8 +13,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// RefreshMinInterval is the minimum wait between refreshes (the cooldown).
|
||||
RefreshMinInterval = 1 * time.Minute
|
||||
RefreshLeeway = 30 * time.Second
|
||||
// RefreshLeeway is how long before expiry we aim to refresh.
|
||||
RefreshLeeway = 30 * time.Second
|
||||
)
|
||||
|
||||
type EncryptedData struct {
|
||||
@@ -166,14 +168,16 @@ func (in *Metadata) IsRefreshOnCooldown() bool {
|
||||
return time.Now().Before(in.RefreshCooldown())
|
||||
}
|
||||
|
||||
// NextRefresh returns when we should next proactively refresh the tokens. It
|
||||
// aims to refresh shortly before expiry, but never before the cooldown.
|
||||
func (in *Metadata) NextRefresh() time.Time {
|
||||
// subtract the leeway to ensure that we refresh before expiry
|
||||
// aim to refresh shortly before the tokens expire
|
||||
next := in.Tokens.ExpireAt.Add(-RefreshLeeway)
|
||||
|
||||
// if inactivity is enabled...
|
||||
// with inactivity enabled, refresh earlier - at the midpoint to the timeout
|
||||
// - so an active user extends the timeout well before the session goes idle
|
||||
timeout := in.Session.TimeoutAt
|
||||
if !timeout.IsZero() {
|
||||
// ...refresh at the half-life between the last refresh and the timeout
|
||||
lastRefresh := in.Tokens.RefreshedAt
|
||||
halfLife := lastRefresh.Add(timeout.Sub(lastRefresh) / 2)
|
||||
|
||||
@@ -182,9 +186,9 @@ func (in *Metadata) NextRefresh() time.Time {
|
||||
}
|
||||
}
|
||||
|
||||
// try to refresh at the first opportunity if the next refresh is in the past
|
||||
if next.Before(time.Now()) {
|
||||
return in.RefreshCooldown()
|
||||
// but never before the cooldown has elapsed
|
||||
if cooldown := in.RefreshCooldown(); next.Before(cooldown) {
|
||||
next = cooldown
|
||||
}
|
||||
|
||||
return next
|
||||
@@ -196,11 +200,14 @@ func (in *Metadata) Refresh(nextExpirySeconds int64) {
|
||||
in.Tokens.ExpireAt = now.Add(time.Duration(nextExpirySeconds) * time.Second)
|
||||
}
|
||||
|
||||
// RefreshCooldown returns the earliest time the tokens may be refreshed again,
|
||||
// throttling calls to the identity provider. It waits RefreshMinInterval after
|
||||
// the last refresh, but caps short-lived tokens at half their lifetime so the
|
||||
// cooldown always leaves room to refresh before they expire.
|
||||
func (in *Metadata) RefreshCooldown() time.Time {
|
||||
refreshed := in.Tokens.RefreshedAt
|
||||
tokenLifetime := in.TokenLifetime()
|
||||
|
||||
// if token lifetime is less than the minimum refresh interval * 2, we'll allow refreshes at the token half-life
|
||||
if tokenLifetime <= RefreshMinInterval*2 {
|
||||
return refreshed.Add(tokenLifetime / 2)
|
||||
}
|
||||
@@ -213,10 +220,6 @@ func (in *Metadata) ShouldRefresh() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
if in.IsRefreshOnCooldown() {
|
||||
return false
|
||||
}
|
||||
|
||||
return time.Now().After(in.NextRefresh())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user