Commit 8b5b2830c4b822cb87d3948691d5523284f7ae70

Authored by Felipe Henrique de Almeida Bormann
2 parents 8dfa451e 3fae436a

Merge branch 'refactoring' of https://github.com/amadeusproject/amadeuslms into refactoring

amadeus/templates/base.html
@@ -118,7 +118,7 @@ @@ -118,7 +118,7 @@
118 <ul class="dropdown-menu pull-right"> 118 <ul class="dropdown-menu pull-right">
119 <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> 119 <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li>
120 <li><a href="{% url 'users:edit_profile' %}">{% trans 'Edit Profile' %}</a></li> 120 <li><a href="{% url 'users:edit_profile' %}">{% trans 'Edit Profile' %}</a></li>
121 - <li><a href="#">{% trans 'Change Password' %}</a></li> 121 + <li><a href="{% url 'users:change_pass' %}">{% trans 'Change Password' %}</a></li>
122 <li><a href="#">{% trans 'Delete Account' %}</a></li> 122 <li><a href="#">{% trans 'Delete Account' %}</a></li>
123 </ul> 123 </ul>
124 </li> 124 </li>
users/forms.py
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 from django import forms 2 from django import forms
3 from django.utils.translation import ugettext_lazy as _ 3 from django.utils.translation import ugettext_lazy as _
4 from rolepermissions.shortcuts import assign_role 4 from rolepermissions.shortcuts import assign_role
  5 +from django.contrib.auth import update_session_auth_hash
5 from .models import User 6 from .models import User
6 7
7 class Validation(forms.ModelForm): 8 class Validation(forms.ModelForm):
@@ -14,49 +15,57 @@ class Validation(forms.ModelForm): @@ -14,49 +15,57 @@ class Validation(forms.ModelForm):
14 if image: 15 if image:
15 if hasattr(image, '_size'): 16 if hasattr(image, '_size'):
16 if image._size > self.MAX_UPLOAD_SIZE: 17 if image._size > self.MAX_UPLOAD_SIZE:
17 - raise forms.ValidationError(_("The image is too large. It should have less than 2MB.")) 18 + self._errors['image'] = [_("The image is too large. It should have less than 2MB.")]
18 19
19 - return image 20 + return ValueError
20 21
21 - def clean_password(self):  
22 - password = self.cleaned_data.get('password') 22 + return image
23 23
  24 + def clean_new_password(self):
  25 + password = self.cleaned_data.get('new_password')
  26 + print(self.cleaned_data)
24 if self.is_edit and len(password) == 0: 27 if self.is_edit and len(password) == 0:
25 return password 28 return password
26 29
27 # At least MIN_LENGTH long 30 # At least MIN_LENGTH long
28 if len(password) < self.MIN_PASS_LENGTH: 31 if len(password) < self.MIN_PASS_LENGTH:
29 - raise forms.ValidationError(_("The password must contain at least % d characters." % self.MIN_PASS_LENGTH)) 32 + self._errors['new_password'] = [_("The new password must contain at least % d characters." % self.MIN_PASS_LENGTH)]
  33 +
  34 + return ValueError
30 35
31 # At least one letter and one non-letter 36 # At least one letter and one non-letter
32 first_isalpha = password[0].isalpha() 37 first_isalpha = password[0].isalpha()
33 if all(c.isalpha() == first_isalpha for c in password): 38 if all(c.isalpha() == first_isalpha for c in password):
34 - raise forms.ValidationError(_('The password must contain at least one letter and at least one digit or a punctuation character.')) 39 + self._errors['new_password'] = [_('The password must contain at least one letter and at least one digit or a punctuation character.')]
  40 +
  41 + return ValueError
