Cancel permissions at some part of function (Django) - django

Is there any possibility to cancel permissions for some part of function, wich specified to function with #is_stuff decorator in Django (1.4.11) with python 2.7?
I mean the following:
#is_stuff(required_perms='<permissions>')
def my_function(request):
if request.POST['key']:
# do something as admin (1)
else:
# there I want to cancel permissions limitation (2)
I know that this is unusual using of decorators. And that decorators called before performing of function. But I am still interested is it possible? Maybe I can make something like this - dynamically change user.is_staff to True as in second link?
Related links where I didn't find answers:
Official docs, official docs (2nd link)

Related

Is there a way to programmatically find which account has been locked out in django-axes?

I would like to check which accounts have been locked out in django-axes. I know this can be done in admin site, but can I get this in a view.py as well?
To see a list of users that are locked you can do the following
from axes.models import AccessAttempt
AccessAttempt.objects.all().values_list('username', flat=True)
You can actually access django-axes just like any other model object. .objects.all() and then you can do some calculations with that.
The Axes documentation describes the AxesBaseHandler.is_locked method.
You can find its definition here.
I use is_locked in my code base - it takes a request and credentials, so it may not seem like the most convenient way to detect whether a user is locked out, but lock-out is determined not only by attempts, but can be configured based on ip-addr, cooldown period, etc.

Check multiple decorators before accessing a view in django

Im using #user_passes_test decorator to check whether the user has permissions to the view. Each usertype is given a function that is used with the decorator. Like this
#user_passes_test(ismanager,login_url='userauth:forbiddnpage')
#user_passes_test(isadministrator,login_url='userauth:forbiddnpage')
Now, if the first one returns false the forbidden page is shown. Is there any way i can get all the decorators to get checked before redirecting or giving access. Thanks for the help.
If you want to test multiple conditions for the same decorator, I suggest you write down a new one which uses user_passes_test and variable number of function name args. You can apply the conditions for ismanager and is_administrator and send the result in lambda to user_passes_test.
Motivation for doing this can be login_required decorator which internally uses user_passes_test in a similar way.
Also, using the same decorator multiple times like you are doing is making code dirty and is a little redundant, so this would be a better solution.

Django how to show errors like in debug mode when DEBUG=False

When DEBUG = False I know errors do get mailed to ADMINs, but I would like to see the errors on the screen if I am logged in as superuser.
Is there a way to trigger it to show the debug screen instead of the 500.html for public users?
As mentioned Sentry, or another service actually is a better choice. But for the case that you really want it your way, you would need a custom 500 handler and in there use django.views.debug.technical_500_response
https://docs.djangoproject.com/en/dev/_modules/django/views/debug/
There's no real documentation on this - except for a simple comment -, since it's a method that shouldn't really be used externally. But you're free to use it:
urls.py
urls.handler500 = views.handler500
views.py
def handler500(request):
if request.user.is_superuser():
return technical_500_response(some, params, dontaskme)
else:
return render(request, "500.html")
If you're not happy with the information generated in the emails, you're better off using something like Sentry to track what happens on your site so that you can see what users come up against.
It uses standard python logging so you can set what level sentry is triggered by, and have various messages in your app to tell you pieces of information, and it automatically picks up the warnings/errors that might occur. It gives you all the kind of information you get from the standard debug error page with the stacktrace, context information etc.

#login_required and is_authenticated() -- When to use which in Django?

I do not see a clear distinction between using #login_required decorator and is_authenticated(): somehow, I think they perform similar checks (though not exactly).
Let say I have a function in my views.py:
def dosomethingNow(request):
if request.user.is_authenticated():
//carry out the function
else:
//redirect to login page
Same function with login_required decorator:
#login_required
def dosomethingNow(request):
//carry out the function
Both the function does similar checks except that is_authenticated(), gives the option of redirecting to homepage if not logged in.
Any other benefits of using one over the other and places where they can't be used interchangeably?
Thanks
In the way you're using them in your example code, they're essentially equivalent.
Using user.is_aunthenticated is more flexible (as you note, you can decide what to do if they're not--output a different template, redirect to a login form, redirect somewhere else, etc.)
However, #login_required is "declarative", which can be nice. You could write a script that listed all of your view functions and whether or not they had the #login_required decorator around them, for instance, so you had a nice report of "login-required" sections of your site. When the checking happens in your own code buried inside the function, you lose that kind of possibility.
So it's a really a question of development style: do you need the flexibility to handle this as a special case? Or does make sense to use a declarative style?
(And, if you wanted a different implementation but a declarative style--say,if you frequently wanted to redirect non-logged-in-users to the homepage, you could write your own decorator, #homepage_if_not_auth, and use that)

How to link with intersphinx to django-specific constructs (like settings)?

With a proper intersphinx setup, you can link to Django classes from your own documentation like this:
:class:`django:django.db.models.Model`
But how do you link to a setting? Django uses its own :setting: construct for that instead of something build-in like :class:. How do I link to a setting with intersphinx?
I've tried various incantations, but none work (and some are probably plain wrong):
:ref:`django:ROOT_URLCONF`
:ref:`django:root_urlconf`
:setting:`django:ROOT_URLCONF`
:ref:`django:setting:ROOT_URLCONF`
:django:setting:`ROOT_URLCONF`
Errors like undefined label: django:root_urlconf and Unknown interpreted text role "setting" greet me.
The problem: my local sphinx did not know about Django's custom sphinx roles, like setting. So a perfectly fine intersphinx reference like this:
:django:setting:`ROOT_URLCONF`
does not work until you've told Sphinx about the intersphinx target's custom role.
In the end got it working by copying a small snippet from Django's sphinx extension as _ext/djangodocs.py next to my documentation:
def setup(app):
app.add_crossref_type(
directivename = "setting",
rolename = "setting",
indextemplate = "pair: %s; setting",
)
And I added the following to my Sphinx' conf.py:
import os
import sys
...
sys.path.append(
os.path.abspath(os.path.join(os.path.dirname(__file__), "_ext")))
# ^^^ I'll do that neater later on.
extensions = ['djangodocs',
# ^^^ I added that one.
'sphinx.ext.autodoc',
...
]
...
So: intersphinx works, but if you point at a custom role, you need to have that custom role defined locally.
You need to look at the objects.inv for django to figure out what the correct cross reference should be.
It appears that:
:std:setting:`ROOT_URLCONF <django:ROOT_URLCONF>`
should work.
Somehow I have the objects.inv for django but can't find the URL I retrieved it from, in theory it should be https://docs.djangoproject.com/en/1.4/objects.inv but that redirects several times eventually resulting in a file-not-found error.