--- /dev/null
+try:
+ from urllib.parse import urlparse, urlunparse
+except ImportError: # Python 2
+ from urlparse import urlparse, urlunparse
+
+from django.conf import settings
+from django.core.urlresolvers import reverse
+from django.http import HttpResponseRedirect, QueryDict
+from django.template.response import TemplateResponse
+from django.utils.http import base36_to_int, is_safe_url
+from django.utils.translation import ugettext as _
+from django.shortcuts import resolve_url
+from django.views.decorators.debug import sensitive_post_parameters
+from django.views.decorators.cache import never_cache
+from django.views.decorators.csrf import csrf_protect
+
+# Avoid shadowing the login() and logout() views below.
+from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login, logout as auth_logout, get_user_model
+from django.contrib.auth.decorators import login_required
+from portal.forms import PasswordResetForm, SetPasswordForm
+from django.contrib.auth.tokens import default_token_generator
+from django.contrib.sites.models import get_current_site
+from django.contrib.auth.hashers import UNUSABLE_PASSWORD, identify_hasher
+
+##
+import os.path, re
+import json
+
+from random import choice
+
+from django.core.mail import send_mail
+from django.contrib import messages
+from django.views.generic import View
+from django.shortcuts import render
+from django.http import HttpResponse, HttpResponseRedirect
+
+from unfold.loginrequired import FreeAccessView
+from ui.topmenu import topmenu_items_live
+
+from manifold.manifoldapi import execute_admin_query
+from manifold.core.query import Query
+from portal.actions import manifold_update_user
+
+from portal.forms import PassResetForm
+from portal.actions import manifold_update_user
+
+
+
+# 4 views for password reset:
+# - password_reset sends the mail
+# - password_reset_done shows a success message for the above
+# - password_reset_confirm checks the link the user clicked and
+# prompts for a new password
+# - password_reset_complete shows a success message for the above
+
+@csrf_protect
+def password_reset(request, is_admin_site=False,
+ template_name='registration/password_reset_form.html',
+ email_template_name='registration/password_reset_email.html',
+ subject_template_name='registration/password_reset_subject.txt',
+ password_reset_form=PasswordResetForm,
+ token_generator=default_token_generator,
+ post_reset_redirect=None,
+ from_email=None,
+ current_app=None,
+ extra_context=None):
+ if post_reset_redirect is None:
+ post_reset_redirect = reverse('portal.django_passresetview.password_reset_done')
+ if request.method == "POST":
+ form = password_reset_form(request.POST)
+ if form.is_valid():
+
+ ### email check in manifold DB ###
+ email = form.cleaned_data['email'] # email inserted on the form
+ user_query = Query().get('local:user').select('user_id','email')
+ user_details = execute_admin_query(request, user_query)
+ flag = 0
+ for user_detail in user_details:
+ if user_detail['email']==email:
+ flag = 1
+ break
+
+ if flag == 0:
+ messages.error(request, 'Sorry, this email is not registered.')
+ return render(request, 'registration/password_reset_form.html', {
+ 'form': form,
+ })
+ ### end of email check in manifold ###
+
+ opts = {
+ 'use_https': request.is_secure(),
+ 'token_generator': token_generator,
+ 'from_email': from_email,
+ 'email_template_name': email_template_name,
+ 'subject_template_name': subject_template_name,
+ 'request': request,
+ }
+ if is_admin_site:
+ opts = dict(opts, domain_override=request.get_host())
+ form.save(**opts)
+ return HttpResponseRedirect(post_reset_redirect)
+ else:
+ form = password_reset_form()
+ context = {
+ 'form': form,
+ }
+ if extra_context is not None:
+ context.update(extra_context)
+ return TemplateResponse(request, template_name, context,
+ current_app=current_app)
+
+
+def password_reset_done(request,
+ template_name='registration/password_reset_done.html',
+ current_app=None, extra_context=None):
+ context = {}
+ if extra_context is not None:
+ context.update(extra_context)
+ return TemplateResponse(request, template_name, context,
+ current_app=current_app)
+
+
+# Doesn't need csrf_protect since no-one can guess the URL
+@sensitive_post_parameters()
+@never_cache
+def password_reset_confirm(request, uidb36=None, token=None,
+ template_name='registration/password_reset_confirm.html',
+ token_generator=default_token_generator,
+ set_password_form=SetPasswordForm,
+ post_reset_redirect=None,
+ current_app=None, extra_context=None):
+ """
+ View that checks the hash in a password reset link and presents a
+ form for entering a new password.
+ """
+ UserModel = get_user_model()
+ assert uidb36 is not None and token is not None # checked by URLconf
+ if post_reset_redirect is None:
+ post_reset_redirect = reverse('portal.django_passresetview.password_reset_complete')
+ try:
+ uid_int = base36_to_int(uidb36)
+ user = UserModel._default_manager.get(pk=uid_int)
+ except (ValueError, OverflowError, UserModel.DoesNotExist):
+ user = None
+
+ if user is not None and token_generator.check_token(user, token):
+ validlink = True
+ if request.method == 'POST':
+ form = set_password_form(user, request.POST)
+ if form.is_valid():
+
+ ### manifold pass update ###
+ #password = form.cleaned_data('password1')
+ password=request.POST['new_password1']
+ user_query = Query().get('local:user').select('user_id','email','password')
+ user_details = execute_admin_query(request, user_query)
+ for user_detail in user_details:
+ if user_detail['email'] == user.email:
+ user_detail['password'] = password
+ #updating password in local:user
+ user_params = { 'password': user_detail['password']}
+ manifold_update_user(request,user.email,user_params)
+ ### end of manifold pass update ###
+
+
+ form.save()
+ return HttpResponseRedirect(post_reset_redirect)
+ else:
+ form = set_password_form(None)
+ else:
+ validlink = False
+ form = None
+ context = {
+ 'form': form,
+ 'validlink': validlink,
+ }
+ if extra_context is not None:
+ context.update(extra_context)
+ return TemplateResponse(request, template_name, context,
+ current_app=current_app)
+
+
+def password_reset_complete(request,
+ template_name='registration/password_reset_complete.html',
+ current_app=None, extra_context=None):
+ context = {
+ 'login_url': resolve_url(settings.LOGIN_URL)
+ }
+ if extra_context is not None:
+ context.update(extra_context)
+ return TemplateResponse(request, template_name, context,
+ current_app=current_app)
+
+
#from crispy_forms.helper import FormHelper
#from crispy_forms.layout import Submit
from django.utils.translation import ugettext_lazy as _
+from django.contrib.auth.tokens import default_token_generator
+from django.contrib.auth import authenticate, get_user_model
+from django.contrib.auth.hashers import UNUSABLE_PASSWORD, identify_hasher
+from django.contrib.sites.models import get_current_site
+from django.utils.http import int_to_base36
+from django.template import loader
+
+
+
# xxx painful, but...
# bootstrap3 requires the <input> fields to be tagged class='form-control'
widget = forms.Select(attrs={'class':'form-control'}),
choices = authority_hrn,
help_text = "An authority responsible for vetting your slice")
+
+
+class PasswordResetForm(forms.Form):
+ error_messages = {
+ 'unknown': _("That email address doesn't have an associated "
+ "user account. Are you sure you've registered?"),
+ 'unusable': _("The user account associated with this email "
+ "address cannot reset the password."),
+ }
+ email = forms.EmailField(label=_("Email"), max_length=254)
+
+ def clean_email(self):
+ """
+ Validates that an active user exists with the given email address.
+ """
+ UserModel = get_user_model()
+ email = self.cleaned_data["email"]
+ self.users_cache = UserModel._default_manager.filter(email__iexact=email)
+ if not len(self.users_cache):
+ raise forms.ValidationError(self.error_messages['unknown'])
+ if not any(user.is_active for user in self.users_cache):
+ # none of the filtered users are active
+ raise forms.ValidationError(self.error_messages['unknown'])
+ if any((user.password == UNUSABLE_PASSWORD)
+ for user in self.users_cache):
+ raise forms.ValidationError(self.error_messages['unusable'])
+ return email
+
+ def save(self, domain_override=None,
+ subject_template_name='registration/password_reset_subject.txt',
+ email_template_name='registration/password_reset_email.html',
+ use_https=False, token_generator=default_token_generator,
+ from_email=None, request=None):
+ """
+ Generates a one-use only link for resetting password and sends to the
+ user.
+ """
+ from django.core.mail import send_mail
+ for user in self.users_cache:
+ if not domain_override:
+ current_site = get_current_site(request)
+ site_name = current_site.name
+ domain = current_site.domain
+ else:
+ site_name = domain = domain_override
+ c = {
+ 'email': user.email,
+ 'domain': domain,
+ 'site_name': site_name,
+ 'uid': int_to_base36(user.pk),
+ 'user': user,
+ 'token': token_generator.make_token(user),
+ 'protocol': use_https and 'https' or 'http',
+ }
+ subject = loader.render_to_string(subject_template_name, c)
+ # Email subject *must not* contain newlines
+ subject = ''.join(subject.splitlines())
+ email = loader.render_to_string(email_template_name, c)
+ send_mail(subject, email, from_email, [user.email])
+
+
+class SetPasswordForm(forms.Form):
+ """
+ A form that lets a user change set his/her password without entering the
+ old password
+ """
+ error_messages = {
+ 'password_mismatch': _("The two password fields didn't match."),
+ }
+ new_password1 = forms.CharField(label=_("New password"),
+ widget=forms.PasswordInput)
+ new_password2 = forms.CharField(label=_("New password confirmation"),
+ widget=forms.PasswordInput)
+
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+ super(SetPasswordForm, self).__init__(*args, **kwargs)
+
+ def clean_new_password2(self):
+ password1 = self.cleaned_data.get('new_password1')
+ password2 = self.cleaned_data.get('new_password2')
+ if password1 and password2:
+ if password1 != password2:
+ raise forms.ValidationError(
+ self.error_messages['password_mismatch'])
+ return password2
+
+ def save(self, commit=True):
+ self.user.set_password(self.cleaned_data['new_password1'])
+ if commit:
+ self.user.save()
+ return self.user
# hopefully these should move in dedicated source files too
from portal.views import PresViewView, pres_view_static, pres_view_methods, pres_view_animation
from portal.views import ValidatePendingView
-
+from portal.django_passresetview import password_reset, password_reset_done, password_reset_confirm, password_reset_complete
# DEPRECATED #named_register_forms = (
# DEPRECATED # ("step1", RegisterUserForm),
url(r'^account/account_process/?$', account_process),
url(r'^register/?$', RegistrationView.as_view(), name='registration'),
url(r'^contact/?$', ContactView.as_view(), name='contact'),
- url(r'^pass_reset/?$', PassResetView.as_view(), name='pass_rest'),
+ #url(r'^pass_reset/?$', PassResetView.as_view(), name='pass_rest'),
# Slice request
url(r'^slice_request/?$', SliceRequestView.as_view(), name='slice_request'),
# Validate pending requests
#url(r'^slice/request/?$', views.slice_request, name='slice_request'),
# Slice confirmation
#url(r'^slice/validate/?$', views.slice_validate, name='slice_validate'),
+ url(r'^pass_reset/$',
+ 'portal.django_passresetview.password_reset',
+ {'post_reset_redirect' : '/portal/password/reset/done/'}),
+ (r'^password/reset/done/$',
+ 'portal.django_passresetview.password_reset_done'),
+ (r'^password/reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
+ 'portal.django_passresetview.password_reset_confirm',
+ {'post_reset_redirect' : '/portal/password/done/'}),
+ (r'^password/done/$',
+ 'portal.django_passresetview.password_reset_complete'),
+ # ...
+
)
# (r'^accounts/', include('registration.backends.default.urls')),
# DEPRECATED # url(r'^$', views.index, name='index'),
# DEPRECATED # url(r"^registerwizard/(?P<step>[-\w]+)/$", register_wizard,
# DEPRECATED # name="register_wizard_step"),
-# DEPRECATED # url(r"^registerwizard/$", register_wizard, name="register_wizard")
+# DEPRECATED # url(r"^registerwizard/$", regster_wizard, name="register_wizard")
--- /dev/null
+{% extends "layout-unfold1.html" %}
+{% load i18n %}
+
+{% block unfold_main %}
+
+
+{% block content %}
+
+<h1>{% trans 'Password reset complete' %}</h1>
+
+<p>{% trans "Your password has been set. You may go ahead and log in now." %}</p>
+
+<p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p>
+
+{% endblock %}
+{% endblock %}
+
--- /dev/null
+{% extends "layout-unfold1.html" %}
+{% load i18n %}
+
+{% block unfold_main %}
+
+
+{% block content %}
+
+{% if validlink %}
+
+<h1>{% trans 'Enter new password' %}</h1>
+
+<p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
+
+<form action="" method="post">{% csrf_token %}
+{{ form.new_password1.errors }}
+<p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p>
+{{ form.new_password2.errors }}
+<p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p>
+<p><input type="submit" value="{% trans 'Change my password' %}" /></p>
+</form>
+
+{% else %}
+
+<h1>{% trans 'Password reset unsuccessful' %}</h1>
+
+<p>{% trans "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}</p>
+
+{% endif %}
+
+{% endblock %}
+{% endblock %}
+
--- /dev/null
+{% extends "layout-unfold1.html" %}
+{% load i18n %}
+
+{% block unfold_main %}
+
+{% block content %}
+
+<h1>{% trans 'Password reset successful' %}</h1>
+
+<p>{% trans "We've emailed you instructions for setting your password to the email address you submitted. You should be receiving it shortly." %}</p>
+
+{% endblock %}
+{% endblock %}
+
--- /dev/null
+{% load i18n %}{% autoescape off %}
+{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
+
+{% trans "Please go to the following page and choose a new password:" %}
+{% block reset_link %}
+{{ protocol }}://{{ domain }}{% url 'portal.django_passresetview.password_reset_confirm' uidb36=uid token=token %}
+{% endblock %}
+{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
+
+{% trans "Thanks for using our site!" %}
+
+{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
+
+{% endautoescape %}
--- /dev/null
+{% extends "layout-unfold1.html" %}
+{% load i18n %}
+
+{% block unfold_main %}
+
+
+
+{% block content %}
+
+<h1>{% trans "Onelab Password reset wizard" %}</h1>
+
+<p>{% trans "Forgotten your password? Enter your email address below, and we'll email instructions for setting a new one." %}</p>
+
+<form action="" method="post">{% csrf_token %}
+{{ form.email.errors }}
+<p><label for="id_email">{% trans 'Email address:' %}</label> {{ form.email }} <input type="submit" value="{% trans 'Reset my password' %}" /></p>
+</form>
+
+{% endblock %}
+{% endblock %}
+