35 42
36 return password 43 return password
37 44
38 def clean_password2(self): 45 def clean_password2(self):
39 - password = self.cleaned_data.get("password") 46 + password = self.cleaned_data.get("new_password")
40 password2 = self.cleaned_data.get("password2") 47 password2 = self.cleaned_data.get("password2")
41 48
42 if self.is_edit and len(password) == 0: 49 if self.is_edit and len(password) == 0:
43 return password2 50 return password2
44 51
45 if password and password2 and password != password2: 52 if password and password2 and password != password2:
46 - raise forms.ValidationError(_('The confirmation password is incorrect.')) 53 + self._errors['password2'] = [_('The confirmation password is incorrect.')]
  54 +
  55 + return ValueError
47 56
48 return password2 57 return password2
49 58
50 class RegisterUserForm(Validation): 59 class RegisterUserForm(Validation):
51 - password = forms.CharField(label=_('Password'), widget = forms.PasswordInput)  
52 - password2 = forms.CharField(label = _('Confirm Password'), widget = forms.PasswordInput) 60 + new_password = forms.CharField(label=_('Password'), widget = forms.PasswordInput(render_value=True))
  61 + password2 = forms.CharField(label = _('Confirm Password'), widget = forms.PasswordInput(render_value=True))
53 62
54 is_edit = False 63 is_edit = False
55 64
56 def save(self, commit=True): 65 def save(self, commit=True):
57 super(RegisterUserForm, self).save(commit=False) 66 super(RegisterUserForm, self).save(commit=False)
58 67
59 - self.instance.set_password(self.cleaned_data['password']) 68 + self.instance.set_password(self.cleaned_data['new_password'])
60 69
61 self.instance.save() 70 self.instance.save()
62 71
@@ -78,9 +87,11 @@ class ProfileForm(Validation): @@ -78,9 +87,11 @@ class ProfileForm(Validation):
78 87
79 class Meta: 88 class Meta:
80 model = User 89 model = User
81 - fields = ['social_name', 'description', 'show_email', 'image'] 90 + fields = ['email', 'username', 'last_name', 'social_name', 'description', 'show_email', 'image']
82 widgets = { 91 widgets = {
83 'description': forms.Textarea, 92 'description': forms.Textarea,
  93 + 'username': forms.TextInput(attrs = {'readonly': 'readonly'}),
  94 + 'last_name': forms.TextInput(attrs = {'readonly': 'readonly'})
84 } 95 }
85 96
86 class UserForm(Validation): 97 class UserForm(Validation):
@@ -94,19 +105,19 @@ class UserForm(Validation): @@ -94,19 +105,19 @@ class UserForm(Validation):
94 self.is_edit = is_update 105 self.is_edit = is_update
95 106
96 if self.is_edit: 107 if self.is_edit:
97 - del self.fields['password'] 108 + del self.fields['new_password']
98 del self.fields['password2'] 109 del self.fields['password2']
99 110
100 if not is_edit: 111 if not is_edit:
101 - password = forms.CharField(label=_('Password'), widget = forms.PasswordInput, required = False)  
102 - password2 = forms.CharField(label = _('Confirm Password'), widget = forms.PasswordInput, required = False) 112 + new_password = forms.CharField(label=_('Password'), widget = forms.PasswordInput(render_value=True), required = False)
  113 + password2 = forms.CharField(label = _('Confirm Password'), widget = forms.PasswordInput(render_value=True), required = False)
