git.iko.soy/typeable/oauth2-proxy
on master help sign in
Move Cipher intialisation to session store initialisation
commitc8dbf1cf60b15d36be128ea805fe57acfea0061b authorJoel Speed <joel.speed@hotmail.co.uk> dateMon 25 May 2020, 13:36 (6 years ago) parentd9af3ff
7 files changed+32−36
pkg/apis/options/sessions.go+2−5 pkg/sessions/cookie/session_store.go+2−2 pkg/sessions/redis/redis_store.go+2−2 pkg/sessions/redis/redis_store_test.go+11−2 pkg/sessions/session_store.go+7−2 pkg/sessions/session_store_test.go+8−14 pkg/validation/options.go−9
pkg/apis/options/sessions.go+2−5
@@ -1,12 +1,9 @@
11package options
22
3−import "github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
4−
53// SessionOptions contains configuration options for the SessionStore providers.
64type SessionOptions struct {
7− Type string `flag:"session-store-type" cfg:"session_store_type"`
8− Cipher encryption.Cipher `cfg:",internal"`
9− Redis RedisStoreOptions `cfg:",squash"`
5+ Type string `flag:"session-store-type" cfg:"session_store_type"`
6+ Redis RedisStoreOptions `cfg:",squash"`
107}
118
129// CookieSessionStoreType is used to indicate the CookieSessionStore should be
pkg/sessions/cookie/session_store.go+2−2
@@ -126,9 +126,9 @@ func (s *SessionStore) makeCookie(req *http.Request, name string, value string,
126126
127127// NewCookieSessionStore initialises a new instance of the SessionStore from
128128// the configuration given
129−func NewCookieSessionStore(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessions.SessionStore, error) {
129+func NewCookieSessionStore(opts *options.SessionOptions, cookieOpts *options.CookieOptions, cipher encryption.Cipher) (sessions.SessionStore, error) {
130130 return &SessionStore{
131− CookieCipher: opts.Cipher,
131+ CookieCipher: cipher,
132132 CookieOptions: cookieOpts,
133133 }, nil
134134}
pkg/sessions/redis/redis_store.go+2−2
@@ -39,7 +39,7 @@ type SessionStore struct {
3939
4040// NewRedisSessionStore initialises a new instance of the SessionStore from
4141// the configuration given
42−func NewRedisSessionStore(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessions.SessionStore, error) {
42+func NewRedisSessionStore(opts *options.SessionOptions, cookieOpts *options.CookieOptions, cipher encryption.Cipher) (sessions.SessionStore, error) {
4343 client, err := newRedisCmdable(opts.Redis)
4444 if err != nil {
4545 return nil, fmt.Errorf("error constructing redis client: %v", err)
@@ -47,7 +47,7 @@ func NewRedisSessionStore(opts *options.SessionOptions, cookieOpts *options.Cook
4747
4848 rs := &SessionStore{
4949 Client: client,
50− CookieCipher: opts.Cipher,
50+ CookieCipher: cipher,
5151 CookieOptions: cookieOpts,
5252 }
5353 return rs, nil
pkg/sessions/redis/redis_store_test.go+11−2
@@ -1,6 +1,7 @@
11package redis
22
33import (
4+ "crypto/rand"
45 "net/http"
56 "net/http/httptest"
67 "net/url"
@@ -10,11 +11,19 @@ import (
1011 "github.com/alicebob/miniredis/v2"
1112 "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options"
1213 "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions"
14+ "github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
1315 "github.com/stretchr/testify/assert"
1416 "github.com/stretchr/testify/require"
1517)
1618
1719func TestRedisStore(t *testing.T) {
20+ secret := make([]byte, 32)
21+ _, err := rand.Read(secret)
22+ assert.NoError(t, err)
23+
24+ cipher, err := encryption.NewBase64Cipher(encryption.NewCFBCipher, encryption.SecretBytes(string(secret)))
25+ assert.NoError(t, err)
26+
1827 t.Run("save session on redis standalone", func(t *testing.T) {
1928 redisServer, err := miniredis.Run()
2029 require.NoError(t, err)
@@ -25,7 +34,7 @@ func TestRedisStore(t *testing.T) {
2534 Host: redisServer.Addr(),
2635 }
2736 opts.Session.Redis.ConnectionURL = redisURL.String()
28− redisStore, err := NewRedisSessionStore(&opts.Session, &opts.Cookie)
37+ redisStore, err := NewRedisSessionStore(&opts.Session, &opts.Cookie, cipher)
2938 require.NoError(t, err)
3039 err = redisStore.Save(
3140 httptest.NewRecorder(),
@@ -49,7 +58,7 @@ func TestRedisStore(t *testing.T) {
4958 opts.Session.Redis.SentinelConnectionURLs = []string{sentinelURL.String()}
5059 opts.Session.Redis.UseSentinel = true
5160 opts.Session.Redis.SentinelMasterName = sentinel.MasterInfo().Name
52− redisStore, err := NewRedisSessionStore(&opts.Session, &opts.Cookie)
61+ redisStore, err := NewRedisSessionStore(&opts.Session, &opts.Cookie, cipher)
5362 require.NoError(t, err)
5463 err = redisStore.Save(
5564 httptest.NewRecorder(),
pkg/sessions/session_store.go+7−2
@@ -5,17 +5,22 @@ import (
55
66 "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options"
77 "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions"
8+ "github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
89 "github.com/oauth2-proxy/oauth2-proxy/pkg/sessions/cookie"
910 "github.com/oauth2-proxy/oauth2-proxy/pkg/sessions/redis"
1011)
1112
1213// NewSessionStore creates a SessionStore from the provided configuration
1314func NewSessionStore(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessions.SessionStore, error) {
15+ cipher, err := encryption.NewBase64Cipher(encryption.NewCFBCipher, encryption.SecretBytes(cookieOpts.Secret))
16+ if err != nil {
17+ return nil, fmt.Errorf("error initialising cipher: %v", err)
18+ }
1419 switch opts.Type {
1520 case options.CookieSessionStoreType:
16− return cookie.NewCookieSessionStore(opts, cookieOpts)
21+ return cookie.NewCookieSessionStore(opts, cookieOpts, cipher)
1722 case options.RedisSessionStoreType:
18− return redis.NewRedisSessionStore(opts, cookieOpts)
23+ return redis.NewRedisSessionStore(opts, cookieOpts, cipher)
1924 default:
2025 return nil, fmt.Errorf("unknown session store type '%s'", opts.Type)
2126 }
pkg/sessions/session_store_test.go+8−14
@@ -353,24 +353,11 @@ var _ = Describe("NewSessionStore", func() {
353353 SameSite: "strict",
354354 }
355355
356− var err error
357− ss, err = sessions.NewSessionStore(opts, cookieOpts)
358− Expect(err).ToNot(HaveOccurred())
359− })
360−
361− SessionStoreInterfaceTests(persistent)
362− })
363−
364− Context("with a cipher", func() {
365− BeforeEach(func() {
356+ // A secret is required but not defaulted
366357 secret := make([]byte, 32)
367358 _, err := rand.Read(secret)
368359 Expect(err).ToNot(HaveOccurred())
369360 cookieOpts.Secret = base64.URLEncoding.EncodeToString(secret)
370− cipher, err := encryption.NewBase64Cipher(encryption.NewCFBCipher, encryption.SecretBytes(cookieOpts.Secret))
371− Expect(err).ToNot(HaveOccurred())
372− Expect(cipher).ToNot(BeNil())
373− opts.Cipher = cipher
374361
375362 ss, err = sessions.NewSessionStore(opts, cookieOpts)
376363 Expect(err).ToNot(HaveOccurred())
@@ -384,9 +371,16 @@ var _ = Describe("NewSessionStore", func() {
384371 ss = nil
385372 opts = &options.SessionOptions{}
386373
374+ // A secret is required to create a Cipher, validation ensures it is the correct
375+ // length before a session store is initialised.
376+ secret := make([]byte, 32)
377+ _, err := rand.Read(secret)
378+ Expect(err).ToNot(HaveOccurred())
379+
387380 // Set default options in CookieOptions
388381 cookieOpts = &options.CookieOptions{
389382 Name: "_oauth2_proxy",
383+ Secret: base64.URLEncoding.EncodeToString(secret),
390384 Path: "/",
391385 Expire: time.Duration(168) * time.Hour,
392386 Refresh: time.Duration(1) * time.Hour,
pkg/validation/options.go−9
@@ -37,8 +37,6 @@ func Validate(o *options.Options) error {
3737 }
3838
3939 msgs := make([]string, 0)
40−
41− var cipher encryption.Cipher
4240 if o.Cookie.Secret == "" {
4341 msgs = append(msgs, "missing setting: cookie-secret")
4442 } else {
@@ -60,12 +58,6 @@ func Validate(o *options.Options) error {
6058 msgs = append(msgs,
6159 fmt.Sprintf("Cookie secret must be 16, 24, or 32 bytes to create an AES cipher. Got %d bytes.%s",
6260 len(encryption.SecretBytes(o.Cookie.Secret)), suffix))
63− } else {
64− var err error
65− cipher, err = encryption.NewBase64Cipher(encryption.NewCFBCipher, encryption.SecretBytes(o.Cookie.Secret))
66− if err != nil {
67− msgs = append(msgs, fmt.Sprintf("cookie-secret error: %v", err))
68− }
6961 }
7062 }
7163
@@ -218,7 +210,6 @@ func Validate(o *options.Options) error {
218210 }
219211 msgs = parseProviderInfo(o, msgs)
220212
221− o.Session.Cipher = cipher
222213 sessionStore, err := sessions.NewSessionStore(&o.Session, &o.Cookie)
223214 if err != nil {
224215 msgs = append(msgs, fmt.Sprintf("error initialising session storage: %v", err))