Commit f923722a authored by BERJON Matthieu's avatar BERJON Matthieu
Browse files

Merge branch 'fix-allauth-email-validation' into 'django'

Fix allauth email validation

See merge request !149
parents 4ce034d6 1083d987
Pipeline #46115 failed with stage
in 1 minute and 6 seconds
......@@ -2,6 +2,7 @@ from django.conf import settings
from django.contrib.auth.mixins import UserPassesTestMixin
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse, JsonResponse
from django.shortcuts import redirect
from .models import Job
from .helpers import get_request_user
......@@ -12,11 +13,18 @@ class IsProviderMixin(object):
"""
def dispatch(self, request, *args, **kwargs):
local_part, domain = request.user.email.split("@")
if domain in settings.ALLOWED_DEVELOPER_DOMAINS:
return super().dispatch(request, *args, **kwargs)
else:
email_addr = request.user.provider_address
if email_addr is None:
# user has no valid email address in the allowed domains
raise PermissionDenied
elif not email_addr.verified:
# user has a valid address but it is still unverified
email_addr.send_confirmation(request)
return redirect("account_email_verification_sent")
else:
# user has a valid and verified address
return super().dispatch(request, *args, **kwargs)
class JobAuthMixin(UserPassesTestMixin):
......
......@@ -11,6 +11,7 @@ from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from taggit.managers import TaggableManager
from allauth.account.models import EmailAddress
from allauth.socialaccount.models import SocialAccount
from django.utils.crypto import get_random_string
......@@ -629,17 +630,43 @@ def create_user_profile(sender, instance, created, **kwargs):
def save_user_profile(sender, instance, **kwargs):
instance.allgouser.save()
@property
def provider_address(user):
"""Get the first EmailAddress in the allowed developer domains
WARNING: the returned EmailAddress may not be verified
This function finds the first allauth EmailAddress of the user that matches
a domain listed in settings.ALLOWED_DEVELOPER_DOMAINS
If None is returned, then the user is not allowed to create a webapp.
When the function returns an EmailAddress this does not automatically imply
that the user can create a webapp, because we still have to ensure that the
email is validated (however this is sufficient for displaying the "create
webapp"/"import webapp" buttons).
"""
for email_addr in EmailAddress.objects.filter(user=user):
try:
_, domain = email_addr.email.split("@")
except ValueError:
# malformatted email
continue
if domain in settings.ALLOWED_DEVELOPER_DOMAINS:
return email_addr
return None
def is_provider(user):
"""Return true if the user belongs to the allowed developer domains
"""Return true if the user has at least one email address in the allowed
developer domains
Warning: this function returns True even if the email address is not
verified
"""
local_part, domain = user.email.split("@")
if domain in settings.ALLOWED_DEVELOPER_DOMAINS:
return True
else:
return False
return user.provider_address is not None
# Add the `is_provider` function as a `User` model method
auth.models.User.add_to_class('provider_address', provider_address)
auth.models.User.add_to_class('is_provider', is_provider)
# NOTE: because there is a circular dependency between models.py and
......
......@@ -402,17 +402,20 @@ class WebappImport(SuccessMessageMixin, LoginRequiredMixin, IsProviderMixin, For
current_user = self.request.user
if not current_user.is_superuser:
# get the user EmailAddress that matches the owner of the imported app
email_addr = EmailAddress.objects.filter(
user=current_user, email=js["user"]).first()
# ensure this app has the same owner
if current_user.email != js["user"]:
if email_addr is None:
return error("""this webapp belongs to another user (if you think
it really belongs to you, then you should contact the
administrators)""")
# ensure the user email is verified
#TODO support gitlab accounts
if not EmailAddress.objects.filter(user=current_user,
email=current_user.email, verified=True).exists():
return error("your e-mail address is not yet verified")
if not email_addr.verified:
email_addr.send_confirmation(request)
return redirect("account_email_verification_sent")
# We can import the webapp !
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment