Skip to content
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

Don't check for auth token during OPTIONS preflight #258

Merged
merged 9 commits into from
Sep 6, 2017

Conversation

SimonBiggs
Copy link

Details provided within #257

@@ -65,7 +65,7 @@ def prepare(self):
package.
"""
server_token = self.settings.get('kg_auth_token')
if server_token:
if (server_token != '') & (self.request.method != 'OPTIONS'):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@rolweber rolweber Sep 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if != '' is the correct check here. Could server_token be None instead of the empty string?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if server_token and self.request.method != 'OPTIONS':

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also looks like a test is failing because self.request does not exist.

Traceback (most recent call last):
  File "/home/travis/build/jupyter/kernel_gateway/kernel_gateway/tests/test_mixins.py", line 49, in test_no_token_required
    self.mixin.prepare()
  File "/home/travis/build/jupyter/kernel_gateway/kernel_gateway/mixins.py", line 68, in prepare
    if (server_token != '') & (self.request.method != 'OPTIONS'):
AttributeError: 'TestableTokenAuthHandler' object has no attribute 'request'

@parente
Copy link
Contributor

parente commented Sep 5, 2017

@SimonBiggs thanks for submitting this. I'm a little miffed why self.request is not available in prepare after glancing at the tornado source for the RequestHandler base class. Maybe it's a test case problem. Try fixing the if-statement per the comments above and let's see where we stand.

If you get stuck debugging the syntax and test problems, feel free to ping for help.

@SimonBiggs
Copy link
Author

SimonBiggs commented Sep 5, 2017

Thanks for the feedback. In https://github.com/jupyter/kernel_gateway/blob/master/kernel_gateway/gatewayapp.py the following is given:

@default('auth_token')
def _auth_token_default(self):
    return os.getenv(self.auth_token_env, '')

I think that makes it so that if auth_token isn't defined it will always be ''. I can explicitly test against '' or if I swap to using logical and instead of & I will also just be able to leave it as if server_token.

I'll update the pull request soon to account for non existing self.requests.method

@SimonBiggs
Copy link
Author

Is there a way to mock CORS requests within nose? I don't really know where to begin. Anyway, I'm just writing a test to cover this case with OPTIONS, however it would be nice to also test CORS + authentication token directly.

@@ -150,6 +150,20 @@ def _set_api():
self.assertRaises(ImportError, _set_api)

@gen_test
def test_options_and_auth_token(self):
"OPTIONS requests should not need to submit a token."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this triple-quoted so that it's a canonical docstring.

@parente
Copy link
Contributor

parente commented Sep 5, 2017

I haven't ever tried to mock a CORS request with Python. I think the test you've added to see if OPTIONS succeeds when a token is set provides enough test coverage and value.

@SimonBiggs
Copy link
Author

@parente Thanks for that.

@@ -64,8 +64,14 @@ def prepare(self):
with the `@web.authenticated` decorated methods in the notebook
package.
"""
request_is_options = False
if 'request' in dir(self):
Copy link
Contributor

@rolweber rolweber Sep 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is not needed, see my latest comment in the conversation.

(original review comment here:)
I'm not too firm in Python myself, but I think the calls to dir() are creating two temporary lists in this section, just to check whether there are attributes. Try the following instead (I haven't checked the exact syntax):

   request_is_options = hasattr(self, 'request') and getattr(self.request, 'method', '') == 'OPTIONS'

https://stackoverflow.com/a/610893/5629418
https://stackoverflow.com/a/611708/5629418
This could also be inlined below as

if server_token and not (...):

But looking further below, client_token is also read from self.request without checking whether that exists, and a request without method wouldn't make any sense. I agree with @parente that it is probably a problem with the test setup if self.request doesn't exist.

@@ -150,6 +150,20 @@ def _set_api():
self.assertRaises(ImportError, _set_api)

@gen_test
def test_options_and_auth_token(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please rename this to test_options_without_auth_token?

@rolweber
Copy link
Contributor

rolweber commented Sep 6, 2017

I found the error message after all...

   AttributeError: 'TestableTokenAuthHandler' object has no attribute 'request'

That's not from a Tornado test, but from some mock I set up to test the auth handler. There is exactly one test which doesn't set the request attribute:
https://github.com/SimonBiggs/kernel_gateway/blob/master/kernel_gateway/tests/test_mixins.py#L46

@SimonBiggs, could you please just copy the attrs = and self.mixin.request = lines from one of the other tests there, and get rid of the check for existence of self.request in the actual code?

@rolweber
Copy link
Contributor

rolweber commented Sep 6, 2017

@SimonBiggs: On second thought, could you add another test case for OPTIONS to the test_mixins.py file? The idea was to cover the complete logic of the auth mixin there.

@SimonBiggs
Copy link
Author

@rolweber @parente I think I managed to implement all of the feedback. Hope I didn't miss anything. This is a much nicer result.

Copy link
Contributor

@rolweber rolweber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this looks very nice. Thanks for flying several rounds :-)

@rolweber
Copy link
Contributor

rolweber commented Sep 6, 2017

@parente: I'll leave the final look and merge to you, in case I missed something.

@parente
Copy link
Contributor

parente commented Sep 6, 2017

LGTM to me. Thanks @SimonBiggs for the code and tests. 🍰 for your first contrib here.

@parente parente merged commit e92d5eb into jupyter-server:master Sep 6, 2017
@SimonBiggs
Copy link
Author

Thanks :). It's a pleasure :). Might this be able to be pushed out in a patch version release to pip?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants