Commit 2fbba969 authored by Birin Sanchez's avatar Birin Sanchez

Add change password function in profile page.

Signed-off-by: Birin Sanchez's avatarBirin Sanchez <birin.sanchez@puri.sm>
parent 3fd18a81
......@@ -151,13 +151,11 @@ SPDX-License-Identifier: AGPL-3.0
{% endif %}
{% if DEBUG_CHANGE_PASSWORD %}
<h2>{% trans "Profile management" %}</h2>
<ul>
<li><a href="{% url 'auth_password_change' %}">{% trans "Change password" %}</a></li>
<li><a href="{% url 'password_change' %}">{% trans "Change password" %}</a></li>
</ul>
{% endif %}
</article>
<nav class="col-2">
......
......@@ -24,7 +24,7 @@ from ldapregister.forms import RegistrationForm
from ldapregister.views import LdhLoginView
from cart.views import CartRegistrationView
from purist.views import Recovery
from purist.views import Recovery, PasswordChange, PasswordChangeDone
from invitation.views import InvitationRegistrationView
#
......@@ -51,6 +51,10 @@ urlpatterns = [
# url(r'^accounts/register/$', RegistrationView.as_view(form_class=RegistrationForm), name='registration_register'),
url(r'^accounts/login/$', LdhLoginView.as_view(), name='auth_login'),
url(r'^accounts/recover/$', Recovery.as_view(), name='password_reset_recover'),
url(r'^accounts/password_change/$', PasswordChange.as_view(),
name='password_change'),
url(r'^accounts/password_change_done/$', PasswordChangeDone.as_view(),
name='password_change_done'),
url(r'^accounts/', include('password_reset.urls')),
url(r'^accounts/', include('registration.backends.simple.urls')),
url(r'^download/', include('django_agpl.urls')),
......
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.forms import PasswordChangeForm \
as BasePasswordChangeForm
from django.contrib.auth import authenticate
from password_reset.forms import PasswordRecoveryForm as BasePasswordRecoveryForm
......@@ -10,3 +13,30 @@ class PasswordRecoveryForm(BasePasswordRecoveryForm):
self.fields['username_or_email'] = forms.CharField(
label = _('Enter your recovery email')
)
class PasswordChangeForm(BasePasswordChangeForm):
# Override clean_old_password() to use authenticate which uses
# LDAP authentication
def clean_old_password(self):
old_password = self.cleaned_data["old_password"]
if not authenticate(
request=None,
username=self.user.get_username(),
password=old_password
):
raise forms.ValidationError(
self.error_messages['password_incorrect'],
code='password_incorrect',
)
return old_password
# Override save() to change password in LDAP and WooCommerce. We
# don't really use commit as the new password is always stored.
def save(self, commit=True):
password = self.cleaned_data["new_password1"]
self.user.set_ldap_password(password)
self.user.set_woocommerce_password(raw_password=password,
woocommerce_id=None)
return self.user
<!DOCTYPE html>
{% load static %}
{% load i18n %}
<!--
Keel (LDH middleware)
Copyright 2017-2018 Purism SPC
https://source.puri.sm/liberty/ldh_middleware
SPDX-License-Identifier: AGPL-3.0
-->
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="{% static 'layout.css' %}"/>
<link rel="stylesheet" href="{% static 'theme.css' %}"/>
<title>{% trans "Change Password" %}</title>
<link rel="icon" sizes="960x960" href="{% static 'favicon.png' %}"/>
<meta name="application-name" content="{{ site_title }}"/>
<meta charset="UTF-8"/>
</head>
<body>
<header>
<div id="title_box">
<a href="{% url 'home' %}"><img class="logo" src="{% static 'logo.png' %}" alt="{{ site_title }}"/></a>
<div id="title_text">
<h1>{% trans "Change Password" %}</h1>
</div>
</div>
<div id="log_state">
{% if request.user.is_authenticated %}
{% trans "Logged in as" %} {{ username }}<br/>
<a href="{% url 'profile' %}">{% trans "Profile" %}</a> |
{% if request.user.is_superuser %}
<a href="{% url 'admin:index' %}">{% trans "Admin" %}</a> |
{% endif %}
<a href="{% url 'auth_logout' %}">{% trans "Log out" %}</a>
{% else %}
{% trans "You are not logged in." %}<br/>
<a href="{% url 'auth_login' %}">{% trans "Log in" %}</a>
<!--
{% trans "or" %}
<a href="{% url 'registration_register' %}">{% trans "register." %}</a>
-->
{% endif %}
</div>
</header>
<hr/>
<main class="col-wrapper form">
<article class="col-1">
<form method="post">{% csrf_token %}
<div>
{% if form.errors %}
<p class="errornote">
{% if form.errors.items|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
</p>
{% endif %}
<p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p>
<fieldset>
<div >
{{ form.old_password.errors }}
{{ form.old_password.label_tag }} {{ form.old_password }}
</div>
<div >
{{ form.new_password1.errors }}
{{ form.new_password1.label_tag }} {{ form.new_password1 }}
{% if form.new_password1.help_text %}
<div class="help">{{ form.new_password1.help_text|safe }}</div>
{% endif %}
</div>
<div >
{{ form.new_password2.errors }}
{{ form.new_password2.label_tag }} {{ form.new_password2 }}
{% if form.new_password2.help_text %}
<div class="help">{{ form.new_password2.help_text|safe }}</div>
{% endif %}
</div>
</fieldset>
<div >
<input type="submit" value="{% trans 'Change my password' %}" class="default" />
</div>
</div>
</form>
</main>
<footer>
<div id="footer_block">
<p>
<em>{{ site_title }}</em> provided by <a href="{{ site_provider_link }}">{{ site_provider }}</a><br />
Code shared under AGPL-3.0-or-later
(<a href="https://source.puri.sm/liberty/ldh_middleware">project</a>,
<a href="{% url 'download-zip' %}">source</a>,
<a href="{% url 'jslicense' %}" rel="jslicense">javascript</a>)
</p>
</div>
</footer>
</body>
</html>
<!DOCTYPE html>
{% load static %}
{% load i18n %}
<!--
Keel (LDH middleware)
Copyright 2017-2018 Purism SPC
https://source.puri.sm/liberty/ldh_middleware
SPDX-License-Identifier: AGPL-3.0
-->
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="{% static 'layout.css' %}"/>
<link rel="stylesheet" href="{% static 'theme.css' %}"/>
<title>{% trans "Change Password" %}</title>
<link rel="icon" sizes="960x960" href="{% static 'favicon.png' %}"/>
<meta name="application-name" content="{{ site_title }}"/>
<meta charset="UTF-8"/>
</head>
<body>
<header>
<div id="title_box">
<a href="{% url 'home' %}"><img class="logo" src="{% static 'logo.png' %}" alt="{{ site_title }}"/></a>
<div id="title_text">
<h1>{% trans "Change Password" %}</h1>
</div>
</div>
<div id="log_state">
{% if request.user.is_authenticated %}
{% trans "Logged in as" %} {{ username }}<br/>
<a href="{% url 'profile' %}">{% trans "Profile" %}</a> |
{% if request.user.is_superuser %}
<a href="{% url 'admin:index' %}">{% trans "Admin" %}</a> |
{% endif %}
<a href="{% url 'auth_logout' %}">{% trans "Log out" %}</a>
{% else %}
{% trans "You are not logged in." %}<br/>
<a href="{% url 'auth_login' %}">{% trans "Log in" %}</a>
<!--
{% trans "or" %}
<a href="{% url 'registration_register' %}">{% trans "register." %}</a>
-->
{% endif %}
</div>
</header>
<hr/>
<main class="col-wrapper form">
<article class="col-1">
<p>{% trans 'Your password was changed successfully.' %}</p>
<a href="{% url 'profile' %}">{% trans "Back to profile" %}</a>
</main>
<footer>
<div id="footer_block">
<p>
<em>{{ site_title }}</em> provided by <a href="{{ site_provider_link }}">{{ site_provider }}</a><br />
Code shared under AGPL-3.0-or-later
(<a href="https://source.puri.sm/liberty/ldh_middleware">project</a>,
<a href="{% url 'download-zip' %}">source</a>,
<a href="{% url 'jslicense' %}" rel="jslicense">javascript</a>)
</p>
</div>
</footer>
</body>
</html>
......@@ -8,7 +8,12 @@ from django.http import Http404, FileResponse
from password_reset.views import Recover
from .serializers import UserSerializer
from .forms import PasswordRecoveryForm
from .forms import PasswordRecoveryForm, PasswordChangeForm
from django.contrib.auth.views import PasswordChangeView \
as BasePasswordChangeView
from django.contrib.auth.views import PasswordChangeDoneView \
as BasePasswordChangeDoneView
from django.urls import reverse_lazy
class UserDetail(APIView):
......@@ -32,6 +37,34 @@ class Recovery(Recover):
form_class = PasswordRecoveryForm
class PasswordChangeDone(BasePasswordChangeDoneView):
template_name = 'purist/change_password_done.html'
def get_context_data(self, **kwargs):
context = super(PasswordChangeDone, self).get_context_data(**kwargs)
context['username'] = self.request.user.get_username()
context['site_title'] = settings.SITE_TITLE
context['site_provider'] = settings.SITE_PROVIDER
if self.extra_context is not None:
context.update(self.extra_context)
return context
class PasswordChange(BasePasswordChangeView):
template_name = 'purist/change_password.html'
form_class = PasswordChangeForm
success_url = reverse_lazy('password_change_done')
def get_context_data(self, **kwargs):
context = super(PasswordChange, self).get_context_data(**kwargs)
context['username'] = self.request.user.get_username()
context['site_title'] = settings.SITE_TITLE
context['site_provider'] = settings.SITE_PROVIDER
if self.extra_context is not None:
context.update(self.extra_context)
return context
def home(request):
render_data = {
"username": request.user.get_username(),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment