Commit 22b917518e2e1105fb74278490055ecc978528a4

Authored by Sergio Oliveira
1 parent fbf424a9

Fixed admin for User model

(flake8 checks as well)
Showing 2 changed files with 97 additions and 103 deletions   Show diff stats
colab/accounts/admin.py
1 1
2 -from django import forms  
3 from django.contrib import admin 2 from django.contrib import admin
4 from django.contrib.auth import get_user_model 3 from django.contrib.auth import get_user_model
5 from django.contrib.auth.admin import UserAdmin 4 from django.contrib.auth.admin import UserAdmin
6 from django.utils.translation import ugettext_lazy as _ 5 from django.utils.translation import ugettext_lazy as _
7 6
8 -from .forms import UserCreationForm 7 +from .forms import UserCreationForm, UserChangeForm
9 8
10 User = get_user_model() 9 User = get_user_model()
11 10
12 11
13 -class CustomUserCreationForm(UserCreationForm):  
14 - class Meta:  
15 - model = User  
16 - fields = ("username", "email")  
17 -  
18 - #def __init__(self, *args, **kwargs):  
19 - # super(CustomUserCreationForm, self).__init__(*args, **kwargs)  
20 - # self.fields['email'].required = True  
21 -  
22 -  
23 -class UserChangeForm(forms.ModelForm):  
24 - class Meta:  
25 - model = User  
26 - fields = ('username', 'first_name', 'last_name', 'email', 'is_active',  
27 - 'is_staff', 'is_superuser', 'groups', 'last_login',  
28 - 'date_joined', 'twitter', 'facebook', 'google_talk',  
29 - 'webpage')  
30 -  
31 - def __init__(self, *args, **kwargs):  
32 - super(UserChangeForm, self).__init__(*args, **kwargs)  
33 - self.fields['email'].required = True  
34 -  
35 -  
36 -  
37 -class MyUserAdmin(UserAdmin): 12 +class CustomUserAdmin(UserAdmin):
38 form = UserChangeForm 13 form = UserChangeForm
39 - add_form = CustomUserCreationForm 14 + add_form = UserCreationForm
40 15
41 fieldsets = ( 16 fieldsets = (
42 (None, {'fields': ('username', 'email', 'password')}), 17 (None, {'fields': ('username', 'email', 'password')}),
43 - (_('Personal info'), {'fields': ('first_name', 'last_name', 'twitter',  
44 - 'facebook', 'google_talk', 'webpage',  
45 - )}),  
46 - (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 18 + (_('Personal info'), {'fields': ('first_name',
  19 + 'last_name',
  20 + 'twitter',
  21 + 'facebook',
  22 + 'google_talk',
  23 + 'webpage')}),
  24 + (_('Permissions'), {'fields': ('is_active',
  25 + 'is_staff',
  26 + 'is_superuser',
47 'groups')}), 27 'groups')}),
48 (_('Important dates'), {'fields': ('last_login', 'date_joined')}) 28 (_('Important dates'), {'fields': ('last_login', 'date_joined')})
49 ) 29 )
@@ -56,4 +36,4 @@ class MyUserAdmin(UserAdmin): @@ -56,4 +36,4 @@ class MyUserAdmin(UserAdmin):
56 ) 36 )
57 37
58 38
59 -admin.site.register(User, MyUserAdmin) 39 +admin.site.register(User, CustomUserAdmin)
colab/accounts/forms.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 2
  3 +from collections import OrderedDict
  4 +
3 from django import forms 5 from django import forms
4 -from django.contrib.auth import get_user_model  
5 -from django.contrib.auth.forms import OrderedDict, ReadOnlyPasswordHashField, \  
6 - default_token_generator 6 +from django.contrib.auth import authenticate, get_user_model
  7 +from django.contrib.auth.forms import ReadOnlyPasswordHashField
  8 +from django.contrib.auth.tokens import default_token_generator
  9 +from django.contrib.sites.shortcuts import get_current_site
  10 +from django.template import loader
  11 +from django.utils.encoding import force_bytes
  12 +from django.utils.http import urlsafe_base64_encode
  13 +from django.utils.text import capfirst