103 114
104 115
105 def save(self, commit=True): 116 def save(self, commit=True):
106 super(UserForm, self).save(commit=False) 117 super(UserForm, self).save(commit=False)
107 118
108 if not self.is_edit: 119 if not self.is_edit:
109 - self.instance.set_password(self.cleaned_data['password']) 120 + self.instance.set_password(self.cleaned_data['new_password'])
110 121
111 self.instance.save() 122 self.instance.save()
112 123
@@ -117,4 +128,46 @@ class UserForm(Validation): @@ -117,4 +128,46 @@ class UserForm(Validation):
117 fields = ['email', 'username', 'last_name', 'social_name', 'description', 'show_email', 'image', 'is_staff', 'is_active'] 128 fields = ['email', 'username', 'last_name', 'social_name', 'description', 'show_email', 'image', 'is_staff', 'is_active']
118 widgets = { 129 widgets = {
119 'description': forms.Textarea, 130 'description': forms.Textarea,
120 - }  
121 \ No newline at end of file 131 \ No newline at end of file
  132 + }
  133 +
  134 +class ChangePassForm(Validation):
  135 + def __init__(self, *args, **kwargs):
  136 + self.user = kwargs.pop('user', None)
  137 + self.request = kwargs.pop('request', None)
  138 + super(ChangePassForm, self).__init__(*args, **kwargs)
  139 +
  140 + is_edit = False
  141 +
  142 + new_password = forms.CharField(label=_('New Password'), widget = forms.PasswordInput(render_value=True), required = True)
  143 + password2 = forms.CharField(label = _('Confirm Password'), widget = forms.PasswordInput(render_value=True), required = True)
  144 +
  145 + def clean_password(self):
  146 + password = self.cleaned_data.get('password', None)
  147 +
  148 + if not self.user.check_password(password):
  149 + self._errors['password'] = [_('The value inputed does not match with your actual password.')]
  150 +
  151 + return ValueError
  152 +
  153 + return password
  154 +
  155 + def save(self, commit=True):
  156 + super(ChangePassForm, self).save(commit=False)
  157 +
  158 + self.instance.set_password(self.cleaned_data['new_password'])
  159 +
  160 + update_session_auth_hash(self.request, self.instance)
  161 +
  162 + self.instance.save()
  163 +
  164 + return self.instance
  165 +
  166 + class Meta:
  167 + model = User
  168 + fields = ['password']
  169 + labels = {
  170 + 'password': _('Actual Password')
  171 + }
  172 + widgets = {
  173 + 'password': forms.PasswordInput
  174 + }
122 \ No newline at end of file 175 \ No newline at end of file
users/templates/users/_form.html
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput"> 7 <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
8 {% if field.auto_id == 'id_image' %} 8 {% if field.auto_id == 'id_image' %}
9 {% if field.field.required %} 9 {% if field.field.required %}
10 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label> 10 + <label for="{{ field.auto_id }}">{{ field.label }} <span>*</span></label>
11 {% else %} 11 {% else %}
12 <label for="{{ field.auto_id }}">{{ field.label }}</label> 12 <label for="{{ field.auto_id }}">{{ field.label }}</label>
13 {% endif %} 13 {% endif %}
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 </div> 22 </div>
23 {% elif field.auto_id == 'id_description' %} 23 {% elif field.auto_id == 'id_description' %}
24 {% if field.field.required %} 24 {% if field.field.required %}
25 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label> 25 + <label for="{{ field.auto_id }}">{{ field.label }} <span>*</span></label>
26 {% else %} 26 {% else %}
27 <label for="{{ field.auto_id }}">{{ field.label }}</label> 27 <label for="{{ field.auto_id }}">{{ field.label }}</label>
28 {% endif %} 28 {% endif %}
@@ -35,7 +35,7 @@ @@ -35,7 +35,7 @@
35 </div> 35 </div>
36 {% else %} 36 {% else %}
37 {% if field.field.required %} 37 {% if field.field.required %}
38 - <label for="{{ field.auto_id }}">{{ field.label }}<span>*</span></label> 38 + <label for="{{ field.auto_id }}">{{ field.label }} <span>*</span></label>
39 {% else %} 39 {% else %}
40 <label for="{{ field.auto_id }}">{{ field.label }}</label> 40 <label for="{{ field.auto_id }}">{{ field.label }}</label>
41 {% endif %} 41 {% endif %}
@@ -56,7 +56,12 @@ @@ -56,7 +56,12 @@
56 {% endif %} 56 {% endif %}
57 </div> 57 </div>
58 {% endfor %} 58 {% endfor %}
59 - <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center">  
60 - <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-primary" /> 59 + <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12">
  60 + <div class="pull-left">
  61 + <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-primary" />
  62 + </div>
  63 + <div class="pull-right">
  64 + <a href="{% url back_url %}" class="btn btn-raised btn-default">{% trans 'Cancel' %}</a>
  65 + </div>
