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