From: Yasin Date: Fri, 25 Apr 2014 15:40:15 +0000 (+0200) Subject: Email Verification: sends link to user to validate the email address X-Git-Tag: myslice-1.1~129 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=d04f3fd85686bee03a961494bdb4a68d6fb07ad4;p=unfold.git Email Verification: sends link to user to validate the email address --- diff --git a/portal/actions.py b/portal/actions.py index c3695e36..b9a07378 100644 --- a/portal/actions.py +++ b/portal/actions.py @@ -6,9 +6,9 @@ import json from django.contrib.auth.models import User from django.template.loader import render_to_string -from django.core.mail import EmailMultiAlternatives +from django.core.mail import EmailMultiAlternatives, send_mail -from myslice.theme import ThemeView +from myslice.theme import ThemeView theme = ThemeView() @@ -37,10 +37,12 @@ def authority_get_pi_emails(request, authority_hrn): print "pi_users = %s" % pi_users if any(d['pi_users'] == None for d in pi_users): - theme.template_name = 'email_default_recipients.txt' - default_email = render_to_string(theme.template, request) - default_email = default_email.replace('\n', '') - return default_email + #theme.template_name = 'email_default_recipients.txt' + #default_email = render_to_string(theme.template, request) + #default_email = default_email.replace('\n', '') + #return default_email + # the above doesn't work + return ['support@myslice.info'] else: pi_user_hrns = [ hrn for x in pi_users for hrn in x['pi_users'] ] query = Query.get('user').filter_by('user_hrn', 'included', pi_user_hrns).select('user_email') @@ -536,9 +538,26 @@ def create_pending_user(wsgi_request, request, user_detail): private_key = request['private_key'], user_hrn = request['user_hrn'], pi = '', # XXX Why not None ? + email_hash = request['email_hash'], + status = 'False', ) b.save() - + # sends email to user to activate the email + theme.template_name = 'activate_user.html' + html_content = render_to_string(theme.template, request) + theme.template_name = 'activate_user.txt' + text_content = render_to_string(theme.template, request) + theme.template_name = 'activate_user_email_subject.txt' + subject = render_to_string(theme.template, request) + subject = subject.replace('\n', '') + sender = 'support@myslice.info' + recipient = [request['email']] + #recipient = recipient.append(request['email']) + + msg = EmailMultiAlternatives(subject, text_content, sender, recipient) + msg.attach_alternative(html_content, "text/html") + msg.send() + # saves the user to django auth_user table [needed for password reset] user = User.objects.create_user(request['email'], request['email'], request['password']) diff --git a/portal/emailactivationview.py b/portal/emailactivationview.py new file mode 100644 index 00000000..dd3788ad --- /dev/null +++ b/portal/emailactivationview.py @@ -0,0 +1,58 @@ +from unfold.loginrequired import FreeAccessView +# +from manifold.core.query import Query +from manifoldapi.manifoldapi import execute_query, execute_admin_query +from portal.actions import manifold_update_user, manifold_update_account, manifold_add_account, manifold_delete_account, sfa_update_user +# +from unfold.page import Page +from ui.topmenu import topmenu_items_live, the_user +# +from django.http import HttpResponse, HttpResponseRedirect +from django.contrib import messages +from django.contrib.auth.decorators import login_required +from myslice.theme import ThemeView +from portal.models import PendingUser +# +import json, os, re, itertools + +# requires login +class ActivateEmailView(FreeAccessView, ThemeView): + template_name = "email_activation.html" + def dispatch(self, *args, **kwargs): + return super(ActivateEmailView, self).dispatch(*args, **kwargs) + + + def get_context_data(self, **kwargs): + + page = Page(self.request) + #page.add_js_files ( [ "js/jquery.validate.js", "js/my_account.register.js", "js/my_account.edit_profile.js" ] ) + #page.add_css_files ( [ "css/onelab.css", "css/account_view.css","css/plugin.css" ] ) + + for key, value in kwargs.iteritems(): + #print "%s = %s" % (key, value) + if key == "hash_code": + hash_code=value + + if PendingUser.objects.filter(email_hash__iexact = hash_code): + #get_user = PendingUser.objects.filter(email_hash__iexact = hash_code) + #get_user.status= 'True' + #get_user.save() + PendingUser.objects.filter(email_hash__iexact = hash_code).update(status='True') + activation = 'success' + else: + activation = 'failed' + + context = super(ActivateEmailView, self).get_context_data(**kwargs) + context['activation_status'] = activation + # XXX This is repeated in all pages + # more general variables expected in the template + context['title'] = 'Platforms connected to MySlice' + # the menu items on the top + context['topmenu_items'] = topmenu_items_live('My Account', page) + # so we can sho who is logged + context['username'] = the_user(self.request) + context['theme'] = self.theme +# context ['firstname'] = config['firstname'] + prelude_env = page.prelude_env() + context.update(prelude_env) + return context diff --git a/portal/models.py b/portal/models.py index 3fa0383e..cc484b5b 100644 --- a/portal/models.py +++ b/portal/models.py @@ -65,6 +65,8 @@ class PendingUser(models.Model): authority_hrn = models.TextField() login = models.TextField() pi = models.TextField() + email_hash = models.TextField() + status = models.TextField() created = models.DateTimeField(auto_now_add = True) # models.ForeignKey(Institution) diff --git a/portal/registrationview.py b/portal/registrationview.py index ab09c9f1..5956f3d6 100644 --- a/portal/registrationview.py +++ b/portal/registrationview.py @@ -1,6 +1,7 @@ import os.path, re import json -from random import randint +from random import randint +from hashlib import md5 from django.views.generic import View from django.template.loader import render_to_string @@ -55,13 +56,17 @@ class RegistrationView (FreeAccessView, ThemeView): current_site = Site.objects.get_current() current_site = current_site.domain + post_email = wsgi_request.POST.get('email','').lower() + email_hash = md5(post_email).digest().encode('base64')[:-1] user_request = { 'first_name' : wsgi_request.POST.get('firstname', ''), 'last_name' : wsgi_request.POST.get('lastname', ''), 'authority_hrn' : wsgi_request.POST.get('authority_hrn', ''), - 'email' : wsgi_request.POST.get('email', '').lower(), + 'email' : post_email, 'password' : wsgi_request.POST.get('password', ''), - 'current_site' : current_site + 'current_site' : current_site, + 'email_hash' : email_hash, + 'validation_link': 'http://' + current_site + '/portal/email_activation/'+ email_hash } # Construct user_hrn from email (XXX Should use common code) diff --git a/portal/templates/activate_user.html b/portal/templates/activate_user.html new file mode 100644 index 00000000..e81a060c --- /dev/null +++ b/portal/templates/activate_user.html @@ -0,0 +1,8 @@ + +
+