61 </div> 66 </div>
62 </form> 67 </form>
63 \ No newline at end of file 68 \ No newline at end of file
users/templates/users/change_password.html
@@ -5,53 +5,16 @@ @@ -5,53 +5,16 @@
5 {% load django_bootstrap_breadcrumbs %} 5 {% load django_bootstrap_breadcrumbs %}
6 6
7 {% block breadcrumbs %} 7 {% block breadcrumbs %}
8 -  
9 - {{ block.super }}  
10 - {% breadcrumb 'Edit' 'users:update_profile' %}  
11 - 8 + {{ block.super }}
  9 + {% breadcrumb 'Change Password' 'users:change_pass' %}
12 {% endblock %} 10 {% endblock %}
13 11
14 {% block content %} 12 {% block content %}
15 - {% if messages %}  
16 - {% for message in messages %}  
17 - <div class="alert alert-success alert-dismissible" role="alert">  
18 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
19 - <span aria-hidden="true">&times;</span>  
20 - </button>  
21 - <p>{{ message }}</p>  
22 - </div>  
23 - {% endfor %}  
24 - {% endif %}  
25 - <div class="row">  
26 - <div class="col-md-12">  
27 - <div class="well well-lg">  
28 - <form method="post" action="" enctype="multipart/form-data">  
29 - {% csrf_token %}  
30 - <div class="form-group">  
31 - <label class="control-label" for="focusedInput1">{% trans 'Current Password' %}</label>  
32 - <input type="password" class="form-control" id="inputPassword" placeholder="{% trans 'Password' %}">  
33 - </div>  
34 - <div class="form-group">  
35 - <label class="control-label" for="focusedInput1">{% trans 'New Password' %}</label>  
36 - <input type="password" class="form-control" id="inputPassword" placeholder="{% trans 'Password' %}">  
37 - </div>  
38 - <div class="form-group">  
39 - <label class="control-label" for="focusedInput1">{% trans 'Confirmation' %}</label>  
40 - <input type="password" class="form-control" id="inputPassword" placeholder="{% trans 'Password' %}">  
41 - </div>  
42 - <div class="row">  
43 - <div class="col-md-3 col-sm-2 col-xs-2">  
44 - <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-block btn-success" /> 13 + <div class="card">
  14 + <div class="card-content">
  15 + <div class="card-body">
  16 + {% include "users/_form.html" with back_url="users:profile" %}
