Opened 9 years ago
Closed 5 years ago
#26480 closed Cleanup/optimization (fixed)
Allow sensitive_variables() to preserve the signature of its decorated function
Reported by: | tpazderka | Owned by: | Baptiste Mispelon |
---|---|---|---|
Component: | Error reporting | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
When the method authenticate
of a custom AuthenticationBackend is decorated with sensitive_variables
, inspect.getcallargs
will always match.
Calling the authenticate
function will attempt to call this backend with any set of credentials and will raise an uncaught TypeError
for an unmatching backend.
Authentication with such decorated backends used to work in version 1.6.
Change History (8)
comment:1 by , 9 years ago
comment:2 by , 9 years ago
It is a commit b89c2a5d9eb70ca36629ef657c98e3371e9a5c4f
.
comment:4 by , 9 years ago
Nothing apart from going back to the previous masking of TypeError... I think that these two behaviours go against each other...
comment:5 by , 9 years ago
Component: | contrib.auth → Error reporting |
---|---|
Summary: | TypeError in authenticate decorated by sensitive_variables → Allow sensitive_variables() to preserve the signature of its decorated function |
Triage Stage: | Unreviewed → Accepted |
Type: | Bug → New feature |
It might be possible to allow sensitive_variables
to preserve the signature of whatever it decorates. Here's code that works until @sensitive_variables
is added:
import inspect from django.views.decorators.debug import sensitive_variables class Backend(object): @sensitive_variables def authenticate(self, username=None, password=None): print(username) inspect.getcallargs(Backend().authenticate, username='foo', password='bar')
comment:6 by , 8 years ago
What about something like this:
def sensitive_variables(*variables): def decorator(func): @functools.wraps(func) def sensitive_variables_wrapper(*func_args, **func_kwargs): ... # Keep the original function for inspection in `authenticate` sensitive_variables_wrapper.sensitive_variables_func = func return sensitive_variables_wrapper return decorator
Function authenticate
would then check the sensitive_variables_func
first.
comment:7 by , 5 years ago
Has patch: | set |
---|---|
Owner: | changed from | to
Status: | new → assigned |
Type: | New feature → Cleanup/optimization |
I've looked into this and it turns out the issue lies with inspect.getcallargs
which doesn't follow the __wrapped__
attribute set by functools.wraps()
.
Using inspect.signature(...).bind(...)
instead of inspect.getcallargs(...)
fixes the issue (as an added bonus, getcallargs()
has been deprecated since Python 3.5 so removing it is a plus).
Could you please try bisecting to find the commit where the behavior changed?