New Register form Complete! Old one deprecated.
[myslice.git] / portal / views.py
1 # -*- coding: utf-8 -*-
2 #
3 # portal/views.py: views for the portal application
4 # This file is part of the Manifold project.
5 #
6 # Authors:
7 #   Jordan AugĂ© <jordan.auge@lip6.fr>
8 #   Mohammed Yasin Rahman <mohammed-yasin.rahman@lip6.fr>
9 # Copyright 2013, UPMC Sorbonne UniversitĂ©s / LIP6
10 #
11 # This program is free software; you can redistribute it and/or modify it under
12 # the terms of the GNU General Public License as published by the Free Software
13 # Foundation; either version 3, or (at your option) any later version.
14
15 # This program is distributed in the hope that it will be useful, but WITHOUT
16 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18 # details.
19
20 # You should have received a copy of the GNU General Public License along with
21 # this program; see the file COPYING.  If not, write to the Free Software
22 # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 from django.conf                 import settings
25 from django.contrib.sites.models import Site, RequestSite
26 from django.contrib              import messages
27 from django.views.generic        import View
28 from django.views.generic.base   import TemplateView
29 from django.shortcuts            import render
30
31 from plugins.lists.simplelist    import SimpleList
32
33 from plugins.pres_view           import PresView
34 from portal.event import Event
35 import json
36
37 from portal                      import signals
38 from portal.forms                import UserRegisterForm, SliceRequestForm, ContactForm
39 from portal.util                 import RegistrationView, ActivationView
40 from portal.models               import PendingUser, PendingSlice
41 from manifold.core.query         import Query
42 from unfold.page                 import Page
43 from myslice.viewutils           import topmenu_items, the_user
44 from django.http                 import HttpResponseRedirect, HttpResponse
45
46 from M2Crypto                    import Rand, RSA, BIO
47 import os, re
48
49 class DashboardView(TemplateView):
50     template_name = "dashboard.html"
51
52     def get_context_data(self, **kwargs):
53         # We might have slices on different registries with different user accounts 
54         # 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
55         # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
56
57         #messages.info(self.request, 'You have logged in')
58         page = Page(self.request)
59
60         # Slow...
61         #slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
62         slice_query = Query().get('user').filter_by('user_hrn', '==', '$user_hrn').select('user_hrn', 'slice.slice_hrn')
63         auth_query  = Query().get('network').select('network_hrn')
64         page.enqueue_query(slice_query)
65         page.enqueue_query(auth_query)
66
67         page.expose_js_metadata()
68         page.expose_queries()
69
70         slicelist = SimpleList(
71             title = None,
72             page  = page,
73             key   = 'slice.slice_hrn',
74             query = slice_query,
75         )
76          
77         authlist = SimpleList(
78             title = None,
79             page  = page,
80             key   = 'network_hrn',
81             query = auth_query,
82         )
83
84         context = super(DashboardView, self).get_context_data(**kwargs)
85         context['person']   = self.request.user
86         context['networks'] = authlist.render(self.request) 
87         context['slices']   = slicelist.render(self.request)
88
89         # XXX This is repeated in all pages
90         # more general variables expected in the template
91         context['title'] = 'Test view that combines various plugins'
92         # the menu items on the top
93         context['topmenu_items'] = topmenu_items('Dashboard', self.request) 
94         # so we can sho who is logged
95         context['username'] = the_user(self.request) 
96
97         context.update(page.prelude_env())
98
99         return context
100
101 # DEPRECATED #class UserRegisterView(RegistrationView):
102 # DEPRECATED #    """
103 # DEPRECATED #    A registration backend which follows a simple workflow:
104 # DEPRECATED #
105 # DEPRECATED #    1. User signs up, inactive account is created.
106 # DEPRECATED #
107 # DEPRECATED #    2. Email is sent to user with activation link.
108 # DEPRECATED #
109 # DEPRECATED #    3. User clicks activation link, account is now active.
110 # DEPRECATED #
111 # DEPRECATED #    Using this backend requires that
112 # DEPRECATED #
113 # DEPRECATED #    * ``registration`` be listed in the ``INSTALLED_APPS`` setting
114 # DEPRECATED #      (since this backend makes use of models defined in this
115 # DEPRECATED #      application).
116 # DEPRECATED #
117 # DEPRECATED #    * The setting ``ACCOUNT_ACTIVATION_DAYS`` be supplied, specifying
118 # DEPRECATED #      (as an integer) the number of days from registration during
119 # DEPRECATED #      which a user may activate their account (after that period
120 # DEPRECATED #      expires, activation will be disallowed).
121 # DEPRECATED #
122 # DEPRECATED #    * The creation of the templates
123 # DEPRECATED #      ``registration/activation_email_subject.txt`` and
124 # DEPRECATED #      ``registration/activation_email.txt``, which will be used for
125 # DEPRECATED #      the activation email. See the notes for this backends
126 # DEPRECATED #      ``register`` method for details regarding these templates.
127 # DEPRECATED #
128 # DEPRECATED #    Additionally, registration can be temporarily closed by adding the
129 # DEPRECATED #    setting ``REGISTRATION_OPEN`` and setting it to
130 # DEPRECATED #    ``False``. Omitting this setting, or setting it to ``True``, will
131 # DEPRECATED #    be interpreted as meaning that registration is currently open and
132 # DEPRECATED #    permitt ed.
133 # DEPRECATED #
134 # DEPRECATED #    Internally, this is accomplished via storing an activation key in
135 # DEPRECATED #    an instance of ``registration.models.RegistrationProfile``. See
136 # DEPRECATED #    that model and its custom manager for full documentation of its
137 # DEPRECATED #    fields and supported operations.
138 # DEPRECATED #    
139 # DEPRECATED #    """
140 # DEPRECATED ## DEPRECATED #    form_class = UserRegisterForm
141 # DEPRECATED #    
142 # DEPRECATED #    def register(self, request, **cleaned_data):
143 # DEPRECATED #        """
144 # DEPRECATED #        Given a username, email address and password, register a new
145 # DEPRECATED #        user account, which will initially be inactive.
146 # DEPRECATED #
147 # DEPRECATED #        Along with the new ``User`` object, a new
148 # DEPRECATED #        ``registration.models.RegistrationProfile`` will be created,
149 # DEPRECATED #        tied to that ``User``, containing the activation key which
150 # DEPRECATED #        will be used for this account.
151 # DEPRECATED #
152 # DEPRECATED #        An email will be sent to the supplied email address; this
153 # DEPRECATED #        email should contain an activation link. The email will be
154 # DEPRECATED #        rendered using two templates. See the documentation for
155 # DEPRECATED #        ``RegistrationProfile.send_activation_email()`` for
156 # DEPRECATED #        information about these templates and the contexts provided to
157 # DEPRECATED #        them.
158 # DEPRECATED #
159 # DEPRECATED #        After the ``User`` and ``RegistrationProfile`` are created and
160 # DEPRECATED #        the activation email is sent, the signal
161 # DEPRECATED #        ``registration.signals.user_registered`` will be sent, with
162 # DEPRECATED #        the new ``User`` as the keyword argument ``user`` and the
163 # DEPRECATED #        class of this backend as the sender.
164 # DEPRECATED #
165 # DEPRECATED #        """
166 # DEPRECATED #        first_name = cleaned_data['first_name']
167 # DEPRECATED #        last_name  = cleaned_data['last_name']
168 # DEPRECATED #        affiliation= cleaned_data['affiliation']
169 # DEPRECATED #        email      = cleaned_data['email']
170 # DEPRECATED #        password   = cleaned_data['password1']
171 # DEPRECATED #        
172 # DEPRECATED #        #password2  = cleaned_data['password2']
173 # DEPRECATED #        keypair    = cleaned_data['keypair']
174 # DEPRECATED #
175 # DEPRECATED #        #if Site._meta.installed:
176 # DEPRECATED #        #    site = Site.objects.get_current()
177 # DEPRECATED #        #else:
178 # DEPRECATED #        #    site = RequestSite(request) 
179 # DEPRECATED #        site = None
180 # DEPRECATED #
181 # DEPRECATED #        new_user = PendingUser.objects.create_inactive_user(first_name, last_name, email, password, site)
182 # DEPRECATED #        signals.user_registered.send(sender=self.__class__,
183 # DEPRECATED #                                     user=new_user,
184 # DEPRECATED #                                     request=request)
185 # DEPRECATED #        return new_user
186 # DEPRECATED #
187 # DEPRECATED #    def get_context_data(self, **kwargs):
188 # DEPRECATED #        context = super(UserRegisterView, self).get_context_data(**kwargs)
189 # DEPRECATED #        context['topmenu_items'] = topmenu_items('Register', self.request)
190 # DEPRECATED #        context['username'] = the_user (self.request)
191 # DEPRECATED #        return context
192 # DEPRECATED #
193 # DEPRECATED #    def registration_allowed(self, request):
194 # DEPRECATED #        """
195 # DEPRECATED #        Indicate whether account registration is currently permitted,
196 # DEPRECATED #        based on the value of the setting ``REGISTRATION_OPEN``. This
197 # DEPRECATED #        is determined as follows:
198 # DEPRECATED #
199 # DEPRECATED #        * If ``REGISTRATION_OPEN`` is not specified in settings, or is
200 # DEPRECATED #          set to ``True``, registration is permitted.
201 # DEPRECATED #
202 # DEPRECATED #        * If ``REGISTRATION_OPEN`` is both specified and set to
203 # DEPRECATED #          ``False``, registration is not permitted.
204 # DEPRECATED #        
205 # DEPRECATED #        """
206 # DEPRECATED #        return getattr(settings, 'REGISTRATION_OPEN', True)
207 # DEPRECATED #
208 # DEPRECATED #    def get_success_url(self, request, user):
209 # DEPRECATED #        """
210 # DEPRECATED #        Return the name of the URL to redirect to after successful
211 # DEPRECATED #        user registration.
212 # DEPRECATED #        
213 # DEPRECATED #        """
214 # DEPRECATED #        return ('user_register_complete', (), {})
215 # DEPRECATED #
216 # DEPRECATED #
217 # DEPRECATED #class UserValidateView(ActivationView):
218 # DEPRECATED #    def activate(self, request, activation_key):
219 # DEPRECATED #        """
220 # DEPRECATED #        Given an an activation key, look up and activate the user
221 # DEPRECATED #        account corresponding to that key (if possible).
222 # DEPRECATED #
223 # DEPRECATED #        After successful activation, the signal
224 # DEPRECATED #        ``registration.signals.user_activated`` will be sent, with the
225 # DEPRECATED #        newly activated ``User`` as the keyword argument ``user`` and
226 # DEPRECATED #        the class of this backend as the sender.
227 # DEPRECATED #        
228 # DEPRECATED #        """
229 # DEPRECATED #        activated_user = RegistrationProfile.objects.activate_user(activation_key)
230 # DEPRECATED #        if activated_user:
231 # DEPRECATED #            signals.user_activated.send(sender=self.__class__,
232 # DEPRECATED #                                        user=activated_user,
233 # DEPRECATED #                                        request=request)
234 # DEPRECATED #        return activated_user
235 # DEPRECATED #
236 # DEPRECATED #    def get_success_url(self, request, user):
237 # DEPRECATED #        return ('registration_activation_complete', (), {})
238 # DEPRECATED #
239 # DEPRECATED #
240 # DEPRECATED #from portal.portalpage  import PortalPage
241 # DEPRECATED #from plugins.wizard     import Wizard
242 # DEPRECATED #from plugins.form       import CreateForm
243 # DEPRECATED #from plugins.raw.raw    import Raw          # XXX
244 # DEPRECATED #
245 # DEPRECATED #from myslice.viewutils  import the_user
246 # DEPRECATED #
247 # DEPRECATED #from django.template.loader import render_to_string
248 # DEPRECATED #from django.template import RequestContext
249 # DEPRECATED #from django.views import generic
250 # DEPRECATED #
251 # DEPRECATED #from django.contrib.formtools.wizard.views import NamedUrlSessionWizardView
252 # DEPRECATED ##from django.core.files.storage import FileSystemStorage
253 # DEPRECATED #from django.core.files.storage import default_storage
254 # DEPRECATED #
255 # DEPRECATED ##class MerlinWizard(NamedUrlSessionWizardView):
256 # DEPRECATED ##
257 # DEPRECATED ##    ...
258 # DEPRECATED ##    ...
259 # DEPRECATED ##
260 # DEPRECATED ##    @classonlymethod
261 # DEPRECATED ##    def as_view(cls, *args, **kwargs):
262 # DEPRECATED ##        kwargs.update({
263 # DEPRECATED ##            'form_list': [
264 # DEPRECATED ##                NameForm,
265 # DEPRECATED ##                QuestForm,
266 # DEPRECATED ##                ColorForm,
267 # DEPRECATED ##            ],
268 # DEPRECATED ##            'url_name': 'merlin_wizard'
269 # DEPRECATED ##        })
270 # DEPRECATED ##        return super(MerlinWizard, cls).as_view(*args, **kwargs)
271 # DEPRECATED #
272 # DEPRECATED #class UserRegisterWizardView(NamedUrlSessionWizardView):
273 # DEPRECATED ##class UserRegisterWizardView(LoginRequiredMixin, NamedUrlSessionWizardView):
274 # DEPRECATED #    # Notice that I specify a file storage instance. If you don't specify this,
275 # DEPRECATED #    # and you need to support FileField or ImageField in your forms, you'll get
276 # DEPRECATED #    # errors from Django. This is something else I think could be handled by
277 # DEPRECATED #    # the views better. Seems to me that it should just use whatever the
278 # DEPRECATED #    # default/specified storage is for the rest of your project/application.
279 # DEPRECATED #    file_storage = default_storage # FileSystemStorage()
280 # DEPRECATED #    template_name = "register_user_wizard.html"
281 # DEPRECATED #
282 # DEPRECATED #    def done(self, form_list, **kwargs):
283 # DEPRECATED #        step1_form = form_list[0]
284 # DEPRECATED #        step2_form = form_list[1]
285 # DEPRECATED #
286 # DEPRECATED #        productext = self.create_product(product_form)
287 # DEPRECATED #        shippings = self.create_shippings(productext, shipping_forms)
288 # DEPRECATED #        images = self.create_images(productext, image_forms)
289 # DEPRECATED #
290 # DEPRECATED #        if all([productext, shippings, images]):
291 # DEPRECATED #            del self.request.session["wizard_product_wizard_view"]
292 # DEPRECATED #
293 # DEPRECATED #            messages.success(self.request,
294 # DEPRECATED #                _("Your product has been created."))
295 # DEPRECATED #            return HttpResponseRedirect(self.get_success_url(productext))
296 # DEPRECATED #
297 # DEPRECATED #        messages.error(self.request, _("Something went wrong creating your "
298 # DEPRECATED #            "product. Please try again or contact support."))
299 # DEPRECATED #        return HttpResponseRedirect(reverse("register_wizard"))
300 # DEPRECATED #
301 # DEPRECATED #    #def get_form_kwargs(self, step):
302 # DEPRECATED #    #    if step == "product":
303 # DEPRECATED #    #        return {"user": self.request.user}
304 # DEPRECATED #    #    return {}
305 # DEPRECATED #
306 # DEPRECATED ## The portal should hook the slice and user creation pages
307 # DEPRECATED #
308 # DEPRECATED #def register_user(request):
309 # DEPRECATED #    
310 # DEPRECATED #    if request.method == 'POST':
311 # DEPRECATED #        form = UserRegisterForm(request.POST) # Nous reprenons les donnĂ©es
312 # DEPRECATED #        if form.is_valid():
313 # DEPRECATED #            first_name = form.cleaned_data['first_name']
314 # DEPRECATED #            last_name  = form.cleaned_data['last_name']
315 # DEPRECATED #            email      = form.cleaned_data['email']
316 # DEPRECATED #            password   = form.cleaned_data['password']
317 # DEPRECATED #            password2  = form.cleaned_data['password2']
318 # DEPRECATED #            keypair    = form.cleaned_data['keypair']
319 # DEPRECATED #            ## Ici nous pouvons traiter les donnĂ©es du formulaire
320 # DEPRECATED #            #sujet = form.cleaned_data['sujet']
321 # DEPRECATED #            #message = form.cleaned_data['message']
322 # DEPRECATED #            #envoyeur = form.cleaned_data['envoyeur']
323 # DEPRECATED #            #renvoi = form.cleaned_data['renvoi']
324 # DEPRECATED #            ## Nous pourrions ici envoyer l'e-mail grâce aux donnĂ©es que nous venons de rĂ©cupĂ©rer
325 # DEPRECATED #            #envoi = True
326 # DEPRECATED #    else:
327 # DEPRECATED #        form = UserRegisterForm()
328 # DEPRECATED #    return render(request, 'register_user.html', locals())
329 # DEPRECATED #
330 # DEPRECATED #def index(request):
331 # DEPRECATED #
332 # DEPRECATED #    WIZARD_TITLE = 'User registration'
333 # DEPRECATED #    STEP1_TITLE  = 'Enter your details'
334 # DEPRECATED #    STEP2_TITLE  = 'Select your institution'
335 # DEPRECATED #    STEP3_TITLE  = 'Authentication'
336 # DEPRECATED #    STEP4_TITLE  = 'Request a slice (optional)'
337 # DEPRECATED #    STEP5_TITLE  = 'Waiting for validation'
338 # DEPRECATED #    STEP6_TITLE  = 'Account validated'
339 # DEPRECATED #
340 # DEPRECATED #    STEP0 = render_to_string('account_validated.html', context_instance=RequestContext(request))
341 # DEPRECATED #    STEP2_HTML   = """
342 # DEPRECATED #    coucou
343 # DEPRECATED #    """
344 # DEPRECATED #    STEP4 = """
345 # DEPRECATED #    mede
346 # DEPRECATED #    """
347 # DEPRECATED #    STEP5 = render_to_string('account_validated.html', context_instance=RequestContext(request))
348 # DEPRECATED #
349 # DEPRECATED #    p = PortalPage(request)
350 # DEPRECATED #
351 # DEPRECATED #    # This is redundant with the Wizard title
352 # DEPRECATED #    p << "<h3>User registration</h3>"
353 # DEPRECATED #
354 # DEPRECATED #    sons = []
355 # DEPRECATED #    start_step = 1
356 # DEPRECATED #
357 # DEPRECATED #    # STEP 1
358 # DEPRECATED #    # If the user already exists (is logged), let's display a summary of his account details
359 # DEPRECATED #    # Otherwise propose a form to fill in
360 # DEPRECATED #    if the_user(request):
361 # DEPRECATED #        # Fill a disabled form with user info
362 # DEPRECATED #        # Please logout to register another user
363 # DEPRECATED #        sons.append(Raw(page=p, title=STEP1_TITLE, togglable=False, html=STEP0))
364 # DEPRECATED #        start_step += 1
365 # DEPRECATED #    else:
366 # DEPRECATED #        # We could pass a list of fields also, instead of retrieving them from metadata
367 # DEPRECATED #        # Otherwise we need some heuristics to display nice forms
368 # DEPRECATED #        # XXX Could we log the user in after the form is validated ?
369 # DEPRECATED #        # XXX Explain the password is for XXX
370 # DEPRECATED #        field_list = [{
371 # DEPRECATED #            'name'        : 'First name',
372 # DEPRECATED #            'field'       : 'firstname',
373 # DEPRECATED #            'type'        : 'text',
374 # DEPRECATED #            'validate_rx' : '^[a-zA-Z -]+$',
375 # DEPRECATED #            'validate_err': 'Your first name must be comprised of letters only',
376 # DEPRECATED #            'description' : 'Enter your first name',
377 # DEPRECATED #        }, {
378 # DEPRECATED #            'name'        : 'Last name',
379 # DEPRECATED #            'field'       : 'lastname',
380 # DEPRECATED #            'type'        : 'text',
381 # DEPRECATED #            'validate_rx' : '^[a-zA-Z -]+$',
382 # DEPRECATED #            'validate_err': 'Your last name must be comprised of letters only',
383 # DEPRECATED #            'description' : 'Enter your last name',
384 # DEPRECATED #        }, { 
385 # DEPRECATED #            'name'        : 'Email',
386 # DEPRECATED #            'field'       : 'email',
387 # DEPRECATED #            'type'        : 'text',
388 # DEPRECATED #            'description' : 'Enter your email address',
389 # DEPRECATED #        }, {
390 # DEPRECATED #            'name'        : 'Password',
391 # DEPRECATED #            'field'       : 'password',
392 # DEPRECATED #            'type'        : 'password',
393 # DEPRECATED #            'description' : 'Enter your password',
394 # DEPRECATED #        }, {
395 # DEPRECATED #            'name'        : 'Confirm password',
396 # DEPRECATED #            'field'       : 'password2',
397 # DEPRECATED #            'type'        : 'password',
398 # DEPRECATED #            'description' : 'Enter your password again',
399 # DEPRECATED #        }]
400 # DEPRECATED #        sons.append(CreateForm(page = p, title = STEP1_TITLE, togglable = False, object = 'local:user', fields = field_list))
401 # DEPRECATED #
402 # DEPRECATED #    # STEP 2
403 # DEPRECATED #    # If the user already exists (is logged), let's display a summary of its institution
404 # DEPRECATED #    # Otherwise propose a form to fill in (we should base our selection on the email)
405 # DEPRECATED #    if the_user(request):
406 # DEPRECATED #        # Fill a disabled form with institution
407 # DEPRECATED #        # Please logout to register another user
408 # DEPRECATED #        sons.append(Raw(page=p, title=STEP2_TITLE, togglable=False, html="User created"))
409 # DEPRECATED #        start_step += 1
410 # DEPRECATED #    else:
411 # DEPRECATED #        sons.append(CreateForm(page = p, title = STEP2_TITLE, togglable = False, object = 'slice')) #institution'))
412 # DEPRECATED #
413 # DEPRECATED #    # STEP3
414 # DEPRECATED #    # Please should your prefered authentication method
415 # DEPRECATED #    # This step should allow the user to either choose the user or managed mode in MySlice
416 # DEPRECATED #    sons.append(Raw(page = p, title = STEP3_TITLE, togglable = False, html = STEP2_HTML))
417 # DEPRECATED #
418 # DEPRECATED #    # Step 4: Request a slice (optional)
419 # DEPRECATED #    sons.append(CreateForm(page = p, title = STEP4_TITLE, togglable = False, object = 'slice'))
420 # DEPRECATED #
421 # DEPRECATED #    # Step 5: Your request is waiting for validation
422 # DEPRECATED #    # Periodic refresh
423 # DEPRECATED #    sons.append(Raw(page = p, title = STEP5_TITLE, togglable = False, html = STEP4))
424 # DEPRECATED #
425 # DEPRECATED #    # Step 6: Account validation  = welcome for newly validated users
426 # DEPRECATED #    # . delegation
427 # DEPRECATED #    # . platforms
428 # DEPRECATED #    # . slice
429 # DEPRECATED #    # . pointers
430 # DEPRECATED #    sons.append(Raw(page = p, title = STEP6_TITLE, togglable = False, html = STEP5))
431 # DEPRECATED #
432 # DEPRECATED #    wizard = Wizard(
433 # DEPRECATED #        page       = p,
434 # DEPRECATED #        title      = WIZARD_TITLE,
435 # DEPRECATED #        togglable  = False,
436 # DEPRECATED #        sons       = sons,
437 # DEPRECATED #        start_step = start_step,
438 # DEPRECATED #    )
439 # DEPRECATED #
440 # DEPRECATED #    p << wizard.render(request) # in portal page if possible
441 # DEPRECATED #
442 # DEPRECATED #    return p.render()
443
444
445 # DEPRECATED ## view for my_account
446 # DEPRECATED # class MyAccountView(TemplateView):
447 # DEPRECATED #    template_name = "my_account.html"
448 # DEPRECATED #    
449 # DEPRECATED #    def from_process(self, request, **cleaned_data): 
450 # DEPRECATED #        #if request.method == 'POST':
451 # DEPRECATED #         #       if request.POST['submit_name']:
452 # DEPRECATED #        if 'fname' in request.POST:            
453 # DEPRECATED #                messsag= "Got Name"
454 # DEPRECATED #                #return render(request, 'portal/my_account.html')
455 # DEPRECATED #                #response = HttpResponse("Here's the text of the Web page.")    
456 # DEPRECATED #                return HttpResponse(message)
457 # DEPRECATED #            
458 # DEPRECATED #    def get_context_data(self, **kwargs):
459 # DEPRECATED #        page = Page(self.request)
460 # DEPRECATED #        context = super(MyAccountView, self).get_context_data(**kwargs)
461 # DEPRECATED #        context['person']   = self.request.user
462 # DEPRECATED #        # XXX This is repeated in all pages
463 # DEPRECATED #        # more general variables expected in the template
464 # DEPRECATED #        context['title'] = 'User Profile Page'
465 # DEPRECATED #        # the menu items on the top
466 # DEPRECATED #        context['topmenu_items'] = topmenu_items('my_account', self.request)
467 # DEPRECATED #        # so we can sho who is logged
468 # DEPRECATED #        context['username'] = the_user(self.request)
469 # DEPRECATED #        context.update(page.prelude_env())
470 # DEPRECATED #        return context
471
472
473
474 # View for my_account form
475 def my_account(request):
476     return render(request, 'my_account.html', {
477         #'form': form,
478         'topmenu_items': topmenu_items('My Account', request),
479         'username': the_user (request)
480     })
481
482
483 #my_acc form value processing
484 def acc_process(request):
485     # getting the user_id from the session [now hardcoded]
486     get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
487     if 'submit_name' in request.POST:
488         edited_first_name =  request.POST['fname']
489         edited_last_name =  request.POST['lname']
490         #email = 'test_email@gmail.com'
491         #password = 'test_pp'
492         #message = 'F_Name: %s L_name: %s dummy_pp: %s' % (first_name, last_name, password)
493         #site = None
494         
495         # insert into DB [needed for registration page]
496         #approach borrowed from register view     
497         #new_user = PendingUser.objects.create_inactive_user(edited_first_name, edited_last_name, email,  password, site) 
498         #conventional approach
499         #b = PendingUser(first_name=edited_first_name, last_name=edited_last_name)
500         #b.save()
501         
502         # select and update [will be used throughout this view]
503         # select the logged in user [for the moment hard coded]
504         #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
505         # update first and last name
506         get_user.first_name = edited_first_name
507         get_user.last_name = edited_last_name
508         get_user.save() 
509
510         return HttpResponse('Success: Name Updated!!')       
511     elif 'submit_pass' in request.POST:
512         edited_password = request.POST['password']
513         # select the logged in user [for the moment hard coded]
514         #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
515         # update password
516         get_user.password = edited_password
517         get_user.save()
518         return HttpResponse('Success: Password Changed!!')
519     elif 'generate' in request.POST:
520         #import os
521         #from M2Crypto import Rand, RSA, BIO
522
523         KEY_LENGTH = 2048
524
525         def blank_callback():
526             "Replace the default dashes"
527             return
528
529         # Random seed
530         Rand.rand_seed (os.urandom (KEY_LENGTH))
531         # Generate key pair
532         key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
533         # Create memory buffers
534         pri_mem = BIO.MemoryBuffer()
535         pub_mem = BIO.MemoryBuffer()
536         # Save keys to buffers
537         key.save_key_bio(pri_mem, None)
538         key.save_pub_key_bio(pub_mem)
539
540         # Get keys 
541         public_key = pub_mem.getvalue()
542         private_key = pri_mem.getvalue()
543         # Saving to DB
544         keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
545         keypair = re.sub("\r", "", keypair)
546         keypair = re.sub("\n", "\\n", keypair)
547         #keypair = keypair.rstrip('\r\n')
548         keypair = ''.join(keypair.split())
549         get_user.keypair = keypair
550         get_user.save()
551         return HttpResponse('Success: New Keypair Generated! %s' % keypair)
552
553     elif 'upload_key' in request.POST:
554         up_file = request.FILES['pubkey']
555         file_content =  up_file.read()
556         file_name = up_file.name
557         file_extension = os.path.splitext(file_name)[1] 
558         allowed_extension =  ['.pub','.txt']
559         if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
560             file_content = '{"user_public_key":"'+ file_content +'"}'
561             file_content = re.sub("\r", "", file_content)
562             file_content = re.sub("\n", "\\n",file_content)
563             file_content = ''.join(file_content.split())
564             get_user.keypair = file_content
565             get_user.save()
566             return HttpResponse('Success: Publickey uploaded! Old records overwritten')
567         else:
568             return HttpResponse('Please upload a valid RSA public key [.txt or .pub].')    
569         
570     else:
571         message = 'You submitted an empty form.'
572         return HttpResponse(message)
573
574 def register_4m_f4f(request):
575     errors = []
576     if request.method == 'POST':
577         #get_email = PendingUser.objects.get(email)
578         reg_fname = request.POST.get('firstname', '')
579         reg_lname = request.POST.get('lastname', '')
580         reg_aff = request.POST.get('affiliation','')
581         reg_email = request.POST.get('email','').lower()
582         
583         #POST value validation  
584         if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
585             errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
586             #return HttpResponse("Only Letters, Numbers, - and _ allowd in First Name")
587             #return render(request, 'register_4m_f4f.html')
588         if (re.search(r'^[\w+\s.@+-]+$', reg_lname) == None):
589             errors.append('Last Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
590             #return HttpResponse("Only Letters, Numbers, - and _ is allowed in Last name")
591             #return render(request, 'register_4m_f4f.html')
592         if (re.search(r'^[\w+\s.@+-]+$', reg_aff) == None):
593             errors.append('Affiliation may contain only letters, numbers, spaces and @/./+/-/_ characters.')
594             #return HttpResponse("Only Letters, Numbers and _ is allowed in Affiliation")
595             #return render(request, 'register_4m_f4f.html')
596         if PendingUser.objects.filter(email__iexact=reg_email):
597             errors.append('Email already registered.Please provide a new email address.')
598             #return HttpResponse("Email Already exists")
599             #return render(request, 'register_4m_f4f.html')
600         if 'generate' in request.POST['question']:
601             #import os
602             #from M2Crypto import Rand, RSA, BIO
603             
604             KEY_LENGTH = 2048
605
606             def blank_callback():
607                 "Replace the default dashes"
608                 return
609
610             # Random seed
611             Rand.rand_seed (os.urandom (KEY_LENGTH))
612             # Generate key pair
613             key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
614             # Create memory buffers
615             pri_mem = BIO.MemoryBuffer()
616             pub_mem = BIO.MemoryBuffer()
617             # Save keys to buffers
618             key.save_key_bio(pri_mem, None)
619             key.save_pub_key_bio(pub_mem)
620             # Get keys 
621             public_key = pub_mem.getvalue()
622             private_key = pri_mem.getvalue()
623             # Saving to DB
624             keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
625             keypair = re.sub("\r", "", keypair)
626             keypair = re.sub("\n", "\\n", keypair)
627             #keypair = keypair.rstrip('\r\n')
628             keypair = ''.join(keypair.split())
629             #return HttpResponse(keypair)
630         else:
631             up_file = request.FILES['user_public_key']
632             file_content =  up_file.read()
633             file_name = up_file.name
634             file_extension = os.path.splitext(file_name)[1]
635             allowed_extension =  ['.pub','.txt']
636             if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
637                 keypair = '{"user_public_key":"'+ file_content +'"}'
638                 keypair = re.sub("\r", "", keypair)
639                 keypair = re.sub("\n", "\\n",keypair)
640                 keypair = ''.join(keypair.split())
641             else:
642                 errors.append('Please upload a valid RSA public key [.txt or .pub].')
643
644         #b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff, 
645         #                email=reg_email, password=request.POST['password'], keypair=keypair)
646         #b.save()
647         if not errors:
648             b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff,
649                             email=reg_email, password=request.POST['password'], keypair=keypair)
650             b.save()
651             return render(request, 'user_register_complete.html')
652
653     return render(request, 'register_4m_f4f.html',{
654         'topmenu_items': topmenu_items('Register', request),
655         'errors': errors,
656         'firstname': request.POST.get('firstname', ''),
657         'lastname': request.POST.get('lastname', ''),
658         'affiliation': request.POST.get('affiliation', ''),
659         'email': request.POST.get('email', ''),
660         'password': request.POST.get('password', ''),           
661     })        
662     
663
664 # view for contact form
665 def contact(request):
666     if request.method == 'POST': # If the form has been submitted...
667         form = ContactForm(request.POST) # A form bound to the POST data
668         if form.is_valid(): # All validation rules pass
669             # Process the data in form.cleaned_data
670             first_name = form.cleaned_data['first_name']
671             last_name = form.cleaned_data['last_name']
672             affiliation = form.cleaned_data['affiliation']
673             subject = form.cleaned_data['subject']
674             message = form.cleaned_data['message']
675             email = form.cleaned_data['email'] # email of the sender
676             cc_myself = form.cleaned_data['cc_myself']
677
678             recipients = ['yasin.upmc@gmail.com']
679             if cc_myself:
680                 recipients.append(email)
681
682             from django.core.mail import send_mail
683             send_mail("Onelab user submitted a query ", [first_name,last_name,affiliation,subject,message], email, recipients)
684             return render(request,'contact_sent.html') # Redirect after POST
685     else:
686         form = ContactForm() # An unbound form
687     
688     return render(request, 'contact.html', {
689         'form': form,
690         'topmenu_items': topmenu_items('Contact Us', request),
691         'username': the_user (request)
692
693     })
694
695
696 def slice_request(request):
697     if request.method == 'POST': # If the form has been submitted...
698         form = SliceRequestForm(request.POST) # A form bound to the POST data
699         if form.is_valid(): # All validation rules pass
700             # Process the data in form.cleaned_data
701             slice_name = form.cleaned_data['slice_name']
702             number_of_nodes = form.cleaned_data['number_of_nodes']
703             type_of_nodes = form.cleaned_data['type_of_nodes']
704             purpose = form.cleaned_data['purpose']
705             email = form.cleaned_data['email'] # email of the sender
706             cc_myself = form.cleaned_data['cc_myself']
707
708             recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
709             if cc_myself:
710                 recipients.append(email)
711
712             from django.core.mail import send_mail
713             send_mail("Onelab New Slice request form submitted", [slice_name,number_of_nodes,type_of_nodes,purpose], email, recipients)
714             return render(request,'slicereq_recvd.html') # Redirect after POST
715     else:
716         form = SliceRequestForm() # An unbound form
717
718 #    template_env = {}
719 #    template_env['form'] = form
720 #    template_env['topmenu_items'] = topmenu_items('Request a slice', request) 
721 #    template_env['unfold1_main'] = render(request, 'slice_request_.html', {
722 #        'form': form,
723 #    })
724 #    from django.shortcuts                import render_to_response
725 #    from django.template                 import RequestContext
726 #    return render_to_response ('view-unfold1.html',template_env,
727 #                               context_instance=RequestContext(request))
728
729     return render(request, 'slice_request.html', {
730         'form': form,
731         'topmenu_items': topmenu_items('Request a slice', request),
732         'username': the_user (request) 
733     })
734
735
736 class PresViewView(TemplateView):
737     template_name = "view-unfold1.html"
738
739     def get_context_data(self, **kwargs):
740
741         page = Page(self.request)
742
743         pres_view = PresView(page = page)
744
745         context = super(PresViewView, self).get_context_data(**kwargs)
746
747         #context['ALL_STATIC'] = "all_static"
748         context['unfold1_main'] = pres_view.render(self.request)
749
750         # XXX This is repeated in all pages
751         # more general variables expected in the template
752         context['title'] = 'Test view that combines various plugins'
753         # the menu items on the top
754         context['topmenu_items'] = topmenu_items('PresView', self.request)
755         # so we can sho who is logged
756         context['username'] = the_user(self.request)
757
758         prelude_env = page.prelude_env()
759         context.update(prelude_env)
760
761         return context
762
763 def json_me(config_file,type):
764     json_answer = ''
765     for ligne in config_file:
766         if not ligne.startswith('#'):
767             args = ligne.split(';')
768             json_answer += str('{ "name": "' + args[0] + '" ,"id":"' + args[1]  + '" ,"descriptif":"' + args[2]+'"')
769             if type!="dynamic":
770                 json_answer += str(',"contraints":')
771                 if args[3]=="":
772                     json_answer += str('""')
773                 else:
774                     json_answer += str(args[3])
775             json_answer += str('},')
776     return json_answer[:-1]
777
778
779 DIR = '/var/myslice/'
780 STATIC = '%s/config_method_static' % DIR
781 DYNAMIC = '%s/config_method_dynamic' % DIR
782 ANIMATION = '%s/config_method_animation' % DIR
783
784 def pres_view_methods(request, type):
785
786     if type ==None:
787         return 0
788     elif type =="static":
789         config = open(STATIC, "r")
790         json_answer = str('{ "options": [')
791         json_answer += str(json_me(config,"static"))
792         json_answer += str('] }')
793         config.close()
794     elif type =="dynamic":
795         config = open(DYNAMIC, "r")
796         json_answer = str('{ "options": [')
797         json_answer += str(json_me(config,"dynamic"))
798         json_answer += str('] }')
799         config.close()
800     elif type =="animation":
801         config = open(ANIMATION, "r")
802         json_answer = str('{ "options": [')
803         json_answer += str(json_me(config,"animation"))
804         json_answer += str('] }')
805         config.close()
806     elif type =="all":
807         config = open(STATIC, "r")
808         json_answer = str('{ "static": [')
809         json_answer += str(json_me(config,"static"))
810         json_answer += str('],')
811         json_answer += str('"dynamic": [')
812         config.close()
813         config = open(DYNAMIC, "r")
814         json_answer += str(json_me(config,"dynamic"))
815         json_answer += str('],')
816         json_answer += str('"animation": [')
817         config.close()
818         config = open(ANIMATION, "r")
819         json_answer += str(json_me(config,"animation"))
820         json_answer += str('] }')
821         config.close()
822     else:
823         return 0
824     return HttpResponse (json_answer, mimetype="application/json")
825
826 def pres_view_animation(request, constraints, id):
827
828 # sites crees depuis 2008
829 # static.py?contraints=']date_created':1262325600&id='name_id"'
830
831     # method = request.getvalue('method') #ex : GetSites
832     #constraints = "']date_created':1262325600"
833     #id = "2"
834
835     if id == None:
836         return 0
837
838     # method = 'GetSites'#request.getvalue('method') #ex : GetSites
839     # constraints = {}#request.getvalue('constraints') // nul = {}
840     # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
841
842     config_file = open(ANIMATION, "r")
843     for ligne in config_file:
844         if not ligne.startswith('#'):
845             ligne = ligne.split('\n')
846             first = ligne[0].split(';')
847             if (str(first[1]) == str(id)):
848                 save = first
849     config_file.close()
850
851     #Les print_method, print_option sont definis par le client (js)
852     #Les animations acceptent que les connexions anonymous
853     # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
854     args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
855
856
857     #Creation d'un objet event
858     event = Event(args)
859     cmd = [{"params": {
860             "data": {
861                 "print_options": event.print_options,
862                 "print_method": event.print_method,
863                 "message": event.data
864             }
865         }
866     }]
867
868     json_answer = json.dumps(cmd)
869     return HttpResponse (json_answer, mimetype="application/json")
870
871 def pres_view_static(request, constraints, id):
872     #constraints = "']date_created':1262325600"
873     #id = "2"
874
875     # method = 'GetSites'#request.getvalue('method') #ex : GetSites
876     # constraints = {}#request.getvalue('constraints') // nul = {}
877     # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
878
879     config_file = open(STATIC, "r")
880     for ligne in config_file:
881         if not ligne.startswith('#'):
882             ligne = ligne.split('\n')
883             first = ligne[0].split(';')
884             if (str(first[1]) == str(id)):
885                 save = first
886     config_file.close()
887
888     #Les print_method, print_option sont definis par le client (js)
889     #Les animations acceptent que les connexions anonymous
890     # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
891     args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
892
893
894     #Creation d'un objet event
895     event = Event(args)
896     cmd = [{"params": {
897             "data": {
898                 "print_options": event.print_options,
899                 "print_method": event.print_method,
900                 "message": event.data
901             }
902         }
903     }]
904
905     json_answer = json.dumps(cmd)
906     return HttpResponse (json_answer, mimetype="application/json")