feat(config): convert cookie property (Not)HTTPOnly boolean to enum

Signed-off-by: Jan Larwig <jan@larwig.com>
This commit is contained in:
Jan Larwig 2025-12-28 10:07:48 +01:00
parent ab6ab29258
commit 82a74a541a
No known key found for this signature in database
GPG Key ID: C2172BFA220A037A
13 changed files with 312 additions and 204 deletions

View File

@ -184,8 +184,9 @@ They may change between releases without notice.
| `injectResponseHeaders` | _[[]Header](#header)_ | InjectResponseHeaders is used to configure headers that should be added<br/>to responses from the proxy.<br/>This is typically used when using the proxy as an external authentication<br/>provider in conjunction with another proxy such as NGINX and its<br/>auth_request module.<br/>Headers may source values from either the authenticated user's session<br/>or from a static secret value. |
| `server` | _[Server](#server)_ | Server is used to configure the HTTP(S) server for the proxy application.<br/>You may choose to run both HTTP and HTTPS servers simultaneously.<br/>This can be done by setting the BindAddress and the SecureBindAddress simultaneously.<br/>To use the secure server you must configure a TLS certificate and key. |
| `metricsServer` | _[Server](#server)_ | MetricsServer is used to configure the HTTP(S) server for metrics.<br/>You may choose to run both HTTP and HTTPS servers simultaneously.<br/>This can be done by setting the BindAddress and the SecureBindAddress simultaneously.<br/>To use the secure server you must configure a TLS certificate and key. |
| `providers` | _[Providers](#providers)_ | Providers is used to configure your provider. **Multiple-providers is not<br/>yet working.** [This feature is tracked in<br/>#925](https://github.com/oauth2-proxy/oauth2-proxy/issues/926) |
| `providers` | _[Providers](#providers)_ | Providers is used to configure your provider.<br/>**Multiple-providers is not yet working.**<br/>[This feature is tracked in #925](https://github.com/oauth2-proxy/oauth2-proxy/issues/926) |
| `cookie` | _[Cookie](#cookie)_ | Cookie is used to configure the cookies used by OAuth2 Proxy.<br/>This includes session and CSRF cookies. |
| `session` | _[SessionOptions](#sessionoptions)_ | Session is used to configure session options used by OAuth2 Proxy.<br/>This includes session storage options. |
### AzureOptions
@ -230,19 +231,27 @@ Cookie contains configuration options relating session and CSRF cookies
| Field | Type | Description |
| ----- | ---- | ----------- |
| `name` | _string_ | Name is the name of the cookie |
| `secret` | _string_ | Secret is the secret used to encrypt/sign the cookie value |
| `secretFile` | _string_ | SecretFile is a file containing the secret used to encrypt/sign the cookie value<br/>instead of specifying it directly in the config. Secret takes precedence over SecretFile |
| `secret` | _[SecretSource](#secretsource)_ | Secret is the secret source used to encrypt/sign the cookie value |
| `domains` | _[]string_ | Domains is a list of domains for which the cookie is valid |
| `path` | _string_ | Path is the path for which the cookie is valid |
| `expire` | _duration_ | Expire is the duration before the cookie expires |
| `refresh` | _duration_ | Refresh is the duration after which the cookie is refreshable |
| `secure` | _bool_ | Secure indicates whether the cookie is only sent over HTTPS |
| `httpOnly` | _bool_ | HTTPOnly indicates whether the cookie is inaccessible to JavaScript |
| `sameSite` | _string_ | SameSite sets the SameSite attribute on the cookie |
| `csrfPerRequest` | _bool_ | CSRFPerRequest indicates whether a unique CSRF token is generated for each request<br/>Enables parallel requests from clients (e.g., multiple tabs) |
| `insecure` | _bool_ | Insecure indicates whether the cookie allows to be sent over HTTP<br/>Default is false, which requires HTTPS |
| `scriptAccess` | _[ScriptAccess](#scriptaccess)_ | ScriptAccess is a wrapper enum for HTTPOnly; indicates whether the<br/>cookie is accessible to JavaScript. Default is deny which translates<br/>to true for HTTPOnly, which helps mitigate certain XSS attacks |
| `sameSite` | _[SameSiteMode](#samesitemode)_ | SameSite sets the SameSite attribute on the cookie |
| `csrfPerRequest` | _bool_ | CSRFPerRequest indicates whether a unique CSRF token is generated for each request<br/>Enables parallel requests from clients (e.g., multiple tabs)<br/>Default is false, which uses a single CSRF token per session |
| `csrfPerRequestLimit` | _int_ | CSRFPerRequestLimit sets a limit on the number of valid CSRF tokens when CSRFPerRequest is enabled<br/>Used to prevent unbounded memory growth from storing too many tokens |
| `csrfExpire` | _duration_ | CSRFExpire sets the duration before a CSRF token expires |
### CookieStoreOptions
(**Appears on:** [SessionOptions](#sessionoptions))
CookieStoreOptions contains configuration options for the CookieSessionStore.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `minimal` | _bool_ | Minimal indicates whether to use minimal cookies for session storage<br/>Default is false |
### GitHubOptions
(**Appears on:** [Provider](#provider))
@ -510,9 +519,44 @@ AlphaConfig](https://oauth2-proxy.github.io/oauth2-proxy/configuration/alpha-con
However, [**the feature to implement multiple providers is not
complete**](https://github.com/oauth2-proxy/oauth2-proxy/issues/926).
### RedisStoreOptions
(**Appears on:** [SessionOptions](#sessionoptions))
RedisStoreOptions contains configuration options for the RedisSessionStore.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `connectionURL` | _string_ | ConnectionURL is the Redis connection URL |
| `username` | _string_ | Username is the Redis username |
| `password` | _string_ | Password is the Redis password |
| `useSentinel` | _bool_ | UseSentinel indicates whether to use Redis Sentinel<br/>Default is false |
| `sentinelPassword` | _string_ | SentinelPassword is the Redis Sentinel password |
| `sentinelMasterName` | _string_ | SentinelMasterName is the Redis Sentinel master name |
| `sentinelConnectionURLs` | _[]string_ | SentinelConnectionURLs is a list of Redis Sentinel connection URLs |
| `useCluster` | _bool_ | UseCluster indicates whether to use Redis Cluster<br/>Default is false |
| `clusterConnectionURLs` | _[]string_ | ClusterConnectionURLs is a list of Redis Cluster connection URLs |
| `caPath` | _string_ | CAPath is the path to the CA certificate for Redis TLS connections |
| `insecureSkipTLSVerify` | _bool_ | InsecureSkipTLSVerify indicates whether to skip TLS verification for Redis connections |
| `idleTimeout` | _int_ | IdleTimeout is the Redis connection idle timeout in seconds |
### SameSiteMode
#### (`string` alias)
(**Appears on:** [Cookie](#cookie))
### ScriptAccess
#### (`string` alias)
(**Appears on:** [Cookie](#cookie))
### SecretSource
(**Appears on:** [ClaimSource](#claimsource), [HeaderValue](#headervalue), [TLS](#tls))
(**Appears on:** [ClaimSource](#claimsource), [Cookie](#cookie), [HeaderValue](#headervalue), [TLS](#tls))
SecretSource references an individual secret value.
Only one source within the struct should be defined at any time.
@ -535,6 +579,26 @@ Server represents the configuration for an HTTP(S) server
| `secureBindAddress` | _string_ | SecureBindAddress is the address on which to serve secure traffic.<br/>Leave blank or set to "-" to disable. |
| `tls` | _[TLS](#tls)_ | TLS contains the information for loading the certificate and key for the<br/>secure traffic and further configuration for the TLS server. |
### SessionOptions
(**Appears on:** [AlphaOptions](#alphaoptions))
SessionOptions contains configuration options for the SessionStore providers.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `type` | _[SessionStoreType](#sessionstoretype)_ | Type is the type of session store to use<br/>Options are "cookie" or "redis"<br/>Default is "cookie" |
| `refresh` | _duration_ | Refresh is the duration after which the session is refreshable |
| `cookie` | _[CookieStoreOptions](#cookiestoreoptions)_ | Cookie is the configuration options for the CookieSessionStore |
| `redis` | _[RedisStoreOptions](#redisstoreoptions)_ | Redis is the configuration options for the RedisSessionStore |
### SessionStoreType
#### (`string` alias)
(**Appears on:** [SessionOptions](#sessionoptions))
### TLS
(**Appears on:** [Server](#server))

View File

@ -180,7 +180,7 @@ func NewOAuthProxy(opts *options.Options, validator func(string) bool) (*OAuthPr
refresh = fmt.Sprintf("after %s", opts.Session.Refresh)
}
logger.Printf("Cookie settings: name:%s insecure(http):%v nothttponly:%v expiry:%s domains:%s path:%s samesite:%s refresh:%s", opts.Cookie.Name, opts.Cookie.Insecure, opts.Cookie.NotHttpOnly, opts.Cookie.Expire, strings.Join(opts.Cookie.Domains, ","), opts.Cookie.Path, opts.Cookie.SameSite, refresh)
logger.Printf("Cookie settings: name:%s insecure(http):%v scriptaccess:%v expiry:%s domains:%s path:%s samesite:%s refresh:%s", opts.Cookie.Name, opts.Cookie.Insecure, opts.Cookie.ScriptAccess, opts.Cookie.Expire, strings.Join(opts.Cookie.Domains, ","), opts.Cookie.Path, opts.Cookie.SameSite, refresh)
trustedIPs := ip.NewNetSet()
for _, ipStr := range opts.TrustedIPs {

View File

@ -41,14 +41,18 @@ type AlphaOptions struct {
// To use the secure server you must configure a TLS certificate and key.
MetricsServer Server `yaml:"metricsServer,omitempty"`
// Providers is used to configure your provider. **Multiple-providers is not
// yet working.** [This feature is tracked in
// #925](https://github.com/oauth2-proxy/oauth2-proxy/issues/926)
// Providers is used to configure your provider.
// **Multiple-providers is not yet working.**
// [This feature is tracked in #925](https://github.com/oauth2-proxy/oauth2-proxy/issues/926)
Providers Providers `yaml:"providers,omitempty"`
// Cookie is used to configure the cookies used by OAuth2 Proxy.
// This includes session and CSRF cookies.
Cookie Cookie `yaml:"cookie,omitempty"`
// Session is used to configure session options used by OAuth2 Proxy.
// This includes session storage options.
Session SessionOptions `yaml:"session,omitempty"`
}
// Initialize alpha options with default values and settings of the core options
@ -68,6 +72,7 @@ func (a *AlphaOptions) ExtractFrom(opts *Options) {
a.MetricsServer = opts.MetricsServer
a.Providers = opts.Providers
a.Cookie = opts.Cookie
a.Session = opts.Session
}
// MergeOptionsWithDefaults replaces alpha options in the Options struct
@ -80,4 +85,5 @@ func (a *AlphaOptions) MergeOptionsWithDefaults(opts *Options) {
opts.MetricsServer = a.MetricsServer
opts.Providers = a.Providers
opts.Cookie = a.Cookie
opts.Session = a.Session
}

View File

@ -11,8 +11,6 @@ import (
const (
// DefaultCookieInsecure is the default value for Cookie.Insecure
DefaultCookieInsecure bool = false
// DefaultCookieNotHttpOnly is the default value for Cookie.NotHttpOnly
DefaultCookieNotHttpOnly bool = false
// DefaultCSRFPerRequest is the default value for Cookie.CSRFPerRequest
DefaultCSRFPerRequest bool = false
)
@ -26,6 +24,14 @@ const (
SameSiteDefault SameSiteMode = ""
)
type ScriptAccess string
const (
ScriptAccessDenied ScriptAccess = "deny"
ScriptAccessAllowed ScriptAccess = "allow"
ScriptAccessNone ScriptAccess = ""
)
// Cookie contains configuration options relating session and CSRF cookies
type Cookie struct {
// Name is the name of the cookie
@ -41,9 +47,10 @@ type Cookie struct {
// Insecure indicates whether the cookie allows to be sent over HTTP
// Default is false, which requires HTTPS
Insecure *bool `yaml:"insecure,omitempty"`
// NotHttpOnly is the inverse of HTTPOnly; indicates whether the cookie is accessible to JavaScript
// Default is false, which helps mitigate certain XSS attacks
NotHttpOnly *bool `yaml:"notHttpOnly,omitempty"`
// ScriptAccess is a wrapper enum for HTTPOnly; indicates whether the
// cookie is accessible to JavaScript. Default is deny which translates
// to true for HTTPOnly, which helps mitigate certain XSS attacks
ScriptAccess ScriptAccess `yaml:"scriptAccess,omitempty"`
// SameSite sets the SameSite attribute on the cookie
SameSite SameSiteMode `yaml:"sameSite,omitempty"`
// CSRFPerRequest indicates whether a unique CSRF token is generated for each request
@ -57,6 +64,8 @@ type Cookie struct {
CSRFExpire time.Duration `yaml:"csrfExpire,omitempty"`
}
// UnmarshalYAML unmarshalles the strings provided for the
// SameSite property to the enum type SameSiteMode
func (m *SameSiteMode) UnmarshalYAML(value *yaml.Node) error {
var s string
if err := value.Decode(&s); err != nil {
@ -71,6 +80,22 @@ func (m *SameSiteMode) UnmarshalYAML(value *yaml.Node) error {
}
}
// UnmarshalYAML unmarshalles the strings provided for the
// ScriptAccess property to the enum type ScriptAccess
func (sa *ScriptAccess) UnmarshalYAML(value *yaml.Node) error {
var s string
if err := value.Decode(&s); err != nil {
return err
}
switch ScriptAccess(s) {
case ScriptAccessAllowed, ScriptAccessDenied, ScriptAccessNone:
*sa = ScriptAccess(s)
return nil
default:
return fmt.Errorf("invalid script access: %s", s)
}
}
// GetSecret returns the cookie secret as a string from the SecretSource
func (c *Cookie) GetSecret() (string, error) {
secret, err := c.Secret.GetSecretValue()
@ -95,8 +120,8 @@ func (c *Cookie) EnsureDefaults() {
if c.Insecure == nil {
c.Insecure = ptr.To(DefaultCookieInsecure)
}
if c.NotHttpOnly == nil {
c.NotHttpOnly = ptr.To(DefaultCookieNotHttpOnly)
if c.ScriptAccess == ScriptAccessNone {
c.ScriptAccess = ScriptAccessDenied
}
if c.CSRFPerRequest == nil {
c.CSRFPerRequest = ptr.To(DefaultCSRFPerRequest)

View File

@ -1,10 +1,8 @@
package options
import (
"encoding/base64"
"time"
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
"github.com/spf13/pflag"
)
@ -46,10 +44,13 @@ func legacyCookieFlagSet() *pflag.FlagSet {
}
func (l *LegacyCookie) convert() Cookie {
// Invert Secure and HTTPOnly to match the new Cookie struct
// which uses Insecure and NotHttpOnly
// Invert Secure and use ScriptAccess property instead of
// HTTPOnly to match new Cookie struct
insecure := !l.Secure
notHTTPOnly := !l.HTTPOnly
scriptAccess := ScriptAccessDenied
if !l.HTTPOnly {
scriptAccess = ScriptAccessAllowed
}
var secret *SecretSource
if l.Secret != "" {
@ -67,7 +68,7 @@ func (l *LegacyCookie) convert() Cookie {
Path: l.Path,
Expire: l.Expire,
Insecure: &insecure,
NotHttpOnly: &notHTTPOnly,
ScriptAccess: scriptAccess,
SameSite: SameSiteMode(l.SameSite),
CSRFPerRequest: &l.CSRFPerRequest,
CSRFPerRequestLimit: l.CSRFPerRequestLimit,

View File

@ -1099,7 +1099,7 @@ var _ = Describe("Legacy Options", func() {
Path: "/",
Expire: time.Duration(168) * time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(false),
ScriptAccess: ScriptAccessDenied,
SameSite: "",
CSRFPerRequest: ptr.To(false),
CSRFPerRequestLimit: 0,

View File

@ -26,12 +26,17 @@ func MakeCookieFromOptions(req *http.Request, name string, value string, opts *o
domain = opts.Domains[len(opts.Domains)-1]
}
httpOnly := true
if opts.ScriptAccess == options.ScriptAccessAllowed {
httpOnly = false
}
c := &http.Cookie{
Name: name,
Value: value,
Path: opts.Path,
Domain: domain,
HttpOnly: !ptr.Deref(opts.NotHttpOnly, options.DefaultCookieNotHttpOnly),
HttpOnly: httpOnly,
Secure: !ptr.Deref(opts.Insecure, options.DefaultCookieInsecure),
SameSite: ParseSameSite(opts.SameSite),
}

View File

@ -114,14 +114,14 @@ var _ = Describe("Cookie Tests", func() {
name: validName,
value: "1",
opts: options.Cookie{
Name: validName,
Secret: options.SecretSource{Value: validSecret},
Domains: domains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Name: validName,
Secret: options.SecretSource{Value: validSecret},
Domains: domains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
expiration: 15 * time.Minute,
now: now,
@ -132,14 +132,14 @@ var _ = Describe("Cookie Tests", func() {
name: validName,
value: "1",
opts: options.Cookie{
Name: validName,
Secret: options.SecretSource{Value: validSecret},
Domains: domains,
Path: "",
Expire: time.Hour * -1,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Name: validName,
Secret: options.SecretSource{Value: validSecret},
Domains: domains,
Path: "",
Expire: time.Hour * -1,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
expiration: time.Hour * -1,
now: now,
@ -150,14 +150,14 @@ var _ = Describe("Cookie Tests", func() {
name: validName,
value: "1",
opts: options.Cookie{
Name: validName,
Secret: options.SecretSource{Value: validSecret},
Domains: domains,
Path: "",
Expire: 0,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Name: validName,
Secret: options.SecretSource{Value: validSecret},
Domains: domains,
Path: "",
Expire: 0,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
expiration: 0,
now: now,

View File

@ -30,7 +30,7 @@ var _ = Describe("CSRF Cookie with non-fixed name Tests", func() {
Path: cookiePath,
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(false),
ScriptAccess: options.ScriptAccessDenied,
CSRFPerRequest: ptr.To(true),
CSRFExpire: time.Duration(5) * time.Minute,
}

View File

@ -31,7 +31,7 @@ var _ = Describe("CSRF Cookie Tests", func() {
Path: cookiePath,
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(false),
ScriptAccess: options.ScriptAccessDenied,
CSRFPerRequest: ptr.To(false),
CSRFExpire: time.Hour,
}

View File

@ -50,11 +50,11 @@ var _ = Describe("NewSessionStore", func() {
Secret: options.SecretSource{
Value: secretValue,
},
Path: "/",
Expire: time.Duration(168) * time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(false),
SameSite: "",
Path: "/",
Expire: time.Duration(168) * time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessDenied,
SameSite: "",
}
})

View File

@ -67,13 +67,13 @@ func RunSessionStoreTests(newSS NewSessionStoreFunc, persistentFastForward Persi
// Set default options in CookieOptions
cookieOpts := &options.Cookie{
Name: "_oauth2_proxy",
Path: "/",
Expire: time.Duration(168) * time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(false),
SameSite: options.SameSiteDefault,
Secret: options.SecretSource{Value: cookieSecret},
Name: "_oauth2_proxy",
Path: "/",
Expire: time.Duration(168) * time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessDenied,
SameSite: options.SameSiteDefault,
Secret: options.SecretSource{Value: cookieSecret},
}
expires := time.Now().Add(1 * time.Hour)
@ -117,14 +117,14 @@ func RunSessionStoreTests(newSS NewSessionStoreFunc, persistentFastForward Persi
BeforeEach(func() {
input.sessionOpts.Refresh = time.Duration(2) * time.Hour
input.cookieOpts = &options.Cookie{
Name: "_cookie_name",
Path: "/path",
Expire: time.Duration(72) * time.Hour,
Insecure: ptr.To(true),
NotHttpOnly: ptr.To(true),
Domains: []string{"example.com"},
SameSite: options.SameSiteStrict,
Secret: options.SecretSource{Value: cookieSecret},
Name: "_cookie_name",
Path: "/path",
Expire: time.Duration(72) * time.Hour,
Insecure: ptr.To(true),
ScriptAccess: options.ScriptAccessAllowed,
Domains: []string{"example.com"},
SameSite: options.SameSiteStrict,
Secret: options.SecretSource{Value: cookieSecret},
}
var err error
@ -149,13 +149,13 @@ func RunSessionStoreTests(newSS NewSessionStoreFunc, persistentFastForward Persi
input.sessionOpts.Refresh = time.Duration(1) * time.Hour
input.cookieOpts = &options.Cookie{
Name: "_oauth2_proxy_file",
Path: "/",
Expire: time.Duration(168) * time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(false),
SameSite: options.SameSiteDefault,
Secret: options.SecretSource{FromFile: tmpfile.Name()},
Name: "_oauth2_proxy_file",
Path: "/",
Expire: time.Duration(168) * time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessDenied,
SameSite: options.SameSiteDefault,
Secret: options.SecretSource{FromFile: tmpfile.Name()},
}
ss, err = newSS(input.sessionOpts, input.cookieOpts)
Expect(err).ToNot(HaveOccurred())
@ -210,7 +210,14 @@ func CheckCookieOptions(in *testInput) {
It("have the correct HTTPOnly set", func() {
for _, cookie := range cookies {
Expect(cookie.HttpOnly).To(Equal(!(*in.cookieOpts.NotHttpOnly)))
var httpOnly bool
if in.cookieOpts.ScriptAccess == options.ScriptAccessAllowed {
httpOnly = false
}
if in.cookieOpts.ScriptAccess == options.ScriptAccessDenied {
httpOnly = true
}
Expect(cookie.HttpOnly).To(Equal(httpOnly))
}
})

View File

@ -74,14 +74,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with valid configuration",
cookie: options.Cookie{
Name: validName,
Secret: validSecret,
Domains: domains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Name: validName,
Secret: validSecret,
Domains: domains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
refresh: 15 * time.Minute,
errStrings: []string{},
@ -94,12 +94,12 @@ func TestValidateCookie(t *testing.T) {
Value: nil,
FromFile: "",
},
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
refresh: 15 * time.Minute,
errStrings: []string{
@ -109,14 +109,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with an invalid cookie secret",
cookie: options.Cookie{
Name: validName,
Secret: invalidSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Name: validName,
Secret: invalidSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
refresh: 15 * time.Minute,
errStrings: []string{
@ -126,14 +126,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with a valid Base64 secret",
cookie: options.Cookie{
Name: validName,
Secret: validBase64Secret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Name: validName,
Secret: validBase64Secret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
refresh: 15 * time.Minute,
errStrings: []string{},
@ -141,14 +141,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with an invalid Base64 secret",
cookie: options.Cookie{
Name: validName,
Secret: invalidBase64Secret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Name: validName,
Secret: invalidBase64Secret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
refresh: 15 * time.Minute,
errStrings: []string{
@ -158,14 +158,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with an invalid name",
cookie: options.Cookie{
Name: invalidName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Name: invalidName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
refresh: 15 * time.Minute,
errStrings: []string{
@ -175,14 +175,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with a name that is too long",
cookie: options.Cookie{
Name: longName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Name: longName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
refresh: 15 * time.Minute,
errStrings: []string{
@ -192,14 +192,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with refresh longer than expire",
cookie: options.Cookie{
Name: validName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: 15 * time.Minute,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Name: validName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: 15 * time.Minute,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
refresh: time.Hour,
errStrings: []string{
@ -209,14 +209,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with samesite \"none\"",
cookie: options.Cookie{
Name: validName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "none",
Name: validName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "none",
},
refresh: 15 * time.Minute,
errStrings: []string{},
@ -224,14 +224,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with samesite \"lax\"",
cookie: options.Cookie{
Name: validName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "none",
Name: validName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "none",
},
refresh: 15 * time.Minute,
errStrings: []string{},
@ -239,14 +239,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with samesite \"strict\"",
cookie: options.Cookie{
Name: validName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "none",
Name: validName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "none",
},
refresh: 15 * time.Minute,
errStrings: []string{},
@ -254,14 +254,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with samesite \"invalid\"",
cookie: options.Cookie{
Name: validName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "invalid",
Name: validName,
Secret: validSecret,
Domains: emptyDomains,
Path: "",
Expire: time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "invalid",
},
refresh: 15 * time.Minute,
errStrings: []string{
@ -271,14 +271,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with a combination of configuration errors",
cookie: options.Cookie{
Name: invalidName,
Secret: invalidSecret,
Domains: domains,
Path: "",
Expire: 15 * time.Minute,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "invalid",
Name: invalidName,
Secret: invalidSecret,
Domains: domains,
Path: "",
Expire: 15 * time.Minute,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "invalid",
},
refresh: time.Hour,
errStrings: []string{
@ -291,14 +291,14 @@ func TestValidateCookie(t *testing.T) {
{
name: "with session cookie configuration",
cookie: options.Cookie{
Name: validName,
Secret: validSecret,
Domains: domains,
Path: "",
Expire: 0,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(true),
SameSite: "",
Name: validName,
Secret: validSecret,
Domains: domains,
Path: "",
Expire: 0,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessAllowed,
SameSite: "",
},
refresh: 15 * time.Minute,
errStrings: []string{},
@ -310,12 +310,12 @@ func TestValidateCookie(t *testing.T) {
Secret: options.SecretSource{
FromFile: tmpfile.Name(),
},
Domains: domains,
Path: "",
Expire: 24 * time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(false),
SameSite: "",
Domains: domains,
Path: "",
Expire: 24 * time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessDenied,
SameSite: "",
},
refresh: 0,
errStrings: []string{},
@ -327,12 +327,12 @@ func TestValidateCookie(t *testing.T) {
Secret: options.SecretSource{
FromFile: "/nonexistent/file.txt",
},
Domains: domains,
Path: "",
Expire: 24 * time.Hour,
Insecure: ptr.To(false),
NotHttpOnly: ptr.To(false),
SameSite: "",
Domains: domains,
Path: "",
Expire: 24 * time.Hour,
Insecure: ptr.To(false),
ScriptAccess: options.ScriptAccessDenied,
SameSite: "",
},
refresh: 0,
errStrings: []string{"could not read cookie secret file: /nonexistent/file.txt"},