7 from django.utils.translation import ugettext_lazy as _ 14 from django.utils.translation import ugettext_lazy as _
8 15
9 from conversejs.models import XMPPAccount 16 from conversejs.models import XMPPAccount
10 17
11 -from ..super_archives.models import MailingList  
12 from .utils.validators import validate_social_account 18 from .utils.validators import validate_social_account
13 from .utils import mailman 19 from .utils import mailman
14 20
@@ -32,7 +38,7 @@ class UserForm(forms.ModelForm): @@ -32,7 +38,7 @@ class UserForm(forms.ModelForm):
32 username = forms.CharField( 38 username = forms.CharField(
33 39
34 # Forces username to be lowercase always 40 # Forces username to be lowercase always
35 - widget=forms.TextInput(attrs={'style' : 'text-transform: lowercase;'}), 41 + widget=forms.TextInput(attrs={'style': 'text-transform: lowercase;'}),
36 ) 42 )
37 required = ('first_name', 'last_name', 'username') 43 required = ('first_name', 'last_name', 'username')
38 44
@@ -50,48 +56,6 @@ class UserForm(forms.ModelForm): @@ -50,48 +56,6 @@ class UserForm(forms.ModelForm):
50 field.required = True 56 field.required = True
51 57
52 58
53 -class UserCreationForm(UserForm):  
54 -  
55 - class Meta:  
56 - model = User  
57 - fields = ('first_name', 'last_name', 'username')  
58 -  
59 - def clean_username(self):  
60 - username = self.cleaned_data['username']  
61 - username = username.strip()  
62 - if not username:  
63 - raise forms.ValidationError(_('This field cannot be blank.'))  
64 - return username  
65 -  
66 -  
67 -class UserCreationFormNoBrowserId(UserCreationForm):  
68 -  
69 - password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)  
70 - password2 = forms.CharField(label=_("Confirm Password "), widget=forms.PasswordInput)  
71 - email = forms.EmailField(label=_("Email address"), required=True)  
72 -  
73 - class Meta:  
74 - model = User  
75 - fields = ('first_name', 'last_name','email', 'username')  
76 -  
77 - def clean_password2(self):  
78 - password1 = self.cleaned_data.get('password1')  
79 - password2 = self.cleaned_data.get('password2')  
80 -  
81 - if password1 and password2 and password1 != password2:  
82 - raise forms.ValidationError(_("The two password fields didn't match."))  
83 - return password2  
84 -  
85 - def save(self, commit=True):  
86 - """  
87 - Saves the new password.  
88 - """  
89 - self.instance.set_password(self.cleaned_data["password1"])  
90 - if commit:  
91 - self.instance.save()  
92 - return self.instance  
93 -  
94 -  
95 class UserUpdateForm(UserForm): 59 class UserUpdateForm(UserForm):
96 bio = forms.CharField( 60 bio = forms.CharField(
97 widget=forms.Textarea(attrs={'rows': '6', 'maxlength': '200'}), 61 widget=forms.Textarea(attrs={'rows': '6', 'maxlength': '200'}),
@@ -102,10 +66,9 @@ class UserUpdateForm(UserForm): @@ -102,10 +66,9 @@ class UserUpdateForm(UserForm):
102 ) 66 )
103 67
104 def __init__(self, *args, **kwargs): 68 def __init__(self, *args, **kwargs):
105 - super (UserUpdateForm, self).__init__(*args, **kwargs) 69 + super(UserUpdateForm, self).__init__(*args, **kwargs)
106 self.fields.pop('username') 70 self.fields.pop('username')
107 71
108 -  
109 class Meta: 72 class Meta:
110 model = User 73 model = User
111 fields = ('first_name', 'last_name', 74 fields = ('first_name', 'last_name',
@@ -113,7 +76,8 @@ class UserUpdateForm(UserForm): @@ -113,7 +76,8 @@ class UserUpdateForm(UserForm):
113 'google_talk', 'github', 'webpage', 'bio') 76 'google_talk', 'github', 'webpage', 'bio')
114 77
115 twitter = SocialAccountField(url='https://twitter.com/', required=False) 78 twitter = SocialAccountField(url='https://twitter.com/', required=False)
116 - facebook = SocialAccountField(url='https://graph.facebook.com/', required=False) 79 + facebook = SocialAccountField(url='https://graph.facebook.com/',
  80 + required=False)
