From d1ef14becc300ee2ad65c07a032daf51dac2ca01 Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Fri, 24 May 2019 17:06:48 +0100 Subject: [PATCH] Move cookie to pkg/encryption --- oauthproxy.go | 4 ++-- options.go | 6 +++--- pkg/apis/options/sessions.go | 6 ++---- pkg/apis/sessions/session_state.go | 8 ++++---- pkg/apis/sessions/session_state_test.go | 14 +++++++------- cookie/cookies.go => pkg/encryption/cipher.go | 2 +- .../encryption/cipher_test.go | 2 +- {cookie => pkg/encryption}/nonce.go | 2 +- pkg/sessions/cookie/session_store.go | 8 ++++---- pkg/sessions/redis/redis_store.go | 12 ++++++------ pkg/sessions/session_store_test.go | 6 +++--- pkg/sessions/utils/utils.go | 6 +++--- providers/provider_default.go | 6 +++--- providers/providers.go | 6 +++--- 14 files changed, 43 insertions(+), 45 deletions(-) rename cookie/cookies.go => pkg/encryption/cipher.go (99%) rename cookie/cookies_test.go => pkg/encryption/cipher_test.go (98%) rename {cookie => pkg/encryption}/nonce.go (93%) diff --git a/oauthproxy.go b/oauthproxy.go index 389b2a9..62d1a18 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -14,9 +14,9 @@ import ( "time" "github.com/mbland/hmacauth" - "github.com/pusher/oauth2_proxy/cookie" "github.com/pusher/oauth2_proxy/logger" sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions" + "github.com/pusher/oauth2_proxy/pkg/encryption" "github.com/pusher/oauth2_proxy/providers" "github.com/yhat/wsutil" ) @@ -555,7 +555,7 @@ func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request) { // OAuthStart starts the OAuth2 authentication flow func (p *OAuthProxy) OAuthStart(rw http.ResponseWriter, req *http.Request) { - nonce, err := cookie.Nonce() + nonce, err := encryption.Nonce() if err != nil { logger.Printf("Error obtaining nonce: %s", err.Error()) p.ErrorPage(rw, 500, "Internal Error", err.Error()) diff --git a/options.go b/options.go index 0460bce..2b506e3 100644 --- a/options.go +++ b/options.go @@ -17,10 +17,10 @@ import ( oidc "github.com/coreos/go-oidc" "github.com/dgrijalva/jwt-go" "github.com/mbland/hmacauth" - "github.com/pusher/oauth2_proxy/cookie" "github.com/pusher/oauth2_proxy/logger" "github.com/pusher/oauth2_proxy/pkg/apis/options" sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions" + "github.com/pusher/oauth2_proxy/pkg/encryption" "github.com/pusher/oauth2_proxy/pkg/sessions" "github.com/pusher/oauth2_proxy/providers" "gopkg.in/natefinch/lumberjack.v2" @@ -268,7 +268,7 @@ func (o *Options) Validate() error { } msgs = parseProviderInfo(o, msgs) - var cipher *cookie.Cipher + var cipher *encryption.Cipher if o.PassAccessToken || o.SetAuthorization || o.PassAuthorization || (o.CookieRefresh != time.Duration(0)) { validCookieSecretSize := false for _, i := range []int{16, 24, 32} { @@ -293,7 +293,7 @@ func (o *Options) Validate() error { len(secretBytes(o.CookieSecret)), suffix)) } else { var err error - cipher, err = cookie.NewCipher(secretBytes(o.CookieSecret)) + cipher, err = encryption.NewCipher(secretBytes(o.CookieSecret)) if err != nil { msgs = append(msgs, fmt.Sprintf("cookie-secret error: %v", err)) } diff --git a/pkg/apis/options/sessions.go b/pkg/apis/options/sessions.go index c72da3d..c96d490 100644 --- a/pkg/apis/options/sessions.go +++ b/pkg/apis/options/sessions.go @@ -1,13 +1,11 @@ package options -import ( - "github.com/pusher/oauth2_proxy/cookie" -) +import "github.com/pusher/oauth2_proxy/pkg/encryption" // SessionOptions contains configuration options for the SessionStore providers. type SessionOptions struct { Type string `flag:"session-store-type" cfg:"session_store_type" env:"OAUTH2_PROXY_SESSION_STORE_TYPE"` - Cipher *cookie.Cipher + Cipher *encryption.Cipher CookieStoreOptions RedisStoreOptions } diff --git a/pkg/apis/sessions/session_state.go b/pkg/apis/sessions/session_state.go index 01789ff..84c0dc9 100644 --- a/pkg/apis/sessions/session_state.go +++ b/pkg/apis/sessions/session_state.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/pusher/oauth2_proxy/cookie" + "github.com/pusher/oauth2_proxy/pkg/encryption" ) // SessionState is used to store information about the currently authenticated user session @@ -66,7 +66,7 @@ func (s *SessionState) String() string { } // EncodeSessionState returns string representation of the current session -func (s *SessionState) EncodeSessionState(c *cookie.Cipher) (string, error) { +func (s *SessionState) EncodeSessionState(c *encryption.Cipher) (string, error) { var ss SessionState if c == nil { // Store only Email and User when cipher is unavailable @@ -133,7 +133,7 @@ func legacyDecodeSessionStatePlain(v string) (*SessionState, error) { // legacyDecodeSessionState attempts to decode the session state string // generated by v3.1.0 or older -func legacyDecodeSessionState(v string, c *cookie.Cipher) (*SessionState, error) { +func legacyDecodeSessionState(v string, c *encryption.Cipher) (*SessionState, error) { chunks := strings.Split(v, "|") if c == nil { @@ -176,7 +176,7 @@ func legacyDecodeSessionState(v string, c *cookie.Cipher) (*SessionState, error) } // DecodeSessionState decodes the session cookie string into a SessionState -func DecodeSessionState(v string, c *cookie.Cipher) (*SessionState, error) { +func DecodeSessionState(v string, c *encryption.Cipher) (*SessionState, error) { var ssj SessionStateJSON var ss *SessionState err := json.Unmarshal([]byte(v), &ssj) diff --git a/pkg/apis/sessions/session_state_test.go b/pkg/apis/sessions/session_state_test.go index a48344e..c8ccff1 100644 --- a/pkg/apis/sessions/session_state_test.go +++ b/pkg/apis/sessions/session_state_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "github.com/pusher/oauth2_proxy/cookie" "github.com/pusher/oauth2_proxy/pkg/apis/sessions" + "github.com/pusher/oauth2_proxy/pkg/encryption" "github.com/stretchr/testify/assert" ) @@ -14,9 +14,9 @@ const secret = "0123456789abcdefghijklmnopqrstuv" const altSecret = "0000000000abcdefghijklmnopqrstuv" func TestSessionStateSerialization(t *testing.T) { - c, err := cookie.NewCipher([]byte(secret)) + c, err := encryption.NewCipher([]byte(secret)) assert.Equal(t, nil, err) - c2, err := cookie.NewCipher([]byte(altSecret)) + c2, err := encryption.NewCipher([]byte(altSecret)) assert.Equal(t, nil, err) s := &sessions.SessionState{ Email: "user@domain.com", @@ -54,9 +54,9 @@ func TestSessionStateSerialization(t *testing.T) { } func TestSessionStateSerializationWithUser(t *testing.T) { - c, err := cookie.NewCipher([]byte(secret)) + c, err := encryption.NewCipher([]byte(secret)) assert.Equal(t, nil, err) - c2, err := cookie.NewCipher([]byte(altSecret)) + c2, err := encryption.NewCipher([]byte(altSecret)) assert.Equal(t, nil, err) s := &sessions.SessionState{ User: "just-user", @@ -146,7 +146,7 @@ func TestExpired(t *testing.T) { type testCase struct { sessions.SessionState Encoded string - Cipher *cookie.Cipher + Cipher *encryption.Cipher Error bool } @@ -203,7 +203,7 @@ func TestDecodeSessionState(t *testing.T) { eString := string(eJSON) eUnix := e.Unix() - c, err := cookie.NewCipher([]byte(secret)) + c, err := encryption.NewCipher([]byte(secret)) assert.NoError(t, err) testCases := []testCase{ diff --git a/cookie/cookies.go b/pkg/encryption/cipher.go similarity index 99% rename from cookie/cookies.go rename to pkg/encryption/cipher.go index 0d354e1..c308330 100644 --- a/cookie/cookies.go +++ b/pkg/encryption/cipher.go @@ -1,4 +1,4 @@ -package cookie +package encryption import ( "crypto/aes" diff --git a/cookie/cookies_test.go b/pkg/encryption/cipher_test.go similarity index 98% rename from cookie/cookies_test.go rename to pkg/encryption/cipher_test.go index 500550e..fb6a4aa 100644 --- a/cookie/cookies_test.go +++ b/pkg/encryption/cipher_test.go @@ -1,4 +1,4 @@ -package cookie +package encryption import ( "encoding/base64" diff --git a/cookie/nonce.go b/pkg/encryption/nonce.go similarity index 93% rename from cookie/nonce.go rename to pkg/encryption/nonce.go index 6def148..69850c4 100644 --- a/cookie/nonce.go +++ b/pkg/encryption/nonce.go @@ -1,4 +1,4 @@ -package cookie +package encryption import ( "crypto/rand" diff --git a/pkg/sessions/cookie/session_store.go b/pkg/sessions/cookie/session_store.go index c40dd23..960be90 100644 --- a/pkg/sessions/cookie/session_store.go +++ b/pkg/sessions/cookie/session_store.go @@ -8,10 +8,10 @@ import ( "strings" "time" - "github.com/pusher/oauth2_proxy/cookie" "github.com/pusher/oauth2_proxy/pkg/apis/options" "github.com/pusher/oauth2_proxy/pkg/apis/sessions" "github.com/pusher/oauth2_proxy/pkg/cookies" + "github.com/pusher/oauth2_proxy/pkg/encryption" "github.com/pusher/oauth2_proxy/pkg/sessions/utils" ) @@ -28,7 +28,7 @@ var _ sessions.SessionStore = &SessionStore{} // interface that stores sessions in client side cookies type SessionStore struct { CookieOptions *options.CookieOptions - CookieCipher *cookie.Cipher + CookieCipher *encryption.Cipher } // Save takes a sessions.SessionState and stores the information from it @@ -53,7 +53,7 @@ func (s *SessionStore) Load(req *http.Request) (*sessions.SessionState, error) { // always http.ErrNoCookie return nil, fmt.Errorf("Cookie %q not present", s.CookieOptions.CookieName) } - val, _, ok := cookie.Validate(c, s.CookieOptions.CookieSecret, s.CookieOptions.CookieExpire) + val, _, ok := encryption.Validate(c, s.CookieOptions.CookieSecret, s.CookieOptions.CookieExpire) if !ok { return nil, errors.New("Cookie Signature not valid") } @@ -96,7 +96,7 @@ func (s *SessionStore) setSessionCookie(rw http.ResponseWriter, req *http.Reques // authentication details func (s *SessionStore) makeSessionCookie(req *http.Request, value string, now time.Time) []*http.Cookie { if value != "" { - value = cookie.SignedValue(s.CookieOptions.CookieSecret, s.CookieOptions.CookieName, value, now) + value = encryption.SignedValue(s.CookieOptions.CookieSecret, s.CookieOptions.CookieName, value, now) } c := s.makeCookie(req, s.CookieOptions.CookieName, value, s.CookieOptions.CookieExpire, now) if len(c.Value) > 4096-len(s.CookieOptions.CookieName) { diff --git a/pkg/sessions/redis/redis_store.go b/pkg/sessions/redis/redis_store.go index 82e941e..ed33d72 100644 --- a/pkg/sessions/redis/redis_store.go +++ b/pkg/sessions/redis/redis_store.go @@ -13,10 +13,10 @@ import ( "time" "github.com/go-redis/redis" - "github.com/pusher/oauth2_proxy/cookie" "github.com/pusher/oauth2_proxy/pkg/apis/options" "github.com/pusher/oauth2_proxy/pkg/apis/sessions" "github.com/pusher/oauth2_proxy/pkg/cookies" + "github.com/pusher/oauth2_proxy/pkg/encryption" ) // TicketData is a structure representing the ticket used in server session storage @@ -28,7 +28,7 @@ type TicketData struct { // SessionStore is an implementation of the sessions.SessionStore // interface that stores sessions in redis type SessionStore struct { - CookieCipher *cookie.Cipher + CookieCipher *encryption.Cipher CookieOptions *options.CookieOptions Client *redis.Client } @@ -106,7 +106,7 @@ func (store *SessionStore) Load(req *http.Request) (*sessions.SessionState, erro return nil, fmt.Errorf("error loading session: %s", err) } - val, _, ok := cookie.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire) + val, _, ok := encryption.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire) if !ok { return nil, fmt.Errorf("Cookie Signature not valid") } @@ -166,7 +166,7 @@ func (store *SessionStore) Clear(rw http.ResponseWriter, req *http.Request) erro return fmt.Errorf("error retrieving cookie: %v", err) } - val, _, ok := cookie.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire) + val, _, ok := encryption.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire) if !ok { return fmt.Errorf("Cookie Signature not valid") } @@ -186,7 +186,7 @@ func (store *SessionStore) Clear(rw http.ResponseWriter, req *http.Request) erro // makeCookie makes a cookie, signing the value if present func (store *SessionStore) makeCookie(req *http.Request, value string, expires time.Duration, now time.Time) *http.Cookie { if value != "" { - value = cookie.SignedValue(store.CookieOptions.CookieSecret, store.CookieOptions.CookieName, value, now) + value = encryption.SignedValue(store.CookieOptions.CookieSecret, store.CookieOptions.CookieName, value, now) } return cookies.MakeCookieFromOptions( req, @@ -230,7 +230,7 @@ func (store *SessionStore) getTicket(requestCookie *http.Cookie) (*TicketData, e } // An existing cookie exists, try to retrieve the ticket - val, _, ok := cookie.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire) + val, _, ok := encryption.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire) if !ok { // Cookie is invalid, create a new ticket return newTicket() diff --git a/pkg/sessions/session_store_test.go b/pkg/sessions/session_store_test.go index 47ad4b7..fd0b0e5 100644 --- a/pkg/sessions/session_store_test.go +++ b/pkg/sessions/session_store_test.go @@ -13,10 +13,10 @@ import ( "github.com/alicebob/miniredis" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/pusher/oauth2_proxy/cookie" "github.com/pusher/oauth2_proxy/pkg/apis/options" sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions" "github.com/pusher/oauth2_proxy/pkg/cookies" + "github.com/pusher/oauth2_proxy/pkg/encryption" "github.com/pusher/oauth2_proxy/pkg/sessions" sessionscookie "github.com/pusher/oauth2_proxy/pkg/sessions/cookie" "github.com/pusher/oauth2_proxy/pkg/sessions/redis" @@ -158,7 +158,7 @@ var _ = Describe("NewSessionStore", func() { BeforeEach(func() { By("Using a valid cookie with a different providers session encoding") broken := "BrokenSessionFromADifferentSessionImplementation" - value := cookie.SignedValue(cookieOpts.CookieSecret, cookieOpts.CookieName, broken, time.Now()) + value := encryption.SignedValue(cookieOpts.CookieSecret, cookieOpts.CookieName, broken, time.Now()) cookie := cookies.MakeCookieFromOptions(request, cookieOpts.CookieName, value, cookieOpts, cookieOpts.CookieExpire, time.Now()) request.AddCookie(cookie) @@ -354,7 +354,7 @@ var _ = Describe("NewSessionStore", func() { _, err := rand.Read(secret) Expect(err).ToNot(HaveOccurred()) cookieOpts.CookieSecret = base64.URLEncoding.EncodeToString(secret) - cipher, err := cookie.NewCipher(utils.SecretBytes(cookieOpts.CookieSecret)) + cipher, err := encryption.NewCipher(utils.SecretBytes(cookieOpts.CookieSecret)) Expect(err).ToNot(HaveOccurred()) Expect(cipher).ToNot(BeNil()) opts.Cipher = cipher diff --git a/pkg/sessions/utils/utils.go b/pkg/sessions/utils/utils.go index 051e9cc..1fb27f4 100644 --- a/pkg/sessions/utils/utils.go +++ b/pkg/sessions/utils/utils.go @@ -3,17 +3,17 @@ package utils import ( "encoding/base64" - "github.com/pusher/oauth2_proxy/cookie" "github.com/pusher/oauth2_proxy/pkg/apis/sessions" + "github.com/pusher/oauth2_proxy/pkg/encryption" ) // CookieForSession serializes a session state for storage in a cookie -func CookieForSession(s *sessions.SessionState, c *cookie.Cipher) (string, error) { +func CookieForSession(s *sessions.SessionState, c *encryption.Cipher) (string, error) { return s.EncodeSessionState(c) } // SessionFromCookie deserializes a session from a cookie value -func SessionFromCookie(v string, c *cookie.Cipher) (s *sessions.SessionState, err error) { +func SessionFromCookie(v string, c *encryption.Cipher) (s *sessions.SessionState, err error) { return sessions.DecodeSessionState(v, c) } diff --git a/providers/provider_default.go b/providers/provider_default.go index 4716014..d87b939 100644 --- a/providers/provider_default.go +++ b/providers/provider_default.go @@ -10,8 +10,8 @@ import ( "net/url" "time" - "github.com/pusher/oauth2_proxy/cookie" "github.com/pusher/oauth2_proxy/pkg/apis/sessions" + "github.com/pusher/oauth2_proxy/pkg/encryption" ) // Redeem provides a default implementation of the OAuth2 token redemption process @@ -96,12 +96,12 @@ func (p *ProviderData) GetLoginURL(redirectURI, state string) string { } // CookieForSession serializes a session state for storage in a cookie -func (p *ProviderData) CookieForSession(s *sessions.SessionState, c *cookie.Cipher) (string, error) { +func (p *ProviderData) CookieForSession(s *sessions.SessionState, c *encryption.Cipher) (string, error) { return s.EncodeSessionState(c) } // SessionFromCookie deserializes a session from a cookie value -func (p *ProviderData) SessionFromCookie(v string, c *cookie.Cipher) (s *sessions.SessionState, err error) { +func (p *ProviderData) SessionFromCookie(v string, c *encryption.Cipher) (s *sessions.SessionState, err error) { return sessions.DecodeSessionState(v, c) } diff --git a/providers/providers.go b/providers/providers.go index 57ace41..baf723d 100644 --- a/providers/providers.go +++ b/providers/providers.go @@ -1,8 +1,8 @@ package providers import ( - "github.com/pusher/oauth2_proxy/cookie" "github.com/pusher/oauth2_proxy/pkg/apis/sessions" + "github.com/pusher/oauth2_proxy/pkg/encryption" ) // Provider represents an upstream identity provider implementation @@ -15,8 +15,8 @@ type Provider interface { ValidateSessionState(*sessions.SessionState) bool GetLoginURL(redirectURI, finalRedirect string) string RefreshSessionIfNeeded(*sessions.SessionState) (bool, error) - SessionFromCookie(string, *cookie.Cipher) (*sessions.SessionState, error) - CookieForSession(*sessions.SessionState, *cookie.Cipher) (string, error) + SessionFromCookie(string, *encryption.Cipher) (*sessions.SessionState, error) + CookieForSession(*sessions.SessionState, *encryption.Cipher) (string, error) } // New provides a new Provider based on the configured provider string