Django user permission inside template - django

I created a custom auth permission in django via admin site, and i added that permission to a user (not a group), now i want to ask if the request user in a template has it but nothing works.It's not a duplicate, i already checked similar questions and none of this work:
{% if perms.auth.add_something %}
{% if 'auth.add_something' in request.user.get_all_permissions %}
{% if request.user.has_perm('add_something') %}
I add my view:
class NotificationSelectView(View):
template = 'myapp/notification_read.html'
def get(self, request, *args, **kwargs):
t = tree(request)
req_var_list = []
analist = notifications_list(request.user)
level = LevelProcess.objects.get(
level_hierarchical = 3
)
subprocess= Process.objects.filter(level = level)
user = request.user
t.update({
'subprocess': subprocess,
'analist':analist,
})
return render(request, self.template, t)
The idea it's to make it inside template, not to use more code in views.
Any ideas ?, thanks in advance.

django in template it uses the variable perms for the permissions of the logged in user so you can use inside template
{% if perms.auth.add_something %}
{{do_smth}}
{% endif %}
from the django documentation there is a section Authentication data in templates which describes also permissions in templates

Related

Pass other object/data into Flask Admin model view edit template

I'm extending the edit template for a ModelView so that I can show some other information from the database that is relevant for determining how to edit the record in this view. I know how to extend the template and get it to work, but I can't figure out how to query an object and use it in the template.
Also I need to use the value from the model/record in querying the new object I need to pass.
Here is my code from init.py:
class MilestoneView(ModelView):
edit_template = '/admin/milestone_model/milestone_edit.html'
can_delete = True
#i need something like this to work:
referrals = Referral.query.filter_by(email=model.email)
#then i need to pass referrals into the template
admin = Admin(app, name="My App", template_mode='bootstrap3')
admin.add_view(MilestoneView(Milestone, db.session, name='Milestones'))
Then from milestone_edit.html, I want something like this to work:
{% extends 'admin/model/edit.html' %}
{% block body %}
{{ super() }}
{% for r in referrals %}
<p>{{ r.name }}</p>
{% endif %}
{% endblock %}
But of course the referrals object is not available to use in the template. How do I customize this ModelView in order to pass this object in from the init file? I've reviewed the available posts on this subject(ish) on here and haven't found an answer. Thanks in advance.
Override your view's render method, see code on Github, and test if the view being rendered is the edit view. Now you can inject any data into the kwargs parameter. For example:
class MilestoneView(ModelView):
def render(self, template, **kwargs):
# we are only interested in the edit page
if template == 'admin/model/milestone_edit.html':
# Get the model, this is just the first few lines of edit_view method
return_url = get_redirect_target() or self.get_url('.index_view')
if not self.can_edit:
return redirect(return_url)
id = get_mdict_item_or_list(request.args, 'id')
if id is None:
return redirect(return_url)
model = self.get_one(id)
if model is None:
flash(gettext('Record does not exist.'), 'error')
return redirect(return_url)
referrals = Referral.query.filter_by(email=model.email)
kwargs['referrals'] = referrals
return super(MilestoneView, self).render(template, **kwargs)
Note how the model is retrieved. This is a direct copy of the code in method edit_view code. Adjust the code for your use-case.
Use the variable referrals in your edit Jinja2 template.
The render method is called in the following routes for each view:
'/' - i.e. the list view code
'/new/' - code
'/edit/' - code
'/details/' - code

Restrict access to Django template

I need to restrict access to a template in Django. This is the scenario:
A guest user uses a form
If the form is validated and fine send the user to the example.com/success/ url.
If the guest user tries to send that link example.com/success to a friend. The friend will see that page as a 404.
I have no clue how to achieve this. Any ideas?
Instead of going to a different URL (/success/), you could just show something different when the form was properly filled. For example, in your view:
def my_view(request, ...):
form = ...
show_success = False
if ... post method ...:
if form.is_valid():
... save etc. ...
show_success = True
return render(request, ..., {'show_success': show_success})
In your template:
{% if show_success %}
Success message here
{% else %}
Form here
{% endif %}

how do I make a query of a user's uploaded files

