// Copyright © 2023 Ory Corp // SPDX-License-Identifier: Apache-2.0 package x import ( "net/http" "time" "github.com/gorilla/sessions" "github.com/pkg/errors" ) // SessionPersistValues adds values to the session store and persists the changes. func SessionPersistValues(w http.ResponseWriter, r *http.Request, s sessions.StoreExact, id string, values map[string]interface{}) error { // The error does not matter because in the worst case we're re-writing the session cookie. cookie, _ := s.Get(r, id) for k, v := range values { cookie.Values[k] = v } return errors.WithStack(cookie.Save(r, w)) } // SessionGetString returns a string for the given id and key or an error if the session is invalid, // the key does not exist, or the key value is not a string. func SessionGetString(r *http.Request, s sessions.StoreExact, id string, key interface{}) (string, error) { check := func(v map[interface{}]interface{}) (string, error) { vv, ok := v[key] if !ok { return "", errors.Errorf("key %s does not exist in cookie: %+v", key, id) } else if vvv, ok := vv.(string); !ok { return "", errors.Errorf("value of key %s is not of type string in cookie", key) } else { return vvv, nil } } var exactErr error cookie, err := s.GetExact(r, id, func(s *sessions.Session) bool { _, exactErr = check(s.Values) return exactErr == nil }) if err != nil { return "", err } else if exactErr != nil { return "", exactErr } return check(cookie.Values) } // SessionGetStringOr returns a string for the given id and key or the fallback value if the session is invalid, // the key does not exist, or the key value is not a string. func SessionGetStringOr(r *http.Request, s sessions.StoreExact, id, key, fallback string) string { v, err := SessionGetString(r, s, id, key) if err != nil { return fallback } return v } func SessionUnset(w http.ResponseWriter, r *http.Request, s sessions.StoreExact, id string) error { cookie, err := s.Get(r, id) if err == nil && cookie.IsNew { // No cookie was sent in the request. We have nothing to do. return nil } cookie.Options.MaxAge = -1 cookie.Values = make(map[interface{}]interface{}) return errors.WithStack(cookie.Save(r, w)) } func SessionSetExpiresIn(w http.ResponseWriter, r *http.Request, s sessions.StoreExact, id string, expiresIn time.Duration) error { cookie, err := s.Get(r, id) if err == nil && cookie.IsNew { // No cookie was sent in the request. We have nothing to do. return nil } cookie.Options.MaxAge = int(expiresIn.Seconds()) return errors.WithStack(cookie.Save(r, w)) } func SessionUnsetKey(w http.ResponseWriter, r *http.Request, s sessions.StoreExact, id, key string) error { cookie, err := s.Get(r, id) if err == nil && cookie.IsNew { // No cookie was sent in the request. We have nothing to do. return nil } delete(cookie.Values, key) return errors.WithStack(cookie.Save(r, w)) }