You've already forked oauth2-proxy
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:
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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"})
|
||||
|
Reference in New Issue
Block a user