Modified Query for list of authorities in Register page, temporary modified filter...
[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         #import os
644         #from M2Crypto import Rand, RSA, BIO
645
646         KEY_LENGTH = 2048
647
648         def blank_callback():
649             "Replace the default dashes"
650             return
651
652         # Random seed
653         Rand.rand_seed (os.urandom (KEY_LENGTH))
654         # Generate key pair
655         key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
656         # Create memory buffers
657         pri_mem = BIO.MemoryBuffer()
658         pub_mem = BIO.MemoryBuffer()
659         # Save keys to buffers
660         key.save_key_bio(pri_mem, None)
661         key.save_pub_key_bio(pub_mem)
662
663         # Get keys 
664         public_key = pub_mem.getvalue()
665         private_key = pri_mem.getvalue()
666         # Saving to DB
667         keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
668         keypair = re.sub("\r", "", keypair)
669         keypair = re.sub("\n", "\\n", keypair)
670         #keypair = keypair.rstrip('\r\n')
671         keypair = ''.join(keypair.split())
672         get_user.keypair = keypair
673         get_user.save()
674         return HttpResponse('Success: New Keypair Generated! %s' % keypair)
675
676     elif 'upload_key' in request.POST:
677         up_file = request.FILES['pubkey']
678         file_content =  up_file.read()
679         file_name = up_file.name
680         file_extension = os.path.splitext(file_name)[1] 
681         allowed_extension =  ['.pub','.txt']
682         if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
683             file_content = '{"user_public_key":"'+ file_content +'"}'
684             file_content = re.sub("\r", "", file_content)
685             file_content = re.sub("\n", "\\n",file_content)
686             file_content = ''.join(file_content.split())
687             get_user.keypair = file_content
688             get_user.save()
689             return HttpResponse('Success: Publickey uploaded! Old records overwritten')
690         else:
691             return HttpResponse('Please upload a valid RSA public key [.txt or .pub].')    
692         
693     else:
694         message = 'You submitted an empty form.'
695         return HttpResponse(message)
696
697 def register_4m_f4f(request):
698     errors = []
699
700     authorities_query = Query.get('authority').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc']).select('name', 'authority_hrn')
701     #authorities_query = Query.get('authority').select('authority_hrn')
702     authorities = execute_query(request, authorities_query)
703
704     if request.method == 'POST':
705         #get_email = PendingUser.objects.get(email)
706         reg_fname = request.POST.get('firstname', '')
707         reg_lname = request.POST.get('lastname', '')
708         reg_aff = request.POST.get('affiliation','')
709         reg_auth = request.POST.get('authority_hrn', '')
710         reg_email = request.POST.get('email','').lower()
711         
712         #POST value validation  
713         if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
714             errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
715             #return HttpResponse("Only Letters, Numbers, - and _ allowd in First Name")
716             #return render(request, 'register_4m_f4f.html')
717         if (re.search(r'^[\w+\s.@+-]+$', reg_lname) == None):
718             errors.append('Last Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
719             #return HttpResponse("Only Letters, Numbers, - and _ is allowed in Last name")
720             #return render(request, 'register_4m_f4f.html')
721         if (re.search(r'^[\w+\s.@+-]+$', reg_aff) == None):
722             errors.append('Affiliation may contain only letters, numbers, spaces and @/./+/-/_ characters.')
723             #return HttpResponse("Only Letters, Numbers and _ is allowed in Affiliation")
724             #return render(request, 'register_4m_f4f.html')
725         # XXX validate authority hrn !!
726         if PendingUser.objects.filter(email__iexact=reg_email):
727             errors.append('Email already registered.Please provide a new email address.')
728             #return HttpResponse("Email Already exists")
729             #return render(request, 'register_4m_f4f.html')
730         if 'generate' in request.POST['question']:
731             #import os
732             #from M2Crypto import Rand, RSA, BIO
733             
734             KEY_LENGTH = 2048
735
736             def blank_callback():
737                 "Replace the default dashes"
738                 return
739
740             # Random seed
741             Rand.rand_seed (os.urandom (KEY_LENGTH))
742             # Generate key pair
743             key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
744             # Create memory buffers
745             pri_mem = BIO.MemoryBuffer()
746             pub_mem = BIO.MemoryBuffer()
747             # Save keys to buffers
748             key.save_key_bio(pri_mem, None)
749             key.save_pub_key_bio(pub_mem)
750             # Get keys 
751             public_key = pub_mem.getvalue()
752             private_key = pri_mem.getvalue()
753             # Saving to DB
754             keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
755             keypair = re.sub("\r", "", keypair)
756             keypair = re.sub("\n", "\\n", keypair)
757             #keypair = keypair.rstrip('\r\n')
758             keypair = ''.join(keypair.split())
759             #return HttpResponse(keypair)
760         else:
761             up_file = request.FILES['user_public_key']
762             file_content =  up_file.read()
763             file_name = up_file.name
764             file_extension = os.path.splitext(file_name)[1]
765             allowed_extension =  ['.pub','.txt']
766             if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
767                 keypair = '{"user_public_key":"'+ file_content +'"}'
768                 keypair = re.sub("\r", "", keypair)
769                 keypair = re.sub("\n", "\\n",keypair)
770                 keypair = ''.join(keypair.split())
771             else:
772                 errors.append('Please upload a valid RSA public key [.txt or .pub].')
773
774         #b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff, 
775         #                email=reg_email, password=request.POST['password'], keypair=keypair)
776         #b.save()
777         if not errors:
778             b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff,
779                             authority_hrn=reg_auth,
780                             email=reg_email, password=request.POST['password'], keypair=keypair)
781             b.save()
782             return render(request, 'user_register_complete.html')
783
784     return render(request, 'register_4m_f4f.html',{
785         'topmenu_items': topmenu_items('Register', request),
786         'errors': errors,
787         'firstname': request.POST.get('firstname', ''),
788         'lastname': request.POST.get('lastname', ''),
789         'affiliation': request.POST.get('affiliation', ''),
790         'authority_hrn': request.POST.get('authority_hrn', ''),
791         'email': request.POST.get('email', ''),
792         'password': request.POST.get('password', ''),           
793         'authorities': authorities
794     })        
795     
796
797 # view for contact form
798 def contact(request):
799     if request.method == 'POST': # If the form has been submitted...
800         form = ContactForm(request.POST) # A form bound to the POST data
801         if form.is_valid(): # All validation rules pass
802             # Process the data in form.cleaned_data
803             first_name = form.cleaned_data['first_name']
804             last_name = form.cleaned_data['last_name']
805             affiliation = form.cleaned_data['affiliation']
806             subject = form.cleaned_data['subject']
807             message = form.cleaned_data['message']
808             email = form.cleaned_data['email'] # email of the sender
809             cc_myself = form.cleaned_data['cc_myself']
810
811             recipients = ['yasin.upmc@gmail.com']
812             if cc_myself:
813                 recipients.append(email)
814
815             from django.core.mail import send_mail
816             send_mail("Onelab user submitted a query ", [first_name,last_name,affiliation,subject,message], email, recipients)
817             return render(request,'contact_sent.html') # Redirect after POST
818     else:
819         form = ContactForm() # An unbound form
820     
821     return render(request, 'contact.html', {
822         'form': form,
823         'topmenu_items': topmenu_items('Contact Us', request),
824         'username': the_user (request)
825
826     })
827
828 @login_required
829 def slice_request(request):
830     if request.method == 'POST': # If the form has been submitted...
831         form = SliceRequestForm(request.POST) # A form bound to the POST data
832         if form.is_valid(): # All validation rules pass
833             # Process the data in form.cleaned_data
834             slice_name = form.cleaned_data['slice_name']
835             number_of_nodes = form.cleaned_data['number_of_nodes']
836             type_of_nodes = form.cleaned_data['type_of_nodes']
837             purpose = form.cleaned_data['purpose']
838             email = form.cleaned_data['email'] # email of the sender
839             cc_myself = form.cleaned_data['cc_myself']
840
841             recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
842             if cc_myself:
843                 recipients.append(email)
844
845             from django.core.mail import send_mail
846             send_mail("Onelab New Slice request form submitted", [slice_name,number_of_nodes,type_of_nodes,purpose], email, recipients)
847             return render(request,'slicereq_recvd.html') # Redirect after POST
848     else:
849         form = SliceRequestForm() # An unbound form
850
851 #    template_env = {}
852 #    template_env['form'] = form
853 #    template_env['topmenu_items'] = topmenu_items('Request a slice', request) 
854 #    template_env['unfold1_main'] = render(request, 'slice_request_.html', {
855 #        'form': form,
856 #    })
857 #    from django.shortcuts                import render_to_response
858 #    from django.template                 import RequestContext
859 #    return render_to_response ('view-unfold1.html',template_env,
860 #                               context_instance=RequestContext(request))
861
862     return render(request, 'slice_request.html', {
863         'form': form,
864         'topmenu_items': topmenu_items('Request a slice', request),
865         'username': the_user (request) 
866     })
867
868
869 class PresViewView(TemplateView):
870     template_name = "view-unfold1.html"
871
872     def get_context_data(self, **kwargs):
873
874         page = Page(self.request)
875
876         pres_view = PresView(page = page)
877
878         context = super(PresViewView, self).get_context_data(**kwargs)
879
880         #context['ALL_STATIC'] = "all_static"
881         context['unfold1_main'] = pres_view.render(self.request)
882
883         # XXX This is repeated in all pages
884         # more general variables expected in the template
885         context['title'] = 'Test view that combines various plugins'
886         # the menu items on the top
887         context['topmenu_items'] = topmenu_items('PresView', self.request)
888         # so we can sho who is logged
889         context['username'] = the_user(self.request)
890
891         prelude_env = page.prelude_env()
892         context.update(prelude_env)
893
894         return context
895
896 def json_me(config_file,type):
897     json_answer = ''
898     for ligne in config_file:
899         if not ligne.startswith('#'):
900             args = ligne.split(';')
901             json_answer += str('{ "name": "' + args[0] + '" ,"id":"' + args[1]  + '" ,"descriptif":"' + args[2]+'"')
902             if type!="dynamic":
903                 json_answer += str(',"contraints":')
904                 if args[3]=="":
905                     json_answer += str('""')
906                 else:
907                     json_answer += str(args[3])
908             json_answer += str('},')
909     return json_answer[:-1]
910
911
912 DIR = '/var/myslice/'
913 STATIC = '%s/config_method_static' % DIR
914 DYNAMIC = '%s/config_method_dynamic' % DIR
915 ANIMATION = '%s/config_method_animation' % DIR
916
917 def pres_view_methods(request, type):
918
919     if type ==None:
920         return 0
921     elif type =="static":
922         config = open(STATIC, "r")
923         json_answer = str('{ "options": [')
924         json_answer += str(json_me(config,"static"))
925         json_answer += str('] }')
926         config.close()
927     elif type =="dynamic":
928         config = open(DYNAMIC, "r")
929         json_answer = str('{ "options": [')
930         json_answer += str(json_me(config,"dynamic"))
931         json_answer += str('] }')
932         config.close()
933     elif type =="animation":
934         config = open(ANIMATION, "r")
935         json_answer = str('{ "options": [')
936         json_answer += str(json_me(config,"animation"))
937         json_answer += str('] }')
938         config.close()
939     elif type =="all":
940         config = open(STATIC, "r")
941         json_answer = str('{ "static": [')
942         json_answer += str(json_me(config,"static"))
943         json_answer += str('],')
944         json_answer += str('"dynamic": [')
945         config.close()
946         config = open(DYNAMIC, "r")
947         json_answer += str(json_me(config,"dynamic"))
948         json_answer += str('],')
949         json_answer += str('"animation": [')
950         config.close()
951         config = open(ANIMATION, "r")
952         json_answer += str(json_me(config,"animation"))
953         json_answer += str('] }')
954         config.close()
955     else:
956         return 0
957     return HttpResponse (json_answer, mimetype="application/json")
958
959 def pres_view_animation(request, constraints, id):
960
961 # sites crees depuis 2008
962 # static.py?contraints=']date_created':1262325600&id='name_id"'
963
964     # method = request.getvalue('method') #ex : GetSites
965     #constraints = "']date_created':1262325600"
966     #id = "2"
967
968     if id == None:
969         return 0
970
971     # method = 'GetSites'#request.getvalue('method') #ex : GetSites
972     # constraints = {}#request.getvalue('constraints') // nul = {}
973     # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
974
975     config_file = open(ANIMATION, "r")
976     for ligne in config_file:
977         if not ligne.startswith('#'):
978             ligne = ligne.split('\n')
979             first = ligne[0].split(';')
980             if (str(first[1]) == str(id)):
981                 save = first
982     config_file.close()
983
984     #Les print_method, print_option sont definis par le client (js)
985     #Les animations acceptent que les connexions anonymous
986     # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
987     args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
988
989
990     #Creation d'un objet event
991     event = Event(args)
992     cmd = [{"params": {
993             "data": {
994                 "print_options": event.print_options,
995                 "print_method": event.print_method,
996                 "message": event.data
997             }
998         }
999     }]
1000
1001     json_answer = json.dumps(cmd)
1002     return HttpResponse (json_answer, mimetype="application/json")
1003
1004 def pres_view_static(request, constraints, id):
1005     #constraints = "']date_created':1262325600"
1006     #id = "2"
1007
1008     # method = 'GetSites'#request.getvalue('method') #ex : GetSites
1009     # constraints = {}#request.getvalue('constraints') // nul = {}
1010     # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
1011
1012     config_file = open(STATIC, "r")
1013     for ligne in config_file:
1014         if not ligne.startswith('#'):
1015             ligne = ligne.split('\n')
1016             first = ligne[0].split(';')
1017             if (str(first[1]) == str(id)):
1018                 save = first
1019     config_file.close()
1020
1021     #Les print_method, print_option sont definis par le client (js)
1022     #Les animations acceptent que les connexions anonymous
1023     # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
1024     args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
1025
1026
1027     #Creation d'un objet event
1028     event = Event(args)
1029     cmd = [{"params": {
1030             "data": {
1031                 "print_options": event.print_options,
1032                 "print_method": event.print_method,
1033                 "message": event.data
1034             }
1035         }
1036     }]
1037
1038     json_answer = json.dumps(cmd)
1039     return HttpResponse (json_answer, mimetype="application/json")
1040
1041 class ValidatePendingView(TemplateView):
1042     template_name = "validate_pending.html"
1043
1044     def get_context_data(self, **kwargs):
1045         # We might have slices on different registries with different user accounts 
1046         # 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
1047         # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
1048
1049         #messages.info(self.request, 'You have logged in')
1050         page = Page(self.request)
1051
1052         ctx_my_authorities = {}
1053         ctx_delegation_authorities = {}
1054
1055
1056         # The user need to be logged in
1057         if the_user(self.request):
1058             # Who can a PI validate:
1059             # His own authorities + those he has credentials for.
1060             # In MySlice we need to look at credentials also.
1061             
1062
1063             # XXX This will have to be asynchroneous. Need to implement barriers,
1064             # for now it will be sufficient to have it working statically
1065
1066             # get user_id to later on query accounts
1067             # XXX Having real query plan on local tables would simplify all this
1068             # XXX $user_email is still not available for local tables
1069             #user_query = Query().get('local:user').filter_by('email', '==', '$user_email').select('user_id')
1070             user_query = Query().get('local:user').filter_by('email', '==', the_user(self.request)).select('user_id')
1071             user, = execute_query(self.request, user_query)
1072             user_id = user['user_id']
1073
1074             # Query manifold to learn about available SFA platforms for more information
1075             # In general we will at least have the portal
1076             # For now we are considering all registries
1077             all_authorities = []
1078             platform_ids = []
1079             sfa_platforms_query = Query().get('local:platform').filter_by('gateway_type', '==', 'sfa').select('platform_id', 'platform', 'auth_type')
1080             sfa_platforms = execute_query(self.request, sfa_platforms_query)
1081             for sfa_platform in sfa_platforms:
1082                 print "SFA PLATFORM > ", sfa_platform['platform']
1083                 if not 'auth_type' in sfa_platform:
1084                     continue
1085                 auth = sfa_platform['auth_type']
1086                 if not auth in all_authorities:
1087                     all_authorities.append(auth)
1088                 platform_ids.append(sfa_platform['platform_id'])
1089
1090             # We can check on which the user has authoritity credentials = PI rights
1091             credential_authorities = set()
1092             credential_authorities_expired = set()
1093
1094             # User account on these registries
1095             user_accounts_query = Query.get('local:account').filter_by('user_id', '==', user_id).filter_by('platform_id', 'included', platform_ids).select('config')
1096             user_accounts = execute_query(self.request, user_accounts_query)
1097             #print "=" * 80
1098             #print user_accounts
1099             #print "=" * 80
1100             for user_account in user_accounts:
1101                 config = json.loads(user_account['config'])
1102                 creds = []
1103                 if 'authority_credentials' in config:
1104                     for authority_hrn, credential in config['authority_credentials'].items():
1105                         #if credential is not expired:
1106                         credential_authorities.add(authority_hrn)
1107                         #else
1108                         #    credential_authorities_expired.add(authority_hrn)
1109                 if 'delegated_authority_credentials' in config:
1110                     for authority_hrn, credential in config['delegated_authority_credentials'].items():
1111                         #if credential is not expired:
1112                         credential_authorities.add(authority_hrn)
1113                         #else
1114                         #    credential_authorities_expired.add(authority_hrn)
1115
1116             print 'credential_authorities =', credential_authorities
1117             print 'credential_authorities_expired =', credential_authorities_expired
1118
1119             # ** Where am I a PI **
1120             # For this we need to ask SFA (of all authorities) = PI function
1121             pi_authorities_query = Query.get('user').filter_by('user_hrn', '==', '$user_hrn').select('pi_authorities')
1122             pi_authorities_tmp = execute_query(self.request, pi_authorities_query)
1123             pi_authorities = set()
1124             for pa in pi_authorities_tmp:
1125                 pi_authorities |= set(pa['pi_authorities'])
1126
1127             print "pi_authorities =", pi_authorities
1128             
1129             # My authorities + I have a credential
1130             pi_credential_authorities = pi_authorities & credential_authorities
1131             pi_no_credential_authorities = pi_authorities - credential_authorities - credential_authorities_expired
1132             pi_expired_credential_authorities = pi_authorities & credential_authorities_expired
1133             # Authorities I've been delegated PI rights
1134             pi_delegation_credential_authorities = credential_authorities - pi_authorities
1135             pi_delegation_expired_authorities = credential_authorities_expired - pi_authorities
1136
1137             print "pi_credential_authorities =", pi_credential_authorities
1138             print "pi_no_credential_authorities =", pi_no_credential_authorities
1139             print "pi_expired_credential_authorities =", pi_expired_credential_authorities
1140             print "pi_delegation_credential_authorities = ", pi_delegation_credential_authorities
1141             print "pi_delegation_expired_authorities = ", pi_delegation_expired_authorities
1142
1143             # Summary intermediary
1144             pi_my_authorities = pi_credential_authorities | pi_no_credential_authorities | pi_expired_credential_authorities
1145             pi_delegation_authorities = pi_delegation_credential_authorities | pi_delegation_expired_authorities
1146
1147             print "--"
1148             print "pi_my_authorities = ", pi_my_authorities
1149             print "pi_delegation_authorities = ", pi_delegation_authorities
1150
1151             # Summary all
1152             queried_pending_authorities = pi_my_authorities | pi_delegation_authorities
1153             print "----"
1154             print "queried_pending_authorities = ", queried_pending_authorities
1155             
1156             # Pending requests + authorities
1157             #pending_users = PendingUser.objects.filter(authority_hrn__in = queried_pending_authorities).all() 
1158             #pending_slices = PendingSlice.objects.filter(authority_hrn__in = queried_pending_authorities).all() 
1159             pending_users = PendingUser.objects.all()
1160             pending_slices = PendingSlice.objects.all()
1161
1162             # Dispatch requests and build the proper structure for the template:
1163
1164             print "pending users =", pending_users
1165             print "pending slices =", pending_slices
1166
1167             for user in pending_users:
1168                 auth_hrn = user.authority_hrn
1169
1170                 request = {}
1171                 request['type'] = 'user'
1172                 request['id'] = 'TODO' # XXX in DB ?
1173                 request['timestamp'] = 'TODO' # XXX in DB ?
1174                 request['details'] = "%s %s <%s>" % (user.first_name, user.last_name, user.email)
1175
1176                 if auth_hrn in pi_my_authorities:
1177                     dest = ctx_my_authorities
1178
1179                     # define the css class
1180                     if auth_hrn in pi_credential_authorities:
1181                         request['allowed'] = 'allowed'
1182                     elif auth_hrn in pi_expired_credential_authorities:
1183                         request['allowed'] = 'expired'
1184                     else: # pi_no_credential_authorities
1185                         request['allowed'] = 'denied'
1186
1187                 elif auth_hrn in pi_delegation_authorities:
1188                     dest = ctx_delegation_authorities
1189
1190                     if auth_hrn in pi_delegation_credential_authorities:
1191                         request['allowed'] = 'allowed'
1192                     else: # pi_delegation_expired_authorities
1193                         request['allowed'] = 'expired'
1194
1195                 else:
1196                     continue
1197                     
1198                 if not auth_hrn in dest:
1199                     dest[auth_hrn] = []
1200                 print "auth_hrn [%s] was added %r" % (auth_hrn, request)
1201                 dest[auth_hrn].append(request) 
1202
1203             for slice in pending_slices:
1204                 auth_hrn = slice.authority_hrn
1205                 if not auth_hrn:
1206                     auth_hrn = "ple.upmc" # XXX HARDCODED
1207
1208                 request = {}
1209                 request['type'] = 'slice'
1210                 request['id'] = 'TODO' # XXX in DB ?
1211                 request['timestamp'] = 'TODO' # XXX in DB ?
1212                 request['details'] = "Number of nodes: %d -- Type of nodes: %s<br/>%s" % ('TODO', 'TODO', 'TODO') # XXX 
1213                 if auth_hrn in pi_my_authorities:
1214                     dest = ctx_my_authorities
1215
1216                     # define the css class
1217                     if auth_hrn in pi_credential_authorities:
1218                         request['allowed'] = 'allowed'
1219                     elif auth_hrn in pi_expired_credential_authorities:
1220                         request['allowed'] = 'expired'
1221                     else: # pi_no_credential_authorities
1222                         request['allowed'] = 'denied'
1223
1224                 elif auth_hrn in pi_delegation_authorities:
1225                     dest = ctx_delegation_authorities
1226
1227                     if auth_hrn in pi_delegation_credential_authorities:
1228                         request['allowed'] = 'allowed'
1229                     else: # pi_delegation_expired_authorities
1230                         request['allowed'] = 'expired'
1231                     
1232                 if not auth_hrn in dest:
1233                     dest[auth_hrn] = []
1234                 dest[auth_hrn].append(request) 
1235
1236         context = super(ValidatePendingView, self).get_context_data(**kwargs)
1237         context['my_authorities']   = ctx_my_authorities
1238         context['delegation_authorities'] = ctx_delegation_authorities
1239
1240         # XXX This is repeated in all pages
1241         # more general variables expected in the template
1242         context['title'] = 'Test view that combines various plugins'
1243         # the menu items on the top
1244         context['topmenu_items'] = topmenu_items('Dashboard', self.request) 
1245         # so we can sho who is logged
1246         context['username'] = the_user(self.request) 
1247
1248         # XXX We need to prepare the page for queries
1249         #context.update(page.prelude_env())
1250
1251         return context