-
Notifications
You must be signed in to change notification settings - Fork 62
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
Add support for optional login_required decorator to require user authentication #30
Add support for optional login_required decorator to require user authentication #30
Conversation
|
Thanks for opening these PRs - I'll try to take a look soon! |
I just want to point out that all three states of this feature are fully tested. Thanks for putting this together! |
# Reload settings - and all dependent modules - from scratch | ||
reload(sys.modules['watchman.settings']) | ||
reload(sys.modules['watchman.decorators']) | ||
reload(sys.modules['watchman.views']) |
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 it make sense to move these statements into a small reload_watchman_modules
utility function since we're doing the same thing over and over in these tests?
Secondly, I'm curious as to why this is necessary - is it to pick up the @override_settings
decorator you're using? Or is it just to guarantee that settings aren't being mixed and matched between tests?
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.
Yes, I think we could refactor this into a function, but I don't think that's strictly necessary because the three tests are the only times these modules will be reloaded. Let me know what you want me to do with this.
Reloading the modules is necessary to pick up the overridden settings, because simply overriding the settings doesn't re-run the
WATCHMAN_LOGIN = getattr(settings, 'WATCHMAN_LOGIN', False)
logic in settings.py
, or the
if settings.WATCHMAN_LOGIN:
....
logic in decorators.py
, or the
from watchman.decorators import token_required, login_required
logic in views.py
, but re-importing all of those modules in that specific order does.
The @override_settings
decorator automatically ensures that the settings do not propagate outside of the decorated test/s (it can also decorate classes).
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.
Ah, makes sense why it's needed now.
I'd be +1 to pulling it out into a small function (generally I like doing that the third time I find myself copy / pasting some code). I wouldn't be surprised if more tests are added which require the reload
as well (eg. once this and #31 are merged in, we may want to test the login_required
functionality on that view as well.
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'll pull the reload()
s out into their own functions then.
I'm not sure what we gain by testing the @login_required
decorator on different endpoints. The three states that test the decorator are:
WATCHMAN_LOGIN = False
, bypass the@login_required
check entirely for unauthenticated usersWATCHMAN_LOGIN = True
, which forAnonymousUser
should HTTP redirect to the site's login pageWATCHMAN_LOGIN = True
, which for authenticated users should return anHTTP 200
status and the normal status JSON
If we know the decorator works the way we want it to (eg: all three settings states are tested) on one endpoint, testing the decorator on an additional endpoint doesn't serve to test the decorator logic any more than is already done. We don't gain any more information about the decorator logic, and we have duplicated a part of our testing burden.
However, once #31 is merged in, we can switch these tests over to use that endpoint instead.
Your thoughts?
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.
Makes sense, thanks!
I'm a bit curious on your use-case for this change - we use automated monitoring of these endpoints heavily, and requiring a user to be logged in would make that difficult. Do you find yourself using watchman manually a lot (eg. checking in the browser)? |
I was planning on utilizing an OAuth client to check the status, which necessitates using the normal Django Put simply, I feel much more comfortable using a default, highly flexible, widely-deployed decorator (eg: There might also be interest in using the I'll fix up the current issues. |
Makes sense - we configure our token w/ an env var, and just load that in the settings file, however I can see the use of adding the built-in django auth as well. Just thinking about that a little bit, I guess that means that right now any user logged in to the site would be able to access the watchman status endpoint (or dashboard from #31) - I wonder if there should be a way to restrict it further to |
Yep, you are correct. There would probably have to be a corresponding permission check added in, which I can write if you like. |
It looks like there's a The built-in decorator may be "unofficial" (and subject to change, although it seems unlikely). Do you think there are use cases for all 3 levels (logged in, staff, superuser), or does it make more sense to pick the most common (I would imagine staff), and move forward with that? |
Hmmm...well, now I'm thinking I might want to refactor the code to allow users to simply point to their own authentication/authorization decorator in their settings, and then default to pointing to your Rough example:
How does that sound? An additional benefit is that it doesn't actually change the existing behavior (eg: using |
Yeah, that's interesting.. we could even provide our own auth decorators (eg. |
I would say simply test the Aside from Django deprecating one of their decorators (which I doubt will happen frequently, if at all), I would be against vendoring or wrapping any built-in decorators, simply because it would increase our testing burden for no real benefit. I am assuming that Django already has tests for the Does that make sense? |
Agree from a testing perspective, but I think that providing a few built-in decorators could be nicer from a UX point of view for devs who just want a basic Django auth decorator. Anyways, adding built in decorators would be simple enough to do in the future, so if you want to update the PR as you've described above, I'm good with that. Will need some doc updates as well about how to configure your own auth decorator. |
The
Update 2: Not sure what happened, but Travis tests passed. |
LGTM |
Add support for optional login_required decorator to require user authentication
This should allow Django's sessions, OAuth, HTTP Auth, etc. to be utilized to protect the status view.