Você está na página 1de 13

Desenvolvimento para a Internet e

Aplicações Móveis 2022/23

1
Django - Decoradores para gerir permissões

Objectivo:

Decoradores
@login_requi @user_passes @permission_
para gerir
permissões
red _test required !

2
1 - Decorador @login_required para restringir o acesso a uma view

Se o user não está logado, por defeito redireciona para settings.LOGIN_URL

from django.contrib.auth.decorators
import login_required

@login_required
def uma_funcao(request):
...

3
Se o objetivo, no caso de o user não estar logado, for redirecionar para outro
url, por exemplo para fazer o login:

from django.contrib.auth.decorators
import login_required

@login_required(login_url='/votacao/login')
def uma_funcao(request):
...

e neste caso o url '/login' deve estar parametrizado em urls.py :

from django.contrib.auth import views as auth_views


(…)
path('/login', auth_views.LoginView.as_view()),
(…)!

4
2 - Restringir o acesso a utilizadores que satisfazem um determinado teste,
por exemplo se o seu email termina com '@iscte-iul.pt' :

from django.contrib.auth.decorators
import user_passes_test

def email_check(user):
return user.email.endswith('@iscte-iul.pt')

@user_passes_test(email_check)
def uma_funcao(request):
...

ou então, se não satisfazem o teste são redirecionados para determinado url:

@user_passes_test(email_check,
login_url='votacao/login')
def uma_funcao(request):
... !

5
3 - Restringir o acesso a utilizadores que satisfazem determinada permissão
para manipular instâncias do modelo de dados:

Por defeito o Django atribui permissões para criar, atualizar e apagar


instâncias do modelo de dados. As permissões existentes por defeito são as
seguintes:

add: users com esta permissão podem criar instâncias do modelo de


dados.
delete: users com esta permissão podem apagar instâncias do
modelo de dados.
change: users com esta permissão podem atualizar instâncias do
modelo de dados.
view: users com esta permissão podem aceder e verificar o conteúdo
de instâncias do modelo de dados.

6
As permissões são identificadas por nomes. Estes nomes respeitam a seguinte
convenção: <nomedaapp>.<nomedaacao>_<nomedomodelo>, sempre em
caracteres minúsculos.

Para além das permissões predefinidas por defeito, podemos criar as nossas
permissões nos nossos modelos de dados. Por exemplo, para dar permissões
específicas a uma instância da classe Empregado começamos por obter o
objeto que contém todas as permissões e depois adicionamos-lhe uma nova
permissão, como no código seguinte:

from django.contrib.auth.models import Permission


from django.contrib.contenttypes.models import ContentType

conteudo = ContentType.objects.get_for_model(Empregado)

permissao =
Permission.objects.get(content_type=conteudo,

7
codename='is_member')

emp = Empregado.objects.create( … )
emp.save()
emp.user_permissions.add(permissao)

user.get_user_permissions() permite obter o nome de todas as


permissões desse user.

user.has_perm('nomedapermissao') retorna True se o user tem uma


dada permissão. Exemplo:

>>> from django.contrib.auth.models import User


>>> u = User.objects.create_user(username='Madalena')

8
>>> u.has_perm('auth.change_user')
False

Quando um user não tem determinada permissão, pode ser levantada uma
exceção do tipo PermissionDenied. Exemplos:

from django.core.exceptions import PermissionDenied

def users_list_view(request):
if not request.user.has_perm('auth.view_user'):
raise PermissionDenied()

9
ou então, com recurso a um decorador:

from django.contrib.auth.decorators import permission_required

@permission_required('auth.view_user')
def users_list_view(request):
( ... )

10
Por exemplo, para verificar a permissão de criar uma questão numa função
em views.py:

from django.contrib.auth.decorators import permission_required

@permission_required('votacao.add_questao')
def cria_questao(request):

ou então com o parâmetro login_url para enviar para uma página de login
caso a permissão não exista:

@permission_required('votacao.add_questao',
login_url='/votacao/login')
def cria_questao(request):

!

11
Quando o decorador não é verificado, por exemplo quando o utilizador não
está logado, ou quando não é administrador, é invocado o url login_url.
Para facilitar esta invocação pode ser utilizada a função reverse_lazy que
permite aceder ao namespace, da seguinte forma:

from django.urls import reverse_lazy

@login_required(
login_url=reverse_lazy('votacao:login'))
def voto(request, questao_id):
(…)

@permission_required('votacao.add_questao',
login_url=reverse_lazy('votacao:login'))
def criarquestao(request):
(…)

12
Finalmente, para verificar permissões em templates pode ser utilizada a
variável perms disponível no templates. Por exemplo, para tornar visível um
botão apenas se o user logado tiver permissão delete:

{% if perms.votacao.delete_questao %}
<input type='submit'> Apaga a Questão </input>
{% endif %}

13

Você também pode gostar