mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2026-10-04 05:31:23 +02:00
feat: support for session options in alpha config and refactoring of cookie options
Signed-off-by: Jan Larwig <jan@larwig.com>
This commit is contained in:
+11
-25
@@ -3,7 +3,6 @@ package validation
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
@@ -11,13 +10,13 @@ import (
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/encryption"
|
||||
)
|
||||
|
||||
func validateCookie(o options.Cookie) []string {
|
||||
msgs := validateCookieSecret(o.Secret, o.SecretFile)
|
||||
func validateCookie(o options.Cookie, refresh time.Duration) []string {
|
||||
msgs := validateCookieSecret(o.Secret)
|
||||
|
||||
if o.Expire != time.Duration(0) && o.Refresh >= o.Expire {
|
||||
if o.Expire != time.Duration(0) && refresh >= o.Expire {
|
||||
msgs = append(msgs, fmt.Sprintf(
|
||||
"cookie_refresh (%q) must be less than cookie_expire (%q)",
|
||||
o.Refresh.String(),
|
||||
refresh.String(),
|
||||
o.Expire.String()))
|
||||
}
|
||||
|
||||
@@ -50,30 +49,17 @@ func validateCookieName(name string) []string {
|
||||
return msgs
|
||||
}
|
||||
|
||||
func validateCookieSecret(secret string, secretFile string) []string {
|
||||
if secret == "" && secretFile == "" {
|
||||
func validateCookieSecret(secret options.SecretSource) []string {
|
||||
if len(secret.Value) == 0 && secret.FromFile == "" {
|
||||
return []string{"missing setting: cookie-secret or cookie-secret-file"}
|
||||
}
|
||||
if secret == "" && secretFile != "" {
|
||||
fileData, err := os.ReadFile(secretFile)
|
||||
if err != nil {
|
||||
return []string{"could not read cookie secret file: " + secretFile}
|
||||
}
|
||||
// Validate the file content as a secret
|
||||
secretBytes := encryption.SecretBytes(string(fileData))
|
||||
switch len(secretBytes) {
|
||||
case 16, 24, 32:
|
||||
// Valid secret size found
|
||||
return []string{}
|
||||
}
|
||||
// Invalid secret size found, return a message
|
||||
return []string{fmt.Sprintf(
|
||||
"cookie_secret from file must be 16, 24, or 32 bytes to create an AES cipher, but is %d bytes",
|
||||
len(secretBytes)),
|
||||
}
|
||||
|
||||
value, err := secret.GetSecretValue()
|
||||
if err != nil {
|
||||
return []string{fmt.Sprintf("error retrieving cookie secret: %v", err)}
|
||||
}
|
||||
|
||||
secretBytes := encryption.SecretBytes(secret)
|
||||
secretBytes := encryption.SecretBytes(string(value))
|
||||
// Check if the secret is a valid length
|
||||
switch len(secretBytes) {
|
||||
case 16, 24, 32:
|
||||
|
||||
+170
-152
@@ -18,10 +18,22 @@ func TestValidateCookie(t *testing.T) {
|
||||
invalidName := "_oauth2;proxy" // Separater character not allowed
|
||||
// 10 times the alphabet should be longer than 256 characters
|
||||
longName := strings.Repeat(alphabet, 10)
|
||||
validSecret := "secretthirtytwobytes+abcdefghijk"
|
||||
invalidSecret := "abcdef" // 6 bytes is not a valid size
|
||||
validBase64Secret := "c2VjcmV0dGhpcnR5dHdvYnl0ZXMrYWJjZGVmZ2hpams" // Base64 encoding of "secretthirtytwobytes+abcdefghijk"
|
||||
invalidBase64Secret := "YWJjZGVmCg" // Base64 encoding of "abcdef"
|
||||
validSecret := options.SecretSource{
|
||||
Value: []byte("secretthirtytwobytes+abcdefghijk"),
|
||||
}
|
||||
// 6 bytes is not a valid size
|
||||
invalidSecret := options.SecretSource{
|
||||
Value: []byte("abcdef"),
|
||||
}
|
||||
|
||||
// Base64 encoding of "secretthirtytwobytes+abcdefghijk"
|
||||
validBase64Secret := options.SecretSource{
|
||||
Value: []byte("c2VjcmV0dGhpcnR5dHdvYnl0ZXMrYWJjZGVmZ2hpams"),
|
||||
}
|
||||
// Base64 encoding of "abcdef"
|
||||
invalidBase64Secret := options.SecretSource{
|
||||
Value: []byte("YWJjZGVmCg"),
|
||||
}
|
||||
emptyDomains := []string{}
|
||||
domains := []string{
|
||||
"a.localhost",
|
||||
@@ -39,7 +51,7 @@ func TestValidateCookie(t *testing.T) {
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
||||
// Write a valid 32-byte secret to the file
|
||||
_, err = tmpfile.Write([]byte(validSecret))
|
||||
_, err = tmpfile.Write(validSecret.Value)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write to temporary file: %v", err)
|
||||
}
|
||||
@@ -56,36 +68,40 @@ func TestValidateCookie(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
cookie options.Cookie
|
||||
refresh time.Duration
|
||||
errStrings []string
|
||||
}{
|
||||
{
|
||||
name: "with valid configuration",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: domains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "",
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: domains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{},
|
||||
},
|
||||
{
|
||||
name: "with no cookie secret",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: "",
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "",
|
||||
Name: validName,
|
||||
Secret: options.SecretSource{
|
||||
Value: nil,
|
||||
FromFile: "",
|
||||
},
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{
|
||||
missingSecretMsg,
|
||||
},
|
||||
@@ -93,16 +109,16 @@ func TestValidateCookie(t *testing.T) {
|
||||
{
|
||||
name: "with an invalid cookie secret",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: invalidSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "",
|
||||
Name: validName,
|
||||
Secret: invalidSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{
|
||||
invalidSecretMsg,
|
||||
},
|
||||
@@ -110,31 +126,31 @@ func TestValidateCookie(t *testing.T) {
|
||||
{
|
||||
name: "with a valid Base64 secret",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: validBase64Secret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "",
|
||||
Name: validName,
|
||||
Secret: validBase64Secret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{},
|
||||
},
|
||||
{
|
||||
name: "with an invalid Base64 secret",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: invalidBase64Secret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "",
|
||||
Name: validName,
|
||||
Secret: invalidBase64Secret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{
|
||||
invalidBase64SecretMsg,
|
||||
},
|
||||
@@ -142,16 +158,16 @@ func TestValidateCookie(t *testing.T) {
|
||||
{
|
||||
name: "with an invalid name",
|
||||
cookie: options.Cookie{
|
||||
Name: invalidName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "",
|
||||
Name: invalidName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{
|
||||
invalidNameMsg,
|
||||
},
|
||||
@@ -159,16 +175,16 @@ 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,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "",
|
||||
Name: longName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{
|
||||
longNameMsg,
|
||||
},
|
||||
@@ -176,16 +192,16 @@ 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,
|
||||
Refresh: time.Hour,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "",
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: 15 * time.Minute,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "",
|
||||
},
|
||||
refresh: time.Hour,
|
||||
errStrings: []string{
|
||||
refreshLongerThanExpireMsg,
|
||||
},
|
||||
@@ -193,61 +209,61 @@ func TestValidateCookie(t *testing.T) {
|
||||
{
|
||||
name: "with samesite \"none\"",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "none",
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "none",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{},
|
||||
},
|
||||
{
|
||||
name: "with samesite \"lax\"",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "none",
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "none",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{},
|
||||
},
|
||||
{
|
||||
name: "with samesite \"strict\"",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "none",
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "none",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{},
|
||||
},
|
||||
{
|
||||
name: "with samesite \"invalid\"",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "invalid",
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: emptyDomains,
|
||||
Path: "",
|
||||
Expire: time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "invalid",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{
|
||||
invalidSameSiteMsg,
|
||||
},
|
||||
@@ -255,16 +271,16 @@ 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,
|
||||
Refresh: time.Hour,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "invalid",
|
||||
Name: invalidName,
|
||||
Secret: invalidSecret,
|
||||
Domains: domains,
|
||||
Path: "",
|
||||
Expire: 15 * time.Minute,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "invalid",
|
||||
},
|
||||
refresh: time.Hour,
|
||||
errStrings: []string{
|
||||
invalidNameMsg,
|
||||
invalidSecretMsg,
|
||||
@@ -275,55 +291,57 @@ func TestValidateCookie(t *testing.T) {
|
||||
{
|
||||
name: "with session cookie configuration",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: domains,
|
||||
Path: "",
|
||||
Expire: 0,
|
||||
Refresh: 15 * time.Minute,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(false),
|
||||
SameSite: "",
|
||||
Name: validName,
|
||||
Secret: validSecret,
|
||||
Domains: domains,
|
||||
Path: "",
|
||||
Expire: 0,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(true),
|
||||
SameSite: "",
|
||||
},
|
||||
refresh: 15 * time.Minute,
|
||||
errStrings: []string{},
|
||||
},
|
||||
{
|
||||
name: "with valid secret file",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: "",
|
||||
SecretFile: tmpfile.Name(),
|
||||
Domains: domains,
|
||||
Path: "",
|
||||
Expire: 24 * time.Hour,
|
||||
Refresh: 0,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(true),
|
||||
SameSite: "",
|
||||
Name: validName,
|
||||
Secret: options.SecretSource{
|
||||
FromFile: tmpfile.Name(),
|
||||
},
|
||||
Domains: domains,
|
||||
Path: "",
|
||||
Expire: 24 * time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(false),
|
||||
SameSite: "",
|
||||
},
|
||||
refresh: 0,
|
||||
errStrings: []string{},
|
||||
},
|
||||
{
|
||||
name: "with nonexistent secret file",
|
||||
cookie: options.Cookie{
|
||||
Name: validName,
|
||||
Secret: "",
|
||||
SecretFile: "/nonexistent/file.txt",
|
||||
Domains: domains,
|
||||
Path: "",
|
||||
Expire: 24 * time.Hour,
|
||||
Refresh: 0,
|
||||
Secure: ptr.To(true),
|
||||
HTTPOnly: ptr.To(true),
|
||||
SameSite: "",
|
||||
Name: validName,
|
||||
Secret: options.SecretSource{
|
||||
FromFile: "/nonexistent/file.txt",
|
||||
},
|
||||
Domains: domains,
|
||||
Path: "",
|
||||
Expire: 24 * time.Hour,
|
||||
Insecure: ptr.To(false),
|
||||
NotHttpOnly: ptr.To(false),
|
||||
SameSite: "",
|
||||
},
|
||||
refresh: 0,
|
||||
errStrings: []string{"could not read cookie secret file: /nonexistent/file.txt"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
errStrings := validateCookie(tc.cookie)
|
||||
errStrings := validateCookie(tc.cookie, tc.refresh)
|
||||
g := NewWithT(t)
|
||||
|
||||
g.Expect(errStrings).To(ConsistOf(tc.errStrings))
|
||||
|
||||
@@ -30,7 +30,7 @@ var _ = Describe("Headers", func() {
|
||||
Values: []options.HeaderValue{
|
||||
{
|
||||
SecretSource: &options.SecretSource{
|
||||
Value: []byte(base64.StdEncoding.EncodeToString([]byte("secret"))),
|
||||
Value: []byte(base64.RawStdEncoding.EncodeToString([]byte("secret"))),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -43,7 +43,7 @@ var _ = Describe("Headers", func() {
|
||||
ClaimSource: &options.ClaimSource{
|
||||
Claim: "email",
|
||||
BasicAuthPassword: &options.SecretSource{
|
||||
Value: []byte(base64.StdEncoding.EncodeToString([]byte("secret"))),
|
||||
Value: []byte(base64.RawStdEncoding.EncodeToString([]byte("secret"))),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
// Validate checks that required options are set and validates those that they
|
||||
// are of the correct format
|
||||
func Validate(o *options.Options) error {
|
||||
msgs := validateCookie(o.Cookie)
|
||||
msgs := validateCookie(o.Cookie, o.Session.Refresh)
|
||||
msgs = append(msgs, validateSessionCookieMinimal(o)...)
|
||||
msgs = append(msgs, validateRedisSessionStore(o)...)
|
||||
msgs = append(msgs, prefixValues("injectRequestHeaders: ", validateHeaders(o.InjectRequestHeaders)...)...)
|
||||
@@ -74,7 +74,7 @@ func Validate(o *options.Options) error {
|
||||
var redirectURL *url.URL
|
||||
redirectURL, msgs = parseURL(o.RawRedirectURL, "redirect", msgs)
|
||||
o.SetRedirectURL(redirectURL)
|
||||
if o.RawRedirectURL == "" && !ptr.Deref(o.Cookie.Secure, options.DefaultCookieSecure) && !o.ReverseProxy {
|
||||
if o.RawRedirectURL == "" && ptr.Deref(o.Cookie.Insecure, options.DefaultCookieInsecure) && !o.ReverseProxy {
|
||||
logger.Print("WARNING: no explicit redirect URL: redirects will default to insecure HTTP")
|
||||
}
|
||||
|
||||
|
||||
@@ -14,12 +14,15 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
cookieSecret = "secretthirtytwobytes+abcdefghijk"
|
||||
clientID = "bazquux"
|
||||
clientSecret = "xyzzyplugh"
|
||||
providerID = "providerID"
|
||||
)
|
||||
|
||||
var (
|
||||
cookieSecret = options.NewSecretSourceFromString("secretthirtytwobytes+abcdefghijk")
|
||||
)
|
||||
|
||||
func testOptions() *options.Options {
|
||||
o := options.NewOptions()
|
||||
o.UpstreamServers.Upstreams = append(o.UpstreamServers.Upstreams, options.Upstream{
|
||||
@@ -125,11 +128,11 @@ func TestCookieRefreshMustBeLessThanCookieExpire(t *testing.T) {
|
||||
o := testOptions()
|
||||
assert.Equal(t, nil, Validate(o))
|
||||
|
||||
o.Cookie.Secret = "0123456789abcdef"
|
||||
o.Cookie.Refresh = o.Cookie.Expire
|
||||
o.Cookie.Secret = options.NewSecretSourceFromString("0123456789abcdef")
|
||||
o.Session.Refresh = o.Cookie.Expire
|
||||
assert.NotEqual(t, nil, Validate(o))
|
||||
|
||||
o.Cookie.Refresh -= time.Duration(1)
|
||||
o.Session.Refresh -= time.Duration(1)
|
||||
assert.Equal(t, nil, Validate(o))
|
||||
}
|
||||
|
||||
@@ -138,23 +141,23 @@ func TestBase64CookieSecret(t *testing.T) {
|
||||
assert.Equal(t, nil, Validate(o))
|
||||
|
||||
// 32 byte, base64 (urlsafe) encoded key
|
||||
o.Cookie.Secret = "yHBw2lh2Cvo6aI_jn_qMTr-pRAjtq0nzVgDJNb36jgQ="
|
||||
o.Cookie.Secret = options.NewSecretSourceFromString("yHBw2lh2Cvo6aI_jn_qMTr-pRAjtq0nzVgDJNb36jgQ=")
|
||||
assert.Equal(t, nil, Validate(o))
|
||||
|
||||
// 32 byte, base64 (urlsafe) encoded key, w/o padding
|
||||
o.Cookie.Secret = "yHBw2lh2Cvo6aI_jn_qMTr-pRAjtq0nzVgDJNb36jgQ"
|
||||
o.Cookie.Secret = options.NewSecretSourceFromString("yHBw2lh2Cvo6aI_jn_qMTr-pRAjtq0nzVgDJNb36jgQ")
|
||||
assert.Equal(t, nil, Validate(o))
|
||||
|
||||
// 24 byte, base64 (urlsafe) encoded key
|
||||
o.Cookie.Secret = "Kp33Gj-GQmYtz4zZUyUDdqQKx5_Hgkv3"
|
||||
o.Cookie.Secret = options.NewSecretSourceFromString("Kp33Gj-GQmYtz4zZUyUDdqQKx5_Hgkv3")
|
||||
assert.Equal(t, nil, Validate(o))
|
||||
|
||||
// 16 byte, base64 (urlsafe) encoded key
|
||||
o.Cookie.Secret = "LFEqZYvYUwKwzn0tEuTpLA=="
|
||||
o.Cookie.Secret = options.NewSecretSourceFromString("LFEqZYvYUwKwzn0tEuTpLA==")
|
||||
assert.Equal(t, nil, Validate(o))
|
||||
|
||||
// 16 byte, base64 (urlsafe) encoded key, w/o padding
|
||||
o.Cookie.Secret = "LFEqZYvYUwKwzn0tEuTpLA"
|
||||
o.Cookie.Secret = options.NewSecretSourceFromString("LFEqZYvYUwKwzn0tEuTpLA")
|
||||
assert.Equal(t, nil, Validate(o))
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,11 @@ import (
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/encryption"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/sessions/redis"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/util/ptr"
|
||||
)
|
||||
|
||||
func validateSessionCookieMinimal(o *options.Options) []string {
|
||||
if !o.Session.Cookie.Minimal {
|
||||
if !ptr.Deref(o.Session.Cookie.Minimal, options.DefaultCookieStoreMinimal) {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
@@ -32,7 +33,7 @@ func validateSessionCookieMinimal(o *options.Options) []string {
|
||||
}
|
||||
}
|
||||
|
||||
if o.Cookie.Refresh != time.Duration(0) {
|
||||
if o.Session.Refresh != time.Duration(0) {
|
||||
msgs = append(msgs,
|
||||
"cookie_refresh > 0 requires oauth tokens in sessions. session_cookie_minimal cannot be set")
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/Bose/minisentinel"
|
||||
"github.com/alicebob/miniredis/v2"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/util/ptr"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
@@ -30,7 +31,7 @@ var _ = Describe("Sessions", func() {
|
||||
opts: &options.Options{
|
||||
Session: options.SessionOptions{
|
||||
Cookie: options.CookieStoreOptions{
|
||||
Minimal: false,
|
||||
Minimal: ptr.To(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -40,7 +41,7 @@ var _ = Describe("Sessions", func() {
|
||||
opts: &options.Options{
|
||||
Session: options.SessionOptions{
|
||||
Cookie: options.CookieStoreOptions{
|
||||
Minimal: false,
|
||||
Minimal: ptr.To(false),
|
||||
},
|
||||
},
|
||||
InjectRequestHeaders: []options.Header{
|
||||
@@ -62,7 +63,7 @@ var _ = Describe("Sessions", func() {
|
||||
opts: &options.Options{
|
||||
Session: options.SessionOptions{
|
||||
Cookie: options.CookieStoreOptions{
|
||||
Minimal: true,
|
||||
Minimal: ptr.To(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -72,7 +73,7 @@ var _ = Describe("Sessions", func() {
|
||||
opts: &options.Options{
|
||||
Session: options.SessionOptions{
|
||||
Cookie: options.CookieStoreOptions{
|
||||
Minimal: true,
|
||||
Minimal: ptr.To(true),
|
||||
},
|
||||
},
|
||||
InjectRequestHeaders: []options.Header{
|
||||
@@ -94,7 +95,7 @@ var _ = Describe("Sessions", func() {
|
||||
opts: &options.Options{
|
||||
Session: options.SessionOptions{
|
||||
Cookie: options.CookieStoreOptions{
|
||||
Minimal: true,
|
||||
Minimal: ptr.To(true),
|
||||
},
|
||||
},
|
||||
InjectResponseHeaders: []options.Header{
|
||||
@@ -116,7 +117,7 @@ var _ = Describe("Sessions", func() {
|
||||
opts: &options.Options{
|
||||
Session: options.SessionOptions{
|
||||
Cookie: options.CookieStoreOptions{
|
||||
Minimal: true,
|
||||
Minimal: ptr.To(true),
|
||||
},
|
||||
},
|
||||
InjectRequestHeaders: []options.Header{
|
||||
@@ -136,12 +137,11 @@ var _ = Describe("Sessions", func() {
|
||||
}),
|
||||
Entry("CookieRefresh conflict", &cookieMinimalTableInput{
|
||||
opts: &options.Options{
|
||||
Cookie: options.Cookie{
|
||||
Refresh: time.Hour,
|
||||
},
|
||||
Cookie: options.Cookie{},
|
||||
Session: options.SessionOptions{
|
||||
Refresh: time.Hour,
|
||||
Cookie: options.CookieStoreOptions{
|
||||
Minimal: true,
|
||||
Minimal: ptr.To(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -151,7 +151,7 @@ var _ = Describe("Sessions", func() {
|
||||
opts: &options.Options{
|
||||
Session: options.SessionOptions{
|
||||
Cookie: options.CookieStoreOptions{
|
||||
Minimal: true,
|
||||
Minimal: ptr.To(true),
|
||||
},
|
||||
},
|
||||
InjectResponseHeaders: []options.Header{
|
||||
@@ -323,7 +323,7 @@ var _ = Describe("Sessions", func() {
|
||||
Session: options.SessionOptions{
|
||||
Type: options.RedisSessionStoreType,
|
||||
Redis: options.RedisStoreOptions{
|
||||
UseSentinel: true,
|
||||
UseSentinel: ptr.To(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -340,7 +340,7 @@ var _ = Describe("Sessions", func() {
|
||||
Type: options.RedisSessionStoreType,
|
||||
Redis: options.RedisStoreOptions{
|
||||
Password: "abcdef123",
|
||||
UseSentinel: true,
|
||||
UseSentinel: ptr.To(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -357,7 +357,7 @@ var _ = Describe("Sessions", func() {
|
||||
Type: options.RedisSessionStoreType,
|
||||
Redis: options.RedisStoreOptions{
|
||||
Password: "zyxwtuv987",
|
||||
UseSentinel: true,
|
||||
UseSentinel: ptr.To(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -371,7 +371,7 @@ var _ = Describe("Sessions", func() {
|
||||
Session: options.SessionOptions{
|
||||
Type: options.RedisSessionStoreType,
|
||||
Redis: options.RedisStoreOptions{
|
||||
UseSentinel: true,
|
||||
UseSentinel: ptr.To(true),
|
||||
SentinelMasterName: "WRONG",
|
||||
},
|
||||
},
|
||||
@@ -386,7 +386,7 @@ var _ = Describe("Sessions", func() {
|
||||
Session: options.SessionOptions{
|
||||
Type: options.RedisSessionStoreType,
|
||||
Redis: options.RedisStoreOptions{
|
||||
UseSentinel: true,
|
||||
UseSentinel: ptr.To(true),
|
||||
SentinelConnectionURLs: []string{"redis://127.0.0.1:65535"},
|
||||
},
|
||||
},
|
||||
@@ -398,8 +398,8 @@ var _ = Describe("Sessions", func() {
|
||||
Session: options.SessionOptions{
|
||||
Type: options.RedisSessionStoreType,
|
||||
Redis: options.RedisStoreOptions{
|
||||
UseSentinel: true,
|
||||
UseCluster: true,
|
||||
UseSentinel: ptr.To(true),
|
||||
UseCluster: ptr.To(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user