-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Move Cipher and Session Store initialisation out of Validation #577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
9d3368d
to
be4d65d
Compare
be4d65d
to
2234306
Compare
2234306
to
d59f97e
Compare
logging_handler_test.go
Outdated
opts.Logging.ExcludePaths = []string{"/ping"} | ||
} | ||
opts.RawRedirectURL = "localhost" | ||
validation.Validate(opts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've started altering these to:
err := validation.Validate(opts)
assert.NoError(t, err)
Wherever I saw them -- otherwise nil point deference panics were creeping in that were much harder to triage the issue quickly.
And my IDE yells at me whenever I try to commit with an unhandled error 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will replace some of them as I go through, don't want to expand the scope of the PR too much though so will only do it near where I've already changed stuff, can make this iterative
oauthproxy_test.go
Outdated
backendURL, _ := url.Parse(backend.URL) | ||
|
||
options := options.NewOptions() | ||
options := baseTestOptions() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've started renaming these to opts
whenever I saw them in tests as well. I think options
shadows the same name options
import.
return email == emailAddress | ||
}) | ||
if err != nil { | ||
panic(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to avoid panics in these helper structs and raised errors that any actual tests with a *testing.T
needed to handle and verify no errors myself.
Want to just leave them for now and I'll handle the cleanup in the msgpack sessions PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you've already sorted this in yours, then I'll leave them as panics and you can just clean up when you rebase if that's ok?
oauthproxy_test.go
Outdated
proxy, err := NewOAuthProxy(opts, func(email string) bool { | ||
return email == emailAddress | ||
}) | ||
assert.Equal(t, nil, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a benefit to this over assert.NoError(t, err)
or just a style preference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really, in fact NoError
is probably better, have changed a bunch
oauthproxy_test.go
Outdated
opts := options.NewOptions() | ||
opts := baseTestOptions() | ||
opts.Upstreams = append(opts.Upstreams, upstream.URL) | ||
opts.ClientID = "aljsal" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These aren't needed since the baseTestOptions
sets alternatives and it looks like we aren't asserting a future value is set to these in any of these tests.
I think this applies to most of these cases with lingering ClientID, ClientSecret, & Cookie.Secrets
oauthproxy_test.go
Outdated
opts.Cookie.Domains = []string{"abc"} | ||
store, err := cookie.NewCookieSessionStore(&opts.Session, &opts.Cookie) | ||
assert.Equal(t, err, nil) | ||
cipher, err := encryption.NewBase64Cipher(encryption.NewCFBCipher, encryption.SecretBytes(opts.Cookie.Secret)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be advantageous in 1 of these 2 tests to flip to the base64 version of the cookie secret option to get coverage of both formats
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've set this one to use the base64. I know what you mean, but ideally it shouldn't matter as we are testing that elsewhere, long term I'd like to see an end to end suite that allows us to flex this kind of thing, long term meaning very long term 😅
pkg/sessions/session_store.go
Outdated
|
||
// NewSessionStore creates a SessionStore from the provided configuration | ||
func NewSessionStore(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessions.SessionStore, error) { | ||
cipher, err := encryption.NewBase64Cipher(encryption.NewCFBCipher, encryption.SecretBytes(cookieOpts.Secret)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this potentially belong inside of the specific New<Type>SessionStore
where they can initialize from the cookieOpts.Secret
they have access to?
One of the things I'm looking at in the session state refactor is more variability of the cipher based on the security scenarios each store has.
At the moment I'm looking at the cookies themselves always using AES-CFB (since it doesn't have repeat IV weakness). But for the inner second encryption of DB store values, AES-GCM is much better suited.
This works fine with that design (since I intend to use CFB on all store's cookies) -- just was curious if we wanted to future proof ourselves a bit and give the particular session full control of its crypto algorithm decisions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the things I'm looking at in the session state refactor is more variability of the cipher based on the security scenarios each store has.
Hadn't really thought about this as it's not something we've done so far, we've always passed the same cipher through. That said, it makes a lot of sense!
I'll take a look at moving it in, or we could do that in another PR later, up to you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I moved it. We need to be vigilant about this and make sure that as we add more session stores that we ensure they're encrypted. I can't remember if the tests cover this or not, but if they don't we should make sure they do (I think there's a test that changes the cookie secret and ensures decryption fails)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good to me! I left some style/design questions that we can either work out here or I can sort out in #632 as that PR bumps into them.
d59f97e
to
7784639
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the tests as per your suggestions, where it made sense I think anyway, I think we can iterate on this as we make changes
I haven't looked at moving the initialisation into the session store just yet, will see if I can find some time
logging_handler_test.go
Outdated
opts.Logging.ExcludePaths = []string{"/ping"} | ||
} | ||
opts.RawRedirectURL = "localhost" | ||
validation.Validate(opts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will replace some of them as I go through, don't want to expand the scope of the PR too much though so will only do it near where I've already changed stuff, can make this iterative
oauthproxy_test.go
Outdated
proxy, err := NewOAuthProxy(opts, func(email string) bool { | ||
return email == emailAddress | ||
}) | ||
assert.Equal(t, nil, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really, in fact NoError
is probably better, have changed a bunch
return email == emailAddress | ||
}) | ||
if err != nil { | ||
panic(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you've already sorted this in yours, then I'll leave them as panics and you can just clean up when you rebase if that's ok?
oauthproxy_test.go
Outdated
opts.Cookie.Domains = []string{"abc"} | ||
store, err := cookie.NewCookieSessionStore(&opts.Session, &opts.Cookie) | ||
assert.Equal(t, err, nil) | ||
cipher, err := encryption.NewBase64Cipher(encryption.NewCFBCipher, encryption.SecretBytes(opts.Cookie.Secret)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've set this one to use the base64. I know what you mean, but ideally it shouldn't matter as we are testing that elsewhere, long term I'd like to see an end to end suite that allows us to flex this kind of thing, long term meaning very long term 😅
pkg/sessions/session_store.go
Outdated
|
||
// NewSessionStore creates a SessionStore from the provided configuration | ||
func NewSessionStore(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessions.SessionStore, error) { | ||
cipher, err := encryption.NewBase64Cipher(encryption.NewCFBCipher, encryption.SecretBytes(cookieOpts.Secret)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the things I'm looking at in the session state refactor is more variability of the cipher based on the security scenarios each store has.
Hadn't really thought about this as it's not something we've done so far, we've always passed the same cipher through. That said, it makes a lot of sense!
I'll take a look at moving it in, or we could do that in another PR later, up to you
edb321f
to
6e1b3b9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 🚀
Thanks for the review @NickMeves |
Description
Refactor the code to move the initialisation of the cipher and the session store out of the validation package. Validation should be static analysis of the options configured and should not be testing anything (eg connecting to redis)
Motivation and Context
Trying to simplify the validation code and give it a clear boundary on what it should and shouldn't be doing
How Has This Been Tested?
Unit tests only
Checklist: