diff --git a/.pylintrc b/.pylintrc index 202755e250ae5fb0af422c2e8911fd074da0b6b3..d2e87aa0b47b1e4f6192ecb9eea10a638235c176 100644 --- a/.pylintrc +++ b/.pylintrc @@ -48,3 +48,4 @@ disable=print-statement, no-member, unused-import, fixme, # no TODOs + too-many-ancestors, diff --git a/requirements_dev.txt b/requirements_dev.txt index a93b314e63d0c40239e8e0f65d54d6c609b513f0..59987ffca874f7dce665b66db8ce184a67332c96 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,4 +1,5 @@ bandit==1.6.2 pylint==2.7.* pylint-django~=2.3.0 +django-cors-headers~=3.7.0 django-stubs diff --git a/rest_api/channelsmiddleware.py b/rest_api/channelsmiddleware.py index acc5559e8b76c9e56f0ae93312aaeddd68e1eb0c..782b33ce9c79ea0135ab6520722e0dda57e3904a 100644 --- a/rest_api/channelsmiddleware.py +++ b/rest_api/channelsmiddleware.py @@ -1,7 +1,7 @@ from urllib.parse import parse_qs -from django.conf import settings from channels.db import database_sync_to_async +from django.conf import settings from django.db import close_old_connections from jwt import decode as jwt_decode from rest_framework_simplejwt.exceptions import InvalidToken, TokenError @@ -35,7 +35,7 @@ class WebsocketJWTAuthMiddleware: try: # This will automatically validate the token and raise an error if token is invalid UntypedToken(token) - except (InvalidToken, TokenError) as e: + except (InvalidToken, TokenError): # Token is invalid return None else: diff --git a/rest_api/serializers.py b/rest_api/serializers.py index 42bc44db7a889793deff522d250d8a4ebfd04845..8a0f0205edcfb01afe4a8d300d1f61b3fe50eb88 100644 --- a/rest_api/serializers.py +++ b/rest_api/serializers.py @@ -4,11 +4,10 @@ from rest_framework import serializers from rest_framework_simplejwt.serializers import TokenObtainPairSerializer from rest_framework_simplejwt.tokens import RefreshToken -from vote.models import Election, Session, Application, Voter, VOTE_CHOICES, VOTE_CHOICES_NO_ABSTENTION, OpenVote, \ - VOTE_ACCEPT, Vote +from vote.models import Election, Session, Application, Voter -class TokenObtainVoterSerializer(serializers.Serializer): +class TokenObtainVoterSerializer(serializers.Serializer): # pylint: disable=W0223 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -24,11 +23,11 @@ class TokenObtainVoterSerializer(serializers.Serializer): except KeyError: pass - self.user = authenticate(**authenticate_kwargs) - if not self.user: + user = authenticate(**authenticate_kwargs) + if not user: raise serializers.ValidationError('could not authenticate user') - refresh = self.get_token(self.user) + refresh = self.get_token(user) data = { 'refresh': str(refresh), 'access': str(refresh.access_token), @@ -42,7 +41,7 @@ class TokenObtainVoterSerializer(serializers.Serializer): return token -class TokenObtainElectionManagerSerializer(TokenObtainPairSerializer): +class TokenObtainElectionManagerSerializer(TokenObtainPairSerializer): # pylint: disable=W0223 @classmethod def get_token(cls, user): token = super().get_token(user) diff --git a/rest_api/views.py b/rest_api/views.py index a434c8d3023ecedc8be54effa3c0f4a27a245691..7f516edc7e15955489d3b31fbd52275e0dcea327 100644 --- a/rest_api/views.py +++ b/rest_api/views.py @@ -89,3 +89,5 @@ class ElectionViewset(viewsets.ReadOnlyModelViewSet): return Response(data={'error': 'not found'}, status=status.HTTP_404_NOT_FOUND) application.delete() return Response(status=status.HTTP_204_NO_CONTENT) + + return Response(status=status.HTTP_400_BAD_REQUEST) diff --git a/vote/models.py b/vote/models.py index ad5a8fbac197312a66b2d3558c1f8442e6b4d390..22c5811a4c3831dc69e7696248ce87c51456b16d 100644 --- a/vote/models.py +++ b/vote/models.py @@ -271,7 +271,8 @@ class Voter(models.Model): email = email_name + '@' + domain_part.lower() return email - def email_user(self, subject, message, from_email=None, **kwargs) -> Tuple[Optional['Voter'], Optional[str]]: + def email_user(self, subject, message, from_email=None, **kwargs) -> Tuple[ + Optional['Voter'], Optional[str]]: # pylint: disable=E1136 """Send an email to this user.""" if self.email is not None: try: @@ -329,7 +330,8 @@ class Voter(models.Model): Voter.send_invitation(test_voter, "mock-up-access-token", from_email) - def send_invitation(self, access_code: str, from_email: str) -> Tuple[Optional['Voter'], Optional[str]]: + def send_invitation(self, access_code: str, from_email: str) -> Tuple[ + Optional['Voter'], Optional[str]]: # pylint: disable=E1136 if not self.email: return None, None subject = f'Invitation for {self.session.title}' diff --git a/wahlfang/settings.py b/wahlfang/settings.py index caafcd9c8368ee100c16358c12e39630e3758f79..f3ceb3a02143c05a207c7bf47c78dee690d3ce5c 100644 --- a/wahlfang/settings.py +++ b/wahlfang/settings.py @@ -12,11 +12,9 @@ https://docs.djangoproject.com/en/3.0/ref/settings/ import logging import os - # Build paths inside the project like this: os.path.join(BASE_DIR, ...) from datetime import timedelta -from corsheaders.defaults import default_headers from django.urls import reverse_lazy BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -52,7 +50,6 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'corsheaders', 'rest_framework', 'crispy_forms', 'vote', @@ -61,11 +58,13 @@ INSTALLED_APPS = [ 'channels', ] +if DEBUG: + INSTALLED_APPS += ['corsheaders'] + if EXPORT_PROMETHEUS_METRICS: INSTALLED_APPS += ['django_prometheus'] MIDDLEWARE = [ - 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', @@ -76,12 +75,16 @@ MIDDLEWARE = [ 'csp.middleware.CSPMiddleware', ] +if DEBUG: + MIDDLEWARE = ['corsheaders.middleware.CorsMiddleware'] + MIDDLEWARE + if EXPORT_PROMETHEUS_METRICS: MIDDLEWARE = ['django_prometheus.middleware.PrometheusBeforeMiddleware'] + \ MIDDLEWARE + \ ['django_prometheus.middleware.PrometheusAfterMiddleware'] -CORS_ALLOW_ALL_ORIGINS = True +if DEBUG: + CORS_ALLOW_ALL_ORIGINS = True ROOT_URLCONF = 'wahlfang.urls'