Skip to content

Commit

Permalink
feat: control edge cache ttl (#3808)
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr committed Mar 8, 2024
1 parent 0b32ce1 commit c9dcce5
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 6 deletions.
8 changes: 7 additions & 1 deletion .schemastore/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2731,10 +2731,16 @@
"properties": {
"cacheable_sessions": {
"type": "boolean",
"title": "Enable Ory Sessions caching",
"title": "Enable Ory Session Edge Caching",
"description": "If enabled allows Ory Sessions to be cached. Only effective in the Ory Network.",
"default": false
},
"cacheable_sessions_max_age": {
"title": "Set Ory Session Edge Caching maximum age",
"description": "Set how long Ory Sessions are cached on the edge. If unset, the session expiry will be used. Only effective in the Ory Network.",
"type": "string",
"pattern": "^([0-9]+(ns|us|ms|s|m|h))+$"
},
"use_continue_with_transitions": {
"type": "boolean",
"title": "Enable new flow transitions using `continue_with` items",
Expand Down
5 changes: 5 additions & 0 deletions driver/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ const (
ViperKeySessionTokenizerTemplates = "session.whoami.tokenizer.templates"
ViperKeySessionWhoAmIAAL = "session.whoami.required_aal"
ViperKeySessionWhoAmICaching = "feature_flags.cacheable_sessions"
ViperKeySessionWhoAmICachingMaxAge = "feature_flags.cacheable_sessions_max_age"
ViperKeyUseContinueWithTransitions = "feature_flags.use_continue_with_transitions"
ViperKeySessionRefreshMinTimeLeft = "session.earliest_possible_extend"
ViperKeyCookieSameSite = "cookies.same_site"
Expand Down Expand Up @@ -1353,6 +1354,10 @@ func (p *Config) SessionWhoAmICaching(ctx context.Context) bool {
return p.GetProvider(ctx).Bool(ViperKeySessionWhoAmICaching)
}

func (p *Config) SessionWhoAmICachingMaxAge(ctx context.Context) time.Duration {
return p.GetProvider(ctx).DurationF(ViperKeySessionWhoAmICachingMaxAge, 0)
}

func (p *Config) UseContinueWithTransitions(ctx context.Context) bool {
return p.GetProvider(ctx).Bool(ViperKeyUseContinueWithTransitions)
}
Expand Down
6 changes: 6 additions & 0 deletions embedx/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2736,6 +2736,12 @@
"description": "If enabled allows Ory Sessions to be cached. Only effective in the Ory Network.",
"default": false
},
"cacheable_sessions_max_age": {
"title": "Set Ory Session Edge Caching maximum age",
"description": "Set how long Ory Sessions are cached on the edge. If unset, the session expiry will be used. Only effective in the Ory Network.",
"type": "string",
"pattern": "^([0-9]+(ns|us|ms|s|m|h))+$"
},
"use_continue_with_transitions": {
"type": "boolean",
"title": "Enable new flow transitions using `continue_with` items",
Expand Down
1 change: 1 addition & 0 deletions internal/client-go/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
7 changes: 6 additions & 1 deletion session/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,12 @@ func (h *Handler) whoami(w http.ResponseWriter, r *http.Request, _ httprouter.Pa

// Set Cache header only when configured, and when no tokenization is requested.
if c.SessionWhoAmICaching(ctx) && len(tokenizeTemplate) == 0 {
w.Header().Set("Ory-Session-Cache-For", fmt.Sprintf("%d", int64(time.Until(s.ExpiresAt).Seconds())))
expiry := time.Until(s.ExpiresAt)
if c.SessionWhoAmICachingMaxAge(ctx) > 0 && expiry > c.SessionWhoAmICachingMaxAge(ctx) {
expiry = c.SessionWhoAmICachingMaxAge(ctx)
}

w.Header().Set("Ory-Session-Cache-For", fmt.Sprintf("%0.f", expiry.Seconds()))
}

if err := h.r.SessionManager().RefreshCookie(ctx, w, r, s); err != nil {
Expand Down
18 changes: 14 additions & 4 deletions session/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ func TestSessionWhoAmI(t *testing.T) {
})

t.Run("case=http methods", func(t *testing.T) {
run := func(t *testing.T, cacheEnabled bool) {
run := func(t *testing.T, cacheEnabled bool, maxAge time.Duration) {
conf.MustSet(ctx, config.ViperKeySessionWhoAmICaching, cacheEnabled)
conf.MustSet(ctx, config.ViperKeySessionWhoAmICachingMaxAge, maxAge)
client := testhelpers.NewClientWithCookies(t)

// No cookie yet -> 401
Expand All @@ -153,6 +154,7 @@ func TestSessionWhoAmI(t *testing.T) {

if cacheEnabled {
assert.NotEmpty(t, res.Header.Get("Ory-Session-Cache-For"))
assert.Equal(t, "60", res.Header.Get("Ory-Session-Cache-For"))
} else {
assert.Empty(t, res.Header.Get("Ory-Session-Cache-For"))
}
Expand Down Expand Up @@ -182,7 +184,11 @@ func TestSessionWhoAmI(t *testing.T) {
assert.NotEmpty(t, res.Header.Get("X-Kratos-Authenticated-Identity-Id"))

if cacheEnabled {
assert.NotEmpty(t, res.Header.Get("Ory-Session-Cache-For"))
if maxAge > 0 {
assert.Equal(t, fmt.Sprintf("%0.f", maxAge.Seconds()), res.Header.Get("Ory-Session-Cache-For"))
} else {
assert.Equal(t, fmt.Sprintf("%0.f", conf.SessionLifespan(ctx).Seconds()), res.Header.Get("Ory-Session-Cache-For"))
}
} else {
assert.Empty(t, res.Header.Get("Ory-Session-Cache-For"))
}
Expand All @@ -198,11 +204,15 @@ func TestSessionWhoAmI(t *testing.T) {
}

t.Run("cache disabled", func(t *testing.T) {
run(t, false)
run(t, false, 0)
})

t.Run("cache enabled", func(t *testing.T) {
run(t, true)
run(t, true, 0)
})

t.Run("cache enabled with max age", func(t *testing.T) {
run(t, true, time.Minute)
})
})

Expand Down

0 comments on commit c9dcce5

Please sign in to comment.