I'm a django newbie trying to finish a upload/download app. I am Using django-registration-redux for user reg/auth and have the following simple model. I've read the docs but haven't been able figure out how to query on a User's related fields namely, fields of a model with foreignkey to User.
here's my model:
from django.contrib.auth.models import User
FileUploads(models.Model):
owner = models.ForeignKey(User)
docfile = models.FileField(nul=True)
docfileuuid = models.UUID()
My question being: Having a specific username, How can I query the list of his/her docfiles?
What I want to accomplish is when the user logs in and navigates through a view let's call it 'localhost:/yourfiles', s/he can be provided a list of his files.
In case of having no owner with foreign key to user, I used the following code to retreive the path to the all uploaded files:
obj = FileUploads.objects.all
uploads = [i.docfile for i in]
Now instead of all the docfiles, I want the ones that belong to the logged-in user.
I read the docs and tried things like:
obj = User.objects.all()
obj.fileuploads_set.all()
But no luck
When a user logs in your application, you do have user object in request.user
In your views.py,
def file_list_view(request):
# This gives you list of file objects.
files = FileUploads.objects.filter(owner=request.user)
return render_to_response('my_template.html', {'files': files})
In your template file
<ul>
{% for file in files %}
<li>{{ file.file_name }}</li>
{% endfor %}
</ul>
Hope this helps.
To get all files belong to a user by querying the username, do:
FileUploads.objects.filter(owner__usename='amir')
In your views.py, you would do:
uploads = FileUploads.objects.filter(owner=request.user)
You can create a simple function view with a context dictionary. Filter the files in your model by the current user logged in which you can get by request.user. And then in your template use a for loop to print all file urls that user has, and by using the {% empty %} template tag to show a message whenever a user doesn't have any files uploaded.
views.py
#login_required
def userfiles(request):
context_dict = {}
files = FileUploads.objects.filter(owner=request.user)
context_dict['files'] = files
return render(request, 'users_files.html', context_dict, )
the template:
{% for file in files %}
file.docfile.url
{% empty %}
You don't have any files uploaded yet.
{% endfor %}

how can I ensure a user will not delete another user object in my website [Django]

I wrote a function that allows the user to delete his article on a blog website. The problem is, if he plays a little with the url, he can access to another article and delete it.
What is the common strategy to avoid such cases with django?
here are the codes I wrote for the fonction:
views.py
def delete_article(request, id):
deleted = False
logged_user = get_logged_user_from_request(request) #that line allow to ensure that the user is connected. I use the session to achieve that instead of extending the User model
offer = get_object_or_404(Offer, id=id)
if request.method == 'POST':
offer.delete()
deleted = True
return render(request, 'offers/delete_article.html', locals())
urls.py
urlpatterns = patterns('article.views',
url(r'^send_article$', 'send_article', name='send_article'),
url(r'^my_articles$', 'show_my_articles', name='my_articles'),
url(r'^article/(?P<id>\d+)$', 'read', name='read'),
url(r'^articles$', 'show_articles', name='articles'),
url(r'^search_article$', 'search', name='search'),
url(r'^delete_article/(?P<id>\d+)$', 'delete_offer', name='delete_offer'),
)
delete_article.html
{% if not deleted %}
Hey, are you sure you want to delete {{ article.title }}?
<form method="POST">
{% csrf_token %}
<button type="submit" class="deleting_offer_button">delete</button>
</form>
{% elif deleted %}
<p>the article was successfully deleted</p>
get back to the homepage<br />
{% endif %}
As you can see, if the user change the numer of the id in the url, he can delete other article when he is directed to the confirmation of deleting page.
What webmasters are doing to ensure users cannot interfere with objects of other users?
HttpResponseForbidden can be used here which uses a 403 status code. A 403 response generally used when authentication was provided, but the authenticated user is not permitted to perform the requested operation.
Assuming you have author as an foreign key in Offer model, you can change your views like this:
In your views.py you have to import :
from django.http import HttpResponseForbidden
And then in your delete_article method use this code
offer = get_object_or_404(Offer, id=id)
if offer.author != request.user:
return HttpResponseForbidden()
When you get the article/offer. Make sure that the owner of that article is the authenticated user.
I'm not sure what your models look like but it would be something like
offer = get_object_or_404(Offer, id=id, author=logged_user)
This way if they don't own the article, it will 404

How do I write a template tag that shows if a user belongs to an app when that app isn't part of the context?

I have an app that has a FK to USER.
In ALL templates I need a template tag that tests to see if the logged in user is in that app.
For instance...
On every page I want to show a template block if the user is in the customer.approved set.
I've been playing with {% if approved in customer.approved %} - but I'm not getting anywhere.
Any suggestions welcome.
I think what you need is a filter, that checks if user is in your model (FK). So in your application_tags.py, you would do something like:
from django import template
from app.models import MyModel
register = template.Library()
#register.filter
def belongs_to_app(user):
if user.is_authenticated(): # Could be AnonymousUser
try:
# Check if there is a object with FK to logged user
m = MyModel.objects.get(user=user)
return True
except MyModel.DoesNotExist:
return False
return False
And in your template:
{% if user|belongs_to_app %}
....
{% endif %}
if yo set user perms you can write a context_processor so that:
def user_is_authorised(request):
if request.user.has_perm('myapp.can_view'):
return {'approved' : True}
else:
return {'approved' : False}
& include this in the CONTEXT_PROCESSORS settings.py tuple as 'myapp.context_processors.py'
more reading at:
https://docs.djangoproject.com/en/dev/topics/auth/#handling-object-permissions &
https://docs.djangoproject.com/en/dev/ref/templates/api/#django-contrib-auth-context-processors-auth
alternatively you can set the application in a session variable and then check this against your customer approved foreign key.