NDOJ/judge/views/mailgun.py

94 lines
3.5 KiB
Python
Raw Permalink Normal View History

2020-01-21 06:35:58 +00:00
import hashlib
import hmac
import logging
from email.utils import parseaddr
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import View
from registration.models import RegistrationProfile
from judge.utils.unicode import utf8bytes
2022-05-14 17:57:27 +00:00
logger = logging.getLogger("judge.mail.activate")
2020-01-21 06:35:58 +00:00
class MailgunActivationView(View):
2022-05-14 17:57:27 +00:00
if hasattr(settings, "MAILGUN_ACCESS_KEY"):
2020-01-21 06:35:58 +00:00
def post(self, request, *args, **kwargs):
params = request.POST
2022-05-14 17:57:27 +00:00
timestamp = params.get("timestamp", "")
token = params.get("token", "")
signature = params.get("signature", "")
2020-01-21 06:35:58 +00:00
2022-05-14 17:57:27 +00:00
logger.debug("Received request: %s", params)
2020-01-21 06:35:58 +00:00
2022-05-14 17:57:27 +00:00
if (
signature
!= hmac.new(
key=utf8bytes(settings.MAILGUN_ACCESS_KEY),
msg=utf8bytes("%s%s" % (timestamp, token)),
digestmod=hashlib.sha256,
).hexdigest()
):
logger.info(
"Rejected request: signature: %s, timestamp: %s, token: %s",
signature,
timestamp,
token,
)
2020-01-21 06:35:58 +00:00
raise PermissionDenied()
2022-05-14 17:57:27 +00:00
_, sender = parseaddr(params.get("from"))
2020-01-21 06:35:58 +00:00
if not sender:
2022-05-14 17:57:27 +00:00
logger.info("Rejected invalid sender: %s", params.get("from"))
2020-01-21 06:35:58 +00:00
return HttpResponse(status=406)
try:
user = User.objects.get(email__iexact=sender)
except (User.DoesNotExist, User.MultipleObjectsReturned):
2022-05-14 17:57:27 +00:00
logger.info(
"Rejected unknown sender: %s: %s", sender, params.get("from")
)
2020-01-21 06:35:58 +00:00
return HttpResponse(status=406)
try:
registration = RegistrationProfile.objects.get(user=user)
except RegistrationProfile.DoesNotExist:
2022-05-14 17:57:27 +00:00
logger.info(
"Rejected sender without RegistrationProfile: %s: %s",
sender,
params.get("from"),
)
2020-01-21 06:35:58 +00:00
return HttpResponse(status=406)
if registration.activated:
2022-05-14 17:57:27 +00:00
logger.info(
"Rejected activated sender: %s: %s", sender, params.get("from")
)
2020-01-21 06:35:58 +00:00
return HttpResponse(status=406)
key = registration.activation_key
2022-05-14 17:57:27 +00:00
if key in params.get("body-plain", "") or key in params.get(
"body-html", ""
):
if RegistrationProfile.objects.activate_user(
key, get_current_site(request)
):
logger.info("Activated sender: %s: %s", sender, params.get("from"))
return HttpResponse("Activated", status=200)
logger.info(
"Failed to activate sender: %s: %s", sender, params.get("from")
)
2020-01-21 06:35:58 +00:00
else:
2022-05-14 17:57:27 +00:00
logger.info(
"Activation key not found: %s: %s", sender, params.get("from")
)
2020-01-21 06:35:58 +00:00
return HttpResponse(status=406)
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super(MailgunActivationView, self).dispatch(request, *args, **kwargs)