117 81
118 82
119 class ListsForm(forms.Form): 83 class ListsForm(forms.Form):
@@ -129,10 +93,11 @@ class ListsForm(forms.Form): @@ -129,10 +93,11 @@ class ListsForm(forms.Form):
129 93
130 class ChangeXMPPPasswordForm(forms.ModelForm): 94 class ChangeXMPPPasswordForm(forms.ModelForm):
131 password1 = forms.CharField(label=_("Password"), 95 password1 = forms.CharField(label=_("Password"),
132 - widget=forms.PasswordInput) 96 + widget=forms.PasswordInput)
133 password2 = forms.CharField(label=_("Password confirmation"), 97 password2 = forms.CharField(label=_("Password confirmation"),
134 - widget=forms.PasswordInput,  
135 - help_text=_("Enter the same password as above, for verification.")) 98 + widget=forms.PasswordInput,
  99 + help_text=_(("Enter the same password as above"
  100 + ", for verification.")))
136 101
137 class Meta: 102 class Meta:
138 model = XMPPAccount 103 model = XMPPAccount
@@ -161,6 +126,7 @@ class ChangeXMPPPasswordForm(forms.ModelForm): @@ -161,6 +126,7 @@ class ChangeXMPPPasswordForm(forms.ModelForm):
161 self.instance.save() 126 self.instance.save()
162 return self.instance 127 return self.instance
163 128
  129 +
164 class UserCreationForm(forms.ModelForm): 130 class UserCreationForm(forms.ModelForm):
165 """ 131 """
166 A form that creates a user, with no privileges, from the given username and 132 A form that creates a user, with no privileges, from the given username and
@@ -171,17 +137,21 @@ class UserCreationForm(forms.ModelForm): @@ -171,17 +137,21 @@ class UserCreationForm(forms.ModelForm):
171 'password_mismatch': _("The two password fields didn't match."), 137 'password_mismatch': _("The two password fields didn't match."),
172 } 138 }
173 username = forms.RegexField(label=_("Username"), max_length=30, 139 username = forms.RegexField(label=_("Username"), max_length=30,
174 - regex=r'^[\w.@+-]+$',  
175 - help_text=_("Required. 30 characters or fewer. Letters, digits and "  
176 - "@/./+/-/_ only."),  
177 - error_messages={  
178 - 'invalid': _("This value may contain only letters, numbers and "  
179 - "@/./+/-/_ characters.")}) 140 + regex=r'^[\w.@+-]+$',
  141 + help_text=_(("Required. 30 characters or fewer"
  142 + ". Letters, digits and "
  143 + "@/./+/-/_ only.")),
  144 + error_messages={
  145 + 'invalid': _(("This value may contain only"
  146 + " letters, numbers and "
  147 + "@/./+/-/_ characters."))})
180 password1 = forms.CharField(label=_("Password"), 148 password1 = forms.CharField(label=_("Password"),
181 - widget=forms.PasswordInput) 149 + widget=forms.PasswordInput)
182 password2 = forms.CharField(label=_("Password confirmation"), 150 password2 = forms.CharField(label=_("Password confirmation"),
183 - widget=forms.PasswordInput,  
184 - help_text=_("Enter the same password as above, for verification.")) 151 + widget=forms.PasswordInput,
  152 + help_text=_(("Enter the same password as above"
  153 + ", for verification.")))
  154 + email = forms.EmailField(required=True)
185 155
186 class Meta: 156 class Meta:
187 model = User 157 model = User
@@ -190,7 +160,7 @@ class UserCreationForm(forms.ModelForm): @@ -190,7 +160,7 @@ class UserCreationForm(forms.ModelForm):
190 def clean_username(self): 160 def clean_username(self):
191 # Since User.username is unique, this check is redundant, 161 # Since User.username is unique, this check is redundant,
192 # but it sets a nicer error message than the ORM. See #13147. 162 # but it sets a nicer error message than the ORM. See #13147.
193 - username = self.cleaned_data["username"] 163 + username = self.cleaned_data["username"].strip()
194 try: 164 try:
195 User._default_manager.get(username=username) 165 User._default_manager.get(username=username)
196 except User.DoesNotExist: 166 except User.DoesNotExist:
@@ -227,9 +197,15 @@ class UserChangeForm(forms.ModelForm): @@ -227,9 +197,15 @@ class UserChangeForm(forms.ModelForm):
227 'invalid': _("This value may contain only letters, numbers and " 197 'invalid': _("This value may contain only letters, numbers and "
228 "@/./+/-/_ characters.")}) 198 "@/./+/-/_ characters.")})
229 password = ReadOnlyPasswordHashField(label=_("Password"), 199 password = ReadOnlyPasswordHashField(label=_("Password"),
230 - help_text=_("Raw passwords are not stored, so there is no way to see "  
231 - "this user's password, but you can change the password "  
232 - "using <a href=\"password/\">this form</a>.")) 200 + help_text=_("Raw passwords are not"
  201 + " stored, so there is no"
  202 + " way to see "
  203 + "this user's password, "
  204 + "but you can change the "
  205 + "password "
  206 + "using <a "
  207 + "href=\"password/\">this"
  208 + " form</a>."))
