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