updater never made it to production
[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 from django.template.loader      import render_to_string
31 from django.core.mail            import send_mail
32 from django.utils.decorators     import method_decorator
33 from django.contrib.auth.decorators import login_required
34
35 from plugins.lists.simplelist    import SimpleList
36 from plugins.hazelnut            import Hazelnut
37 from plugins.pres_view           import PresView
38 from portal.event import Event
39 import json
40
41 from portal                      import signals
42 from portal.forms                import SliceRequestForm, ContactForm
43 from portal.util                 import RegistrationView, ActivationView
44 from portal.models               import PendingUser, PendingSlice
45 from portal.actions              import authority_get_pi_emails, get_request_by_authority
46 from manifold.core.query         import Query
47 from manifold.manifoldapi        import execute_query
48 from unfold.page                 import Page
49 from myslice.viewutils           import topmenu_items, the_user
50 from django.http                 import HttpResponseRedirect, HttpResponse
51
52 from M2Crypto                    import Rand, RSA, BIO
53 import os, re
54
55 class DashboardView(TemplateView):
56     template_name = "dashboard.html"
57     
58     #This view requires login 
59     @method_decorator(login_required)
60     def dispatch(self, *args, **kwargs):
61         return super(DashboardView, self).dispatch(*args, **kwargs)
62
63     def get_context_data(self, **kwargs):
64         # We might have slices on different registries with different user accounts 
65         # 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
66         # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
67
68         #messages.info(self.request, 'You have logged in')
69         page = Page(self.request)
70
71         # Slow...
72         #slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
73         slice_query = Query().get('user').filter_by('user_hrn', '==', '$user_hrn').select('user_hrn', 'slice.slice_hrn')
74         auth_query  = Query().get('network').select('network_hrn')
75         print "AUTH QUERY =====================", auth_query
76         print "filter", auth_query.filters
77         page.enqueue_query(slice_query)
78         page.enqueue_query(auth_query)
79
80         page.expose_js_metadata()
81         page.expose_queries()
82
83         slicelist = SimpleList(
84             title = None,
85             page  = page,
86             key   = 'slice.slice_hrn',
87             query = slice_query,
88         )
89          
90         authlist = SimpleList(
91             title = None,
92             page  = page,
93             key   = 'network_hrn',
94             query = auth_query,
95         )
96
97         context = super(DashboardView, self).get_context_data(**kwargs)
98         context['person']   = self.request.user
99         context['networks'] = authlist.render(self.request) 
100         context['slices']   = slicelist.render(self.request)
101
102         # XXX This is repeated in all pages
103         # more general variables expected in the template
104         context['title'] = 'Test view that combines various plugins'
105         # the menu items on the top
106         context['topmenu_items'] = topmenu_items('Dashboard', self.request) 
107         # so we can sho who is logged
108         context['username'] = the_user(self.request) 
109
110         context.update(page.prelude_env())
111
112         return context
113
114 # DEPRECATED #class UserRegisterView(RegistrationView):
115 # DEPRECATED #    """
116 # DEPRECATED #    A registration backend which follows a simple workflow:
117 # DEPRECATED #
118 # DEPRECATED #    1. User signs up, inactive account is created.
119 # DEPRECATED #
120 # DEPRECATED #    2. Email is sent to user with activation link.
121 # DEPRECATED #
122 # DEPRECATED #    3. User clicks activation link, account is now active.
123 # DEPRECATED #
124 # DEPRECATED #    Using this backend requires that
125 # DEPRECATED #
126 # DEPRECATED #    * ``registration`` be listed in the ``INSTALLED_APPS`` setting
127 # DEPRECATED #      (since this backend makes use of models defined in this
128 # DEPRECATED #      application).
129 # DEPRECATED #
130 # DEPRECATED #    * The setting ``ACCOUNT_ACTIVATION_DAYS`` be supplied, specifying
131 # DEPRECATED #      (as an integer) the number of days from registration during
132 # DEPRECATED #      which a user may activate their account (after that period
133 # DEPRECATED #      expires, activation will be disallowed).
134 # DEPRECATED #
135 # DEPRECATED #    * The creation of the templates
136 # DEPRECATED #      ``registration/activation_email_subject.txt`` and
137 # DEPRECATED #      ``registration/activation_email.txt``, which will be used for
138 # DEPRECATED #      the activation email. See the notes for this backends
139 # DEPRECATED #      ``register`` method for details regarding these templates.
140 # DEPRECATED #
141 # DEPRECATED #    Additionally, registration can be temporarily closed by adding the
142 # DEPRECATED #    setting ``REGISTRATION_OPEN`` and setting it to
143 # DEPRECATED #    ``False``. Omitting this setting, or setting it to ``True``, will
144 # DEPRECATED #    be interpreted as meaning that registration is currently open and
145 # DEPRECATED #    permitt ed.
146 # DEPRECATED #
147 # DEPRECATED #    Internally, this is accomplished via storing an activation key in
148 # DEPRECATED #    an instance of ``registration.models.RegistrationProfile``. See
149 # DEPRECATED #    that model and its custom manager for full documentation of its
150 # DEPRECATED #    fields and supported operations.
151 # DEPRECATED #    
152 # DEPRECATED #    """
153 # DEPRECATED ## DEPRECATED #    form_class = UserRegisterForm
154 # DEPRECATED #    
155 # DEPRECATED #    def register(self, request, **cleaned_data):
156 # DEPRECATED #        """
157 # DEPRECATED #        Given a username, email address and password, register a new
158 # DEPRECATED #        user account, which will initially be inactive.
159 # DEPRECATED #
160 # DEPRECATED #        Along with the new ``User`` object, a new
161 # DEPRECATED #        ``registration.models.RegistrationProfile`` will be created,
162 # DEPRECATED #        tied to that ``User``, containing the activation key which
163 # DEPRECATED #        will be used for this account.
164 # DEPRECATED #
165 # DEPRECATED #        An email will be sent to the supplied email address; this
166 # DEPRECATED #        email should contain an activation link. The email will be
167 # DEPRECATED #        rendered using two templates. See the documentation for
168 # DEPRECATED #        ``RegistrationProfile.send_activation_email()`` for
169 # DEPRECATED #        information about these templates and the contexts provided to
170 # DEPRECATED #        them.
171 # DEPRECATED #
172 # DEPRECATED #        After the ``User`` and ``RegistrationProfile`` are created and
173 # DEPRECATED #        the activation email is sent, the signal
174 # DEPRECATED #        ``registration.signals.user_registered`` will be sent, with
175 # DEPRECATED #        the new ``User`` as the keyword argument ``user`` and the
176 # DEPRECATED #        class of this backend as the sender.
177 # DEPRECATED #
178 # DEPRECATED #        """
179 # DEPRECATED #        first_name = cleaned_data['first_name']
180 # DEPRECATED #        last_name  = cleaned_data['last_name']
181 # DEPRECATED #        affiliation= cleaned_data['affiliation']
182 # DEPRECATED #        email      = cleaned_data['email']
183 # DEPRECATED #        password   = cleaned_data['password1']
184 # DEPRECATED #        
185 # DEPRECATED #        #password2  = cleaned_data['password2']
186 # DEPRECATED #        keypair    = cleaned_data['keypair']
187 # DEPRECATED #
188 # DEPRECATED #        #if Site._meta.installed:
189 # DEPRECATED #        #    site = Site.objects.get_current()
190 # DEPRECATED #        #else:
191 # DEPRECATED #        #    site = RequestSite(request) 
192 # DEPRECATED #        site = None
193 # DEPRECATED #
194 # DEPRECATED #        new_user = PendingUser.objects.create_inactive_user(first_name, last_name, email, password, site)
195 # DEPRECATED #        signals.user_registered.send(sender=self.__class__,
196 # DEPRECATED #                                     user=new_user,
197 # DEPRECATED #                                     request=request)
198 # DEPRECATED #        return new_user
199 # DEPRECATED #
200 # DEPRECATED #    def get_context_data(self, **kwargs):
201 # DEPRECATED #        context = super(UserRegisterView, self).get_context_data(**kwargs)
202 # DEPRECATED #        context['topmenu_items'] = topmenu_items('Register', self.request)
203 # DEPRECATED #        context['username'] = the_user (self.request)
204 # DEPRECATED #        return context
205 # DEPRECATED #
206 # DEPRECATED #    def registration_allowed(self, request):
207 # DEPRECATED #        """
208 # DEPRECATED #        Indicate whether account registration is currently permitted,
209 # DEPRECATED #        based on the value of the setting ``REGISTRATION_OPEN``. This
210 # DEPRECATED #        is determined as follows:
211 # DEPRECATED #
212 # DEPRECATED #        * If ``REGISTRATION_OPEN`` is not specified in settings, or is
213 # DEPRECATED #          set to ``True``, registration is permitted.
214 # DEPRECATED #
215 # DEPRECATED #        * If ``REGISTRATION_OPEN`` is both specified and set to
216 # DEPRECATED #          ``False``, registration is not permitted.
217 # DEPRECATED #        
218 # DEPRECATED #        """
219 # DEPRECATED #        return getattr(settings, 'REGISTRATION_OPEN', True)
220 # DEPRECATED #
221 # DEPRECATED #    def get_success_url(self, request, user):
222 # DEPRECATED #        """
223 # DEPRECATED #        Return the name of the URL to redirect to after successful
224 # DEPRECATED #        user registration.
225 # DEPRECATED #        
226 # DEPRECATED #        """
227 # DEPRECATED #        return ('user_register_complete', (), {})
228 # DEPRECATED #
229 # DEPRECATED #
230 # DEPRECATED #class UserValidateView(ActivationView):
231 # DEPRECATED #    def activate(self, request, activation_key):
232 # DEPRECATED #        """
233 # DEPRECATED #        Given an an activation key, look up and activate the user
234 # DEPRECATED #        account corresponding to that key (if possible).
235 # DEPRECATED #
236 # DEPRECATED #        After successful activation, the signal
237 # DEPRECATED #        ``registration.signals.user_activated`` will be sent, with the
238 # DEPRECATED #        newly activated ``User`` as the keyword argument ``user`` and
239 # DEPRECATED #        the class of this backend as the sender.
240 # DEPRECATED #        
241 # DEPRECATED #        """
242 # DEPRECATED #        activated_user = RegistrationProfile.objects.activate_user(activation_key)
243 # DEPRECATED #        if activated_user:
244 # DEPRECATED #            signals.user_activated.send(sender=self.__class__,
245 # DEPRECATED #                                        user=activated_user,
246 # DEPRECATED #                                        request=request)
247 # DEPRECATED #        return activated_user
248 # DEPRECATED #
249 # DEPRECATED #    def get_success_url(self, request, user):
250 # DEPRECATED #        return ('registration_activation_complete', (), {})
251 # DEPRECATED #
252 # DEPRECATED #
253 # DEPRECATED #from portal.portalpage  import PortalPage
254 # DEPRECATED #from plugins.wizard     import Wizard
255 # DEPRECATED #from plugins.form       import CreateForm
256 # DEPRECATED #from plugins.raw.raw    import Raw          # XXX
257 # DEPRECATED #
258 # DEPRECATED #from myslice.viewutils  import the_user
259 # DEPRECATED #
260 # DEPRECATED #from django.template.loader import render_to_string
261 # DEPRECATED #from django.template import RequestContext
262 # DEPRECATED #from django.views import generic
263 # DEPRECATED #
264 # DEPRECATED #from django.contrib.formtools.wizard.views import NamedUrlSessionWizardView
265 # DEPRECATED ##from django.core.files.storage import FileSystemStorage
266 # DEPRECATED #from django.core.files.storage import default_storage
267 # DEPRECATED #
268 # DEPRECATED ##class MerlinWizard(NamedUrlSessionWizardView):
269 # DEPRECATED ##
270 # DEPRECATED ##    ...
271 # DEPRECATED ##    ...
272 # DEPRECATED ##
273 # DEPRECATED ##    @classonlymethod
274 # DEPRECATED ##    def as_view(cls, *args, **kwargs):
275 # DEPRECATED ##        kwargs.update({
276 # DEPRECATED ##            'form_list': [
277 # DEPRECATED ##                NameForm,
278 # DEPRECATED ##                QuestForm,
279 # DEPRECATED ##                ColorForm,
280 # DEPRECATED ##            ],
281 # DEPRECATED ##            'url_name': 'merlin_wizard'
282 # DEPRECATED ##        })
283 # DEPRECATED ##        return super(MerlinWizard, cls).as_view(*args, **kwargs)
284 # DEPRECATED #
285 # DEPRECATED #class UserRegisterWizardView(NamedUrlSessionWizardView):
286 # DEPRECATED ##class UserRegisterWizardView(LoginRequiredMixin, NamedUrlSessionWizardView):
287 # DEPRECATED #    # Notice that I specify a file storage instance. If you don't specify this,
288 # DEPRECATED #    # and you need to support FileField or ImageField in your forms, you'll get
289 # DEPRECATED #    # errors from Django. This is something else I think could be handled by
290 # DEPRECATED #    # the views better. Seems to me that it should just use whatever the
291 # DEPRECATED #    # default/specified storage is for the rest of your project/application.
292 # DEPRECATED #    file_storage = default_storage # FileSystemStorage()
293 # DEPRECATED #    template_name = "register_user_wizard.html"
294 # DEPRECATED #
295 # DEPRECATED #    def done(self, form_list, **kwargs):
296 # DEPRECATED #        step1_form = form_list[0]
297 # DEPRECATED #        step2_form = form_list[1]
298 # DEPRECATED #
299 # DEPRECATED #        productext = self.create_product(product_form)
300 # DEPRECATED #        shippings = self.create_shippings(productext, shipping_forms)
301 # DEPRECATED #        images = self.create_images(productext, image_forms)
302 # DEPRECATED #
303 # DEPRECATED #        if all([productext, shippings, images]):
304 # DEPRECATED #            del self.request.session["wizard_product_wizard_view"]
305 # DEPRECATED #
306 # DEPRECATED #            messages.success(self.request,
307 # DEPRECATED #                _("Your product has been created."))
308 # DEPRECATED #            return HttpResponseRedirect(self.get_success_url(productext))
309 # DEPRECATED #
310 # DEPRECATED #        messages.error(self.request, _("Something went wrong creating your "
311 # DEPRECATED #            "product. Please try again or contact support."))
312 # DEPRECATED #        return HttpResponseRedirect(reverse("register_wizard"))
313 # DEPRECATED #
314 # DEPRECATED #    #def get_form_kwargs(self, step):
315 # DEPRECATED #    #    if step == "product":
316 # DEPRECATED #    #        return {"user": self.request.user}
317 # DEPRECATED #    #    return {}
318 # DEPRECATED #
319 # DEPRECATED ## The portal should hook the slice and user creation pages
320 # DEPRECATED #
321 # DEPRECATED #def register_user(request):
322 # DEPRECATED #    
323 # DEPRECATED #    if request.method == 'POST':
324 # DEPRECATED #        form = UserRegisterForm(request.POST) # Nous reprenons les donnĂ©es
325 # DEPRECATED #        if form.is_valid():
326 # DEPRECATED #            first_name = form.cleaned_data['first_name']
327 # DEPRECATED #            last_name  = form.cleaned_data['last_name']
328 # DEPRECATED #            email      = form.cleaned_data['email']
329 # DEPRECATED #            password   = form.cleaned_data['password']
330 # DEPRECATED #            password2  = form.cleaned_data['password2']
331 # DEPRECATED #            keypair    = form.cleaned_data['keypair']
332 # DEPRECATED #            ## Ici nous pouvons traiter les donnĂ©es du formulaire
333 # DEPRECATED #            #sujet = form.cleaned_data['sujet']
334 # DEPRECATED #            #message = form.cleaned_data['message']
335 # DEPRECATED #            #envoyeur = form.cleaned_data['envoyeur']
336 # DEPRECATED #            #renvoi = form.cleaned_data['renvoi']
337 # DEPRECATED #            ## Nous pourrions ici envoyer l'e-mail grâce aux donnĂ©es que nous venons de rĂ©cupĂ©rer
338 # DEPRECATED #            #envoi = True
339 # DEPRECATED #    else:
340 # DEPRECATED #        form = UserRegisterForm()
341 # DEPRECATED #    return render(request, 'register_user.html', locals())
342 # DEPRECATED #
343 # DEPRECATED #def index(request):
344 # DEPRECATED #
345 # DEPRECATED #    WIZARD_TITLE = 'User registration'
346 # DEPRECATED #    STEP1_TITLE  = 'Enter your details'
347 # DEPRECATED #    STEP2_TITLE  = 'Select your institution'
348 # DEPRECATED #    STEP3_TITLE  = 'Authentication'
349 # DEPRECATED #    STEP4_TITLE  = 'Request a slice (optional)'
350 # DEPRECATED #    STEP5_TITLE  = 'Waiting for validation'
351 # DEPRECATED #    STEP6_TITLE  = 'Account validated'
352 # DEPRECATED #
353 # DEPRECATED #    STEP0 = render_to_string('account_validated.html', context_instance=RequestContext(request))
354 # DEPRECATED #    STEP2_HTML   = """
355 # DEPRECATED #    coucou
356 # DEPRECATED #    """
357 # DEPRECATED #    STEP4 = """
358 # DEPRECATED #    mede
359 # DEPRECATED #    """
360 # DEPRECATED #    STEP5 = render_to_string('account_validated.html', context_instance=RequestContext(request))
361 # DEPRECATED #
362 # DEPRECATED #    p = PortalPage(request)
363 # DEPRECATED #
364 # DEPRECATED #    # This is redundant with the Wizard title
365 # DEPRECATED #    p << "<h3>User registration</h3>"
366 # DEPRECATED #
367 # DEPRECATED #    sons = []
368 # DEPRECATED #    start_step = 1
369 # DEPRECATED #
370 # DEPRECATED #    # STEP 1
371 # DEPRECATED #    # If the user already exists (is logged), let's display a summary of his account details
372 # DEPRECATED #    # Otherwise propose a form to fill in
373 # DEPRECATED #    if the_user(request):
374 # DEPRECATED #        # Fill a disabled form with user info
375 # DEPRECATED #        # Please logout to register another user
376 # DEPRECATED #        sons.append(Raw(page=p, title=STEP1_TITLE, togglable=False, html=STEP0))
377 # DEPRECATED #        start_step += 1
378 # DEPRECATED #    else:
379 # DEPRECATED #        # We could pass a list of fields also, instead of retrieving them from metadata
380 # DEPRECATED #        # Otherwise we need some heuristics to display nice forms
381 # DEPRECATED #        # XXX Could we log the user in after the form is validated ?
382 # DEPRECATED #        # XXX Explain the password is for XXX
383 # DEPRECATED #        field_list = [{
384 # DEPRECATED #            'name'        : 'First name',
385 # DEPRECATED #            'field'       : 'firstname',
386 # DEPRECATED #            'type'        : 'text',
387 # DEPRECATED #            'validate_rx' : '^[a-zA-Z -]+$',
388 # DEPRECATED #            'validate_err': 'Your first name must be comprised of letters only',
389 # DEPRECATED #            'description' : 'Enter your first name',
390 # DEPRECATED #        }, {
391 # DEPRECATED #            'name'        : 'Last name',
392 # DEPRECATED #            'field'       : 'lastname',
393 # DEPRECATED #            'type'        : 'text',
394 # DEPRECATED #            'validate_rx' : '^[a-zA-Z -]+$',
395 # DEPRECATED #            'validate_err': 'Your last name must be comprised of letters only',
396 # DEPRECATED #            'description' : 'Enter your last name',
397 # DEPRECATED #        }, { 
398 # DEPRECATED #            'name'        : 'Email',
399 # DEPRECATED #            'field'       : 'email',
400 # DEPRECATED #            'type'        : 'text',
401 # DEPRECATED #            'description' : 'Enter your email address',
402 # DEPRECATED #        }, {
403 # DEPRECATED #            'name'        : 'Password',
404 # DEPRECATED #            'field'       : 'password',
405 # DEPRECATED #            'type'        : 'password',
406 # DEPRECATED #            'description' : 'Enter your password',
407 # DEPRECATED #        }, {
408 # DEPRECATED #            'name'        : 'Confirm password',
409 # DEPRECATED #            'field'       : 'password2',
410 # DEPRECATED #            'type'        : 'password',
411 # DEPRECATED #            'description' : 'Enter your password again',
412 # DEPRECATED #        }]
413 # DEPRECATED #        sons.append(CreateForm(page = p, title = STEP1_TITLE, togglable = False, object = 'local:user', fields = field_list))
414 # DEPRECATED #
415 # DEPRECATED #    # STEP 2
416 # DEPRECATED #    # If the user already exists (is logged), let's display a summary of its institution
417 # DEPRECATED #    # Otherwise propose a form to fill in (we should base our selection on the email)
418 # DEPRECATED #    if the_user(request):
419 # DEPRECATED #        # Fill a disabled form with institution
420 # DEPRECATED #        # Please logout to register another user
421 # DEPRECATED #        sons.append(Raw(page=p, title=STEP2_TITLE, togglable=False, html="User created"))
422 # DEPRECATED #        start_step += 1
423 # DEPRECATED #    else:
424 # DEPRECATED #        sons.append(CreateForm(page = p, title = STEP2_TITLE, togglable = False, object = 'slice')) #institution'))
425 # DEPRECATED #
426 # DEPRECATED #    # STEP3
427 # DEPRECATED #    # Please should your prefered authentication method
428 # DEPRECATED #    # This step should allow the user to either choose the user or managed mode in MySlice
429 # DEPRECATED #    sons.append(Raw(page = p, title = STEP3_TITLE, togglable = False, html = STEP2_HTML))
430 # DEPRECATED #
431 # DEPRECATED #    # Step 4: Request a slice (optional)
432 # DEPRECATED #    sons.append(CreateForm(page = p, title = STEP4_TITLE, togglable = False, object = 'slice'))
433 # DEPRECATED #
434 # DEPRECATED #    # Step 5: Your request is waiting for validation
435 # DEPRECATED #    # Periodic refresh
436 # DEPRECATED #    sons.append(Raw(page = p, title = STEP5_TITLE, togglable = False, html = STEP4))
437 # DEPRECATED #
438 # DEPRECATED #    # Step 6: Account validation  = welcome for newly validated users
439 # DEPRECATED #    # . delegation
440 # DEPRECATED #    # . platforms
441 # DEPRECATED #    # . slice
442 # DEPRECATED #    # . pointers
443 # DEPRECATED #    sons.append(Raw(page = p, title = STEP6_TITLE, togglable = False, html = STEP5))
444 # DEPRECATED #
445 # DEPRECATED #    wizard = Wizard(
446 # DEPRECATED #        page       = p,
447 # DEPRECATED #        title      = WIZARD_TITLE,
448 # DEPRECATED #        togglable  = False,
449 # DEPRECATED #        sons       = sons,
450 # DEPRECATED #        start_step = start_step,
451 # DEPRECATED #    )
452 # DEPRECATED #
453 # DEPRECATED #    p << wizard.render(request) # in portal page if possible
454 # DEPRECATED #
455 # DEPRECATED #    return p.render()
456
457
458 # DEPRECATED ## view for my_account
459 # DEPRECATED # class MyAccountView(TemplateView):
460 # DEPRECATED #    template_name = "my_account.html"
461 # DEPRECATED #    
462 # DEPRECATED #    def from_process(self, request, **cleaned_data): 
463 # DEPRECATED #        #if request.method == 'POST':
464 # DEPRECATED #         #       if request.POST['submit_name']:
465 # DEPRECATED #        if 'fname' in request.POST:            
466 # DEPRECATED #                messsag= "Got Name"
467 # DEPRECATED #                #return render(request, 'portal/my_account.html')
468 # DEPRECATED #                #response = HttpResponse("Here's the text of the Web page.")    
469 # DEPRECATED #                return HttpResponse(message)
470 # DEPRECATED #            
471 # DEPRECATED #    def get_context_data(self, **kwargs):
472 # DEPRECATED #        page = Page(self.request)
473 # DEPRECATED #        context = super(MyAccountView, self).get_context_data(**kwargs)
474 # DEPRECATED #        context['person']   = self.request.user
475 # DEPRECATED #        # XXX This is repeated in all pages
476 # DEPRECATED #        # more general variables expected in the template
477 # DEPRECATED #        context['title'] = 'User Profile Page'
478 # DEPRECATED #        # the menu items on the top
479 # DEPRECATED #        context['topmenu_items'] = topmenu_items('my_account', self.request)
480 # DEPRECATED #        # so we can sho who is logged
481 # DEPRECATED #        context['username'] = the_user(self.request)
482 # DEPRECATED #        context.update(page.prelude_env())
483 # DEPRECATED #        return context
484
485 # View for platforms
486 class PlatformsView(TemplateView):
487     template_name = "platforms.html"
488
489     def get_context_data(self, **kwargs):
490         page = Page(self.request)
491
492         #network_query  = Query().get('local:platform').filter_by('disabled', '==', '0').select('platform','platform_longname','gateway_type')
493         network_query  = Query().get('local:platform').select('platform','platform_longname','gateway_type')
494         page.enqueue_query(network_query)
495
496         page.expose_js_metadata()
497         page.expose_queries()
498         networklist = Hazelnut(
499             page  = page,
500             title = 'List',
501             domid = 'checkboxes',
502             # this is the query at the core of the slice list
503             query = network_query,
504             query_all = network_query,
505             checkboxes = False,
506             datatables_options = {
507             # for now we turn off sorting on the checkboxes columns this way
508             # this of course should be automatic in hazelnut
509             'aoColumns'      : [None, None, None, None, {'bSortable': False}],
510             'iDisplayLength' : 25,
511             'bLengthChange'  : True,
512             },
513         )
514 #
515 #        networklist = SimpleList(
516 #            title = None,
517 #            page  = page,
518 #            key   = 'platform',
519 #            query = network_query,
520 #        )
521
522         context = super(PlatformsView, self).get_context_data(**kwargs)
523         context['person']   = self.request.user
524         context['networks'] = networklist.render(self.request)
525
526         # XXX This is repeated in all pages
527         # more general variables expected in the template
528         context['title'] = 'Platforms connected to MySlice'
529         # the menu items on the top
530         context['topmenu_items'] = topmenu_items('Platforms', self.request)
531         # so we can sho who is logged
532         context['username'] = the_user(self.request)
533
534         context.update(page.prelude_env())
535
536         return context
537
538
539
540 # View for 1 platform and its details
541 class PlatformView(TemplateView):
542     template_name = "platform.html"
543
544     def get_context_data(self, **kwargs):
545         page = Page(self.request)
546
547         for key, value in kwargs.iteritems():
548             print "%s = %s" % (key, value)       
549             if key == "platformname":
550                 platformname=value
551                 
552         network_query  = Query().get('local:platform').filter_by('platform', '==', platformname).select('platform','platform_longname','gateway_type')
553         page.enqueue_query(network_query)
554
555         page.expose_js_metadata()
556         page.expose_queries()
557         networklist = Hazelnut(
558             page  = page,
559             title = 'List',
560             domid = 'checkboxes',
561             # this is the query at the core of the slice list
562             query = network_query,
563             query_all = network_query,
564             checkboxes = False,
565             datatables_options = {
566             # for now we turn off sorting on the checkboxes columns this way
567             # this of course should be automatic in hazelnut
568             'aoColumns'      : [None, None, None, None, {'bSortable': False}],
569             'iDisplayLength' : 25,
570             'bLengthChange'  : True,
571             },
572         )
573 #
574 #        networklist = SimpleList(
575 #            title = None,
576 #            page  = page,
577 #            key   = 'platform',
578 #            query = network_query,
579 #        )
580
581         context = super(PlatformView, self).get_context_data(**kwargs)
582         context['person']   = self.request.user
583         context['networks'] = networklist.render(self.request)
584
585         # XXX This is repeated in all pages
586         # more general variables expected in the template
587         context['title'] = 'Platforms connected to MySlice'
588         # the menu items on the top
589         context['topmenu_items'] = topmenu_items('Platforms', self.request)
590         # so we can sho who is logged
591         context['username'] = the_user(self.request)
592
593         context.update(page.prelude_env())
594
595         return context
596
597
598
599 #class for my_account
600 class AccountView(TemplateView):
601     template_name = "my_account.html"
602     
603     #This view requires login 
604     @method_decorator(login_required)
605     def dispatch(self, *args, **kwargs):
606         return super(AccountView, self).dispatch(*args, **kwargs)
607
608
609     def get_context_data(self, **kwargs):
610         #page = Page(self.request)
611
612         user_query  = Query().get('local:user').select('config','email')
613         user_details = execute_query(self.request, user_query)
614         
615         # not always found in user_details...
616         config={}
617         for user_detail in user_details:
618             #email = user_detail['email']
619             if user_detail['config']:
620                 config = json.loads(user_detail['config'])
621
622         platform_query  = Query().get('local:platform').select('platform_id','platform')
623         account_query  = Query().get('local:account').select('user_id','platform_id','auth_type','config')
624         platform_details = execute_query(self.request, platform_query)
625         account_details = execute_query(self.request, account_query)
626        
627         # initial assignment needed for users having no account  
628         platform_name = ''
629         account_type = ''
630         account_usr_hrn = ''
631         account_pub_key = ''       
632         for account_detail in account_details:
633             for platform_detail in platform_details:
634                 if platform_detail['platform_id'] == account_detail['platform_id']:
635                     platform_name = platform_detail['platform']
636                     account_type = account_detail['auth_type']
637                     account_config = json.loads(account_detail['config'])
638                     
639                     # a bit more pythonic
640                     account_usr_hrn = account_config.get('user_hrn','N/A')
641                     account_pub_key = account_config.get('user_public_key','N/A')
642         
643         #page.enqueue_query(network_query)
644
645         #page.expose_js_metadata()
646         #page.expose_queries()
647
648         #userlist = SimpleList(
649         #    title = None,
650         #    page  = page,
651         #    key   = 'user_id',
652         #    query = network_query,
653         #)
654
655         context = super(AccountView, self).get_context_data(**kwargs)
656         context['platform_name'] = platform_name
657         context['account_type'] = account_type
658         context['account_usr_hrn'] = account_usr_hrn
659         context['account_pub_key'] = account_pub_key 
660         context['person']   = self.request.user
661         context ['firstname'] = config.get('firstname',"?")
662         context ['lastname'] = config.get('lastname',"?")
663         context ['fullname'] = context['firstname'] +' '+ context['lastname']
664         context ['affiliation'] = config.get('affiliation',"Unknown Affiliation")
665         #context['users'] = userlist.render(self.request)
666         
667         # XXX This is repeated in all pages
668         # more general variables expected in the template
669         context['title'] = 'Platforms connected to MySlice'
670         # the menu items on the top
671         context['topmenu_items'] = topmenu_items('My Account', self.request)
672         # so we can sho who is logged
673         context['username'] = the_user(self.request)
674 #        context ['firstname'] = config['firstname']
675         #context.update(page.prelude_env())
676         return context
677
678
679
680
681
682
683 @login_required
684 # View for my_account form
685 #def my_account(request):
686 #    return render(request, 'my_account.html', {
687 #        #'form': form,
688 #        'topmenu_items': topmenu_items('My Account', request),
689 #        'username': the_user (request)
690 #    })
691
692
693 @login_required
694 #my_acc form value processing
695 def acc_process(request):
696     # getting the user_id from the session [now hardcoded]
697     get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
698     # getting user info from manifold
699     if 'submit_name' in request.POST:
700         edited_first_name =  request.POST['fname']
701         edited_last_name =  request.POST['lname']
702         #email = 'test_email@gmail.com'
703         #password = 'test_pp'
704         #message = 'F_Name: %s L_name: %s dummy_pp: %s' % (first_name, last_name, password)
705         #site = None
706         
707         # insert into DB [needed for registration page]
708         #approach borrowed from register view     
709         #new_user = PendingUser.objects.create_inactive_user(edited_first_name, edited_last_name, email,  password, site) 
710         #conventional approach
711         #b = PendingUser(first_name=edited_first_name, last_name=edited_last_name)
712         #b.save()
713         
714         # select and update [will be used throughout this view]
715         # select the logged in user [for the moment hard coded]
716         #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
717         # update first and last name
718         get_user.first_name = edited_first_name
719         get_user.last_name = edited_last_name
720         get_user.save() 
721
722         return HttpResponse('Sucess: First Name and Last Name Updated!')       
723     elif 'submit_pass' in request.POST:
724         edited_password = request.POST['password']
725         # select the logged in user [for the moment hard coded]
726         #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
727         # update password
728         get_user.password = edited_password
729         get_user.save()
730         return HttpResponse('Success: Password Changed!!')
731     elif 'generate' in request.POST:
732         # Generate public and private keys using SFA Library
733         from sfa.trust.certificate  import Keypair
734         k = Keypair(create=True)
735         public_key = k.get_pubkey_string()
736         private_key = k.as_pem()
737        
738 # DEPRECATED
739 #        KEY_LENGTH = 2048
740 #
741 #        def blank_callback():
742 #            "Replace the default dashes"
743 #            return
744 #
745 #        # Random seed
746 #        Rand.rand_seed (os.urandom (KEY_LENGTH))
747 #        # Generate key pair
748 #        key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
749 #        # Create memory buffers
750 #        pri_mem = BIO.MemoryBuffer()
751 #        pub_mem = BIO.MemoryBuffer()
752 #        # Save keys to buffers
753 #        key.save_key_bio(pri_mem, None)
754 #        key.save_pub_key_bio(pub_mem)
755 #
756 #        # Get keys 
757 #        public_key = pub_mem.getvalue()
758 #        private_key = pri_mem.getvalue()
759         private_key = ''.join(private_key.split())
760         public_key = "ssh-rsa " + public_key
761         # Saving to DB
762         keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
763 #        keypair = re.sub("\r", "", keypair)
764 #        keypair = re.sub("\n", "\\n", keypair)
765 #        #keypair = keypair.rstrip('\r\n')
766 #        keypair = ''.join(keypair.split())
767         get_user.keypair = keypair
768         get_user.save()
769         return HttpResponse('Success: New Keypair Generated! %s' % keypair)
770
771     elif 'upload_key' in request.POST:
772         up_file = request.FILES['pubkey']
773         file_content =  up_file.read()
774         file_name = up_file.name
775         file_extension = os.path.splitext(file_name)[1] 
776         allowed_extension =  ['.pub','.txt']
777         if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
778             file_content = '{"user_public_key":"'+ file_content +'"}'
779             file_content = re.sub("\r", "", file_content)
780             file_content = re.sub("\n", "\\n",file_content)
781             file_content = ''.join(file_content.split())
782             get_user.keypair = file_content
783             get_user.save()
784             return HttpResponse('Success: Publickey uploaded! Old records overwritten')
785         else:
786             return HttpResponse('Please upload a valid RSA public key [.txt or .pub].')    
787         
788     else:
789         message = 'You submitted an empty form.'
790         return HttpResponse(message)
791
792 def register_4m_f4f(request):
793     errors = []
794
795     authorities_query = Query.get('authority').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc']).select('name', 'authority_hrn')
796     #authorities_query = Query.get('authority').select('authority_hrn')
797     authorities = execute_query(request, authorities_query)
798
799     if request.method == 'POST':
800         # We shall use a form here
801
802         #get_email = PendingUser.objects.get(email)
803         reg_fname = request.POST.get('firstname', '')
804         reg_lname = request.POST.get('lastname', '')
805         reg_aff = request.POST.get('affiliation','')
806         reg_auth = request.POST.get('authority_hrn', '')
807         reg_email = request.POST.get('email','').lower()
808         
809         #POST value validation  
810         if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
811             errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
812             #return HttpResponse("Only Letters, Numbers, - and _ allowd in First Name")
813             #return render(request, 'register_4m_f4f.html')
814         if (re.search(r'^[\w+\s.@+-]+$', reg_lname) == None):
815             errors.append('Last Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
816             #return HttpResponse("Only Letters, Numbers, - and _ is allowed in Last name")
817             #return render(request, 'register_4m_f4f.html')
818         if (re.search(r'^[\w+\s.@+-]+$', reg_aff) == None):
819             errors.append('Affiliation may contain only letters, numbers, spaces and @/./+/-/_ characters.')
820             #return HttpResponse("Only Letters, Numbers and _ is allowed in Affiliation")
821             #return render(request, 'register_4m_f4f.html')
822         # XXX validate authority hrn !!
823         if PendingUser.objects.filter(email__iexact=reg_email):
824             errors.append('Email already registered.Please provide a new email address.')
825             #return HttpResponse("Email Already exists")
826             #return render(request, 'register_4m_f4f.html')
827         if 'generate' in request.POST['question']:
828             # Generate public and private keys using SFA Library
829             from sfa.trust.certificate  import Keypair
830             k = Keypair(create=True)
831             public_key = k.get_pubkey_string()
832             private_key = k.as_pem()
833
834 # DEPRECATED
835 #            #import os
836 #            #from M2Crypto import Rand, RSA, BIO
837 #            
838 #            KEY_LENGTH = 2048
839 #
840 #            def blank_callback():
841 #                "Replace the default dashes"
842 #                return
843 #
844 #            # Random seed
845 #            Rand.rand_seed (os.urandom (KEY_LENGTH))
846 #            # Generate key pair
847 #            key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
848 #            # Create memory buffers
849 #            pri_mem = BIO.MemoryBuffer()
850 #            pub_mem = BIO.MemoryBuffer()
851 #            # Save keys to buffers
852 #            key.save_key_bio(pri_mem, None)
853 #            key.save_pub_key_bio(pub_mem)
854 #            # Get keys 
855 #            public_key = pub_mem.getvalue()
856 #            private_key = pri_mem.getvalue()
857
858             private_key = ''.join(private_key.split())
859             public_key = "ssh-rsa " + public_key
860             # Saving to DB
861             keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
862 #            keypair = re.sub("\r", "", keypair)
863 #            keypair = re.sub("\n", "\\n", keypair)
864 #            #keypair = keypair.rstrip('\r\n')
865 #            keypair = ''.join(keypair.split())
866         else:
867             up_file = request.FILES['user_public_key']
868             file_content =  up_file.read()
869             file_name = up_file.name
870             file_extension = os.path.splitext(file_name)[1]
871             allowed_extension =  ['.pub','.txt']
872             if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
873                 keypair = '{"user_public_key":"'+ file_content +'"}'
874                 keypair = re.sub("\r", "", keypair)
875                 keypair = re.sub("\n", "\\n",keypair)
876                 keypair = ''.join(keypair.split())
877             else:
878                 errors.append('Please upload a valid RSA public key [.txt or .pub].')
879
880         #b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff, 
881         #                email=reg_email, password=request.POST['password'], keypair=keypair)
882         #b.save()
883         if not errors:
884             b = PendingUser(
885                 first_name=reg_fname, 
886                 last_name=reg_lname, 
887                 affiliation=reg_aff,
888                 authority_hrn=reg_auth,
889                 email=reg_email, 
890                 password=request.POST['password'],
891                 keypair=keypair
892             )
893             b.save()
894
895             # Send email
896             ctx = {
897                 first_name   : reg_fname, 
898                 last_name    : reg_lname, 
899                 affiliation  : reg_aff,
900                 authority_hrn: reg_auth,
901                 email        : reg_email, 
902                 keypair      : keypair,
903                 cc_myself    : True # form.cleaned_data['cc_myself']
904             }
905
906             recipients = authority_get_pi_emails(authority_hrn)
907             if ctx['cc_myself']:
908                 recipients.append(ctx['email'])
909
910             msg = render_to_string('user_request_email.txt', ctx)
911             send_mail("Onelab New User request submitted", msg, email, recipients)
912
913             return render(request, 'user_register_complete.html')
914
915     return render(request, 'register_4m_f4f.html',{
916         'topmenu_items': topmenu_items('Register', request),
917         'errors': errors,
918         'firstname': request.POST.get('firstname', ''),
919         'lastname': request.POST.get('lastname', ''),
920         'affiliation': request.POST.get('affiliation', ''),
921         'authority_hrn': request.POST.get('authority_hrn', ''),
922         'email': request.POST.get('email', ''),
923         'password': request.POST.get('password', ''),           
924         'authorities': authorities
925     })        
926     
927
928 # view for contact form
929 def contact(request):
930     if request.method == 'POST': # If the form has been submitted...
931         form = ContactForm(request.POST) # A form bound to the POST data
932         if form.is_valid(): # All validation rules pass
933             # Process the data in form.cleaned_data
934             first_name = form.cleaned_data['first_name']
935             last_name = form.cleaned_data['last_name']
936             affiliation = form.cleaned_data['affiliation']
937             subject = form.cleaned_data['subject']
938             message = form.cleaned_data['message']
939             email = form.cleaned_data['email'] # email of the sender
940             cc_myself = form.cleaned_data['cc_myself']
941
942             #recipients = authority_get_pi_emails(authority_hrn)
943             recipients = ['yasin.upmc@gmail.com']
944             if cc_myself:
945                 recipients.append(email)
946
947             from django.core.mail import send_mail
948             send_mail("Onelab user submitted a query ", [first_name,last_name,affiliation,subject,message], email, recipients)
949             return render(request,'contact_sent.html') # Redirect after POST
950     else:
951         form = ContactForm() # An unbound form
952     
953     return render(request, 'contact.html', {
954         'form': form,
955         'topmenu_items': topmenu_items('Contact Us', request),
956         'username': the_user (request)
957
958     })
959
960 @login_required
961 def slice_request(request):
962     errors = []
963
964     authorities_query = Query.get('authority').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc']).select('name', 'authority_hrn')
965     #authorities_query = Query.get('authority').select('authority_hrn')
966     authorities = execute_query(request, authorities_query)
967
968     authority_hrn_tuple = []
969     for authority in authorities:
970         authority_hrn_tuple.append((authority['authority_hrn'], authority['name']))
971     authority_hrn_initial = {'authority_hrn': authority_hrn_tuple}
972         
973     # request.POST or None ?
974     if request.method == 'POST':
975         # The form has been submitted
976         form = SliceRequestForm(request.POST, initial=authority_hrn_initial) 
977
978         if form.is_valid():
979             slice_name      = form.cleaned_data['slice_name']
980             authority_hrn   = form.cleaned_data['authority_hrn']
981             number_of_nodes = form.cleaned_data['number_of_nodes']
982             type_of_nodes   = form.cleaned_data['type_of_nodes']
983             purpose         = form.cleaned_data['purpose']
984             
985             s = PendingSlice(
986                 slice_name      = slice_name,
987                 authority_hrn   = authority_hrn,
988                 number_of_nodes = number_of_nodes,
989                 type_of_nodes   = type_of_nodes,
990                 purpose         = purpose
991             )
992             s.save()
993
994             # All validation rules pass; process data in form.cleaned_data
995             # slice_name, number_of_nodes, type_of_nodes, purpose
996             email = form.cleaned_data['email'] # email of the sender
997             cc_myself = form.cleaned_data['cc_myself']
998
999             # The recipients are the PI of the authority
1000             recipients = authority_get_pi_emails(authority_hrn)
1001             #recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
1002             if cc_myself:
1003                 recipients.append(email)
1004             msg = render_to_string('slice_request_email.txt', form.cleaned_data)
1005             send_mail("Onelab New Slice request form submitted", msg, email, recipients)
1006
1007             return render(request,'slicereq_recvd.html') # Redirect after POST
1008     else:
1009         form = SliceRequestForm(initial=authority_hrn_initial)
1010
1011 #    template_env = {}
1012 #    template_env['form'] = form
1013 #    template_env['topmenu_items'] = topmenu_items('Request a slice', request) 
1014 #    template_env['unfold1_main'] = render(request, 'slice_request_.html', {
1015 #        'form': form,
1016 #    })
1017 #    from django.shortcuts                import render_to_response
1018 #    from django.template                 import RequestContext
1019 #    return render_to_response ('view-unfold1.html',template_env,
1020 #                               context_instance=RequestContext(request))
1021
1022     return render(request, 'slice_request.html', {
1023         'form': form,
1024         'topmenu_items': topmenu_items('Request a slice', request),
1025         'username': the_user (request) 
1026     })
1027
1028
1029 class PresViewView(TemplateView):
1030     template_name = "view-unfold1.html"
1031
1032     def get_context_data(self, **kwargs):
1033
1034         page = Page(self.request)
1035
1036         pres_view = PresView(page = page)
1037
1038         context = super(PresViewView, self).get_context_data(**kwargs)
1039
1040         #context['ALL_STATIC'] = "all_static"
1041         context['unfold1_main'] = pres_view.render(self.request)
1042
1043         # XXX This is repeated in all pages
1044         # more general variables expected in the template
1045         context['title'] = 'Test view that combines various plugins'
1046         # the menu items on the top
1047         context['topmenu_items'] = topmenu_items('PresView', self.request)
1048         # so we can sho who is logged
1049         context['username'] = the_user(self.request)
1050
1051         prelude_env = page.prelude_env()
1052         context.update(prelude_env)
1053
1054         return context
1055
1056 def json_me(config_file,type):
1057     json_answer = ''
1058     for ligne in config_file:
1059         if not ligne.startswith('#'):
1060             args = ligne.split(';')
1061             json_answer += str('{ "name": "' + args[0] + '" ,"id":"' + args[1]  + '" ,"descriptif":"' + args[2]+'"')
1062             if type!="dynamic":
1063                 json_answer += str(',"contraints":')
1064                 if args[3]=="":
1065                     json_answer += str('""')
1066                 else:
1067                     json_answer += str(args[3])
1068             json_answer += str('},')
1069     return json_answer[:-1]
1070
1071
1072 DIR = '/var/myslice/'
1073 STATIC = '%s/config_method_static' % DIR
1074 DYNAMIC = '%s/config_method_dynamic' % DIR
1075 ANIMATION = '%s/config_method_animation' % DIR
1076
1077 def pres_view_methods(request, type):
1078
1079     if type ==None:
1080         return 0
1081     elif type =="static":
1082         config = open(STATIC, "r")
1083         json_answer = str('{ "options": [')
1084         json_answer += str(json_me(config,"static"))
1085         json_answer += str('] }')
1086         config.close()
1087     elif type =="dynamic":
1088         config = open(DYNAMIC, "r")
1089         json_answer = str('{ "options": [')
1090         json_answer += str(json_me(config,"dynamic"))
1091         json_answer += str('] }')
1092         config.close()
1093     elif type =="animation":
1094         config = open(ANIMATION, "r")
1095         json_answer = str('{ "options": [')
1096         json_answer += str(json_me(config,"animation"))
1097         json_answer += str('] }')
1098         config.close()
1099     elif type =="all":
1100         config = open(STATIC, "r")
1101         json_answer = str('{ "static": [')
1102         json_answer += str(json_me(config,"static"))
1103         json_answer += str('],')
1104         json_answer += str('"dynamic": [')
1105         config.close()
1106         config = open(DYNAMIC, "r")
1107         json_answer += str(json_me(config,"dynamic"))
1108         json_answer += str('],')
1109         json_answer += str('"animation": [')
1110         config.close()
1111         config = open(ANIMATION, "r")
1112         json_answer += str(json_me(config,"animation"))
1113         json_answer += str('] }')
1114         config.close()
1115     else:
1116         return 0
1117     return HttpResponse (json_answer, mimetype="application/json")
1118
1119 def pres_view_animation(request, constraints, id):
1120
1121 # sites crees depuis 2008
1122 # static.py?contraints=']date_created':1262325600&id='name_id"'
1123
1124     # method = request.getvalue('method') #ex : GetSites
1125     #constraints = "']date_created':1262325600"
1126     #id = "2"
1127
1128     if id == None:
1129         return 0
1130
1131     # method = 'GetSites'#request.getvalue('method') #ex : GetSites
1132     # constraints = {}#request.getvalue('constraints') // nul = {}
1133     # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
1134
1135     config_file = open(ANIMATION, "r")
1136     for ligne in config_file:
1137         if not ligne.startswith('#'):
1138             ligne = ligne.split('\n')
1139             first = ligne[0].split(';')
1140             if (str(first[1]) == str(id)):
1141                 save = first
1142     config_file.close()
1143
1144     #Les print_method, print_option sont definis par le client (js)
1145     #Les animations acceptent que les connexions anonymous
1146     # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
1147     args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
1148
1149
1150     #Creation d'un objet event
1151     event = Event(args)
1152     cmd = [{"params": {
1153             "data": {
1154                 "print_options": event.print_options,
1155                 "print_method": event.print_method,
1156                 "message": event.data
1157             }
1158         }
1159     }]
1160
1161     json_answer = json.dumps(cmd)
1162     return HttpResponse (json_answer, mimetype="application/json")
1163
1164 def pres_view_static(request, constraints, id):
1165     #constraints = "']date_created':1262325600"
1166     #id = "2"
1167
1168     # method = 'GetSites'#request.getvalue('method') #ex : GetSites
1169     # constraints = {}#request.getvalue('constraints') // nul = {}
1170     # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
1171
1172     config_file = open(STATIC, "r")
1173     for ligne in config_file:
1174         if not ligne.startswith('#'):
1175             ligne = ligne.split('\n')
1176             first = ligne[0].split(';')
1177             if (str(first[1]) == str(id)):
1178                 save = first
1179     config_file.close()
1180
1181     #Les print_method, print_option sont definis par le client (js)
1182     #Les animations acceptent que les connexions anonymous
1183     # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
1184     args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
1185
1186
1187     #Creation d'un objet event
1188     event = Event(args)
1189     cmd = [{"params": {
1190             "data": {
1191                 "print_options": event.print_options,
1192                 "print_method": event.print_method,
1193                 "message": event.data
1194             }
1195         }
1196     }]
1197
1198     json_answer = json.dumps(cmd)
1199     return HttpResponse (json_answer, mimetype="application/json")
1200
1201 class ValidatePendingView(TemplateView):
1202     template_name = "validate_pending.html"
1203
1204     def get_context_data(self, **kwargs):
1205         # We might have slices on different registries with different user accounts 
1206         # 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
1207         # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
1208
1209         #messages.info(self.request, 'You have logged in')
1210         page = Page(self.request)
1211
1212         ctx_my_authorities = {}
1213         ctx_delegation_authorities = {}
1214
1215
1216         # The user need to be logged in
1217         if the_user(self.request):
1218             # Who can a PI validate:
1219             # His own authorities + those he has credentials for.
1220             # In MySlice we need to look at credentials also.
1221             
1222
1223             # XXX This will have to be asynchroneous. Need to implement barriers,
1224             # for now it will be sufficient to have it working statically
1225
1226             # get user_id to later on query accounts
1227             # XXX Having real query plan on local tables would simplify all this
1228             # XXX $user_email is still not available for local tables
1229             #user_query = Query().get('local:user').filter_by('email', '==', '$user_email').select('user_id')
1230             user_query = Query().get('local:user').filter_by('email', '==', the_user(self.request)).select('user_id')
1231             user, = execute_query(self.request, user_query)
1232             user_id = user['user_id']
1233
1234             # Query manifold to learn about available SFA platforms for more information
1235             # In general we will at least have the portal
1236             # For now we are considering all registries
1237             all_authorities = []
1238             platform_ids = []
1239             sfa_platforms_query = Query().get('local:platform').filter_by('gateway_type', '==', 'sfa').select('platform_id', 'platform', 'auth_type')
1240             sfa_platforms = execute_query(self.request, sfa_platforms_query)
1241             for sfa_platform in sfa_platforms:
1242                 print "SFA PLATFORM > ", sfa_platform['platform']
1243                 if not 'auth_type' in sfa_platform:
1244                     continue
1245                 auth = sfa_platform['auth_type']
1246                 if not auth in all_authorities:
1247                     all_authorities.append(auth)
1248                 platform_ids.append(sfa_platform['platform_id'])
1249
1250             # We can check on which the user has authoritity credentials = PI rights
1251             credential_authorities = set()
1252             credential_authorities_expired = set()
1253
1254             # User account on these registries
1255             user_accounts_query = Query.get('local:account').filter_by('user_id', '==', user_id).filter_by('platform_id', 'included', platform_ids).select('config')
1256             user_accounts = execute_query(self.request, user_accounts_query)
1257             #print "=" * 80
1258             #print user_accounts
1259             #print "=" * 80
1260             for user_account in user_accounts:
1261                 config = json.loads(user_account['config'])
1262                 creds = []
1263                 if 'authority_credentials' in config:
1264                     for authority_hrn, credential in config['authority_credentials'].items():
1265                         #if credential is not expired:
1266                         credential_authorities.add(authority_hrn)
1267                         #else
1268                         #    credential_authorities_expired.add(authority_hrn)
1269                 if 'delegated_authority_credentials' in config:
1270                     for authority_hrn, credential in config['delegated_authority_credentials'].items():
1271                         #if credential is not expired:
1272                         credential_authorities.add(authority_hrn)
1273                         #else
1274                         #    credential_authorities_expired.add(authority_hrn)
1275
1276             print 'credential_authorities =', credential_authorities
1277             print 'credential_authorities_expired =', credential_authorities_expired
1278
1279             # ** Where am I a PI **
1280             # For this we need to ask SFA (of all authorities) = PI function
1281             pi_authorities_query = Query.get('user').filter_by('user_hrn', '==', '$user_hrn').select('pi_authorities')
1282             pi_authorities_tmp = execute_query(self.request, pi_authorities_query)
1283             pi_authorities = set()
1284             for pa in pi_authorities_tmp:
1285                 pi_authorities |= set(pa['pi_authorities'])
1286
1287             print "pi_authorities =", pi_authorities
1288             
1289             # My authorities + I have a credential
1290             pi_credential_authorities = pi_authorities & credential_authorities
1291             pi_no_credential_authorities = pi_authorities - credential_authorities - credential_authorities_expired
1292             pi_expired_credential_authorities = pi_authorities & credential_authorities_expired
1293             # Authorities I've been delegated PI rights
1294             pi_delegation_credential_authorities = credential_authorities - pi_authorities
1295             pi_delegation_expired_authorities = credential_authorities_expired - pi_authorities
1296
1297             print "pi_credential_authorities =", pi_credential_authorities
1298             print "pi_no_credential_authorities =", pi_no_credential_authorities
1299             print "pi_expired_credential_authorities =", pi_expired_credential_authorities
1300             print "pi_delegation_credential_authorities = ", pi_delegation_credential_authorities
1301             print "pi_delegation_expired_authorities = ", pi_delegation_expired_authorities
1302
1303             # Summary intermediary
1304             pi_my_authorities = pi_credential_authorities | pi_no_credential_authorities | pi_expired_credential_authorities
1305             pi_delegation_authorities = pi_delegation_credential_authorities | pi_delegation_expired_authorities
1306
1307             print "--"
1308             print "pi_my_authorities = ", pi_my_authorities
1309             print "pi_delegation_authorities = ", pi_delegation_authorities
1310
1311             # Summary all
1312             queried_pending_authorities = pi_my_authorities | pi_delegation_authorities
1313             print "----"
1314             print "queried_pending_authorities = ", queried_pending_authorities
1315
1316             requests = get_request_by_authority(queried_pending_authorities)
1317             for request in requests:
1318                 auth_hrn = request['authority_hrn']
1319
1320                 if auth_hrn in pi_my_authorities:
1321                     dest = ctx_my_authorities
1322
1323                     # define the css class
1324                     if auth_hrn in pi_credential_authorities:
1325                         request['allowed'] = 'allowed'
1326                     elif auth_hrn in pi_expired_credential_authorities:
1327                         request['allowed'] = 'expired'
1328                     else: # pi_no_credential_authorities
1329                         request['allowed'] = 'denied'
1330
1331                 elif auth_hrn in pi_delegation_authorities:
1332                     dest = ctx_delegation_authorities
1333
1334                     if auth_hrn in pi_delegation_credential_authorities:
1335                         request['allowed'] = 'allowed'
1336                     else: # pi_delegation_expired_authorities
1337                         request['allowed'] = 'expired'
1338
1339                 else:
1340                     continue
1341
1342                 if not auth_hrn in dest:
1343                     dest[auth_hrn] = []
1344                 dest[auth_hrn].append(request) 
1345         
1346         context = super(ValidatePendingView, self).get_context_data(**kwargs)
1347         context['my_authorities']   = ctx_my_authorities
1348         context['delegation_authorities'] = ctx_delegation_authorities
1349
1350         # XXX This is repeated in all pages
1351         # more general variables expected in the template
1352         context['title'] = 'Test view that combines various plugins'
1353         # the menu items on the top
1354         context['topmenu_items'] = topmenu_items('Dashboard', self.request) 
1355         # so we can sho who is logged
1356         context['username'] = the_user(self.request) 
1357
1358         # XXX We need to prepare the page for queries
1359         #context.update(page.prelude_env())
1360
1361         return context