forms.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. from PIL import Image
  2. from django.conf import settings
  3. from django.core.exceptions import ValidationError
  4. from django.utils.translation import ugettext_lazy as _
  5. from django import forms
  6. from misago.ranks.models import Rank
  7. from misago.roles.models import Role
  8. from misago.users.models import User
  9. from misago.users.validators import validate_username, validate_password, validate_email
  10. from misago.forms import Form, YesNoSwitch
  11. class UserForm(Form):
  12. username = forms.CharField(max_length=255)
  13. title = forms.CharField(max_length=255, required=False)
  14. rank = forms.ModelChoiceField(queryset=Rank.objects.order_by('order').all(), required=False, empty_label=_('No rank assigned'))
  15. roles = False
  16. email = forms.EmailField(max_length=255)
  17. new_password = forms.CharField(max_length=255, required=False, widget=forms.PasswordInput)
  18. signature = forms.CharField(widget=forms.Textarea, required=False)
  19. avatar_custom = forms.CharField(max_length=255, required=False)
  20. avatar_ban = forms.BooleanField(widget=YesNoSwitch, required=False)
  21. avatar_ban_reason_user = forms.CharField(widget=forms.Textarea, required=False)
  22. avatar_ban_reason_admin = forms.CharField(widget=forms.Textarea, required=False)
  23. signature_ban = forms.BooleanField(widget=YesNoSwitch, required=False)
  24. signature_ban_reason_user = forms.CharField(widget=forms.Textarea, required=False)
  25. signature_ban_reason_admin = forms.CharField(widget=forms.Textarea, required=False)
  26. def __init__(self, user=None, *args, **kwargs):
  27. self.request = kwargs['request']
  28. self.user = user
  29. super(UserForm, self).__init__(*args, **kwargs)
  30. def finalize_form(self):
  31. self.layout = [
  32. [
  33. _("Basic Account Settings"),
  34. [
  35. ('username', {'label': _("Username"), 'help_text': _("Username is name under which user is known to other users. Between 3 and 15 characters, only letters and digits are allowed.")}),
  36. ('title', {'label': _("User Title"), 'help_text': _("To override user title with custom one, enter it here.")}),
  37. ('rank', {'label': _("User Rank"), 'help_text': _("This user rank.")}),
  38. ('roles', {'label': _("User Roles"), 'help_text': _("This user roles. Roles are sets of user permissions")}),
  39. ],
  40. ],
  41. [
  42. _("Sign-in Credentials"),
  43. [
  44. ('email', {'label': _("E-mail Address"), 'help_text': _("Member e-mail address.")}),
  45. ('new_password', {'label': _("Change User Password"), 'help_text': _("If you wish to change user password, enter here new password. Otherwhise leave this field blank."), 'has_value': False}),
  46. ],
  47. ],
  48. [
  49. _("User Avatar"),
  50. [
  51. ('avatar_custom', {'label': _("Set Non-Standard Avatar"), 'help_text': _("You can make this member use special avatar by entering name of image file located in avatars directory here.")}),
  52. ('avatar_ban', {'label': _("Lock Member's Avatar"), 'help_text': _("If you set this field to yes, this member's avatar will be deleted and replaced with random one selected from _removed gallery and member will not be able to change his avatar.")}),
  53. ('avatar_ban_reason_user', {'label': _("User-visible reason for lock"), 'help_text': _("You can leave message to member explaining why he or she is unable to change his avatar anymore. This message will be displayed to member in his control panel.")}),
  54. ('avatar_ban_reason_admin', {'label': _("Forum Team-visible reason for lock"), 'help_text': _("You can leave message to other forum team members exmplaining why this member's avatar has been locked.")}),
  55. ],
  56. ],
  57. [
  58. _("User Signature"),
  59. [
  60. ('signature', {'label': _("Signature"), 'help_text': _("Signature is short message attached at end of member's messages.")}),
  61. ('signature_ban', {'label': _("Lock Member's Signature"), 'help_text': _("If you set this field to yes, this member will not be able to change his signature.")}),
  62. ('signature_ban_reason_user', {'label': _("User-visible reason for lock"), 'help_text': _("You can leave message to member explaining why he or she is unable to edit his signature anymore. This message will be displayed to member in his control panel.")}),
  63. ('signature_ban_reason_admin', {'label': _("Forum Team-visible reason for lock"), 'help_text': _("You can leave message to other forum team members exmplaining why this member's signature has been locked.")}),
  64. ],
  65. ],
  66. ]
  67. # Roles list
  68. if self.request.user.is_god():
  69. self.fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.order_by('name').all(), error_messages={'required': _("User must have at least one role assigned.")})
  70. else:
  71. self.fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.filter(protected__exact=False).order_by('name').all(), required=False)
  72. # Keep non-gods from editing protected members sign-in credentials
  73. if self.user.is_protected() and not self.request.user.is_god() and self.user.pk != self.request.user.pk:
  74. del self.fields['email']
  75. del self.fields['new_password']
  76. del self.layout[1]
  77. def clean_username(self):
  78. org_username = self.user.username
  79. validate_username(self.cleaned_data['username'], self.request.settings)
  80. self.user.set_username(self.cleaned_data['username'])
  81. try:
  82. self.user.full_clean()
  83. except ValidationError as e:
  84. self.user.is_username_valid(e)
  85. self.user.set_username(org_username)
  86. return self.cleaned_data['username']
  87. def clean_email(self):
  88. self.user.set_email(self.cleaned_data['email'])
  89. try:
  90. self.user.full_clean()
  91. except ValidationError as e:
  92. self.user.is_email_valid(e)
  93. return self.cleaned_data['email']
  94. def clean_new_password(self):
  95. if self.cleaned_data['new_password']:
  96. validate_password(self.cleaned_data['new_password'], self.request.settings)
  97. self.user.set_password(self.cleaned_data['new_password'])
  98. try:
  99. self.user.full_clean()
  100. except ValidationError as e:
  101. self.user.is_password_valid(e)
  102. return self.cleaned_data['new_password']
  103. return ''
  104. def clean_avatar_custom(self):
  105. if self.cleaned_data['avatar_custom']:
  106. try:
  107. avatar_image = Image.open('%s/avatars/%s' % (settings.STATICFILES_DIRS[0], self.cleaned_data['avatar_custom']))
  108. except IOError:
  109. raise ValidationError(_("Avatar does not exist or is not image file."))
  110. return self.cleaned_data['avatar_custom']
  111. return ''
  112. class NewUserForm(Form):
  113. username = forms.CharField(max_length=255)
  114. title = forms.CharField(max_length=255, required=False)
  115. rank = forms.ModelChoiceField(queryset=Rank.objects.order_by('order').all(), required=False, empty_label=_('No rank assigned'))
  116. roles = False
  117. email = forms.EmailField(max_length=255)
  118. password = forms.CharField(max_length=255, widget=forms.PasswordInput)
  119. layout = [
  120. [
  121. _("Basic Account Settings"),
  122. [
  123. ('username', {'label': _("Username"), 'help_text': _("Username is name under which user is known to other users. Between 3 and 15 characters, only letters and digits are allowed.")}),
  124. ('title', {'label': _("User Title"), 'help_text': _("To override user title with custom one, enter it here.")}),
  125. ('rank', {'label': _("User Rank"), 'help_text': _("This user rank.")}),
  126. ('roles', {'label': _("User Roles"), 'help_text': _("This user roles. Roles are sets of user permissions")}),
  127. ],
  128. ],
  129. [
  130. _("Sign-in Credentials"),
  131. [
  132. ('email', {'label': _("E-mail Address"), 'help_text': _("Member e-mail address.")}),
  133. ('password', {'label': _("User Password"), 'help_text': _("Member password."), 'has_value': False}),
  134. ],
  135. ],
  136. ]
  137. def __init__(self, *args, **kwargs):
  138. self.request = kwargs['request']
  139. # Roles list
  140. if self.request.user.is_god():
  141. self.base_fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.order_by('name').all(), error_messages={'required': _("User must have at least one role assigned.")})
  142. else:
  143. self.base_fields['roles'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.filter(protected__exact=False).order_by('name').all(), required=False)
  144. super(NewUserForm, self).__init__(*args, **kwargs)
  145. def clean_username(self):
  146. validate_username(self.cleaned_data['username'])
  147. new_user = User.objects.get_blank_user()
  148. new_user.set_username(self.cleaned_data['username'])
  149. try:
  150. new_user.full_clean()
  151. except ValidationError as e:
  152. new_user.is_username_valid(e)
  153. return self.cleaned_data['username']
  154. def clean_email(self):
  155. new_user = User.objects.get_blank_user()
  156. new_user.set_email(self.cleaned_data['email'])
  157. try:
  158. new_user.full_clean()
  159. except ValidationError as e:
  160. new_user.is_email_valid(e)
  161. return self.cleaned_data['email']
  162. def clean_password(self):
  163. new_user = User.objects.get_blank_user()
  164. new_user.set_password(self.cleaned_data['password'])
  165. try:
  166. new_user.full_clean()
  167. except ValidationError as e:
  168. new_user.is_password_valid(e)
  169. validate_password(self.cleaned_data['password'])
  170. return self.cleaned_data['password']
  171. class SearchUsersForm(Form):
  172. username = forms.CharField(max_length=255, required=False)
  173. email = forms.CharField(max_length=255, required=False)
  174. activation = forms.TypedMultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=((0, _("Already Active")), (1, _("By User")), (2, _("By Administrator"))), coerce=int, required=False)
  175. rank = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Rank.objects.order_by('order').all(), required=False)
  176. role = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Role.objects.order_by('name').all(), required=False)
  177. layout = (
  178. (
  179. _("Search Users"),
  180. (
  181. ('username', {'label': _("Username"), 'attrs': {'placeholder': _("Username contains...")}}),
  182. ('email', {'label': _("E-mail Address"), 'attrs': {'placeholder': _("E-mail address contains...")}}),
  183. ('activation', {'label': _("Activation Requirement")}),
  184. ('rank', {'label': _("Rank is")}),
  185. ('role', {'label': _("Has Role")}),
  186. ),
  187. ),
  188. )