""" 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