1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-08-08 22:46:33 +02:00

feat(cookie): add feature support for cookie-secret-file (#3104)

* feat: add feature support for cookie-secret-file

---------

Signed-off-by: Jan Larwig <jan@larwig.com>
Co-Authored-By: Sandy Chen <Yuxuan.Chen@morganstanley.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
This commit is contained in:
Sandy Chen
2025-07-23 01:59:55 +09:00
committed by GitHub
parent 137e59d526
commit dc8b1623a2
10 changed files with 226 additions and 36 deletions

View File

@ -3,6 +3,7 @@ package validation
import (
"fmt"
"net/http"
"os"
"sort"
"time"
@ -11,7 +12,7 @@ import (
)
func validateCookie(o options.Cookie) []string {
msgs := validateCookieSecret(o.Secret)
msgs := validateCookieSecret(o.Secret, o.SecretFile)
if o.Expire != time.Duration(0) && o.Refresh >= o.Expire {
msgs = append(msgs, fmt.Sprintf(
@ -49,9 +50,27 @@ func validateCookieName(name string) []string {
return msgs
}
func validateCookieSecret(secret string) []string {
if secret == "" {
return []string{"missing setting: cookie-secret"}
func validateCookieSecret(secret string, secretFile string) []string {
if secret == "" && secretFile == "" {
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)),
}
}
secretBytes := encryption.SecretBytes(secret)

View File

@ -1,6 +1,7 @@
package validation
import (
"os"
"strings"
"testing"
"time"
@ -29,9 +30,23 @@ func TestValidateCookie(t *testing.T) {
"a.cba.localhost",
}
// Create a temporary file for the valid secret file test
tmpfile, err := os.CreateTemp("", "cookie-secret-test")
if err != nil {
t.Fatalf("Failed to create temporary file: %v", err)
}
defer os.Remove(tmpfile.Name())
// Write a valid 32-byte secret to the file
_, err = tmpfile.Write([]byte(validSecret))
if err != nil {
t.Fatalf("Failed to write to temporary file: %v", err)
}
tmpfile.Close()
invalidNameMsg := "invalid cookie name: \"_oauth2;proxy\""
longNameMsg := "cookie name should be under 256 characters: cookie name is 260 characters"
missingSecretMsg := "missing setting: cookie-secret"
missingSecretMsg := "missing setting: cookie-secret or cookie-secret-file"
invalidSecretMsg := "cookie_secret must be 16, 24, or 32 bytes to create an AES cipher, but is 6 bytes"
invalidBase64SecretMsg := "cookie_secret must be 16, 24, or 32 bytes to create an AES cipher, but is 10 bytes"
refreshLongerThanExpireMsg := "cookie_refresh (\"1h0m0s\") must be less than cookie_expire (\"15m0s\")"
@ -271,6 +286,38 @@ func TestValidateCookie(t *testing.T) {
},
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: true,
HTTPOnly: true,
SameSite: "",
},
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: true,
HTTPOnly: true,
SameSite: "",
},
errStrings: []string{"could not read cookie secret file: /nonexistent/file.txt"},
},
}
for _, tc := range testCases {

View File

@ -48,7 +48,7 @@ func TestNewOptions(t *testing.T) {
assert.NotEqual(t, nil, err)
expected := errorMsg([]string{
"missing setting: cookie-secret",
"missing setting: cookie-secret or cookie-secret-file",
"provider has empty id: ids are required for all providers",
"provider missing setting: client-id",
"missing setting: client-secret or client-secret-file"})