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