316 lines
11 KiB
Python
316 lines
11 KiB
Python
from typing import Any
|
|
|
|
from django import forms
|
|
from django.core.exceptions import ValidationError
|
|
from django.core import validators
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from module_project import constants
|
|
|
|
from . import models
|
|
# from .backend import EmailBackend
|
|
# from phonenumber_field.formfields import PhoneNumberField
|
|
from .iam_constant import PRINCIPAL_TYPE_ADMIN, PRINCIPAL_TYPE_SUBADMIN
|
|
from django.contrib.auth import authenticate
|
|
|
|
|
|
class CustomAuthenticationForm(forms.Form):
|
|
email = forms.EmailField(
|
|
max_length=254,
|
|
widget=forms.TextInput(attrs={"autofocus": True}),
|
|
label=_("Email"),
|
|
)
|
|
password = forms.CharField(
|
|
label=_("Password"),
|
|
strip=False,
|
|
widget=forms.PasswordInput(attrs={"autocomplete": "current-password"}),
|
|
)
|
|
|
|
def clean(self):
|
|
email = self.cleaned_data.get("email")
|
|
password = self.cleaned_data.get("password")
|
|
self.user = None
|
|
if email and password:
|
|
|
|
user = authenticate(email=email, password=password)
|
|
|
|
if user is None:
|
|
raise ValidationError({"__all__": [constants.INVALID_EMAIL_PASSWORD]})
|
|
elif not user.is_active:
|
|
raise ValidationError({"__all__": [constants.ACCOUNT_DEACTIVATED]})
|
|
self.user = user
|
|
return self.cleaned_data
|
|
|
|
|
|
class IAmPrincipalForm(forms.ModelForm):
|
|
password = forms.CharField(
|
|
widget=forms.PasswordInput(attrs={"autocomplete": "off"}),
|
|
validators=[
|
|
validators.MinLengthValidator(
|
|
limit_value=6, message="Password must be at least 6 characters long. "
|
|
)
|
|
],
|
|
)
|
|
confirm_password = forms.CharField(
|
|
widget=forms.PasswordInput(attrs={"autocomplete": "off"})
|
|
)
|
|
|
|
class Meta:
|
|
model = models.IAmPrincipal
|
|
fields = [
|
|
"principal_type",
|
|
"first_name",
|
|
"last_name",
|
|
"email",
|
|
"password",
|
|
"confirm_password",
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
instance = kwargs.get("instance")
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["principal_type"].queryset = models.IAmPrincipalType.objects.filter(
|
|
active=True, deleted=False, name__in=(PRINCIPAL_TYPE_ADMIN, PRINCIPAL_TYPE_SUBADMIN)
|
|
)
|
|
# If it's a create action, exclude 'is_active' field
|
|
if instance is not None and instance.pk is not None:
|
|
self.fields.pop("password", None)
|
|
self.fields.pop("confirm_password", None)
|
|
|
|
def clean_email(self):
|
|
email = self.cleaned_data.get("email")
|
|
# Skip uniqueness validation if it's an update action (instance exists)
|
|
if self.instance and self.instance.email == email:
|
|
return email
|
|
if models.IAmPrincipal.objects.filter(email=email).exists():
|
|
raise forms.ValidationError(constants.EMAIL_EXISTS)
|
|
|
|
return email
|
|
|
|
def save(self, commit=True):
|
|
instance = super().save(commit=False)
|
|
# Check if it's a new object (create action) or an existing one (update action)
|
|
if not instance.pk: # pk is None for new objects
|
|
instance.username = self.cleaned_data["email"]
|
|
instance.set_password(self.cleaned_data["password"])
|
|
|
|
principal_type = self.cleaned_data.get("principal_type")
|
|
if principal_type is not None:
|
|
# Set is_superuser and is_staff based on principal_type
|
|
if principal_type == models.IAmPrincipalType.objects.get(name=PRINCIPAL_TYPE_ADMIN):
|
|
instance.is_superuser = True
|
|
elif principal_type == models.IAmPrincipalType.objects.get(name=PRINCIPAL_TYPE_SUBADMIN):
|
|
instance.is_staff = True
|
|
if commit:
|
|
instance.save()
|
|
return instance
|
|
|
|
|
|
class IAmPrincipalProfileForm(forms.ModelForm):
|
|
GENDER_CHOICES = (
|
|
("male", "Male"),
|
|
("female", "Female"),
|
|
("other", "Other"),
|
|
)
|
|
first_name = forms.CharField(required=True)
|
|
last_name = forms.CharField(required=True)
|
|
email = forms.EmailField(required=True)
|
|
password = forms.CharField(
|
|
widget=forms.PasswordInput(attrs={"autocomplete": "off"})
|
|
)
|
|
confirm_password = forms.CharField(
|
|
widget=forms.PasswordInput(attrs={"autocomplete": "off"})
|
|
)
|
|
# date_of_birth = forms.CharField(widget=forms.DateInput(attrs={'type': 'date'}))
|
|
phone_number = forms.CharField(
|
|
widget=forms.TextInput(),
|
|
)
|
|
# is_staff = forms.BooleanField(
|
|
# label="Staff Status",
|
|
# label_suffix="",
|
|
# initial=True,
|
|
# required=False,
|
|
# help_text="Check this box to designate that this user will be assigned permissions in the future.",
|
|
# )
|
|
# is_superuser = forms.BooleanField(
|
|
# label="SuperAdmin Status",
|
|
# label_suffix="",
|
|
# required=False,
|
|
# help_text="Check this box to designates that this user has all permissions without explicitly assigning them.",
|
|
# )
|
|
# gender = forms.ChoiceField(choices=GENDER_CHOICES)
|
|
|
|
class Meta:
|
|
model = models.IAmPrincipal
|
|
fields = [
|
|
"principal_type",
|
|
"first_name",
|
|
"last_name",
|
|
"email",
|
|
"password",
|
|
"confirm_password",
|
|
# 'gender',
|
|
# 'date_of_birth',
|
|
"phone_number",
|
|
# 'address_line1',
|
|
# 'address_line2',
|
|
# 'city',
|
|
# 'state',
|
|
# 'country',
|
|
# 'post_code',
|
|
# 'profile_photo',
|
|
# "is_staff",
|
|
# "is_superuser",
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
instance = kwargs.get("instance")
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["principal_type"].queryset = models.IAmPrincipalType.objects.filter(
|
|
active=True, deleted=False
|
|
)
|
|
# self.fields['principal_source'].queryset = models.IAmPrincipalSource.objects.filter(active=True, deleted=False)
|
|
# Check if an instance is provided and customize the form fields accordingly
|
|
if instance is not None:
|
|
# Exclude the 'password' and 'confirm_password' fields
|
|
self.fields.pop("password", None)
|
|
self.fields.pop("confirm_password", None)
|
|
|
|
# Make the 'email' field read-only
|
|
self.fields["email"].widget.attrs["readonly"] = True
|
|
|
|
# Modify the 'is_superuser' field to be not required
|
|
# self.fields["is_superuser"].required = False
|
|
# self.fields["is_staff"].required = False
|
|
|
|
# Add or modify the 'is_active' field
|
|
self.fields["is_active"] = forms.BooleanField(
|
|
label="Active",
|
|
initial=instance.is_active,
|
|
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
|
|
required=False,
|
|
)
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
password = cleaned_data.get("password")
|
|
confirm_password = cleaned_data.get("confirm_password")
|
|
|
|
if password and confirm_password and password != confirm_password:
|
|
self.add_error("confirm_password", "Password does not match")
|
|
return cleaned_data
|
|
|
|
def save(self, commit=True):
|
|
user = super().save(commit=False)
|
|
user.set_password(self.cleaned_data["password"])
|
|
if commit:
|
|
user.save()
|
|
return user
|
|
|
|
class ProfileEditForm(forms.ModelForm):
|
|
gender = forms.ChoiceField(choices=(('Male', 'Male'),('Female', 'Female'),('Other', 'Other')))
|
|
profile_photo = forms.ImageField(required=False)
|
|
|
|
class Meta:
|
|
model = models.IAmPrincipal
|
|
fields = [
|
|
"profile_photo",
|
|
"first_name",
|
|
"last_name",
|
|
"date_of_birth",
|
|
"gender",
|
|
"phone_no"
|
|
]
|
|
|
|
|
|
class IAmPrincipalGroupLinkForm(IAmPrincipalForm):
|
|
|
|
class Meta:
|
|
model = models.IAmPrincipal
|
|
fields = [
|
|
"principal_type",
|
|
"first_name",
|
|
"last_name",
|
|
"email",
|
|
"password",
|
|
"confirm_password",
|
|
"principal_group",
|
|
]
|
|
|
|
principal_group = forms.ModelMultipleChoiceField(
|
|
label="Groups",
|
|
queryset=models.IAmPrincipalGroup.objects.filter(active=True, deleted=False),
|
|
required=False,
|
|
widget=forms.widgets.SelectMultiple(
|
|
attrs={"class": "form_select js-example-basic-multiple"}
|
|
),
|
|
)
|
|
|
|
def save(self, commit=True):
|
|
# First, save the instance of the IAmPrincipal model as usual
|
|
principal = super().save(commit=False)
|
|
# If the principal_group field has data
|
|
if self.cleaned_data['principal_group']:
|
|
# Get the principal_group data
|
|
principal_group_data = self.cleaned_data['principal_group']
|
|
# Update the many-to-many relationship
|
|
principal.principal_group.set(principal_group_data)
|
|
# Save the instance to the database
|
|
if commit:
|
|
principal.save()
|
|
|
|
class IAmPrincipalTypeForm(forms.ModelForm):
|
|
class Meta:
|
|
model = models.IAmPrincipalType
|
|
fields = ["name", "active"]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
instance = kwargs.get("instance")
|
|
super().__init__(*args, **kwargs)
|
|
|
|
if instance is None:
|
|
self.fields.pop("active")
|
|
|
|
|
|
class IAmPrincipalGroupRoleLinkForm(forms.ModelForm):
|
|
class Meta:
|
|
model = models.IAmPrincipalGroup
|
|
fields = ["name", "role", "active"]
|
|
|
|
role = forms.ModelMultipleChoiceField(
|
|
queryset=models.IAmRole.objects.filter(active=True, deleted=False),
|
|
required=False,
|
|
widget=forms.widgets.SelectMultiple(
|
|
attrs={"class": "form-select js-example-basic-multiple"}
|
|
),
|
|
)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
instance = kwargs.get("instance")
|
|
# data = kwargs.get('data')
|
|
super().__init__(*args, **kwargs)
|
|
|
|
if instance is None:
|
|
# This is an add operation, exclude the 'active' field
|
|
self.fields.pop("active")
|
|
|
|
|
|
class IAmPrincipalRoleAppResourceActionLinkForm(forms.ModelForm):
|
|
class Meta:
|
|
model = models.IAmRole
|
|
fields = ["name", "active", "app_resource_action"]
|
|
required = {"app_resource_action": False}
|
|
|
|
app_resource_action = forms.ModelMultipleChoiceField(
|
|
queryset=models.IAmAppResourceActionLink.objects.all(),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
required=False,
|
|
)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
instance = kwargs.get("instance")
|
|
super().__init__(*args, **kwargs)
|
|
|
|
if instance is None:
|
|
self.fields.pop("active")
|