Browse Source

Bloqueia /voto-individual/ para usuários sem Votante/can_vote

Antes, usuários autenticados sem registro de Votante ou sem a
permissão parlamentares.can_vote recebiam HTTP 200 com um template
de erro (e, antes do commit anterior, ainda traziam o JS de auto-
reload). Agora a view exige as duas condições no início e retorna
HTTP 403 caso falhe:

- @permission_required('parlamentares.can_vote', raise_exception=True)
  garante a permissão (com raise_exception para 403 ao invés do
  redirect padrão pra LOGIN_URL).
- Checagem inline de Votante.objects.filter(user=...).exists() pega
  o caso de superusers (que passam pelo bypass automático de
  permissões do Django mas não têm cadastro de Votante) e de
  qualquer custom group que conceda can_vote sem o cadastro.

Mantém HTTP 200 com mensagem amigável para falhas de estado que
um votante legítimo pode encontrar (nenhuma matéria aberta,
parlamentar não presente na sessão).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pull/3831/head
joao 18 hours ago
parent
commit
62f0bbd389
  1. 44
      sapl/painel/views.py

44
sapl/painel/views.py

@ -3,8 +3,9 @@ import json
import logging import logging
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.decorators import (login_required, permission_required,
from django.core.exceptions import ObjectDoesNotExist user_passes_test)
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.urls import reverse from django.urls import reverse
from django.db.models import Q from django.db.models import Q
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse
@ -200,39 +201,22 @@ def can_vote(context, context_vars, request):
@login_required @login_required
@permission_required('parlamentares.can_vote', raise_exception=True)
def votante_view(request): def votante_view(request):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
username = request.user.username if request.user.is_authenticated else 'AnonymousUser' username = request.user.username
# Pega o votante relacionado ao usuário
template_name = 'painel/voto_individual.html'
context = {}
context_vars = {}
try: if not Votante.objects.filter(user=request.user).exists():
logger.debug(f'user={username}. Tentando obter objeto Votante com user={request.user}.') logger.warning(
if not request.user.is_anonymous and request.user.is_authenticated: f'user={username} sem cadastro de Votante tentou acessar /voto-individual/.'
votante = Votante.objects.get(user=request.user) )
else: raise PermissionDenied
raise ObjectDoesNotExist
except ObjectDoesNotExist: template_name = 'painel/voto_individual.html'
logger.error(f"user={username}. Usuário (user={request.user}) não cadastrado como votante na tela de parlamentares. "
"Contate a administração de sua Casa Legislativa!")
msg = _("Usuário não cadastrado como votante na tela de parlamentares. Contate a administração de sua Casa Legislativa!")
context.update({'error_message': msg})
return render(request, template_name, context)
context_vars = {'votante': votante}
context = {'head_title': str(_('Votação Individual'))} context = {'head_title': str(_('Votação Individual'))}
context_vars = {'votante': Votante.objects.get(user=request.user)}
# Verifica se usuário possui permissão para votar context, context_vars = can_vote(context, context_vars, request)
if 'parlamentares.can_vote' in request.user.get_all_permissions():
context, context_vars = can_vote(context, context_vars, request)
logger.debug("user=" + username + ". Verificando se usuário {} possui permissão para votar.".format(request.user))
else:
logger.error("user=" + username + ". Usuário {} sem permissão para votar.".format(request.user))
context.update({'permissao': False,
'error_message': 'Usuário sem permissão para votar.'})
# Salva o voto # Salva o voto
if request.method == 'POST': if request.method == 'POST':

Loading…
Cancel
Save