Email Verification: sends link to user to validate the email address
authorYasin <mohammed-yasin.rahman@lip6.fr>
Fri, 25 Apr 2014 15:40:15 +0000 (17:40 +0200)
committerYasin <mohammed-yasin.rahman@lip6.fr>
Fri, 25 Apr 2014 15:40:15 +0000 (17:40 +0200)
portal/actions.py
portal/emailactivationview.py [new file with mode: 0644]
portal/models.py
portal/registrationview.py
portal/templates/activate_user.html [new file with mode: 0644]
portal/templates/activate_user.txt [new file with mode: 0644]
portal/templates/activate_user_email_subject.txt [new file with mode: 0644]
portal/templates/email_activation.html [new file with mode: 0644]
portal/urls.py

index c3695e3..b9a0737 100644 (file)
@@ -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 (file)
index 0000000..dd3788a
--- /dev/null
@@ -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
index 3fa0383..cc484b5 100644 (file)
@@ -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)
 
index ab09c9f..5956f3d 100644 (file)
@@ -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 (file)
index 0000000..e81a060
--- /dev/null
@@ -0,0 +1,8 @@
+<img src="https://onelab.eu/templates/onelab2/images/logo.png">
+<br>
+<h1>You have registered to {{current_site}}</h1>
+<br>
+<h1>Please validate your email address by clicking the following link<h1>
+<br>
+<a href={{validation_link}}>{{validation_link}}</a>
+
diff --git a/portal/templates/activate_user.txt b/portal/templates/activate_user.txt
new file mode 100644 (file)
index 0000000..b5eb224
--- /dev/null
@@ -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 (file)
index 0000000..0e76f7c
--- /dev/null
@@ -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 (file)
index 0000000..b9df80e
--- /dev/null
@@ -0,0 +1,23 @@
+{% extends "layout.html" %}
+
+{% block content %}
+
+<div class="row">
+       <h1><img src="{{ STATIC_URL }}img/icon_user_small.png" alt="User Registration" /> Experimenter registration</h1>
+</div>
+<div class="row">
+       {%if activation_status == 'success'%}
+               <h3>Email activation complete !</h3>
+               <p>Your account is pending for validation.</p>
+               <p>PI of your institution is responsible for validating your account.</p>
+               <p>You will be notified once your account is validated.</p>
+               <p>In the meantime, you can login to the portal with your email and password and browse through the limited access features.</p>
+       {%else%}
+               <h3>Email activation Failed !</h3>
+               <p>Your email address is not registered in our server.</p>
+               <p>Please <a href="/portal/register">register</a> to get access to the portal.</p> 
+               <p>If you have already registered and still having this message, please <a href="/portal/contact/">contact support.</a> </p>
+       {%endif%}
+ </div>
+
+{% endblock %}
index c55c07b..c7df398 100644 (file)
@@ -4,7 +4,10 @@
 # This file is part of the Manifold project.
 #
 # Authors:
-#   Jordan Augé <jordan.auge@lip6.fr>
+#   Jordan Augé <jordan.auge@lip6.fr
+#   Loic Baron  <loic.baron@lip6.fr>
+#   Mohammed Yasin Rahman <mohammed-yasin.rahman@lip6.fr>
+#   Ciro Scognamiglio   <ciro.scognamiglio@lip6.fr>
 # Copyright 2013, UPMC Sorbonne Universités / LIP6
 #
 # This program is free software; you can redistribute it and/or modify it under
 # 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<hash_code>[\w\W\-]+)/?$', ActivateEmailView.as_view(), name='email_activate'), 
     url(r'^pass_reset/$', 
         'portal.django_passresetview.password_reset', 
         {'post_reset_redirect' : '/portal/password/reset/done/'}),