Merge branch 'jordan' of ssh://git.onelab.eu/git/myslice into jordan
[myslice.git] / portal / views.py
index f213986..60e149c 100644 (file)
@@ -5,6 +5,7 @@
 #
 # Authors:
 #   Jordan Augé <jordan.auge@lip6.fr>
 #
 # Authors:
 #   Jordan Augé <jordan.auge@lip6.fr>
+#   Mohammed Yasin Rahman <mohammed-yasin.rahman@lip6.fr>
 # Copyright 2013, UPMC Sorbonne Universités / LIP6
 #
 # This program is free software; you can redistribute it and/or modify it under
 # Copyright 2013, UPMC Sorbonne Universités / LIP6
 #
 # This program is free software; you can redistribute it and/or modify it under
 
 from django.conf                 import settings
 from django.contrib.sites.models import Site, RequestSite
 
 from django.conf                 import settings
 from django.contrib.sites.models import Site, RequestSite
+from django.contrib              import messages
 from django.views.generic        import View
 from django.views.generic.base   import TemplateView
 from django.shortcuts            import render
 from django.views.generic        import View
 from django.views.generic.base   import TemplateView
 from django.shortcuts            import render
+
 from plugins.lists.simplelist    import SimpleList
 from plugins.lists.simplelist    import SimpleList
+from plugins.hazelnut            import Hazelnut
+from plugins.pres_view           import PresView
+from portal.event import Event
+import json
+
 from portal                      import signals
 from portal                      import signals
-from portal.forms                import UserRegisterForm, SliceRequestForm
+from portal.forms                import SliceRequestForm, ContactForm
 from portal.util                 import RegistrationView, ActivationView
 from portal.models               import PendingUser, PendingSlice
 from manifold.core.query         import Query
 from unfold.page                 import Page
 from portal.util                 import RegistrationView, ActivationView
 from portal.models               import PendingUser, PendingSlice
 from manifold.core.query         import Query
 from unfold.page                 import Page
+from myslice.viewutils           import topmenu_items, the_user
+from django.http                 import HttpResponseRedirect, HttpResponse
+
+from M2Crypto                    import Rand, RSA, BIO
+import os, re
 
 class DashboardView(TemplateView):
     template_name = "dashboard.html"
 
     def get_context_data(self, **kwargs):
 
 class DashboardView(TemplateView):
     template_name = "dashboard.html"
 
     def get_context_data(self, **kwargs):
-        user_hrn = 'ple.upmc.jordan_auge'
+        # We might have slices on different registries with different user accounts 
+        # We note that this portal could be specific to a given registry, to which we register users, but i'm not sure that simplifies things
+        # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
 
 
+        #messages.info(self.request, 'You have logged in')
         page = Page(self.request)
 
         # Slow...
         #slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
         page = Page(self.request)
 
         # Slow...
         #slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
-        slice_query = Query().get('user').filter_by('user_hrn', '==', user_hrn).select('slice.slice_hrn')
+        slice_query = Query().get('user').filter_by('user_hrn', '==', '$user_hrn').select('user_hrn', 'slice.slice_hrn')
         auth_query  = Query().get('network').select('network_hrn')
         page.enqueue_query(slice_query)
         page.enqueue_query(auth_query)
 
         auth_query  = Query().get('network').select('network_hrn')
         page.enqueue_query(slice_query)
         page.enqueue_query(auth_query)
 