45 </div> 17 </div>
46 - <div class="col-md-3 col-sm-2 col-xs-2">  
47 - <a href="{% url 'users:profile' %}" class="btn btn-raised btn-block btn-default" >{% trans 'Cancel' %}</a>  
48 - </div>  
49 - </div>  
50 - </form>  
51 - </div>  
52 - </div> 18 + </div>
53 </div> 19 </div>
54 -  
55 -  
56 - <br clear="all" />  
57 {% endblock %} 20 {% endblock %}
users/templates/users/create.html
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 <div class="card"> 11 <div class="card">
12 <div class="card-content"> 12 <div class="card-content">
13 <div class="card-body"> 13 <div class="card-body">
14 - {% include 'users/_form.html' %} 14 + {% include 'users/_form.html' with back_url="users:manage" %}
15 </div> 15 </div>
16 </div> 16 </div>
17 </div> 17 </div>
users/templates/users/edit_profile.html
@@ -12,62 +12,13 @@ @@ -12,62 +12,13 @@
12 12
13 13
14 {% block content %} 14 {% block content %}
15 - {% if messages %}  
16 - {% for message in messages %}  
17 - <div class="alert alert-success alert-dismissible" role="alert">  
18 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
19 - <span aria-hidden="true">&times;</span>  
20 - </button>  
21 - <p>{{ message }}</p>  
22 - </div>  
23 - {% endfor %}  
24 - {% endif %}  
25 - <div class="card mg-b-5m">  
26 - <div class="card-content">  
27 - <div class="card-body">  
28 - <form method="post" action="" enctype="multipart/form-data">  
29 - {% csrf_token %}  
30 - {% for field in form %}  
31 - <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">  
32 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
33 - {% if field.auto_id == 'id_image' %}  
34 - {% render_field field class='form-control input-sm' %}  
35 - <div class="input-group">  
36 - <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your file...' %}">  
37 - <span class="input-group-btn input-group-sm">  
38 - <button type="button" class="btn btn-fab btn-fab-mini">  
39 - <i class="material-icons">attach_file</i>  
40 - </button>  
41 - </span>  
42 - </div>  
43 - {% elif field.auto_id == 'id_description' %}  
44 - {% render_field field class='form-control text_wysiwyg' %}  
45 - {% else %}  
46 - {% render_field field class='form-control' %}  
47 - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>  
48 - {% endif %}  
49 - {% if field.errors %}  
50 - <div class="alert alert-danger alert-dismissible" role="alert">  
51 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
52 - <span aria-hidden="true">&times;</span>  
53 - </button>  
54 - <ul>  
55 - {% for error in field.errors %}  
56 - <li>{{ error }}</li>  
57 - {% endfor %}  
58 - </ul>  
59 - </div>  
60 - {% endif %}  
61 - </div>  
62 - {% endfor %}  
63 - <div class="col-md-offset-2 col-md-2 col-sm-2 col-xs-2">  
64 - <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-success" />  
65 - </div>  
66 - <div class="col-md-offset-3 col-md-2 col-sm-2 col-xs-2">  
67 - <a href="{% url 'users:profile' %}" class="btn btn-raised btn-default" >{% trans 'Cancel' %}</a>  
68 - </div>  
69 - </form>  
70 - </div>  
71 - </div>  
72 - </div> 15 + <div class="card">
  16 + <div class="card-content">
  17 + <div class="card-body">
  18 + {% include "users/_form.html" with back_url="users:profile" %}
  19 + </div>
  20 + </div>
  21 + </div>
  22 + <br clear="all" />
  23 + <br clear="all" />