233 209
234 class Meta: 210 class Meta:
235 model = User 211 model = User
@@ -241,6 +217,9 @@ class UserChangeForm(forms.ModelForm): @@ -241,6 +217,9 @@ class UserChangeForm(forms.ModelForm):
241 if f is not None: 217 if f is not None:
242 f.queryset = f.queryset.select_related('content_type') 218 f.queryset = f.queryset.select_related('content_type')
243 219
  220 + # Set email as required field
  221 + self.fields['email'].required = True
  222 +
244 def clean_password(self): 223 def clean_password(self):
245 # Regardless of what the user provides, return the initial value. 224 # Regardless of what the user provides, return the initial value.
246 # This is done here, rather than on the field, because the 225 # This is done here, rather than on the field, because the
@@ -248,6 +227,37 @@ class UserChangeForm(forms.ModelForm): @@ -248,6 +227,37 @@ class UserChangeForm(forms.ModelForm):
248 return self.initial["password"] 227 return self.initial["password"]
249 228
250 229
  230 +class UserCreationFormNoBrowserId(UserCreationForm):
  231 +
  232 + password1 = forms.CharField(label=_("Password"),
  233 + widget=forms.PasswordInput)
  234 + password2 = forms.CharField(label=_("Confirm Password "),
  235 + widget=forms.PasswordInput)
  236 + email = forms.EmailField(label=_("Email address"), required=True)
  237 +
  238 + class Meta:
  239 + model = User
  240 + fields = ('first_name', 'last_name', 'email', 'username')
  241 +
  242 + def clean_password2(self):
  243 + password1 = self.cleaned_data.get('password1')
  244 + password2 = self.cleaned_data.get('password2')
  245 +
  246 + if password1 and password2 and password1 != password2:
  247 + raise forms.ValidationError(
  248 + _("The two password fields didn't match."))
  249 + return password2
  250 +
  251 + def save(self, commit=True):
  252 + """
  253 + Saves the new password.
  254 + """
  255 + self.instance.set_password(self.cleaned_data["password1"])
  256 + if commit:
  257 + self.instance.save()
  258 + return self.instance
  259 +
  260 +
251 class AuthenticationForm(forms.Form): 261 class AuthenticationForm(forms.Form):
252 """ 262 """
253 Base class for authenticating users. Extend this to get a form that accepts 263 Base class for authenticating users. Extend this to get a form that accepts
@@ -273,9 +283,11 @@ class AuthenticationForm(forms.Form): @@ -273,9 +283,11 @@ class AuthenticationForm(forms.Form):
273 283
274 # Set the label for the "username" field. 284 # Set the label for the "username" field.
275 UserModel = get_user_model() 285 UserModel = get_user_model()
276 - self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD) 286 + self.username_field = UserModel._meta.get_field(
  287 + UserModel.USERNAME_FIELD)
277 if self.fields['username'].label is None: 288 if self.fields['username'].label is None:
278 - self.fields['username'].label = capfirst(self.username_field.verbose_name) 289 + self.fields['username'].label = capfirst(
  290 + self.username_field.verbose_name)
279 291
280 def clean(self): 292 def clean(self):
281 username = self.cleaned_data.get('username') 293 username = self.cleaned_data.get('username')
@@ -362,10 +374,12 @@ class PasswordResetForm(forms.Form): @@ -362,10 +374,12 @@ class PasswordResetForm(forms.Form):
362 email = loader.render_to_string(email_template_name, c) 374 email = loader.render_to_string(email_template_name, c)
363 375
364 if html_email_template_name: 376 if html_email_template_name:
365 - html_email = loader.render_to_string(html_email_template_name, c) 377 + html_email = loader.render_to_string(html_email_template_name,
  378 + c)
366 else: 379 else:
367 html_email = None 380 html_email = None
368 - send_mail(subject, email, from_email, [user.email], html_message=html_email) 381 + send_mail(subject, email, from_email, [user.email],
  382 + html_message=html_email)
369 383
370 384
371 class SetPasswordForm(forms.Form): 385 class SetPasswordForm(forms.Form):