2025-08-12 13:33:25 +03:00

226 lines
8.2 KiB
Python

"""
Forms for Accounts app CRUD operations.
"""
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.core.exceptions import ValidationError
from .models import User, TwoFactorDevice, SocialAccount, UserSession, PasswordHistory
class UserForm(forms.ModelForm):
"""
Form for updating user information.
"""
class Meta:
model = User
fields = [
'first_name', 'last_name', 'email', 'phone_number', 'mobile_number',
'employee_id', 'role', 'department', 'bio', 'user_timezone', 'language',
'theme', 'is_active', 'is_approved'
]
widgets = {
'first_name': forms.TextInput(attrs={'class': 'form-control'}),
'last_name': forms.TextInput(attrs={'class': 'form-control'}),
'email': forms.EmailInput(attrs={'class': 'form-control'}),
'phone_number': forms.TextInput(attrs={'class': 'form-control'}),
'mobile_number': forms.TextInput(attrs={'class': 'form-control'}),
'employee_id': forms.TextInput(attrs={'class': 'form-control'}),
'role': forms.Select(attrs={'class': 'form-select'}),
'department': forms.TextInput(attrs={'class': 'form-control'}),
'bio': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
'user_timezone': forms.Select(attrs={'class': 'form-select'}),
'language': forms.Select(attrs={'class': 'form-select'}),
'theme': forms.Select(attrs={'class': 'form-select'}),
'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'is_approved': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
}
class UserCreateForm(UserCreationForm):
"""
Form for creating new users.
"""
first_name = forms.CharField(max_length=150, required=True)
last_name = forms.CharField(max_length=150, required=True)
email = forms.EmailField(required=True)
employee_id = forms.CharField(max_length=50, required=False)
role = forms.ChoiceField(choices=User._meta.get_field('role').choices, required=True)
department = forms.CharField(max_length=100, required=False)
class Meta:
model = User
fields = [
'username', 'first_name', 'last_name', 'email', 'employee_id',
'role', 'department', 'password1', 'password2'
]
widgets = {
'username': forms.TextInput(attrs={'class': 'form-control'}),
'first_name': forms.TextInput(attrs={'class': 'form-control'}),
'last_name': forms.TextInput(attrs={'class': 'form-control'}),
'email': forms.EmailInput(attrs={'class': 'form-control'}),
'employee_id': forms.TextInput(attrs={'class': 'form-control'}),
'role': forms.Select(attrs={'class': 'form-select'}),
'department': forms.TextInput(attrs={'class': 'form-control'}),
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password1'].widget.attrs.update({'class': 'form-control'})
self.fields['password2'].widget.attrs.update({'class': 'form-control'})
class TwoFactorDeviceForm(forms.ModelForm):
"""
Form for two-factor device management.
"""
class Meta:
model = TwoFactorDevice
fields = ['user', 'name', 'device_type', 'phone_number', 'email_address']
widgets = {
'user': forms.Select(attrs={'class': 'form-select'}),
'name': forms.TextInput(attrs={'class': 'form-control'}),
'device_type': forms.Select(attrs={'class': 'form-select'}),
'phone_number': forms.TextInput(attrs={'class': 'form-control'}),
'email_address': forms.EmailInput(attrs={'class': 'form-control'}),
}
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user and hasattr(user, 'tenant'):
self.fields['user'].queryset = User.objects.filter(
tenant=user.tenant,
is_active=True
).order_by('last_name', 'first_name')
def clean(self):
cleaned_data = super().clean()
device_type = cleaned_data.get('device_type')
phone_number = cleaned_data.get('phone_number')
email_address = cleaned_data.get('email_address')
if device_type == 'SMS' and not phone_number:
raise ValidationError('Phone number is required for SMS devices.')
if device_type == 'EMAIL' and not email_address:
raise ValidationError('Email address is required for email devices.')
return cleaned_data
class SocialAccountForm(forms.ModelForm):
"""
Form for social account management.
"""
class Meta:
model = SocialAccount
fields = ['user', 'provider', 'provider_id', 'display_name', 'profile_url']
widgets = {
'user': forms.Select(attrs={'class': 'form-select'}),
'provider': forms.TextInput(attrs={'class': 'form-control'}),
'provider_id': forms.TextInput(attrs={'class': 'form-control'}),
'display_name': forms.TextInput(attrs={'class': 'form-control'}),
'profile_url': forms.URLInput(attrs={'class': 'form-control'}),
}
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user and hasattr(user, 'tenant'):
self.fields['user'].queryset = User.objects.filter(
tenant=user.tenant,
is_active=True
).order_by('last_name', 'first_name')
class AccountsSearchForm(forms.Form):
"""
Form for searching accounts data.
"""
search = forms.CharField(
max_length=255,
required=False,
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Search users, sessions, devices...'
})
)
role = forms.ChoiceField(
choices=[('', 'All Roles')] + list(User._meta.get_field('role').choices),
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
status = forms.ChoiceField(
choices=[
('', 'All Status'),
('active', 'Active'),
('inactive', 'Inactive'),
('pending', 'Pending Approval')
],
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
date_from = forms.DateField(
required=False,
widget=forms.DateInput(attrs={
'class': 'form-control',
'type': 'date'
})
)
date_to = forms.DateField(
required=False,
widget=forms.DateInput(attrs={
'class': 'form-control',
'type': 'date'
})
)
class PasswordChangeForm(forms.Form):
"""
Form for changing user passwords.
"""
old_password = forms.CharField(
widget=forms.PasswordInput(attrs={'class': 'form-control'}),
label='Current Password'
)
new_password1 = forms.CharField(
widget=forms.PasswordInput(attrs={'class': 'form-control'}),
label='New Password'
)
new_password2 = forms.CharField(
widget=forms.PasswordInput(attrs={'class': 'form-control'}),
label='Confirm New Password'
)
def __init__(self, user, *args, **kwargs):
self.user = user
super().__init__(*args, **kwargs)
def clean_old_password(self):
old_password = self.cleaned_data.get('old_password')
if not self.user.check_password(old_password):
raise ValidationError('Your old password was entered incorrectly.')
return old_password
def clean(self):
cleaned_data = super().clean()
password1 = cleaned_data.get('new_password1')
password2 = cleaned_data.get('new_password2')
if password1 and password2:
if password1 != password2:
raise ValidationError('The two password fields didn\'t match.')
return cleaned_data
def save(self):
password = self.cleaned_data['new_password1']
self.user.set_password(password)
self.user.save()
return self.user