73 {% endblock %} 24 {% endblock %}
users/templates/users/update.html
@@ -14,21 +14,10 @@ @@ -14,21 +14,10 @@
14 14
15 15
16 {% block content %} 16 {% block content %}
17 - {% if messages %}  
18 - {% for message in messages %}  
19 - <div class="alert alert-success alert-dismissible" role="alert">  
20 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
21 - <span aria-hidden="true">&times;</span>  
22 - </button>  
23 - <p>{{ message }}</p>  
24 - </div>  
25 - {% endfor %}  
26 - {% endif %}  
27 -  
28 <div class="card mg-b-5m"> 17 <div class="card mg-b-5m">
29 <div class="card-content"> 18 <div class="card-content">
30 <div class="card-body"> 19 <div class="card-body">
31 - {% include 'users/_form.html' %} 20 + {% include 'users/_form.html' with back_url="users:manage" %}
32 </div> 21 </div>
33 </div> 22 </div>
34 </div> 23 </div>
@@ -12,4 +12,5 @@ urlpatterns = [ @@ -12,4 +12,5 @@ urlpatterns = [
12 url(r'^create/$', views.CreateView.as_view(), name = 'create'), 12 url(r'^create/$', views.CreateView.as_view(), name = 'create'),
13 url(r'^profile/$', views.Profile.as_view(), name = 'profile'), 13 url(r'^profile/$', views.Profile.as_view(), name = 'profile'),
14 url(r'^edit_profile/$', views.UpdateProfile.as_view(), name = 'edit_profile'), 14 url(r'^edit_profile/$', views.UpdateProfile.as_view(), name = 'edit_profile'),
  15 + url(r'^change_pass/$', views.ChangePassView.as_view(), name='change_pass'),
15 ] 16 ]
users/views.py
@@ -14,7 +14,7 @@ from itertools import chain @@ -14,7 +14,7 @@ from itertools import chain
14 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 14 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
15 15
16 from .models import User 16 from .models import User
17 -from .forms import RegisterUserForm, ProfileForm, UserForm 17 +from .forms import RegisterUserForm, ProfileForm, UserForm, ChangePassForm
18 18
19 #API IMPORTS 19 #API IMPORTS
20 from rest_framework import viewsets 20 from rest_framework import viewsets
@@ -179,6 +179,44 @@ class UpdateView(LoginRequiredMixin, generic.UpdateView): @@ -179,6 +179,44 @@ class UpdateView(LoginRequiredMixin, generic.UpdateView):
179 179
180 return context 180 return context
181 181
  182 +class ChangePassView(LoginRequiredMixin, generic.UpdateView):
  183 + login_url = reverse_lazy("users:login")
  184 + redirect_field_name = 'next'
  185 +
  186 + template_name = 'users/change_password.html'
  187 + slug_field = 'email'
  188 + slug_url_kwarg = 'email'
  189 + context_object_name = 'acc'
  190 + model = User
  191 + form_class = ChangePassForm
  192 + success_url = reverse_lazy('users:profile')
  193 +
  194 + def get_form_kwargs(self):
  195 + kwargs = super(ChangePassView, self).get_form_kwargs()
  196 +
  197 + kwargs.update({'user': self.request.user})
  198 + kwargs.update({'request': self.request})
  199 +
  200 + return kwargs
  201 +
  202 + def get_object(self):
  203 + user = get_object_or_404(User, email = self.request.user.email)
  204 +
  205 + return user
  206 +
  207 + def form_valid(self, form):
  208 + form.save()
  209 +
  210 + messages.success(self.request, _('Password changed successfully!'))
  211 +
  212 + return super(ChangePassView, self).form_valid(form)
  213 +
  214 + def get_context_data (self, **kwargs):
  215 + context = super(ChangePassView, self).get_context_data(**kwargs)
  216 + context['title'] = _("Change Password")
  217 +
  218 + return context
  219 +
182 class Profile(LoginRequiredMixin, generic.DetailView): 220 class Profile(LoginRequiredMixin, generic.DetailView):
183 login_url = reverse_lazy("users:login") 221 login_url = reverse_lazy("users:login")
184 redirect_field_name = 'next' 222 redirect_field_name = 'next'
@@ -187,7 +225,7 @@ class Profile(LoginRequiredMixin, generic.DetailView): @@ -187,7 +225,7 @@ class Profile(LoginRequiredMixin, generic.DetailView):
187 template_name = 'users/profile.html' 225 template_name = 'users/profile.html'
188 226
189 def get_object(self): 227 def get_object(self):
190 - user = get_object_or_404(User, username = self.request.user.username) 228 + user = get_object_or_404(User, email = self.request.user.email)
191 229
192 return user 230 return user
193 231
@@ -254,12 +292,12 @@ def login(request): @@ -254,12 +292,12 @@ def login(request):
254 user = authenticate(username=username, password=password) 292 user = authenticate(username=username, password=password)
255 if user is not None: 293 if user is not None:
256 login_user(request, user) 294 login_user(request, user)
257 - return redirect(reverse("users:login")) 295 + return redirect(reverse("home"))
258 else: 296 else:
259 messages.add_message(request, messages.ERROR, _('E-mail or password are incorrect.')) 297 messages.add_message(request, messages.ERROR, _('E-mail or password are incorrect.'))
260 context["username"] = username 298 context["username"] = username
261 elif request.user.is_authenticated: 299 elif request.user.is_authenticated:
262 - return redirect('home') 300 + return redirect(reverse('home'))
263 301
264 return render(request,"users/login.html",context) 302 return render(request,"users/login.html",context)
265 303