Home > database >  How to restrict Django user account creation to given usernames / addresses / practical values?
How to restrict Django user account creation to given usernames / addresses / practical values?

Time:03-26

We've set up Django user account creation / login through this tutorial, and we've restricted content to auth'd users only through the likes of {% if user.is_authenticated %} and if request.user.is_authenticated. All works great. But there's still nothing stopping anyone from going to the site and registering an account providing any values for username / email address / password.

We want to restrict user account creation to specific usernames / emails / IPs / any practical value. Could we check if a value is in some whitelist by inserting something like if email in ['[email protected]']: somewhere? Something that emails out an invite link?

We've found the docs on Permissions and Authorization and many SO questions on customizing functionality for types of users, yet we couldn't find any on restricting account creation itself, so perhaps we're missing something.

We could start creating different types of users, but we're wary of getting ahead of ourselves by attempting a more advanced solution before figuring out this basic step. Are we approaching this in the right way?

CodePudding user response:

Good day, there could be many ways to achieve what you're asking. A simple trick could be to use validators.

As the tutorial you followed does not dive in details, you will have to make extra steps.

I don't know your project structure, therefore I assume you know django's basics.

Create a custom validator

In a file called validators.py add following (c.f django EmailValidator) :

from django.core.validators import EmailValidator
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _

EMAIL_LIST = []

validate_email = EmailValidator(allowlist=EMAIL_PATTERN)

Change EMAIL_PATTERN as you wish.

Create a custom form

In a file called forms.py add something as follow :

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _

from validators import validate_email


class CustomUserCreationForm(UserCreationForm):

    email = forms.EmailField(label=_("Email"), validators=[validate_email])

    class Meta:
        model = User
        fields = [
            "username",
            "email",
            "password1",
            "password2",
        ]

Create a custom signup view

In your views.py

from django.urls import reverse_lazy
from django.views.generic import CreateView
from forms import CustomUserCreationForm

class SignupView(CreateView):
    form_class = CustomUserCreationForm
    template_name = "the-place-of-your/registration-template.html"
    success_url = reverse_lazy("you-custom-success-url-name")

You will have to create a custom template.

Edit your urls

urlpatterns = [
    ...
    path("", include("django.contrib.auth.urls")),
    path("signup/", SignupView.as_view(), name="signup"),
    ...
]

My modest demonstration is a way to achieve a restriction on email validation using allowlist arg. There is many other ways to do so.

  • Related