pennersr / django-allauth

Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication.
https://allauth.org
MIT License
9.55k stars 3.03k forks source link

Implement COPPA Law Mechanism For Sign Ups #2503

Closed 9mido closed 1 year ago

9mido commented 4 years ago

To prevent children from accessing website content they shouldn't, it would be nice for allauth to have a sign up mechanism to email parents to get their parental consent (similar to Lego and Nintendo). Once the parent confirms the email sent from the child's signup attempt, the child can then log in normally.

Another perhaps easier way would be to prevent children from signing up if they enter a young age before accessing the sign up form. This is similar to Zoom's approach where they have an "For verification, please confirm your date of birth" dropdown form and if the user enters a young birthday, set a cookie to prevent them from signing up.

If storing age/birthday in the database, PII/GDPR laws come into play so encrypting the age would be needed. But I do not think database storage for this feature is necessary.

A setting like ACCOUNT_CHILD_AGE = True|False would enable or disable this feature.

Examples: Lego.com https://identity.lego.com/en-US/register/ Nintendo.com https://accounts.nintendo.com/register Zoom: https://zoom.us/signup Khan Academy: https://www.khanacademy.org/signup

9mido commented 3 years ago

Here is one method to implement a date of birth validation to the signup form. No database storage of the user age is needed:

Forms.py:

from allauth.account.forms import SignupForm

class CustomSignupForm(SignupForm):
    def clean_date_of_birth(self):
        dob = self.cleaned_data['date_of_birth']
        today = date.today()
        if (dob.year + 18, dob.month, dob.day) > (today.year, today.month, today.day):
            raise forms.ValidationError('You must be at least 18 years old to sign up')
        return dob

    date_of_birth = forms.DateField(widget=forms.DateInput(attrs={'autocomplete':'off', 'id':'date_of_birth','type':'date', }), required=True)

    def __init__(self, *args, **kwargs):
        super(CustomSignupForm, self).__init__(*args, **kwargs)
        self.fields['date_of_birth'].label = "Date of Birth"

Settings.py:

ACCOUNT_FORMS = {
    'signup': 'app_name.forms.CustomSignupForm',
}

Signup.html:

{{ form.date_of_birth }}

pennersr commented 1 year ago

This would increase scope considerably -- let's skip this for now.