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