1 # -*- coding: utf-8 -*-
3 # portal/views.py: views for the portal application
4 # This file is part of the Manifold project.
7 # Jordan Augé <jordan.auge@lip6.fr>
8 # Mohammed Yasin Rahman <mohammed-yasin.rahman@lip6.fr>
9 # Copyright 2013, UPMC Sorbonne Universités / LIP6
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.
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
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.
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
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
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
52 from M2Crypto import Rand, RSA, BIO
55 class DashboardView(TemplateView):
56 template_name = "dashboard.html"
58 #This view requires login
59 @method_decorator(login_required)
60 def dispatch(self, *args, **kwargs):
61 return super(DashboardView, self).dispatch(*args, **kwargs)
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
68 #messages.info(self.request, 'You have logged in')
69 page = Page(self.request)
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)
80 page.expose_js_metadata()
83 slicelist = SimpleList(
86 key = 'slice.slice_hrn',
90 authlist = SimpleList(
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)
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)
110 context.update(page.prelude_env())
114 # DEPRECATED #class UserRegisterView(RegistrationView):
116 # DEPRECATED # A registration backend which follows a simple workflow:
118 # DEPRECATED # 1. User signs up, inactive account is created.
120 # DEPRECATED # 2. Email is sent to user with activation link.
122 # DEPRECATED # 3. User clicks activation link, account is now active.
124 # DEPRECATED # Using this backend requires that
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).
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).
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.
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.
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.
153 # DEPRECATED ## DEPRECATED # form_class = UserRegisterForm
155 # DEPRECATED # def register(self, request, **cleaned_data):
157 # DEPRECATED # Given a username, email address and password, register a new
158 # DEPRECATED # user account, which will initially be inactive.
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.
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
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.
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']
185 # DEPRECATED # #password2 = cleaned_data['password2']
186 # DEPRECATED # keypair = cleaned_data['keypair']
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
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
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
206 # DEPRECATED # def registration_allowed(self, request):
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:
212 # DEPRECATED # * If ``REGISTRATION_OPEN`` is not specified in settings, or is
213 # DEPRECATED # set to ``True``, registration is permitted.
215 # DEPRECATED # * If ``REGISTRATION_OPEN`` is both specified and set to
216 # DEPRECATED # ``False``, registration is not permitted.
219 # DEPRECATED # return getattr(settings, 'REGISTRATION_OPEN', True)
221 # DEPRECATED # def get_success_url(self, request, user):
223 # DEPRECATED # Return the name of the URL to redirect to after successful
224 # DEPRECATED # user registration.
227 # DEPRECATED # return ('user_register_complete', (), {})
230 # DEPRECATED #class UserValidateView(ActivationView):
231 # DEPRECATED # def activate(self, request, activation_key):
233 # DEPRECATED # Given an an activation key, look up and activate the user
234 # DEPRECATED # account corresponding to that key (if possible).
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.
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
249 # DEPRECATED # def get_success_url(self, request, user):
250 # DEPRECATED # return ('registration_activation_complete', (), {})
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
258 # DEPRECATED #from myslice.viewutils import the_user
260 # DEPRECATED #from django.template.loader import render_to_string
261 # DEPRECATED #from django.template import RequestContext
262 # DEPRECATED #from django.views import generic
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
268 # DEPRECATED ##class MerlinWizard(NamedUrlSessionWizardView):
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,
281 # DEPRECATED ## 'url_name': 'merlin_wizard'
283 # DEPRECATED ## return super(MerlinWizard, cls).as_view(*args, **kwargs)
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"
295 # DEPRECATED # def done(self, form_list, **kwargs):
296 # DEPRECATED # step1_form = form_list[0]
297 # DEPRECATED # step2_form = form_list[1]
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)
303 # DEPRECATED # if all([productext, shippings, images]):
304 # DEPRECATED # del self.request.session["wizard_product_wizard_view"]
306 # DEPRECATED # messages.success(self.request,
307 # DEPRECATED # _("Your product has been created."))
308 # DEPRECATED # return HttpResponseRedirect(self.get_success_url(productext))
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"))
314 # DEPRECATED # #def get_form_kwargs(self, step):
315 # DEPRECATED # # if step == "product":
316 # DEPRECATED # # return {"user": self.request.user}
317 # DEPRECATED # # return {}
319 # DEPRECATED ## The portal should hook the slice and user creation pages
321 # DEPRECATED #def register_user(request):
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
340 # DEPRECATED # form = UserRegisterForm()
341 # DEPRECATED # return render(request, 'register_user.html', locals())
343 # DEPRECATED #def index(request):
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'
353 # DEPRECATED # STEP0 = render_to_string('account_validated.html', context_instance=RequestContext(request))
354 # DEPRECATED # STEP2_HTML = """
355 # DEPRECATED # coucou
357 # DEPRECATED # STEP4 = """
360 # DEPRECATED # STEP5 = render_to_string('account_validated.html', context_instance=RequestContext(request))
362 # DEPRECATED # p = PortalPage(request)
364 # DEPRECATED # # This is redundant with the Wizard title
365 # DEPRECATED # p << "<h3>User registration</h3>"
367 # DEPRECATED # sons = []
368 # DEPRECATED # start_step = 1
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
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',
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',
398 # DEPRECATED # 'name' : 'Email',
399 # DEPRECATED # 'field' : 'email',
400 # DEPRECATED # 'type' : 'text',
401 # DEPRECATED # 'description' : 'Enter your email address',
403 # DEPRECATED # 'name' : 'Password',
404 # DEPRECATED # 'field' : 'password',
405 # DEPRECATED # 'type' : 'password',
406 # DEPRECATED # 'description' : 'Enter your password',
408 # DEPRECATED # 'name' : 'Confirm password',
409 # DEPRECATED # 'field' : 'password2',
410 # DEPRECATED # 'type' : 'password',
411 # DEPRECATED # 'description' : 'Enter your password again',
413 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP1_TITLE, togglable = False, object = 'local:user', fields = field_list))
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
424 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP2_TITLE, togglable = False, object = 'slice')) #institution'))
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))
431 # DEPRECATED # # Step 4: Request a slice (optional)
432 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP4_TITLE, togglable = False, object = 'slice'))
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))
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))
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,
453 # DEPRECATED # p << wizard.render(request) # in portal page if possible
455 # DEPRECATED # return p.render()
458 # DEPRECATED ## view for my_account
459 # DEPRECATED # class MyAccountView(TemplateView):
460 # DEPRECATED # template_name = "my_account.html"
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)
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
486 class PlatformsView(TemplateView):
487 template_name = "platforms.html"
489 def get_context_data(self, **kwargs):
490 page = Page(self.request)
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)
496 page.expose_js_metadata()
497 page.expose_queries()
498 networklist = Hazelnut(
501 domid = 'checkboxes',
502 # this is the query at the core of the slice list
503 query = network_query,
504 query_all = network_query,
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,
515 # networklist = SimpleList(
519 # query = network_query,
522 context = super(PlatformsView, self).get_context_data(**kwargs)
523 context['person'] = self.request.user
524 context['networks'] = networklist.render(self.request)
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)
534 context.update(page.prelude_env())
540 # View for 1 platform and its details
541 class PlatformView(TemplateView):
542 template_name = "platform.html"
544 def get_context_data(self, **kwargs):
545 page = Page(self.request)
547 for key, value in kwargs.iteritems():
548 print "%s = %s" % (key, value)
549 if key == "platformname":
552 network_query = Query().get('local:platform').filter_by('platform', '==', platformname).select('platform','platform_longname','gateway_type')
553 page.enqueue_query(network_query)
555 page.expose_js_metadata()
556 page.expose_queries()
557 networklist = Hazelnut(
560 domid = 'checkboxes',
561 # this is the query at the core of the slice list
562 query = network_query,
563 query_all = network_query,
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,
574 # networklist = SimpleList(
578 # query = network_query,
581 context = super(PlatformView, self).get_context_data(**kwargs)
582 context['person'] = self.request.user
583 context['networks'] = networklist.render(self.request)
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)
593 context.update(page.prelude_env())
599 #class for my_account
600 class AccountView(TemplateView):
601 template_name = "my_account.html"
603 #This view requires login
604 @method_decorator(login_required)
605 def dispatch(self, *args, **kwargs):
606 return super(AccountView, self).dispatch(*args, **kwargs)
609 def get_context_data(self, **kwargs):
610 #page = Page(self.request)
612 user_query = Query().get('local:user').select('config','email')
613 user_details = execute_query(self.request, user_query)
615 # not always found in user_details...
617 for user_detail in user_details:
618 #email = user_detail['email']
619 if user_detail['config']:
620 config = json.loads(user_detail['config'])
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)
627 # initial assignment needed for users having no account
632 platform_name_list = []
633 account_type_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')
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)
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)]
656 context = super(AccountView, self).get_context_data(**kwargs)
657 context['data'] = lst
658 context['person'] = self.request.user
659 context ['firstname'] = config.get('firstname',"?")
660 context ['lastname'] = config.get('lastname',"?")
661 context ['fullname'] = context['firstname'] +' '+ context['lastname']
662 context ['affiliation'] = config.get('affiliation',"Unknown Affiliation")
663 #context['users'] = userlist.render(self.request)
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())
682 # View for my_account form
683 #def my_account(request):
684 # return render(request, 'my_account.html', {
686 # 'topmenu_items': topmenu_items('My Account', request),
687 # 'username': the_user (request)
692 #my_acc form value processing
693 def acc_process(request):
694 # getting the user_id from the session [now hardcoded]
695 get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
696 # getting user info from manifold
697 if 'submit_name' in request.POST:
698 edited_first_name = request.POST['fname']
699 edited_last_name = request.POST['lname']
700 #email = 'test_email@gmail.com'
701 #password = 'test_pp'
702 #message = 'F_Name: %s L_name: %s dummy_pp: %s' % (first_name, last_name, password)
705 # insert into DB [needed for registration page]
706 #approach borrowed from register view
707 #new_user = PendingUser.objects.create_inactive_user(edited_first_name, edited_last_name, email, password, site)
708 #conventional approach
709 #b = PendingUser(first_name=edited_first_name, last_name=edited_last_name)
712 # select and update [will be used throughout this view]
713 # select the logged in user [for the moment hard coded]
714 #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
715 # update first and last name
716 #get_user.first_name = edited_first_name
717 #get_user.last_name = edited_last_name
719 #user_params = {'config':'hello'}
720 #query = Query.update('local:user').set(user_params).select('config')
721 #results = execute_query(request,query)
723 # raise Exception, "Failed to update user: %s" % user_params['config']
725 #return result['config']
726 # create user is working fine :)
727 #user_params = ({'config':'"firstname":"HELLO"'},{'password':'hello'})
728 #user_params = { 'config':'{"firstname":"HEY"}'}
729 #user_params = {'email':'aa@aa.com','password':'demo'}
730 #manifold_add_user(request,user_params)
731 #manifold_update_user(request,user_params)
733 return HttpResponse('Sucess: First Name and Last Name Updated!')
734 elif 'submit_pass' in request.POST:
735 edited_password = request.POST['password']
736 # select the logged in user [for the moment hard coded]
737 #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
739 get_user.password = edited_password
741 return HttpResponse('Success: Password Changed!!')
742 elif 'generate' in request.POST:
743 # Generate public and private keys using SFA Library
744 from sfa.trust.certificate import Keypair
745 k = Keypair(create=True)
746 public_key = k.get_pubkey_string()
747 private_key = k.as_pem()
752 # def blank_callback():
753 # "Replace the default dashes"
757 # Rand.rand_seed (os.urandom (KEY_LENGTH))
758 # # Generate key pair
759 # key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
760 # # Create memory buffers
761 # pri_mem = BIO.MemoryBuffer()
762 # pub_mem = BIO.MemoryBuffer()
763 # # Save keys to buffers
764 # key.save_key_bio(pri_mem, None)
765 # key.save_pub_key_bio(pub_mem)
768 # public_key = pub_mem.getvalue()
769 # private_key = pri_mem.getvalue()
770 private_key = ''.join(private_key.split())
771 public_key = "ssh-rsa " + public_key
773 keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
774 # keypair = re.sub("\r", "", keypair)
775 # keypair = re.sub("\n", "\\n", keypair)
776 # #keypair = keypair.rstrip('\r\n')
777 # keypair = ''.join(keypair.split())
778 get_user.keypair = keypair
780 return HttpResponse('Success: New Keypair Generated! %s' % keypair)
782 elif 'upload_key' in request.POST:
783 up_file = request.FILES['pubkey']
784 file_content = up_file.read()
785 file_name = up_file.name
786 file_extension = os.path.splitext(file_name)[1]
787 allowed_extension = ['.pub','.txt']
788 if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
789 file_content = '{"user_public_key":"'+ file_content +'"}'
790 file_content = re.sub("\r", "", file_content)
791 file_content = re.sub("\n", "\\n",file_content)
792 file_content = ''.join(file_content.split())
793 get_user.keypair = file_content
795 return HttpResponse('Success: Publickey uploaded! Old records overwritten')
797 return HttpResponse('Please upload a valid RSA public key [.txt or .pub].')
800 message = 'You submitted an empty form.'
801 return HttpResponse(message)
803 def register_4m_f4f(request):
806 authorities_query = Query.get('authority').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc']).select('name', 'authority_hrn')
807 #authorities_query = Query.get('authority').select('authority_hrn')
808 authorities = execute_query(request, authorities_query)
810 if request.method == 'POST':
811 # We shall use a form here
813 #get_email = PendingUser.objects.get(email)
814 reg_fname = request.POST.get('firstname', '')
815 reg_lname = request.POST.get('lastname', '')
816 reg_aff = request.POST.get('affiliation','')
817 reg_auth = request.POST.get('authority_hrn', '')
818 reg_email = request.POST.get('email','').lower()
820 #POST value validation
821 if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
822 errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
823 #return HttpResponse("Only Letters, Numbers, - and _ allowd in First Name")
824 #return render(request, 'register_4m_f4f.html')
825 if (re.search(r'^[\w+\s.@+-]+$', reg_lname) == None):
826 errors.append('Last Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
827 #return HttpResponse("Only Letters, Numbers, - and _ is allowed in Last name")
828 #return render(request, 'register_4m_f4f.html')
829 if (re.search(r'^[\w+\s.@+-]+$', reg_aff) == None):
830 errors.append('Affiliation may contain only letters, numbers, spaces and @/./+/-/_ characters.')
831 #return HttpResponse("Only Letters, Numbers and _ is allowed in Affiliation")
832 #return render(request, 'register_4m_f4f.html')
833 # XXX validate authority hrn !!
834 if PendingUser.objects.filter(email__iexact=reg_email):
835 errors.append('Email already registered.Please provide a new email address.')
836 #return HttpResponse("Email Already exists")
837 #return render(request, 'register_4m_f4f.html')
838 if 'generate' in request.POST['question']:
839 # Generate public and private keys using SFA Library
840 from sfa.trust.certificate import Keypair
841 k = Keypair(create=True)
842 public_key = k.get_pubkey_string()
843 private_key = k.as_pem()
847 # #from M2Crypto import Rand, RSA, BIO
851 # def blank_callback():
852 # "Replace the default dashes"
856 # Rand.rand_seed (os.urandom (KEY_LENGTH))
857 # # Generate key pair
858 # key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
859 # # Create memory buffers
860 # pri_mem = BIO.MemoryBuffer()
861 # pub_mem = BIO.MemoryBuffer()
862 # # Save keys to buffers
863 # key.save_key_bio(pri_mem, None)
864 # key.save_pub_key_bio(pub_mem)
866 # public_key = pub_mem.getvalue()
867 # private_key = pri_mem.getvalue()
869 private_key = ''.join(private_key.split())
870 public_key = "ssh-rsa " + public_key
872 keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
873 # keypair = re.sub("\r", "", keypair)
874 # keypair = re.sub("\n", "\\n", keypair)
875 # #keypair = keypair.rstrip('\r\n')
876 # keypair = ''.join(keypair.split())
878 up_file = request.FILES['user_public_key']
879 file_content = up_file.read()
880 file_name = up_file.name
881 file_extension = os.path.splitext(file_name)[1]
882 allowed_extension = ['.pub','.txt']
883 if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
884 keypair = '{"user_public_key":"'+ file_content +'"}'
885 keypair = re.sub("\r", "", keypair)
886 keypair = re.sub("\n", "\\n",keypair)
887 keypair = ''.join(keypair.split())
889 errors.append('Please upload a valid RSA public key [.txt or .pub].')
891 #b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff,
892 # email=reg_email, password=request.POST['password'], keypair=keypair)
896 first_name=reg_fname,
899 authority_hrn=reg_auth,
901 password=request.POST['password'],
908 first_name : reg_fname,
909 last_name : reg_lname,
910 affiliation : reg_aff,
911 authority_hrn: reg_auth,
914 cc_myself : True # form.cleaned_data['cc_myself']
917 recipients = authority_get_pi_emails(authority_hrn)
919 recipients.append(ctx['email'])
921 msg = render_to_string('user_request_email.txt', ctx)
922 send_mail("Onelab New User request submitted", msg, email, recipients)
924 return render(request, 'user_register_complete.html')
926 return render(request, 'register_4m_f4f.html',{
927 'topmenu_items': topmenu_items('Register', request),
929 'firstname': request.POST.get('firstname', ''),
930 'lastname': request.POST.get('lastname', ''),
931 'affiliation': request.POST.get('affiliation', ''),
932 'authority_hrn': request.POST.get('authority_hrn', ''),
933 'email': request.POST.get('email', ''),
934 'password': request.POST.get('password', ''),
935 'authorities': authorities
939 # view for contact form
940 def contact(request):
941 if request.method == 'POST': # If the form has been submitted...
942 form = ContactForm(request.POST) # A form bound to the POST data
943 if form.is_valid(): # All validation rules pass
944 # Process the data in form.cleaned_data
945 first_name = form.cleaned_data['first_name']
946 last_name = form.cleaned_data['last_name']
947 affiliation = form.cleaned_data['affiliation']
948 subject = form.cleaned_data['subject']
949 message = form.cleaned_data['message']
950 email = form.cleaned_data['email'] # email of the sender
951 cc_myself = form.cleaned_data['cc_myself']
953 #recipients = authority_get_pi_emails(authority_hrn)
954 recipients = ['yasin.upmc@gmail.com']
956 recipients.append(email)
958 from django.core.mail import send_mail
959 send_mail("Onelab user submitted a query ", [first_name,last_name,affiliation,subject,message], email, recipients)
960 return render(request,'contact_sent.html') # Redirect after POST
962 form = ContactForm() # An unbound form
964 return render(request, 'contact.html', {
966 'topmenu_items': topmenu_items('Contact Us', request),
967 'username': the_user (request)
972 def slice_request(request):
975 authorities_query = Query.get('authority').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc']).select('name', 'authority_hrn')
976 #authorities_query = Query.get('authority').select('authority_hrn')
977 authorities = execute_query(request, authorities_query)
979 authority_hrn_tuple = []
980 for authority in authorities:
981 authority_hrn_tuple.append((authority['authority_hrn'], authority['name']))
982 authority_hrn_initial = {'authority_hrn': authority_hrn_tuple}
984 # request.POST or None ?
985 if request.method == 'POST':
986 # The form has been submitted
987 form = SliceRequestForm(request.POST, initial=authority_hrn_initial)
990 slice_name = form.cleaned_data['slice_name']
991 authority_hrn = form.cleaned_data['authority_hrn']
992 number_of_nodes = form.cleaned_data['number_of_nodes']
993 type_of_nodes = form.cleaned_data['type_of_nodes']
994 purpose = form.cleaned_data['purpose']
997 slice_name = slice_name,
998 authority_hrn = authority_hrn,
999 number_of_nodes = number_of_nodes,
1000 type_of_nodes = type_of_nodes,
1005 # All validation rules pass; process data in form.cleaned_data
1006 # slice_name, number_of_nodes, type_of_nodes, purpose
1007 email = form.cleaned_data['email'] # email of the sender
1008 cc_myself = form.cleaned_data['cc_myself']
1010 # The recipients are the PI of the authority
1011 recipients = authority_get_pi_emails(authority_hrn)
1012 #recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
1014 recipients.append(email)
1015 msg = render_to_string('slice_request_email.txt', form.cleaned_data)
1016 send_mail("Onelab New Slice request form submitted", msg, email, recipients)
1018 return render(request,'slicereq_recvd.html') # Redirect after POST
1020 form = SliceRequestForm(initial=authority_hrn_initial)
1023 # template_env['form'] = form
1024 # template_env['topmenu_items'] = topmenu_items('Request a slice', request)
1025 # template_env['unfold1_main'] = render(request, 'slice_request_.html', {
1028 # from django.shortcuts import render_to_response
1029 # from django.template import RequestContext
1030 # return render_to_response ('view-unfold1.html',template_env,
1031 # context_instance=RequestContext(request))
1033 return render(request, 'slice_request.html', {
1035 'topmenu_items': topmenu_items('Request a slice', request),
1036 'username': the_user (request)
1040 class PresViewView(TemplateView):
1041 template_name = "view-unfold1.html"
1043 def get_context_data(self, **kwargs):
1045 page = Page(self.request)
1047 pres_view = PresView(page = page)
1049 context = super(PresViewView, self).get_context_data(**kwargs)
1051 #context['ALL_STATIC'] = "all_static"
1052 context['unfold1_main'] = pres_view.render(self.request)
1054 # XXX This is repeated in all pages
1055 # more general variables expected in the template
1056 context['title'] = 'Test view that combines various plugins'
1057 # the menu items on the top
1058 context['topmenu_items'] = topmenu_items('PresView', self.request)
1059 # so we can sho who is logged
1060 context['username'] = the_user(self.request)
1062 prelude_env = page.prelude_env()
1063 context.update(prelude_env)
1067 def json_me(config_file,type):
1069 for ligne in config_file:
1070 if not ligne.startswith('#'):
1071 args = ligne.split(';')
1072 json_answer += str('{ "name": "' + args[0] + '" ,"id":"' + args[1] + '" ,"descriptif":"' + args[2]+'"')
1074 json_answer += str(',"contraints":')
1076 json_answer += str('""')
1078 json_answer += str(args[3])
1079 json_answer += str('},')
1080 return json_answer[:-1]
1083 DIR = '/var/myslice/'
1084 STATIC = '%s/config_method_static' % DIR
1085 DYNAMIC = '%s/config_method_dynamic' % DIR
1086 ANIMATION = '%s/config_method_animation' % DIR
1088 def pres_view_methods(request, type):
1092 elif type =="static":
1093 config = open(STATIC, "r")
1094 json_answer = str('{ "options": [')
1095 json_answer += str(json_me(config,"static"))
1096 json_answer += str('] }')
1098 elif type =="dynamic":
1099 config = open(DYNAMIC, "r")
1100 json_answer = str('{ "options": [')
1101 json_answer += str(json_me(config,"dynamic"))
1102 json_answer += str('] }')
1104 elif type =="animation":
1105 config = open(ANIMATION, "r")
1106 json_answer = str('{ "options": [')
1107 json_answer += str(json_me(config,"animation"))
1108 json_answer += str('] }')
1111 config = open(STATIC, "r")
1112 json_answer = str('{ "static": [')
1113 json_answer += str(json_me(config,"static"))
1114 json_answer += str('],')
1115 json_answer += str('"dynamic": [')
1117 config = open(DYNAMIC, "r")
1118 json_answer += str(json_me(config,"dynamic"))
1119 json_answer += str('],')
1120 json_answer += str('"animation": [')
1122 config = open(ANIMATION, "r")
1123 json_answer += str(json_me(config,"animation"))
1124 json_answer += str('] }')
1128 return HttpResponse (json_answer, mimetype="application/json")
1130 def pres_view_animation(request, constraints, id):
1132 # sites crees depuis 2008
1133 # static.py?contraints=']date_created':1262325600&id='name_id"'
1135 # method = request.getvalue('method') #ex : GetSites
1136 #constraints = "']date_created':1262325600"
1142 # method = 'GetSites'#request.getvalue('method') #ex : GetSites
1143 # constraints = {}#request.getvalue('constraints') // nul = {}
1144 # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
1146 config_file = open(ANIMATION, "r")
1147 for ligne in config_file:
1148 if not ligne.startswith('#'):
1149 ligne = ligne.split('\n')
1150 first = ligne[0].split(';')
1151 if (str(first[1]) == str(id)):
1155 #Les print_method, print_option sont definis par le client (js)
1156 #Les animations acceptent que les connexions anonymous
1157 # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
1158 args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
1161 #Creation d'un objet event
1165 "print_options": event.print_options,
1166 "print_method": event.print_method,
1167 "message": event.data
1172 json_answer = json.dumps(cmd)
1173 return HttpResponse (json_answer, mimetype="application/json")
1175 def pres_view_static(request, constraints, id):
1176 #constraints = "']date_created':1262325600"
1179 # method = 'GetSites'#request.getvalue('method') #ex : GetSites
1180 # constraints = {}#request.getvalue('constraints') // nul = {}
1181 # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
1183 config_file = open(STATIC, "r")
1184 for ligne in config_file:
1185 if not ligne.startswith('#'):
1186 ligne = ligne.split('\n')
1187 first = ligne[0].split(';')
1188 if (str(first[1]) == str(id)):
1192 #Les print_method, print_option sont definis par le client (js)
1193 #Les animations acceptent que les connexions anonymous
1194 # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
1195 args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
1198 #Creation d'un objet event
1202 "print_options": event.print_options,
1203 "print_method": event.print_method,
1204 "message": event.data
1209 json_answer = json.dumps(cmd)
1210 return HttpResponse (json_answer, mimetype="application/json")
1212 class ValidatePendingView(TemplateView):
1213 template_name = "validate_pending.html"
1215 def get_context_data(self, **kwargs):
1216 # We might have slices on different registries with different user accounts
1217 # We note that this portal could be specific to a given registry, to which we register users, but i'm not sure that simplifies things
1218 # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
1220 #messages.info(self.request, 'You have logged in')
1221 page = Page(self.request)
1223 ctx_my_authorities = {}
1224 ctx_delegation_authorities = {}
1227 # The user need to be logged in
1228 if the_user(self.request):
1229 # Who can a PI validate:
1230 # His own authorities + those he has credentials for.
1231 # In MySlice we need to look at credentials also.
1234 # XXX This will have to be asynchroneous. Need to implement barriers,
1235 # for now it will be sufficient to have it working statically
1237 # get user_id to later on query accounts
1238 # XXX Having real query plan on local tables would simplify all this
1239 # XXX $user_email is still not available for local tables
1240 #user_query = Query().get('local:user').filter_by('email', '==', '$user_email').select('user_id')
1241 user_query = Query().get('local:user').filter_by('email', '==', the_user(self.request)).select('user_id')
1242 user, = execute_query(self.request, user_query)
1243 user_id = user['user_id']
1245 # Query manifold to learn about available SFA platforms for more information
1246 # In general we will at least have the portal
1247 # For now we are considering all registries
1248 all_authorities = []
1250 sfa_platforms_query = Query().get('local:platform').filter_by('gateway_type', '==', 'sfa').select('platform_id', 'platform', 'auth_type')
1251 sfa_platforms = execute_query(self.request, sfa_platforms_query)
1252 for sfa_platform in sfa_platforms:
1253 print "SFA PLATFORM > ", sfa_platform['platform']
1254 if not 'auth_type' in sfa_platform:
1256 auth = sfa_platform['auth_type']
1257 if not auth in all_authorities:
1258 all_authorities.append(auth)
1259 platform_ids.append(sfa_platform['platform_id'])
1261 # We can check on which the user has authoritity credentials = PI rights
1262 credential_authorities = set()
1263 credential_authorities_expired = set()
1265 # User account on these registries
1266 user_accounts_query = Query.get('local:account').filter_by('user_id', '==', user_id).filter_by('platform_id', 'included', platform_ids).select('config')
1267 user_accounts = execute_query(self.request, user_accounts_query)
1269 #print user_accounts
1271 for user_account in user_accounts:
1272 config = json.loads(user_account['config'])
1274 if 'authority_credentials' in config:
1275 for authority_hrn, credential in config['authority_credentials'].items():
1276 #if credential is not expired:
1277 credential_authorities.add(authority_hrn)
1279 # credential_authorities_expired.add(authority_hrn)
1280 if 'delegated_authority_credentials' in config:
1281 for authority_hrn, credential in config['delegated_authority_credentials'].items():
1282 #if credential is not expired:
1283 credential_authorities.add(authority_hrn)
1285 # credential_authorities_expired.add(authority_hrn)
1287 print 'credential_authorities =', credential_authorities
1288 print 'credential_authorities_expired =', credential_authorities_expired
1290 # ** Where am I a PI **
1291 # For this we need to ask SFA (of all authorities) = PI function
1292 pi_authorities_query = Query.get('user').filter_by('user_hrn', '==', '$user_hrn').select('pi_authorities')
1293 pi_authorities_tmp = execute_query(self.request, pi_authorities_query)
1294 pi_authorities = set()
1295 for pa in pi_authorities_tmp:
1296 pi_authorities |= set(pa['pi_authorities'])
1298 print "pi_authorities =", pi_authorities
1300 # My authorities + I have a credential
1301 pi_credential_authorities = pi_authorities & credential_authorities
1302 pi_no_credential_authorities = pi_authorities - credential_authorities - credential_authorities_expired
1303 pi_expired_credential_authorities = pi_authorities & credential_authorities_expired
1304 # Authorities I've been delegated PI rights
1305 pi_delegation_credential_authorities = credential_authorities - pi_authorities
1306 pi_delegation_expired_authorities = credential_authorities_expired - pi_authorities
1308 print "pi_credential_authorities =", pi_credential_authorities
1309 print "pi_no_credential_authorities =", pi_no_credential_authorities
1310 print "pi_expired_credential_authorities =", pi_expired_credential_authorities
1311 print "pi_delegation_credential_authorities = ", pi_delegation_credential_authorities
1312 print "pi_delegation_expired_authorities = ", pi_delegation_expired_authorities
1314 # Summary intermediary
1315 pi_my_authorities = pi_credential_authorities | pi_no_credential_authorities | pi_expired_credential_authorities
1316 pi_delegation_authorities = pi_delegation_credential_authorities | pi_delegation_expired_authorities
1319 print "pi_my_authorities = ", pi_my_authorities
1320 print "pi_delegation_authorities = ", pi_delegation_authorities
1323 queried_pending_authorities = pi_my_authorities | pi_delegation_authorities
1325 print "queried_pending_authorities = ", queried_pending_authorities
1327 requests = get_request_by_authority(queried_pending_authorities)
1328 for request in requests:
1329 auth_hrn = request['authority_hrn']
1331 if auth_hrn in pi_my_authorities:
1332 dest = ctx_my_authorities
1334 # define the css class
1335 if auth_hrn in pi_credential_authorities:
1336 request['allowed'] = 'allowed'
1337 elif auth_hrn in pi_expired_credential_authorities:
1338 request['allowed'] = 'expired'
1339 else: # pi_no_credential_authorities
1340 request['allowed'] = 'denied'
1342 elif auth_hrn in pi_delegation_authorities:
1343 dest = ctx_delegation_authorities
1345 if auth_hrn in pi_delegation_credential_authorities:
1346 request['allowed'] = 'allowed'
1347 else: # pi_delegation_expired_authorities
1348 request['allowed'] = 'expired'
1353 if not auth_hrn in dest:
1355 dest[auth_hrn].append(request)
1357 context = super(ValidatePendingView, self).get_context_data(**kwargs)
1358 context['my_authorities'] = ctx_my_authorities
1359 context['delegation_authorities'] = ctx_delegation_authorities
1361 # XXX This is repeated in all pages
1362 # more general variables expected in the template
1363 context['title'] = 'Test view that combines various plugins'
1364 # the menu items on the top
1365 context['topmenu_items'] = topmenu_items('Dashboard', self.request)
1366 # so we can sho who is logged
1367 context['username'] = the_user(self.request)
1369 # XXX We need to prepare the page for queries
1370 #context.update(page.prelude_env())