You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

forms.py 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. import string
  2. import random
  3. from django.contrib.auth.forms import AuthenticationForm
  4. from django.utils.translation import ugettext_lazy as _
  5. from django.core.exceptions import ObjectDoesNotExist
  6. from django import forms
  7. from django.db.models import get_model
  8. from django.contrib.auth.models import User
  9. from django.contrib.auth import forms as auth_forms
  10. from django.conf import settings
  11. from django.core import validators
  12. from django.utils.http import int_to_base36
  13. from django.contrib.sites.models import get_current_site
  14. from django.contrib.auth.tokens import default_token_generator
  15. from oscar.core.loading import get_profile_class, get_class
  16. Dispatcher = get_class('customer.utils', 'Dispatcher')
  17. CommunicationEventType = get_model('customer', 'communicationeventtype')
  18. def generate_username():
  19. uname = ''.join([random.choice(string.letters + string.digits + '_') for i in range(30)])
  20. try:
  21. User.objects.get(username=uname)
  22. return generate_username()
  23. except User.DoesNotExist:
  24. return uname
  25. class PasswordResetForm(auth_forms.PasswordResetForm):
  26. communication_type_code = "PASSWORD_RESET"
  27. def save(self, subject_template_name='registration/password_reset_subject.txt',
  28. email_template_name='registration/password_reset_email.html',
  29. use_https=False, token_generator=default_token_generator,
  30. from_email=None, request=None, **kwargs):
  31. """
  32. Generates a one-use only link for resetting password and sends to the
  33. user.
  34. """
  35. for user in self.users_cache:
  36. current_site = get_current_site(request)
  37. ctx = {
  38. 'email': user.email,
  39. 'domain': current_site.domain,
  40. 'site_name': current_site.name,
  41. 'uid': int_to_base36(user.id),
  42. 'token': token_generator.make_token(user),
  43. 'protocol': use_https and 'https' or 'http',
  44. 'site': current_site,
  45. }
  46. self.send_reset_email(user, ctx)
  47. def send_reset_email(self, user, extra_context=None):
  48. code = self.communication_type_code
  49. ctx = {
  50. 'user': user,
  51. 'static_base_url': getattr(settings, 'OSCAR_STATIC_BASE_URL', None)
  52. }
  53. if extra_context:
  54. ctx.update(extra_context)
  55. try:
  56. event_type = CommunicationEventType.objects.get(code=code)
  57. except CommunicationEventType.DoesNotExist:
  58. # No event in database, attempt to find templates for this type
  59. messages = CommunicationEventType.objects.get_and_render(code, ctx)
  60. else:
  61. # Create order event
  62. messages = event_type.get_messages(ctx)
  63. if messages and messages['body']:
  64. dispatcher = Dispatcher()
  65. dispatcher.dispatch_user_messages(user, messages)
  66. class EmailAuthenticationForm(AuthenticationForm):
  67. """
  68. Extends the standard django AuthenticationForm, to support 75 character
  69. usernames. 75 character usernames are needed to support the EmailOrUsername
  70. auth backend.
  71. """
  72. username = forms.EmailField(label=_('Email Address'))
  73. class CommonPasswordValidator(validators.BaseValidator):
  74. # See http://www.smartplanet.com/blog/business-brains/top-20-most-common-passwords-of-all-time-revealed-8216123456-8216princess-8216qwerty/4519
  75. forbidden_passwords = [
  76. 'password',
  77. '1234',
  78. '12345'
  79. '123456',
  80. '123456y',
  81. '123456789',
  82. 'iloveyou',
  83. 'princess',
  84. 'monkey',
  85. 'rockyou',
  86. 'babygirl',
  87. 'monkey',
  88. 'qwerty',
  89. '654321',
  90. 'dragon',
  91. 'pussy',
  92. 'baseball',
  93. 'football',
  94. 'letmein',
  95. 'monkey',
  96. '696969',
  97. 'abc123',
  98. 'qwe123',
  99. 'qweasd',
  100. 'mustang',
  101. 'michael',
  102. 'shadow',
  103. 'master',
  104. 'jennifer',
  105. '111111',
  106. '2000',
  107. 'jordan',
  108. 'superman'
  109. 'harley'
  110. ]
  111. message = _("Please choose a less common password")
  112. code = 'password'
  113. def __init__(self, password_file=None):
  114. self.limit_value = password_file
  115. def clean(self, value):
  116. return value.strip()
  117. def compare(self, value, limit):
  118. return value in self.forbidden_passwords
  119. def get_forbidden_passwords(self):
  120. if self.limit_value is None:
  121. return self.forbidden_passwords
  122. class EmailUserCreationForm(forms.ModelForm):
  123. email = forms.EmailField(label=_('Email Address'))
  124. password1 = forms.CharField(label=_('Password'), widget=forms.PasswordInput,
  125. validators=[validators.MinLengthValidator(6),
  126. CommonPasswordValidator()])
  127. password2 = forms.CharField(label=_('Confirm Password'), widget=forms.PasswordInput)
  128. class Meta:
  129. model = User
  130. fields = ('email',)
  131. def clean_email(self):
  132. email = self.cleaned_data['email'].lower()
  133. try:
  134. User.objects.get(email=email)
  135. except User.DoesNotExist:
  136. return email
  137. raise forms.ValidationError(_("A user with that email address already exists."))
  138. def clean_password2(self):
  139. password1 = self.cleaned_data.get('password1', '')
  140. password2 = self.cleaned_data.get('password2', '')
  141. if password1 != password2:
  142. raise forms.ValidationError(_("The two password fields didn't match."))
  143. return password2
  144. def save(self, commit=True):
  145. user = super(EmailUserCreationForm, self).save(commit=False)
  146. user.set_password(self.cleaned_data['password1'])
  147. user.username = generate_username()
  148. if commit:
  149. user.save()
  150. return user
  151. class SearchByDateRangeForm(forms.Form):
  152. date_from = forms.DateField(required=False, label="From")
  153. date_to = forms.DateField(required=False, label="To")
  154. def clean(self):
  155. if self.is_valid() and not self.cleaned_data['date_from'] and not self.cleaned_data['date_to']:
  156. raise forms.ValidationError(_("At least one date field is required."))
  157. return super(SearchByDateRangeForm, self).clean()
  158. def description(self):
  159. if not self.is_bound or not self.is_valid():
  160. return 'All orders'
  161. date_from = self.cleaned_data['date_from']
  162. date_to = self.cleaned_data['date_to']
  163. if date_from and date_to:
  164. return 'Orders placed between %s and %s' % (date_from, date_to)
  165. elif date_from and not date_to:
  166. return 'Orders placed since %s' % date_from
  167. elif not date_from and date_to:
  168. return 'Orders placed until %s' % date_to
  169. def get_filters(self):
  170. date_from = self.cleaned_data['date_from']
  171. date_to = self.cleaned_data['date_to']
  172. if date_from and date_to:
  173. return {'date_placed__range': [date_from, date_to]}
  174. elif date_from and not date_to:
  175. return {'date_placed__gt': date_from}
  176. elif not date_from and date_to:
  177. return {'date_placed__lt': date_to}
  178. return {}
  179. class UserForm(forms.ModelForm):
  180. def __init__(self, user, *args, **kwargs):
  181. self.user = user
  182. kwargs['instance'] = user
  183. super(UserForm, self).__init__(*args, **kwargs)
  184. class Meta:
  185. model = User
  186. exclude = ('username', 'password', 'is_staff', 'is_superuser',
  187. 'is_active', 'last_login', 'date_joined',
  188. 'user_permissions', 'groups')
  189. if hasattr(settings, 'AUTH_PROFILE_MODULE'):
  190. Profile = get_profile_class()
  191. class UserAndProfileForm(forms.ModelForm):
  192. first_name = forms.CharField(label=_('First name'), max_length=128)
  193. last_name = forms.CharField(label=_('Last name'), max_length=128)
  194. email = forms.EmailField(label=_('Email address'))
  195. # Fields from user model
  196. user_fields = ('first_name', 'last_name', 'email')
  197. def __init__(self, user, *args, **kwargs):
  198. self.user = user
  199. try:
  200. instance = user.get_profile()
  201. except ObjectDoesNotExist:
  202. # User has no profile, try a blank one
  203. instance = Profile(user=user)
  204. kwargs['instance'] = instance
  205. super(UserAndProfileForm, self).__init__(*args, **kwargs)
  206. # Add user fields
  207. self.fields['first_name'].initial = self.instance.user.first_name
  208. self.fields['last_name'].initial = self.instance.user.last_name
  209. self.fields['email'].initial = self.instance.user.email
  210. # Ensure user fields are above profile
  211. order = list(self.user_fields)
  212. for field_name in self.fields.keys():
  213. if field_name not in self.user_fields:
  214. order.append(field_name)
  215. self.fields.keyOrder = order
  216. class Meta:
  217. model = Profile
  218. exclude = ('user',)
  219. def save(self, *args, **kwargs):
  220. user = self.instance.user
  221. user.first_name = self.cleaned_data['first_name']
  222. user.last_name = self.cleaned_data['last_name']
  223. user.email = self.cleaned_data['email']
  224. user.save()
  225. return super(ProfileForm, self).save(*args,**kwargs)
  226. ProfileForm = UserAndProfileForm
  227. else:
  228. ProfileForm = UserForm