You have registered to {{current_site}}

+
+

Please validate your email address by clicking the following link

+
+{{validation_link}} + diff --git a/portal/templates/activate_user.txt b/portal/templates/activate_user.txt new file mode 100644 index 00000000..b5eb224d --- /dev/null +++ b/portal/templates/activate_user.txt @@ -0,0 +1,7 @@ +You have registered to {{current_site}} +Please validate your email address by clicking the following link: + +{{validation_link}} + + + diff --git a/portal/templates/activate_user_email_subject.txt b/portal/templates/activate_user_email_subject.txt new file mode 100644 index 00000000..0e76f7c6 --- /dev/null +++ b/portal/templates/activate_user_email_subject.txt @@ -0,0 +1 @@ +{{current_site}} Portal user email activation diff --git a/portal/templates/email_activation.html b/portal/templates/email_activation.html new file mode 100644 index 00000000..b9df80e5 --- /dev/null +++ b/portal/templates/email_activation.html @@ -0,0 +1,23 @@ +{% extends "layout.html" %} + +{% block content %} + +
+

User Registration Experimenter registration

+
+
+ {%if activation_status == 'success'%} +

Email activation complete !

+

Your account is pending for validation.

+

PI of your institution is responsible for validating your account.

+

You will be notified once your account is validated.

+

In the meantime, you can login to the portal with your email and password and browse through the limited access features.

+ {%else%} +

Email activation Failed !

+

Your email address is not registered in our server.

+

Please register to get access to the portal.

+

If you have already registered and still having this message, please contact support.

+ {%endif%} +
+ +{% endblock %} diff --git a/portal/urls.py b/portal/urls.py index c55c07b9..c7df3989 100644 --- a/portal/urls.py +++ b/portal/urls.py @@ -4,7 +4,10 @@ # This file is part of the Manifold project. # # Authors: -# Jordan Augé +# Jordan Augé +# Mohammed Yasin Rahman +# Ciro Scognamiglio # Copyright 2013, UPMC Sorbonne Universités / LIP6 # # This program is free software; you can redistribute it and/or modify it under @@ -20,28 +23,28 @@ # this program; see the file COPYING. If not, write to the Free Software # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -from django.views.generic.base import TemplateView -from django.conf.urls import patterns, include, url - -from portal.about import AboutView -from portal.institution import InstitutionView -from portal.usersview import UsersView -from portal.manageuserview import UserView, user_process -from portal.platformsview import PlatformsView -from portal.platformview import PlatformView -from portal.resourceview import ResourceView -from portal.dashboardview import DashboardView -from portal.accountview import AccountView, account_process -from portal.contactview import ContactView -from portal.slicerequestview import SliceRequestView -from portal.registrationview import RegistrationView -from portal.joinview import JoinView -from portal.sliceviewold import SliceView -from portal.validationview import ValidatePendingView -#from portal.experimentview import ExperimentView -from portal.documentationview import DocumentationView -from portal.supportview import SupportView +from django.views.generic.base import TemplateView +from django.conf.urls import patterns, include, url +from portal.about import AboutView +from portal.institution import InstitutionView +from portal.usersview import UsersView +from portal.manageuserview import UserView, user_process +from portal.platformsview import PlatformsView +from portal.platformview import PlatformView +from portal.resourceview import ResourceView +from portal.dashboardview import DashboardView +from portal.accountview import AccountView, account_process +from portal.contactview import ContactView +from portal.slicerequestview import SliceRequestView +from portal.registrationview import RegistrationView +from portal.joinview import JoinView +from portal.sliceviewold import SliceView +from portal.validationview import ValidatePendingView +#from portal.experimentview import ExperimentView +from portal.documentationview import DocumentationView +from portal.supportview import SupportView +from portal.emailactivationview import ActivateEmailView # 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.django_passresetview import password_reset, password_reset_done, password_reset_confirm, password_reset_complete @@ -98,6 +101,7 @@ urlpatterns = patterns('', #url(r'^slice/request/?$', views.slice_request, name='slice_request'), # Slice confirmation #url(r'^slice/validate/?$', views.slice_validate, name='slice_validate'), + url(r'^email_activation/(?P[\w\W\-]+)/?$', ActivateEmailView.as_view(), name='email_activate'), url(r'^pass_reset/$', 'portal.django_passresetview.password_reset', {'post_reset_redirect' : '/portal/password/reset/done/'}),