base setup
This commit is contained in:
165
at_django_boilerplate/accounts/forms.py
Executable file
165
at_django_boilerplate/accounts/forms.py
Executable file
@@ -0,0 +1,165 @@
|
||||
from django import forms
|
||||
from django.contrib.auth.forms import PasswordResetForm
|
||||
from django.utils.http import urlsafe_base64_encode
|
||||
from django.utils.encoding import force_bytes
|
||||
from django.contrib.auth.tokens import default_token_generator
|
||||
from django.contrib.auth.password_validation import (validate_password,
|
||||
get_password_validators,
|
||||
MinimumLengthValidator,
|
||||
UserAttributeSimilarityValidator,
|
||||
CommonPasswordValidator,
|
||||
NumericPasswordValidator,)
|
||||
from django.conf import settings
|
||||
from .models import CustomUser
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from at_django_boilerplate.utils.hash_utils import hexdigest
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UserSignUpForm(forms.ModelForm):
|
||||
password = forms.CharField(widget=forms.PasswordInput)
|
||||
confirm_password = forms.CharField(widget=forms.PasswordInput)
|
||||
terms_accepted = forms.BooleanField(required=True, label='I accept the terms and conditions')
|
||||
|
||||
class Meta:
|
||||
model = CustomUser
|
||||
fields = ['first_name', 'last_name', 'email','contact_number','dob','password','confirm_password','terms_accepted']
|
||||
widgets = {
|
||||
'dob': forms.DateInput(attrs={'type': 'date'}),
|
||||
'first_name': forms.TextInput(attrs={'type': 'text'}),
|
||||
'last_name': forms.TextInput(attrs={'type': 'text'}),
|
||||
'email': forms.EmailInput(attrs={'type': 'email'}),
|
||||
'contact_number': forms.TextInput(attrs={'type': 'text'}),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['password'].help_text = self.get_password_requirements()
|
||||
|
||||
def get_password_requirements(self):
|
||||
password_validators = get_password_validators(settings.AUTH_PASSWORD_VALIDATORS)
|
||||
requirements = []
|
||||
for validator in password_validators:
|
||||
if isinstance(validator, MinimumLengthValidator):
|
||||
requirements.append(f"*Password must be at least {validator.min_length} characters long.<br>")
|
||||
elif isinstance(validator, UserAttributeSimilarityValidator):
|
||||
requirements.append("*Password cannot be too similar to your other personal information.<br>")
|
||||
elif isinstance(validator, CommonPasswordValidator):
|
||||
requirements.append("*Password cannot be a commonly used password.<br>")
|
||||
elif isinstance(validator, NumericPasswordValidator):
|
||||
requirements.append("*Password cannot be entirely numeric.<br>")
|
||||
return " ".join(requirements)
|
||||
|
||||
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
password = cleaned_data.get("password")
|
||||
confirm_password = cleaned_data.get("confirm_password")
|
||||
|
||||
if password and confirm_password:
|
||||
try:
|
||||
validate_password(password, self.instance)
|
||||
except forms.ValidationError as error:
|
||||
self.add_error('password', error)
|
||||
return cleaned_data
|
||||
|
||||
if password != confirm_password:
|
||||
self.add_error('confirm_password', "Passwords do not match")
|
||||
|
||||
return cleaned_data
|
||||
|
||||
|
||||
|
||||
class SigninForm(forms.Form):
|
||||
username = forms.CharField(max_length=65)
|
||||
password = forms.CharField(max_length=65, widget=forms.PasswordInput)
|
||||
|
||||
|
||||
class CustomPasswordResetForm(PasswordResetForm):
|
||||
|
||||
def get_users(self, email):
|
||||
"""Given an email, return matching user(s) who should receive a reset."""
|
||||
email_hash = hexdigest(email)
|
||||
active_custom_users = CustomUser.objects.filter(email_hash=email_hash)
|
||||
active_users = [user for user in active_custom_users ]
|
||||
valid_users = [u for u in active_users if u.has_usable_password()]
|
||||
return valid_users
|
||||
|
||||
|
||||
def save(self, domain_override=None,
|
||||
subject_template_name='reset/password_reset_subject.txt',
|
||||
email_template_name='reset/password_reset_email.html',
|
||||
use_https=False, token_generator=default_token_generator,
|
||||
from_email=None, request=None, html_email_template_name=None,
|
||||
extra_email_context=None):
|
||||
"""
|
||||
Generates a one-use only link for resetting password and sends to the user.
|
||||
"""
|
||||
email = self.cleaned_data["email"]
|
||||
for user in self.get_users(email):
|
||||
context = {
|
||||
'email': email,
|
||||
'domain': domain_override or request.get_host(),
|
||||
'request':request,
|
||||
'site_name': 'we-kwick',
|
||||
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
|
||||
'user': user,
|
||||
'token': token_generator.make_token(user),
|
||||
'protocol': 'https' if use_https else 'http',
|
||||
**(extra_email_context or {}),
|
||||
}
|
||||
from_email = settings.EMAIL_HOST_USER
|
||||
# print('From:',from_email)
|
||||
# print('Email Template:',email_template_name)
|
||||
# print('HTML Email Template:',html_email_template_name)
|
||||
self.send_mail(
|
||||
subject_template_name, email_template_name, context, from_email,
|
||||
email, html_email_template_name=html_email_template_name,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class ProfileUpdateForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = CustomUser
|
||||
fields = [ 'contact_number']
|
||||
widgets = {
|
||||
'dob': forms.DateInput(attrs={'type': 'date'}),
|
||||
}
|
||||
|
||||
class UpdateProfileForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = CustomUser
|
||||
fields = [ 'contact_number']
|
||||
widgets = {
|
||||
'dob': forms.DateInput(attrs={'type': 'date'}),
|
||||
}
|
||||
|
||||
|
||||
|
||||
def validate_image(file):
|
||||
valid_mime_types = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml']
|
||||
valid_file_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.svg','.JPG']
|
||||
|
||||
file_mime_type = file.content_type
|
||||
if file_mime_type not in valid_mime_types:
|
||||
raise ValidationError(_('Unsupported file type. Please upload a JPEG, PNG, GIF, or SVG image.'))
|
||||
|
||||
extension = file.name.split('.')[-1].lower()
|
||||
if not any(file.name.endswith(ext) for ext in valid_file_extensions):
|
||||
raise ValidationError(_('Unsupported file extension.'))
|
||||
|
||||
class ProfilePictureUpdateForm(forms.ModelForm):
|
||||
profile_photo = forms.ImageField(
|
||||
widget=forms.ClearableFileInput(attrs={'accept': 'image/jpeg,image/png,image/gif,image/svg+xml'}),
|
||||
validators=[validate_image]
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = CustomUser
|
||||
fields = ['profile_photo']
|
||||
Reference in New Issue
Block a user