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