+        page.expose_js_metadata()
         page.expose_queries()
 
         slicelist = SimpleList(
         page.expose_queries()
 
         slicelist = SimpleList(
@@ -69,141 +86,157 @@ class DashboardView(TemplateView):
         context['networks'] = authlist.render(self.request) 
         context['slices']   = slicelist.render(self.request)
 
         context['networks'] = authlist.render(self.request) 
         context['slices']   = slicelist.render(self.request)
 
+        # XXX This is repeated in all pages
+        # more general variables expected in the template
+        context['title'] = 'Test view that combines various plugins'
+        # the menu items on the top
+        context['topmenu_items'] = topmenu_items('Dashboard', self.request) 
+        # so we can sho who is logged
+        context['username'] = the_user(self.request) 
+
         context.update(page.prelude_env())
 
         return context
 
         context.update(page.prelude_env())
 
         return context
 
-class UserRegisterView(RegistrationView):
-    """
-    A registration backend which follows a simple workflow:
-
-    1. User signs up, inactive account is created.
-
-    2. Email is sent to user with activation link.
-
-    3. User clicks activation link, account is now active.
-
-    Using this backend requires that
-
-    * ``registration`` be listed in the ``INSTALLED_APPS`` setting
-      (since this backend makes use of models defined in this
-      application).
-
-    * The setting ``ACCOUNT_ACTIVATION_DAYS`` be supplied, specifying
-      (as an integer) the number of days from registration during
-      which a user may activate their account (after that period
-      expires, activation will be disallowed).
-
-    * The creation of the templates
-      ``registration/activation_email_subject.txt`` and
-      ``registration/activation_email.txt``, which will be used for
-      the activation email. See the notes for this backends
-      ``register`` method for details regarding these templates.
-
-    Additionally, registration can be temporarily closed by adding the
-    setting ``REGISTRATION_OPEN`` and setting it to
-    ``False``. Omitting this setting, or setting it to ``True``, will
-    be interpreted as meaning that registration is currently open and
-    permitted.
-
-    Internally, this is accomplished via storing an activation key in
-    an instance of ``registration.models.RegistrationProfile``. See
-    that model and its custom manager for full documentation of its
-    fields and supported operations.
-    
-    """
-    form_class = UserRegisterForm
-    
-    def register(self, request, **cleaned_data):
-        """
-        Given a username, email address and password, register a new
-        user account, which will initially be inactive.
-
-        Along with the new ``User`` object, a new
-        ``registration.models.RegistrationProfile`` will be created,
-        tied to that ``User``, containing the activation key which
-        will be used for this account.
-
-        An email will be sent to the supplied email address; this
-        email should contain an activation link. The email will be
-        rendered using two templates. See the documentation for
-        ``RegistrationProfile.send_activation_email()`` for
-        information about these templates and the contexts provided to
-        them.
-
-        After the ``User`` and ``RegistrationProfile`` are created and
-        the activation email is sent, the signal
-        ``registration.signals.user_registered`` will be sent, with
-        the new ``User`` as the keyword argument ``user`` and the
-        class of this backend as the sender.
-
-        """
-        first_name = cleaned_data['first_name']
-        last_name  = cleaned_data['last_name']
-        email      = cleaned_data['email']
-        password   = cleaned_data['password1']
-        #password2  = cleaned_data['password2']
-        keypair    = cleaned_data['keypair']
-
-        #if Site._meta.installed:
-        #    site = Site.objects.get_current()
-        #else:
-        #    site = RequestSite(request) 
-        site = None
-
-        new_user = PendingUser.objects.create_inactive_user(first_name, last_name, email, password, site)
-        signals.user_registered.send(sender=self.__class__,
-                                     user=new_user,
-                                     request=request)
-        return new_user
-
-    def registration_allowed(self, request):
-        """
-        Indicate whether account registration is currently permitted,
-        based on the value of the setting ``REGISTRATION_OPEN``. This
-        is determined as follows:
-
-        * If ``REGISTRATION_OPEN`` is not specified in settings, or is
-          set to ``True``, registration is permitted.
-
-        * If ``REGISTRATION_OPEN`` is both specified and set to
-          ``False``, registration is not permitted.
-        
-        """
-        return getattr(settings, 'REGISTRATION_OPEN', True)
-
-    def get_success_url(self, request, user):
-        """
-        Return the name of the URL to redirect to after successful
-        user registration.
-        
-        """
-        return ('user_register_complete', (), {})
-
-
-class UserValidateView(ActivationView):
-    def activate(self, request, activation_key):
-        """
-        Given an an activation key, look up and activate the user
-        account corresponding to that key (if possible).
-
-        After successful activation, the signal
-        ``registration.signals.user_activated`` will be sent, with the
-        newly activated ``User`` as the keyword argument ``user`` and
-        the class of this backend as the sender.
-        
-        """
-        activated_user = RegistrationProfile.objects.activate_user(activation_key)
-        if activated_user:
-            signals.user_activated.send(sender=self.__class__,
-                                        user=activated_user,
-                                        request=request)
-        return activated_user
-
-    def get_success_url(self, request, user):
-        return ('registration_activation_complete', (), {})
-
-
+# DEPRECATED #class UserRegisterView(RegistrationView):
+# DEPRECATED #    """
+# DEPRECATED #    A registration backend which follows a simple workflow:
+# DEPRECATED #
+# DEPRECATED #    1. User signs up, inactive account is created.
+# DEPRECATED #
+# DEPRECATED #    2. Email is sent to user with activation link.
+# DEPRECATED #
+# DEPRECATED #    3. User clicks activation link, account is now active.
+# DEPRECATED #
+# DEPRECATED #    Using this backend requires that
+# DEPRECATED #
+# DEPRECATED #    * ``registration`` be listed in the ``INSTALLED_APPS`` setting
+# DEPRECATED #      (since this backend makes use of models defined in this
+# DEPRECATED #      application).
+# DEPRECATED #
+# DEPRECATED #    * The setting ``ACCOUNT_ACTIVATION_DAYS`` be supplied, specifying
+# DEPRECATED #      (as an integer) the number of days from registration during
+# DEPRECATED #      which a user may activate their account (after that period
+# DEPRECATED #      expires, activation will be disallowed).
+# DEPRECATED #
+# DEPRECATED #    * The creation of the templates
+# DEPRECATED #      ``registration/activation_email_subject.txt`` and
+# DEPRECATED #      ``registration/activation_email.txt``, which will be used for
+# DEPRECATED #      the activation email. See the notes for this backends
+# DEPRECATED #      ``register`` method for details regarding these templates.
+# DEPRECATED #
+# DEPRECATED #    Additionally, registration can be temporarily closed by adding the
+# DEPRECATED #    setting ``REGISTRATION_OPEN`` and setting it to
+# DEPRECATED #    ``False``. Omitting this setting, or setting it to ``True``, will
+# DEPRECATED #    be interpreted as meaning that registration is currently open and
+# DEPRECATED #    permitt ed.
+# DEPRECATED #
+# DEPRECATED #    Internally, this is accomplished via storing an activation key in
+# DEPRECATED #    an instance of ``registration.models.RegistrationProfile``. See
+# DEPRECATED #    that model and its custom manager for full documentation of its
+# DEPRECATED #    fields and supported operations.
+# DEPRECATED #    
+# DEPRECATED #    """
+# DEPRECATED ## DEPRECATED #    form_class = UserRegisterForm
+# DEPRECATED #    
+# DEPRECATED #    def register(self, request, **cleaned_data):
+# DEPRECATED #        """
+# DEPRECATED #        Given a username, email address and password, register a new
+# DEPRECATED #        user account, which will initially be inactive.
+# DEPRECATED #
+# DEPRECATED #        Along with the new ``User`` object, a new
+# DEPRECATED #        ``registration.models.RegistrationProfile`` will be created,
+# DEPRECATED #        tied to that ``User``, containing the activation key which
+# DEPRECATED #        will be used for this account.
+# DEPRECATED #
+# DEPRECATED #        An email will be sent to the supplied email address; this
+# DEPRECATED #        email should contain an activation link. The email will be
+# DEPRECATED #        rendered using two templates. See the documentation for
+# DEPRECATED #        ``RegistrationProfile.send_activation_email()`` for
+# DEPRECATED #        information about these templates and the contexts provided to
+# DEPRECATED #        them.
+# DEPRECATED #
+# DEPRECATED #        After the ``User`` and ``RegistrationProfile`` are created and
+# DEPRECATED #        the activation email is sent, the signal
+# DEPRECATED #        ``registration.signals.user_registered`` will be sent, with
+# DEPRECATED #        the new ``User`` as the keyword argument ``user`` and the
+# DEPRECATED #        class of this backend as the sender.
+# DEPRECATED #
+# DEPRECATED #        """
+# DEPRECATED #        first_name = cleaned_data['first_name']
+# DEPRECATED #        last_name  = cleaned_data['last_name']
+# DEPRECATED #        affiliation= cleaned_data['affiliation']
+# DEPRECATED #        email      = cleaned_data['email']
+# DEPRECATED #        password   = cleaned_data['password1']
+# DEPRECATED #        
+# DEPRECATED #        #password2  = cleaned_data['password2']
+# DEPRECATED #        keypair    = cleaned_data['keypair']
+# DEPRECATED #
+# DEPRECATED #        #if Site._meta.installed:
+# DEPRECATED #        #    site = Site.objects.get_current()
+# DEPRECATED #        #else:
+# DEPRECATED #        #    site = RequestSite(request) 
+# DEPRECATED #        site = None
+# DEPRECATED #
+# DEPRECATED #        new_user = PendingUser.objects.create_inactive_user(first_name, last_name, email, password, site)
+# DEPRECATED #        signals.user_registered.send(sender=self.__class__,
+# DEPRECATED #                                     user=new_user,
+# DEPRECATED #                                     request=request)
+# DEPRECATED #        return new_user
+# DEPRECATED #
+# DEPRECATED #    def get_context_data(self, **kwargs):
+# DEPRECATED #        context = super(UserRegisterView, self).get_context_data(**kwargs)
+# DEPRECATED #        context['topmenu_items'] = topmenu_items('Register', self.request)
+# DEPRECATED #        context['username'] = the_user (self.request)
+# DEPRECATED #        return context
+# DEPRECATED #
+# DEPRECATED #    def registration_allowed(self, request):
+# DEPRECATED #        """
+# DEPRECATED #        Indicate whether account registration is currently permitted,
+# DEPRECATED #        based on the value of the setting ``REGISTRATION_OPEN``. This
+# DEPRECATED #        is determined as follows:
+# DEPRECATED #
+# DEPRECATED #        * If ``REGISTRATION_OPEN`` is not specified in settings, or is
+# DEPRECATED #          set to ``True``, registration is permitted.
+# DEPRECATED #
+# DEPRECATED #        * If ``REGISTRATION_OPEN`` is both specified and set to
+# DEPRECATED #          ``False``, registration is not permitted.
+# DEPRECATED #        
+# DEPRECATED #        """
+# DEPRECATED #        return getattr(settings, 'REGISTRATION_OPEN', True)
+# DEPRECATED #
+# DEPRECATED #    def get_success_url(self, request, user):
+# DEPRECATED #        """
+# DEPRECATED #        Return the name of the URL to redirect to after successful
+# DEPRECATED #        user registration.
+# DEPRECATED #        
+# DEPRECATED #        """
+# DEPRECATED #        return ('user_register_complete', (), {})
+# DEPRECATED #
+# DEPRECATED #
+# DEPRECATED #class UserValidateView(ActivationView):
+# DEPRECATED #    def activate(self, request, activation_key):
+# DEPRECATED #        """
+# DEPRECATED #        Given an an activation key, look up and activate the user
+# DEPRECATED #        account corresponding to that key (if possible).
+# DEPRECATED #
+# DEPRECATED #        After successful activation, the signal
+# DEPRECATED #        ``registration.signals.user_activated`` will be sent, with the
+# DEPRECATED #        newly activated ``User`` as the keyword argument ``user`` and
+# DEPRECATED #        the class of this backend as the sender.
+# DEPRECATED #        
+# DEPRECATED #        """
+# DEPRECATED #        activated_user = RegistrationProfile.objects.activate_user(activation_key)
+# DEPRECATED #        if activated_user:
+# DEPRECATED #            signals.user_activated.send(sender=self.__class__,
+# DEPRECATED #                                        user=activated_user,
+# DEPRECATED #                                        request=request)
+# DEPRECATED #        return activated_user
+# DEPRECATED #
+# DEPRECATED #    def get_success_url(self, request, user):
+# DEPRECATED #        return ('registration_activation_complete', (), {})
+# DEPRECATED #
+# DEPRECATED #
 # DEPRECATED #from portal.portalpage  import PortalPage
 # DEPRECATED #from plugins.wizard     import Wizard
 # DEPRECATED #from plugins.form       import CreateForm
 # DEPRECATED #from portal.portalpage  import PortalPage
 # DEPRECATED #from plugins.wizard     import Wizard
 # DEPRECATED #from plugins.form       import CreateForm
@@ -407,3 +440,518 @@ class UserValidateView(ActivationView):
 # DEPRECATED #    p << wizard.render(request) # in portal page if possible
 # DEPRECATED #
 # DEPRECATED #    return p.render()
 # DEPRECATED #    p << wizard.render(request) # in portal page if possible
 # DEPRECATED #
 # DEPRECATED #    return p.render()
+
+
+# DEPRECATED ## view for my_account
+# DEPRECATED # class MyAccountView(TemplateView):
+# DEPRECATED #    template_name = "my_account.html"
+# DEPRECATED #    
+# DEPRECATED #    def from_process(self, request, **cleaned_data): 
+# DEPRECATED #        #if request.method == 'POST':
+# DEPRECATED #         #       if request.POST['submit_name']:
+# DEPRECATED #        if 'fname' in request.POST:            
+# DEPRECATED #                messsag= "Got Name"
+# DEPRECATED #                #return render(request, 'portal/my_account.html')
+# DEPRECATED #                #response = HttpResponse("Here's the text of the Web page.")    
+# DEPRECATED #                return HttpResponse(message)
+# DEPRECATED #            
+# DEPRECATED #    def get_context_data(self, **kwargs):
+# DEPRECATED #        page = Page(self.request)
+# DEPRECATED #        context = super(MyAccountView, self).get_context_data(**kwargs)
+# DEPRECATED #        context['person']   = self.request.user
+# DEPRECATED #        # XXX This is repeated in all pages
+# DEPRECATED #        # more general variables expected in the template
+# DEPRECATED #        context['title'] = 'User Profile Page'
+# DEPRECATED #        # the menu items on the top
+# DEPRECATED #        context['topmenu_items'] = topmenu_items('my_account', self.request)
+# DEPRECATED #        # so we can sho who is logged
+# DEPRECATED #        context['username'] = the_user(self.request)
+# DEPRECATED #        context.update(page.prelude_env())
+# DEPRECATED #        return context
+
+
+
+# View for my_account form
+def my_account(request):
+    return render(request, 'my_account.html', {
+        #'form': form,
+        'topmenu_items': topmenu_items('My Account', request),
+        'username': the_user (request)
+    })
+
+# View for platforms
+class PlatformsView(TemplateView):
+    template_name = "platforms.html"
+
+    def get_context_data(self, **kwargs):
+        page = Page(self.request)
+
+        network_query  = Query().get('local:platform').filter_by('disabled', '==', '0').select('platform','platform_longname','gateway_type')
+        page.enqueue_query(network_query)
+
+        page.expose_js_metadata()
+        page.expose_queries()
+        networklist = Hazelnut(
+            page  = page,
+            title = 'List',
+            domid = 'checkboxes',
+            # this is the query at the core of the slice list
+            query = network_query,
+            query_all = network_query,
+            checkboxes = False,
+            datatables_options = {
+            # for now we turn off sorting on the checkboxes columns this way
+            # this of course should be automatic in hazelnut
+            'aoColumns'      : [None, None, None, None, {'bSortable': False}],
+            'iDisplayLength' : 25,
+            'bLengthChange'  : True,
+            },
+        )
+#
+#        networklist = SimpleList(
+#            title = None,
+#            page  = page,
+#            key   = 'platform',
+#            query = network_query,
+#        )
+
+        context = super(PlatformsView, self).get_context_data(**kwargs)
+        context['person']   = self.request.user
+        context['networks'] = networklist.render(self.request)
+
+        # 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('Platforms', self.request)
+        # so we can sho who is logged
+        context['username'] = the_user(self.request)
+
+        context.update(page.prelude_env())
+
+        return context
+
+#my_acc form value processing
+def acc_process(request):
+    # getting the user_id from the session [now hardcoded]
+    get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
+    if 'submit_name' in request.POST:
+        edited_first_name =  request.POST['fname']
+        edited_last_name =  request.POST['lname']
+        #email = 'test_email@gmail.com'
+        #password = 'test_pp'
+        #message = 'F_Name: %s L_name: %s dummy_pp: %s' % (first_name, last_name, password)
+        #site = None
+        
+        # insert into DB [needed for registration page]
+        #approach borrowed from register view     
+        #new_user = PendingUser.objects.create_inactive_user(edited_first_name, edited_last_name, email,  password, site) 
+        #conventional approach
+        #b = PendingUser(first_name=edited_first_name, last_name=edited_last_name)
+        #b.save()
+        
+        # select and update [will be used throughout this view]
+        # select the logged in user [for the moment hard coded]
+        #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
+        # update first and last name
+        get_user.first_name = edited_first_name
+        get_user.last_name = edited_last_name
+        get_user.save() 
+
+        return HttpResponse('Success: Name Updated!!')       
+    elif 'submit_pass' in request.POST:
+        edited_password = request.POST['password']
+        # select the logged in user [for the moment hard coded]
+        #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
+        # update password
+        get_user.password = edited_password
+        get_user.save()
+        return HttpResponse('Success: Password Changed!!')
+    elif 'generate' in request.POST:
+        #import os
+        #from M2Crypto import Rand, RSA, BIO
+
+        KEY_LENGTH = 2048
+
+        def blank_callback():
+            "Replace the default dashes"
+            return
+
+        # Random seed
+        Rand.rand_seed (os.urandom (KEY_LENGTH))
+        # Generate key pair
+        key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
+        # Create memory buffers
+        pri_mem = BIO.MemoryBuffer()
+        pub_mem = BIO.MemoryBuffer()
+        # Save keys to buffers
+        key.save_key_bio(pri_mem, None)
+        key.save_pub_key_bio(pub_mem)
+
+        # Get keys 
+        public_key = pub_mem.getvalue()
+        private_key = pri_mem.getvalue()
+        # Saving to DB
+        keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
+        keypair = re.sub("\r", "", keypair)
+        keypair = re.sub("\n", "\\n", keypair)
+        #keypair = keypair.rstrip('\r\n')
+        keypair = ''.join(keypair.split())
+        get_user.keypair = keypair
+        get_user.save()
+        return HttpResponse('Success: New Keypair Generated! %s' % keypair)
+
+    elif 'upload_key' in request.POST:
+        up_file = request.FILES['pubkey']
+        file_content =  up_file.read()
+        file_name = up_file.name
+        file_extension = os.path.splitext(file_name)[1] 
+        allowed_extension =  ['.pub','.txt']
+        if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
+            file_content = '{"user_public_key":"'+ file_content +'"}'
+            file_content = re.sub("\r", "", file_content)
+            file_content = re.sub("\n", "\\n",file_content)
+            file_content = ''.join(file_content.split())
+            get_user.keypair = file_content
+            get_user.save()
+            return HttpResponse('Success: Publickey uploaded! Old records overwritten')
+        else:
+            return HttpResponse('Please upload a valid RSA public key [.txt or .pub].')    
+        
+    else:
+        message = 'You submitted an empty form.'
+        return HttpResponse(message)
+
+def register_4m_f4f(request):
+    errors = []
+    if request.method == 'POST':
+        #get_email = PendingUser.objects.get(email)
+        reg_fname = request.POST.get('firstname', '')
+        reg_lname = request.POST.get('lastname', '')
+        reg_aff = request.POST.get('affiliation','')
+        reg_email = request.POST.get('email','').lower()
+        
+        #POST value validation  
+        if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
+            errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
+            #return HttpResponse("Only Letters, Numbers, - and _ allowd in First Name")
+            #return render(request, 'register_4m_f4f.html')
+        if (re.search(r'^[\w+\s.@+-]+$', reg_lname) == None):
+            errors.append('Last Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
+            #return HttpResponse("Only Letters, Numbers, - and _ is allowed in Last name")
+            #return render(request, 'register_4m_f4f.html')
+        if (re.search(r'^[\w+\s.@+-]+$', reg_aff) == None):
+            errors.append('Affiliation may contain only letters, numbers, spaces and @/./+/-/_ characters.')
+            #return HttpResponse("Only Letters, Numbers and _ is allowed in Affiliation")
+            #return render(request, 'register_4m_f4f.html')
+        if PendingUser.objects.filter(email__iexact=reg_email):
+            errors.append('Email already registered.Please provide a new email address.')
+            #return HttpResponse("Email Already exists")
+            #return render(request, 'register_4m_f4f.html')
+        if 'generate' in request.POST['question']:
+            #import os
+            #from M2Crypto import Rand, RSA, BIO
+            
+            KEY_LENGTH = 2048
+
+            def blank_callback():
+                "Replace the default dashes"
+                return
+
+            # Random seed
+            Rand.rand_seed (os.urandom (KEY_LENGTH))
+            # Generate key pair
+            key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
+            # Create memory buffers
+            pri_mem = BIO.MemoryBuffer()
+            pub_mem = BIO.MemoryBuffer()
+            # Save keys to buffers
+            key.save_key_bio(pri_mem, None)
+            key.save_pub_key_bio(pub_mem)
+            # Get keys 
+            public_key = pub_mem.getvalue()
+            private_key = pri_mem.getvalue()
+            # Saving to DB
+            keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
+            keypair = re.sub("\r", "", keypair)
+            keypair = re.sub("\n", "\\n", keypair)
+            #keypair = keypair.rstrip('\r\n')
+            keypair = ''.join(keypair.split())
+            #return HttpResponse(keypair)
+        else:
+            up_file = request.FILES['user_public_key']
+            file_content =  up_file.read()
+            file_name = up_file.name
+            file_extension = os.path.splitext(file_name)[1]
+            allowed_extension =  ['.pub','.txt']
+            if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
+                keypair = '{"user_public_key":"'+ file_content +'"}'
+                keypair = re.sub("\r", "", keypair)
+                keypair = re.sub("\n", "\\n",keypair)
+                keypair = ''.join(keypair.split())
+            else:
+                errors.append('Please upload a valid RSA public key [.txt or .pub].')
+
+        #b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff, 
+        #                email=reg_email, password=request.POST['password'], keypair=keypair)
+        #b.save()
+        if not errors:
+            b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff,
+                            email=reg_email, password=request.POST['password'], keypair=keypair)
+            b.save()
+            return render(request, 'user_register_complete.html')
+
+    return render(request, 'register_4m_f4f.html',{
+        'topmenu_items': topmenu_items('Register', request),
+        'errors': errors,
+        'firstname': request.POST.get('firstname', ''),
+        'lastname': request.POST.get('lastname', ''),
+        'affiliation': request.POST.get('affiliation', ''),
+        'email': request.POST.get('email', ''),
+        'password': request.POST.get('password', ''),           
+    })        
+    
+
+# view for contact form
+def contact(request):
+    if request.method == 'POST': # If the form has been submitted...
+        form = ContactForm(request.POST) # A form bound to the POST data
+        if form.is_valid(): # All validation rules pass
+            # Process the data in form.cleaned_data
+            first_name = form.cleaned_data['first_name']
+            last_name = form.cleaned_data['last_name']
+            affiliation = form.cleaned_data['affiliation']
+            subject = form.cleaned_data['subject']
+            message = form.cleaned_data['message']
+            email = form.cleaned_data['email'] # email of the sender
+            cc_myself = form.cleaned_data['cc_myself']
+
+            recipients = ['yasin.upmc@gmail.com']
+            if cc_myself:
+                recipients.append(email)
+
+            from django.core.mail import send_mail
+            send_mail("Onelab user submitted a query ", [first_name,last_name,affiliation,subject,message], email, recipients)
+            return render(request,'contact_sent.html') # Redirect after POST
+    else:
+        form = ContactForm() # An unbound form
+    
+    return render(request, 'contact.html', {
+        'form': form,
+        'topmenu_items': topmenu_items('Contact Us', request),
+        'username': the_user (request)
+
+    })
+
+
+def slice_request(request):
+    if request.method == 'POST': # If the form has been submitted...
+        form = SliceRequestForm(request.POST) # A form bound to the POST data
+        if form.is_valid(): # All validation rules pass
+            # Process the data in form.cleaned_data
+            slice_name = form.cleaned_data['slice_name']
+            number_of_nodes = form.cleaned_data['number_of_nodes']
+            type_of_nodes = form.cleaned_data['type_of_nodes']
+            purpose = form.cleaned_data['purpose']
+            email = form.cleaned_data['email'] # email of the sender
+            cc_myself = form.cleaned_data['cc_myself']
+
+            recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
+            if cc_myself:
+                recipients.append(email)
+
+            from django.core.mail import send_mail
+            send_mail("Onelab New Slice request form submitted", [slice_name,number_of_nodes,type_of_nodes,purpose], email, recipients)
+            return render(request,'slicereq_recvd.html') # Redirect after POST
+    else:
+        form = SliceRequestForm() # An unbound form
+
+#    template_env = {}
+#    template_env['form'] = form
+#    template_env['topmenu_items'] = topmenu_items('Request a slice', request) 
+#    template_env['unfold1_main'] = render(request, 'slice_request_.html', {
+#        'form': form,
+#    })
+#    from django.shortcuts                import render_to_response
+#    from django.template                 import RequestContext
+#    return render_to_response ('view-unfold1.html',template_env,
+#                               context_instance=RequestContext(request))
+
+    return render(request, 'slice_request.html', {
+        'form': form,
+        'topmenu_items': topmenu_items('Request a slice', request),
+        'username': the_user (request) 
+    })
+
+
+class PresViewView(TemplateView):
+    template_name = "view-unfold1.html"
+
+    def get_context_data(self, **kwargs):
+
+        page = Page(self.request)
+
+        pres_view = PresView(page = page)
+
+        context = super(PresViewView, self).get_context_data(**kwargs)
+
+        #context['ALL_STATIC'] = "all_static"
+        context['unfold1_main'] = pres_view.render(self.request)
+
+        # XXX This is repeated in all pages
+        # more general variables expected in the template
+        context['title'] = 'Test view that combines various plugins'
+        # the menu items on the top
+        context['topmenu_items'] = topmenu_items('PresView', self.request)
+        # so we can sho who is logged
+        context['username'] = the_user(self.request)
+
+        prelude_env = page.prelude_env()
+        context.update(prelude_env)
+
+        return context
+
+def json_me(config_file,type):
+    json_answer = ''
+    for ligne in config_file:
+        if not ligne.startswith('#'):
+            args = ligne.split(';')
+            json_answer += str('{ "name": "' + args[0] + '" ,"id":"' + args[1]  + '" ,"descriptif":"' + args[2]+'"')
+            if type!="dynamic":
+                json_answer += str(',"contraints":')
+                if args[3]=="":
+                    json_answer += str('""')
+                else:
+                    json_answer += str(args[3])
+            json_answer += str('},')
+    return json_answer[:-1]
+
+
+DIR = '/var/myslice/'
+STATIC = '%s/config_method_static' % DIR
+DYNAMIC = '%s/config_method_dynamic' % DIR
+ANIMATION = '%s/config_method_animation' % DIR
+
+def pres_view_methods(request, type):
+
+    if type ==None:
+        return 0
+    elif type =="static":
+        config = open(STATIC, "r")
+        json_answer = str('{ "options": [')
+        json_answer += str(json_me(config,"static"))
+        json_answer += str('] }')
+        config.close()
+    elif type =="dynamic":
+        config = open(DYNAMIC, "r")
+        json_answer = str('{ "options": [')
+        json_answer += str(json_me(config,"dynamic"))
+        json_answer += str('] }')
+        config.close()
+    elif type =="animation":
+        config = open(ANIMATION, "r")
+        json_answer = str('{ "options": [')
+        json_answer += str(json_me(config,"animation"))
+        json_answer += str('] }')
+        config.close()
+    elif type =="all":
+        config = open(STATIC, "r")
+        json_answer = str('{ "static": [')
+        json_answer += str(json_me(config,"static"))
+        json_answer += str('],')
+        json_answer += str('"dynamic": [')
+        config.close()
+        config = open(DYNAMIC, "r")
+        json_answer += str(json_me(config,"dynamic"))
+        json_answer += str('],')
+        json_answer += str('"animation": [')
+        config.close()
+        config = open(ANIMATION, "r")
+        json_answer += str(json_me(config,"animation"))
+        json_answer += str('] }')
+        config.close()
+    else:
+        return 0
+    return HttpResponse (json_answer, mimetype="application/json")
+
+def pres_view_animation(request, constraints, id):
+
+# sites crees depuis 2008
+# static.py?contraints=']date_created':1262325600&id='name_id"'
+
+    # method = request.getvalue('method') #ex : GetSites
+    #constraints = "']date_created':1262325600"
+    #id = "2"
+
+    if id == None:
+        return 0
+
+    # method = 'GetSites'#request.getvalue('method') #ex : GetSites
+    # constraints = {}#request.getvalue('constraints') // nul = {}
+    # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
+
+    config_file = open(ANIMATION, "r")
+    for ligne in config_file:
+        if not ligne.startswith('#'):
+            ligne = ligne.split('\n')
+            first = ligne[0].split(';')
+            if (str(first[1]) == str(id)):
+                save = first
+    config_file.close()
+
+    #Les print_method, print_option sont definis par le client (js)
+    #Les animations acceptent que les connexions anonymous
+    # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
+    args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
+
+
+    #Creation d'un objet event
+    event = Event(args)
+    cmd = [{"params": {
+            "data": {
+                "print_options": event.print_options,
+                "print_method": event.print_method,
+                "message": event.data
+            }
+        }
+    }]
+
+    json_answer = json.dumps(cmd)
+    return HttpResponse (json_answer, mimetype="application/json")
+
+def pres_view_static(request, constraints, id):
+    #constraints = "']date_created':1262325600"
+    #id = "2"
+
+    # method = 'GetSites'#request.getvalue('method') #ex : GetSites
+    # constraints = {}#request.getvalue('constraints') // nul = {}
+    # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
+
+    config_file = open(STATIC, "r")
+    for ligne in config_file:
+        if not ligne.startswith('#'):
+            ligne = ligne.split('\n')
+            first = ligne[0].split(';')
+            if (str(first[1]) == str(id)):
+                save = first
+    config_file.close()
+
+    #Les print_method, print_option sont definis par le client (js)
+    #Les animations acceptent que les connexions anonymous
+    # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
+    args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
+
+
+    #Creation d'un objet event
+    event = Event(args)
+    cmd = [{"params": {
+            "data": {
+                "print_options": event.print_options,
+                "print_method": event.print_method,
+                "message": event.data
+            }
+        }
+    }]
+
+    json_answer = json.dumps(cmd)
+    return HttpResponse (json_answer, mimetype="application/json")