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