Flask and Auth0 - How to check if user is authenticated in Jinja - flask

I'm using Auth0 for authentication in my Flask application, and wondering how to check if the user is authenticated in the Jinja template.
I'm wondering if there's a way to do something similar to how LoginManager does it:
{% if current_user.is_anonymous %} #<-- This here
<li>Login</li>
{% else %}
<li>Profile</li>
<li>Logout</li>
{% endif %}

you have two options:
using the global g object which is automatically available in templates with the before_app_request hook, read more on the official Flask tutorial:
#bp.before_app_request
def load_logged_in_user():
"""If a user id is stored in the session, load the user object from
the database into ``g.user``."""
user_id = session.get("user_id")
if user_id is None:
g.user = None
else:
g.user = (
get_db().execute("SELECT * FROM user WHERE id = ?", (user_id,)).fetchone()
)
and then in your template :
{% if g.user %}
<li><span>{{ g.user['username'] }}</span>
<li>Log Out
{% else %}
<li>Register
<li>Log In
{% endif %}
inject your current_user object to the context processor, flask-login is your good inspiration (without decorator) :
[..]
def _get_user():
if has_request_context() and not hasattr(_request_ctx_stack.top, 'user'):
current_app.login_manager._load_user()
return getattr(_request_ctx_stack.top, 'user', None)
[..]
def _user_context_processor():
return dict(current_user=_get_user())
and then get the current app (maybe you'll need to import current_app object in your case)
[..]
app.context_processor(_user_context_processor)
then you can use the current_user like :
{% if current_user.is_anonymous %} #<-- This here
<li>Login</li>
{% else %}
<li>Profile</li>
<li>Logout</li>
{% endif %}

Related

why django username parameters passed to urls is connecting directly and how prevent it

I'm trying to access to a user profil if urls parameters is profile/username
it work but i have a security problem because user is directly connected.
How i can define in django user profil access depending if user is authenticated or not
profil.html
{% if user.is_authenticated %}
<p>{{ user.username}}</p>
edit your profile
{% else %}
<p>{{ user.username}}</p>
<p>basic profile of user</p>
{% endif%}
views.py
def profil(request,username):
user=get_object_or_404(User, username=username)
context = {
'user':user
}
return render(request, 'service/profil.html',context)
You can use the login required decorator. Just add it to your view:
from django.contrib.auth.decorators import login_required
#login_required
def profil(request, username):
...
I fixed my problem condition was
{% if request.user == requested_user %}
<p>{{ requested_user.username}}</p>
edit your profile
{% else %}
<p>{{ requested_user.username}}</p>
<p>basic profile of user</p>
{% endif%}

Check if text exists in Django template context variable

This may not be the best way of doing this (open to suggestions). But I want to display a button on my home page depending on the value of a Boolean in the custom user model.
I am passing the value of this boolean via context in the view. But I can't seem to get the template logic to work.
Models.py
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
isAdmin = models.BooleanField(default = False,)
#more models...
views.py
from django.views.generic import TemplateView
from django.contrib.auth import get_user_model
from accounts.models import CustomUser
class HomePageView(TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
if self.request.user.is_authenticated:
adminStatus = CustomUser.objects.get(id=self.request.user.id)
print(adminStatus.isAdmin)
context['adminStatus'] = str(adminStatus.isAdmin)
return context
home page template.html
{% extends 'base.html' %}
{% block body %}
{% if user.is_authenticated %}
<h4>Hi {{ user.username }}!</h4>
<a class="btn btn-primary btn-lg" href="{% url 'dashboard' %}" role="button"> Go to Dashboard</a>
{% else %}
<p>You are not logged in</p>
login
</div>
{% if adminStatus == "True" %}
<h1>test</h1>
<div class = "adminPanel">
<a class="btn btn-primary btn-lg" href="{% url 'newEquipment' %}" role="button"> add new equipment</a>
</div>
{% endif %}
{% endif %}
{% endblock %}
I can't see the "newEquipment" button even though the adminStatus context is equal to "True", as verified by the print() command.
I have a feeling my template logic is not correct. I also tried:
{% if adminStatus contains "True" %}
In the view, context['adminStatus'] is defined only when the user is logged in. Meanwhile in the template, you are checking for adminStatus when the user is not logged in.
First the return context statement needs to be un-indented once, so that context (with or without adminStatus) is available regardless:
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
if self.request.user.is_authenticated:
adminStatus = CustomUser.objects.get(id=self.request.user.id)
context['adminStatus'] = adminStatus.isAdmin
return context
Next, yes you probably need to fix your template logic. Assuming you want to check for adminStatus only if the user is logged in, it should look like:
{% if user.is_authenticated %}
<h4>Hi {{ user.username }}!</h4>
...
{% if adminStatus %}
<h1>test</h1>
...
{% endif %}
{% else %}
<p>You are not logged in</p>
...
{% endif %}
Original answer:
In the view, you likely don't have to stringify adminStatus.isAdmin.
context['adminStatus'] = adminStatus.isAdmin
If passed to the context as a boolean, you should be able to use this expression in the template:
{% if adminStatus %}

No reverse match error but the function exists?

I am trying to implement a renew function for a key inventory system. But when I render that page, it shows a Reversematcherror even though I mapped the correct URL and used the correct function name.
Here is my template:(The URL tag is on the super long line all the way to the right)
{% block content %}
<h1>All Borrowed Keys</h1>
{% if keyinstance_list %}
<ul>
{% for keyinst in keyinstance_list %}
<li class="{% if keyinst.is_overdue %}text-danger{% endif %}">
{{keyinst.roomkey}}
({{ keyinst.due_back }})
{% if user.is_staff %}
- {{ keyinst.borrower }}
{% endif %}
{% if perms.catalog.can_mark_returned %}
- Renew
{% endif %}
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no keys borrowed.</p>
{% endif %}
{% endblock %}
My urls.py:
path('key/<uuid:pk>/renew/', views.renew_key_user, name='renew-key-user'),
path('key/<int:pk>/detail', views.KeyDetailView.as_view(), name='roomkey-detail'),
Views.py:
#permission_required('catalog.can_mark_returned')
def renew_key_user(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk = pk)
# If this is a POST request then process the Form data
if request.method == 'POST':
# Create a form instance and populate it with data from the request (binding):
form = RenewKeyForm(request.POST)
# Check if the form is valid:
if form.is_valid():
# process the data in form.cleaned_data as required (here we just write it to the model due_back field)
key_inst.due_back = form.cleaned_data['renewal_date']
key_inst.save()
# redirect to a new URL:
return HttpResponseRedirect(reverse('all-borrowed-keys') )
# If this is a GET (or any other method) create the default form.
else:
proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
form = RenewKeyForm(initial={'renewal_date': proposed_renewal_date,})
return render(request, 'catalog/roomkey_renew_user.html', {'form': form, 'keyinst':key_inst})
class KeyDetailView(generic.DetailView):
model = RoomKey
The error is saying
Reverse for 'views.renew_key_user' not found. 'views.renew_key_user'
is not a valid view function or pattern name.
Update this line in your template.
Renew
as name in url is renew-key-user
path('key/<uuid:pk>/renew/', views.renew_key_user, name='renew-key-user'),
Your URL name contains - hyphen not _ underscore
change this renew_key_user to renew-key-user in your template
Renew
Your template is asking for 'roomkey-detail' but the urls snippet you've provided only shows a url named 'renew-key-user'. Unless there are more url definitions you're not showing us, the code is failing as expected since it can't find a URL with the name you're asking for.

How to change template based on user authentication in django

If user successfully login i need to show one template. if user not login i need to show another template.
I created two templates one is base.html another one is base_login.html template.
IF user successfully login i need to call base_login.html other wise base.html. i am using below to achieve this. it's not giving expected result. How do achieve this?
{% if user.is_authenticated %}
<p>Welcome {{ user.username }} !!!</p>
{% extends "base_login.html" %}
{% else %}
{% extends "base.html" %}
{% endif %}
If your template goes invalid, I suggest you to it at the views.py, an example:
from django.shortcuts import render, render_to_response
def homepage(request):
template_name = 'homepage.html'
extended_template = 'base_login.html'
if request.user.is_authenticated():
extended_template = 'base.html'
return render(
request, template_name,
{'extended_template': extended_template, ...}
)
# homepage.html
{% extends extended_template %}
{% block content %}
{% if request.user.is_authenticated %}
Hello {{ request.user }}
{% endif %}
{% endif %}
Note: if function of render still doesn't work well, please try with render_to_response such as this answer: https://stackoverflow.com/a/1331183/6396981

Django 1.5 Creating multiple instances of model in ModelAdmin

I'm kind of puzzled with this task:
I have 2 tables: User, Codes
I want to generate randomly codes in a specific pattern.
I've already written that part as a function, but it's hard to implement the function
in the ModelAdmin.
So I would be very pleased if someone knows a trick to accomplish this.
It would be enough to have a button in the User form to envoke the function, which then creates these codes.
But how do I implement such a button?
Is there a way to to this?
EDIT: typo
SOLUTION:
Since I want to generate vouchers for a particular user I can edit the admin.py like this:
class MyUserAdmin(UserAdmin):
def vouchers(self, obj):
return "<a href='%s'>Generate vouchers</a>" % reverse(gen_voucher_view, kwargs={'user':obj.pk,})
vouchers.allow_tags = True
list_display = (..., 'vouchers')
which represents a clickable link in the admin view of my User model.
Now I connect the link to my view in urls.py by adding
url(r'admin/gen_vouchers/(?P<user>\w+)/$', gen_voucher_view, name='gen_voucher_view')
to urlpatterns.
For creating the vouchers I provide a form in forms.py
class VoucherGeneratorForm(forms.Form):
user = forms.CharField(User, required=True, widget=forms.HiddenInput())
amount = forms.IntegerField(min_value=0, max_value=500, required=True)
readonly = ('user', )
In views.py I'm adding my view function:
#login_required
def gen_voucher_view(request, user):
if request.method == 'POST': # If the form has been submitted...
form = VoucherGeneratorForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# GENERATE vouchers here by using form.cleaned_data['amount']
# and user (generate_vouchers is a self defined function)
vouchers = generate_vouchers(user, form.cleaned_data['amount']
# set error or info message
if len(vouchers) == form.cleaned_data['amount']:
messages.info(request, "Successfully generated %d voucher codes for %s" % (form.cleaned_data['amount'], user))
else:
messages.error(request, "Something went wrong")
u = User.objects.get(pk=user)
form = VoucherGeneratorForm(initial={'user':user}) # An unbound form
return render_to_response('admin/codes.html', {'request': request, 'user':user, 'form':form, 'userobj': u}, context_instance=RequestContext(request))
else:
form = VoucherGeneratorForm(initial={'user':user}) # An unbound form
Last but not least create a template admin/codes.html where my form is displayed:
{% extends "admin/base_site.html" %}
{% load i18n admin_static static %}
{% block breadcrumbs %}
<div class="breadcrumbs">
{% trans 'Home' %}
›
{% trans 'Users' %}
›
{% trans 'Vouchercodes' %}
›
Voucher Generator
</div>
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}" />{% endblock %}
{% block content %}
<div id="content-main">
{% if request.user.is_active and request.user.is_staff or userobj and userobj.is_active and userobj.is_staff %}
<h1 id="generator_title">Generate vouchers for {{user}}</h1>
<form id="formular_generator" action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<table>{{ form }}</table>
<button id="generatebutton" type="submit" name="action" value="generate">Generate</input>
</form>
{% else %}
<p>{% trans "You don't have permission to access this site." %}</p>
</div>
{% endif %}
{% endblock %}
{% block sidebar %}
{% endblock %}
Done!
To export them in a pdf I used admin actions, as propsed by Sumeet Dhariwal below.
U mean that you need to run a script from within the admin ?
If so check out django-admin-tools
http://django-admin-tools.readthedocs.org/en/latest/dashboard.html
SOLUTION FOUND:
no that was not what i meant, because I want to generate vouchers for 1 particular user and not for more, but that's a good remark.