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.utils.decorators import method_decorator
31 from django.contrib.auth.decorators import login_required
33 from plugins.lists.simplelist import SimpleList
34 from plugins.hazelnut import Hazelnut
35 from plugins.pres_view import PresView
36 from portal.event import Event
39 from portal import signals
40 from portal.forms import SliceRequestForm, ContactForm
41 from portal.util import RegistrationView, ActivationView
42 from portal.models import PendingUser, PendingSlice
43 from manifold.core.query import Query
44 from manifold.manifoldapi import execute_query
45 from unfold.page import Page
46 from myslice.viewutils import topmenu_items, the_user
47 from django.http import HttpResponseRedirect, HttpResponse
49 from M2Crypto import Rand, RSA, BIO
52 class DashboardView(TemplateView):
53 template_name = "dashboard.html"
55 #This view requires login
56 @method_decorator(login_required)
57 def dispatch(self, *args, **kwargs):
58 return super(DashboardView, self).dispatch(*args, **kwargs)
60 def get_context_data(self, **kwargs):
61 # We might have slices on different registries with different user accounts
62 # We note that this portal could be specific to a given registry, to which we register users, but i'm not sure that simplifies things
63 # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
65 #messages.info(self.request, 'You have logged in')
66 page = Page(self.request)
69 #slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
70 slice_query = Query().get('user').filter_by('user_hrn', '==', '$user_hrn').select('user_hrn', 'slice.slice_hrn')
71 auth_query = Query().get('network').select('network_hrn')
72 print "AUTH QUERY =====================", auth_query
73 print "filter", auth_query.filters
74 page.enqueue_query(slice_query)
75 page.enqueue_query(auth_query)
77 page.expose_js_metadata()
80 slicelist = SimpleList(
83 key = 'slice.slice_hrn',
87 authlist = SimpleList(
94 context = super(DashboardView, self).get_context_data(**kwargs)
95 context['person'] = self.request.user
96 context['networks'] = authlist.render(self.request)
97 context['slices'] = slicelist.render(self.request)
99 # XXX This is repeated in all pages
100 # more general variables expected in the template
101 context['title'] = 'Test view that combines various plugins'
102 # the menu items on the top
103 context['topmenu_items'] = topmenu_items('Dashboard', self.request)
104 # so we can sho who is logged
105 context['username'] = the_user(self.request)
107 context.update(page.prelude_env())
111 # DEPRECATED #class UserRegisterView(RegistrationView):
113 # DEPRECATED # A registration backend which follows a simple workflow:
115 # DEPRECATED # 1. User signs up, inactive account is created.
117 # DEPRECATED # 2. Email is sent to user with activation link.
119 # DEPRECATED # 3. User clicks activation link, account is now active.
121 # DEPRECATED # Using this backend requires that
123 # DEPRECATED # * ``registration`` be listed in the ``INSTALLED_APPS`` setting
124 # DEPRECATED # (since this backend makes use of models defined in this
125 # DEPRECATED # application).
127 # DEPRECATED # * The setting ``ACCOUNT_ACTIVATION_DAYS`` be supplied, specifying
128 # DEPRECATED # (as an integer) the number of days from registration during
129 # DEPRECATED # which a user may activate their account (after that period
130 # DEPRECATED # expires, activation will be disallowed).
132 # DEPRECATED # * The creation of the templates
133 # DEPRECATED # ``registration/activation_email_subject.txt`` and
134 # DEPRECATED # ``registration/activation_email.txt``, which will be used for
135 # DEPRECATED # the activation email. See the notes for this backends
136 # DEPRECATED # ``register`` method for details regarding these templates.
138 # DEPRECATED # Additionally, registration can be temporarily closed by adding the
139 # DEPRECATED # setting ``REGISTRATION_OPEN`` and setting it to
140 # DEPRECATED # ``False``. Omitting this setting, or setting it to ``True``, will
141 # DEPRECATED # be interpreted as meaning that registration is currently open and
142 # DEPRECATED # permitt ed.
144 # DEPRECATED # Internally, this is accomplished via storing an activation key in
145 # DEPRECATED # an instance of ``registration.models.RegistrationProfile``. See
146 # DEPRECATED # that model and its custom manager for full documentation of its
147 # DEPRECATED # fields and supported operations.
150 # DEPRECATED ## DEPRECATED # form_class = UserRegisterForm
152 # DEPRECATED # def register(self, request, **cleaned_data):
154 # DEPRECATED # Given a username, email address and password, register a new
155 # DEPRECATED # user account, which will initially be inactive.
157 # DEPRECATED # Along with the new ``User`` object, a new
158 # DEPRECATED # ``registration.models.RegistrationProfile`` will be created,
159 # DEPRECATED # tied to that ``User``, containing the activation key which
160 # DEPRECATED # will be used for this account.
162 # DEPRECATED # An email will be sent to the supplied email address; this
163 # DEPRECATED # email should contain an activation link. The email will be
164 # DEPRECATED # rendered using two templates. See the documentation for
165 # DEPRECATED # ``RegistrationProfile.send_activation_email()`` for
166 # DEPRECATED # information about these templates and the contexts provided to
169 # DEPRECATED # After the ``User`` and ``RegistrationProfile`` are created and
170 # DEPRECATED # the activation email is sent, the signal
171 # DEPRECATED # ``registration.signals.user_registered`` will be sent, with
172 # DEPRECATED # the new ``User`` as the keyword argument ``user`` and the
173 # DEPRECATED # class of this backend as the sender.
176 # DEPRECATED # first_name = cleaned_data['first_name']
177 # DEPRECATED # last_name = cleaned_data['last_name']
178 # DEPRECATED # affiliation= cleaned_data['affiliation']
179 # DEPRECATED # email = cleaned_data['email']
180 # DEPRECATED # password = cleaned_data['password1']
182 # DEPRECATED # #password2 = cleaned_data['password2']
183 # DEPRECATED # keypair = cleaned_data['keypair']
185 # DEPRECATED # #if Site._meta.installed:
186 # DEPRECATED # # site = Site.objects.get_current()
187 # DEPRECATED # #else:
188 # DEPRECATED # # site = RequestSite(request)
189 # DEPRECATED # site = None
191 # DEPRECATED # new_user = PendingUser.objects.create_inactive_user(first_name, last_name, email, password, site)
192 # DEPRECATED # signals.user_registered.send(sender=self.__class__,
193 # DEPRECATED # user=new_user,
194 # DEPRECATED # request=request)
195 # DEPRECATED # return new_user
197 # DEPRECATED # def get_context_data(self, **kwargs):
198 # DEPRECATED # context = super(UserRegisterView, self).get_context_data(**kwargs)
199 # DEPRECATED # context['topmenu_items'] = topmenu_items('Register', self.request)
200 # DEPRECATED # context['username'] = the_user (self.request)
201 # DEPRECATED # return context
203 # DEPRECATED # def registration_allowed(self, request):
205 # DEPRECATED # Indicate whether account registration is currently permitted,
206 # DEPRECATED # based on the value of the setting ``REGISTRATION_OPEN``. This
207 # DEPRECATED # is determined as follows:
209 # DEPRECATED # * If ``REGISTRATION_OPEN`` is not specified in settings, or is
210 # DEPRECATED # set to ``True``, registration is permitted.
212 # DEPRECATED # * If ``REGISTRATION_OPEN`` is both specified and set to
213 # DEPRECATED # ``False``, registration is not permitted.
216 # DEPRECATED # return getattr(settings, 'REGISTRATION_OPEN', True)
218 # DEPRECATED # def get_success_url(self, request, user):
220 # DEPRECATED # Return the name of the URL to redirect to after successful
221 # DEPRECATED # user registration.
224 # DEPRECATED # return ('user_register_complete', (), {})
227 # DEPRECATED #class UserValidateView(ActivationView):
228 # DEPRECATED # def activate(self, request, activation_key):
230 # DEPRECATED # Given an an activation key, look up and activate the user
231 # DEPRECATED # account corresponding to that key (if possible).
233 # DEPRECATED # After successful activation, the signal
234 # DEPRECATED # ``registration.signals.user_activated`` will be sent, with the
235 # DEPRECATED # newly activated ``User`` as the keyword argument ``user`` and
236 # DEPRECATED # the class of this backend as the sender.
239 # DEPRECATED # activated_user = RegistrationProfile.objects.activate_user(activation_key)
240 # DEPRECATED # if activated_user:
241 # DEPRECATED # signals.user_activated.send(sender=self.__class__,
242 # DEPRECATED # user=activated_user,
243 # DEPRECATED # request=request)
244 # DEPRECATED # return activated_user
246 # DEPRECATED # def get_success_url(self, request, user):
247 # DEPRECATED # return ('registration_activation_complete', (), {})
250 # DEPRECATED #from portal.portalpage import PortalPage
251 # DEPRECATED #from plugins.wizard import Wizard
252 # DEPRECATED #from plugins.form import CreateForm
253 # DEPRECATED #from plugins.raw.raw import Raw # XXX
255 # DEPRECATED #from myslice.viewutils import the_user
257 # DEPRECATED #from django.template.loader import render_to_string
258 # DEPRECATED #from django.template import RequestContext
259 # DEPRECATED #from django.views import generic
261 # DEPRECATED #from django.contrib.formtools.wizard.views import NamedUrlSessionWizardView
262 # DEPRECATED ##from django.core.files.storage import FileSystemStorage
263 # DEPRECATED #from django.core.files.storage import default_storage
265 # DEPRECATED ##class MerlinWizard(NamedUrlSessionWizardView):
270 # DEPRECATED ## @classonlymethod
271 # DEPRECATED ## def as_view(cls, *args, **kwargs):
272 # DEPRECATED ## kwargs.update({
273 # DEPRECATED ## 'form_list': [
274 # DEPRECATED ## NameForm,
275 # DEPRECATED ## QuestForm,
276 # DEPRECATED ## ColorForm,
278 # DEPRECATED ## 'url_name': 'merlin_wizard'
280 # DEPRECATED ## return super(MerlinWizard, cls).as_view(*args, **kwargs)
282 # DEPRECATED #class UserRegisterWizardView(NamedUrlSessionWizardView):
283 # DEPRECATED ##class UserRegisterWizardView(LoginRequiredMixin, NamedUrlSessionWizardView):
284 # DEPRECATED # # Notice that I specify a file storage instance. If you don't specify this,
285 # DEPRECATED # # and you need to support FileField or ImageField in your forms, you'll get
286 # DEPRECATED # # errors from Django. This is something else I think could be handled by
287 # DEPRECATED # # the views better. Seems to me that it should just use whatever the
288 # DEPRECATED # # default/specified storage is for the rest of your project/application.
289 # DEPRECATED # file_storage = default_storage # FileSystemStorage()
290 # DEPRECATED # template_name = "register_user_wizard.html"
292 # DEPRECATED # def done(self, form_list, **kwargs):
293 # DEPRECATED # step1_form = form_list[0]
294 # DEPRECATED # step2_form = form_list[1]
296 # DEPRECATED # productext = self.create_product(product_form)
297 # DEPRECATED # shippings = self.create_shippings(productext, shipping_forms)
298 # DEPRECATED # images = self.create_images(productext, image_forms)
300 # DEPRECATED # if all([productext, shippings, images]):
301 # DEPRECATED # del self.request.session["wizard_product_wizard_view"]
303 # DEPRECATED # messages.success(self.request,
304 # DEPRECATED # _("Your product has been created."))
305 # DEPRECATED # return HttpResponseRedirect(self.get_success_url(productext))
307 # DEPRECATED # messages.error(self.request, _("Something went wrong creating your "
308 # DEPRECATED # "product. Please try again or contact support."))
309 # DEPRECATED # return HttpResponseRedirect(reverse("register_wizard"))
311 # DEPRECATED # #def get_form_kwargs(self, step):
312 # DEPRECATED # # if step == "product":
313 # DEPRECATED # # return {"user": self.request.user}
314 # DEPRECATED # # return {}
316 # DEPRECATED ## The portal should hook the slice and user creation pages
318 # DEPRECATED #def register_user(request):
320 # DEPRECATED # if request.method == 'POST':
321 # DEPRECATED # form = UserRegisterForm(request.POST) # Nous reprenons les données
322 # DEPRECATED # if form.is_valid():
323 # DEPRECATED # first_name = form.cleaned_data['first_name']
324 # DEPRECATED # last_name = form.cleaned_data['last_name']
325 # DEPRECATED # email = form.cleaned_data['email']
326 # DEPRECATED # password = form.cleaned_data['password']
327 # DEPRECATED # password2 = form.cleaned_data['password2']
328 # DEPRECATED # keypair = form.cleaned_data['keypair']
329 # DEPRECATED # ## Ici nous pouvons traiter les données du formulaire
330 # DEPRECATED # #sujet = form.cleaned_data['sujet']
331 # DEPRECATED # #message = form.cleaned_data['message']
332 # DEPRECATED # #envoyeur = form.cleaned_data['envoyeur']
333 # DEPRECATED # #renvoi = form.cleaned_data['renvoi']
334 # DEPRECATED # ## Nous pourrions ici envoyer l'e-mail grâce aux données que nous venons de récupérer
335 # DEPRECATED # #envoi = True
337 # DEPRECATED # form = UserRegisterForm()
338 # DEPRECATED # return render(request, 'register_user.html', locals())
340 # DEPRECATED #def index(request):
342 # DEPRECATED # WIZARD_TITLE = 'User registration'
343 # DEPRECATED # STEP1_TITLE = 'Enter your details'
344 # DEPRECATED # STEP2_TITLE = 'Select your institution'
345 # DEPRECATED # STEP3_TITLE = 'Authentication'
346 # DEPRECATED # STEP4_TITLE = 'Request a slice (optional)'
347 # DEPRECATED # STEP5_TITLE = 'Waiting for validation'
348 # DEPRECATED # STEP6_TITLE = 'Account validated'
350 # DEPRECATED # STEP0 = render_to_string('account_validated.html', context_instance=RequestContext(request))
351 # DEPRECATED # STEP2_HTML = """
352 # DEPRECATED # coucou
354 # DEPRECATED # STEP4 = """
357 # DEPRECATED # STEP5 = render_to_string('account_validated.html', context_instance=RequestContext(request))
359 # DEPRECATED # p = PortalPage(request)
361 # DEPRECATED # # This is redundant with the Wizard title
362 # DEPRECATED # p << "<h3>User registration</h3>"
364 # DEPRECATED # sons = []
365 # DEPRECATED # start_step = 1
367 # DEPRECATED # # STEP 1
368 # DEPRECATED # # If the user already exists (is logged), let's display a summary of his account details
369 # DEPRECATED # # Otherwise propose a form to fill in
370 # DEPRECATED # if the_user(request):
371 # DEPRECATED # # Fill a disabled form with user info
372 # DEPRECATED # # Please logout to register another user
373 # DEPRECATED # sons.append(Raw(page=p, title=STEP1_TITLE, togglable=False, html=STEP0))
374 # DEPRECATED # start_step += 1
376 # DEPRECATED # # We could pass a list of fields also, instead of retrieving them from metadata
377 # DEPRECATED # # Otherwise we need some heuristics to display nice forms
378 # DEPRECATED # # XXX Could we log the user in after the form is validated ?
379 # DEPRECATED # # XXX Explain the password is for XXX
380 # DEPRECATED # field_list = [{
381 # DEPRECATED # 'name' : 'First name',
382 # DEPRECATED # 'field' : 'firstname',
383 # DEPRECATED # 'type' : 'text',
384 # DEPRECATED # 'validate_rx' : '^[a-zA-Z -]+$',
385 # DEPRECATED # 'validate_err': 'Your first name must be comprised of letters only',
386 # DEPRECATED # 'description' : 'Enter your first name',
388 # DEPRECATED # 'name' : 'Last name',
389 # DEPRECATED # 'field' : 'lastname',
390 # DEPRECATED # 'type' : 'text',
391 # DEPRECATED # 'validate_rx' : '^[a-zA-Z -]+$',
392 # DEPRECATED # 'validate_err': 'Your last name must be comprised of letters only',
393 # DEPRECATED # 'description' : 'Enter your last name',
395 # DEPRECATED # 'name' : 'Email',
396 # DEPRECATED # 'field' : 'email',
397 # DEPRECATED # 'type' : 'text',
398 # DEPRECATED # 'description' : 'Enter your email address',
400 # DEPRECATED # 'name' : 'Password',
401 # DEPRECATED # 'field' : 'password',
402 # DEPRECATED # 'type' : 'password',
403 # DEPRECATED # 'description' : 'Enter your password',
405 # DEPRECATED # 'name' : 'Confirm password',
406 # DEPRECATED # 'field' : 'password2',
407 # DEPRECATED # 'type' : 'password',
408 # DEPRECATED # 'description' : 'Enter your password again',
410 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP1_TITLE, togglable = False, object = 'local:user', fields = field_list))
412 # DEPRECATED # # STEP 2
413 # DEPRECATED # # If the user already exists (is logged), let's display a summary of its institution
414 # DEPRECATED # # Otherwise propose a form to fill in (we should base our selection on the email)
415 # DEPRECATED # if the_user(request):
416 # DEPRECATED # # Fill a disabled form with institution
417 # DEPRECATED # # Please logout to register another user
418 # DEPRECATED # sons.append(Raw(page=p, title=STEP2_TITLE, togglable=False, html="User created"))
419 # DEPRECATED # start_step += 1
421 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP2_TITLE, togglable = False, object = 'slice')) #institution'))
423 # DEPRECATED # # STEP3
424 # DEPRECATED # # Please should your prefered authentication method
425 # DEPRECATED # # This step should allow the user to either choose the user or managed mode in MySlice
426 # DEPRECATED # sons.append(Raw(page = p, title = STEP3_TITLE, togglable = False, html = STEP2_HTML))
428 # DEPRECATED # # Step 4: Request a slice (optional)
429 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP4_TITLE, togglable = False, object = 'slice'))
431 # DEPRECATED # # Step 5: Your request is waiting for validation
432 # DEPRECATED # # Periodic refresh
433 # DEPRECATED # sons.append(Raw(page = p, title = STEP5_TITLE, togglable = False, html = STEP4))
435 # DEPRECATED # # Step 6: Account validation = welcome for newly validated users
436 # DEPRECATED # # . delegation
437 # DEPRECATED # # . platforms
438 # DEPRECATED # # . slice
439 # DEPRECATED # # . pointers
440 # DEPRECATED # sons.append(Raw(page = p, title = STEP6_TITLE, togglable = False, html = STEP5))
442 # DEPRECATED # wizard = Wizard(
443 # DEPRECATED # page = p,
444 # DEPRECATED # title = WIZARD_TITLE,
445 # DEPRECATED # togglable = False,
446 # DEPRECATED # sons = sons,
447 # DEPRECATED # start_step = start_step,
450 # DEPRECATED # p << wizard.render(request) # in portal page if possible
452 # DEPRECATED # return p.render()
455 # DEPRECATED ## view for my_account
456 # DEPRECATED # class MyAccountView(TemplateView):
457 # DEPRECATED # template_name = "my_account.html"
459 # DEPRECATED # def from_process(self, request, **cleaned_data):
460 # DEPRECATED # #if request.method == 'POST':
461 # DEPRECATED # # if request.POST['submit_name']:
462 # DEPRECATED # if 'fname' in request.POST:
463 # DEPRECATED # messsag= "Got Name"
464 # DEPRECATED # #return render(request, 'portal/my_account.html')
465 # DEPRECATED # #response = HttpResponse("Here's the text of the Web page.")
466 # DEPRECATED # return HttpResponse(message)
468 # DEPRECATED # def get_context_data(self, **kwargs):
469 # DEPRECATED # page = Page(self.request)
470 # DEPRECATED # context = super(MyAccountView, self).get_context_data(**kwargs)
471 # DEPRECATED # context['person'] = self.request.user
472 # DEPRECATED # # XXX This is repeated in all pages
473 # DEPRECATED # # more general variables expected in the template
474 # DEPRECATED # context['title'] = 'User Profile Page'
475 # DEPRECATED # # the menu items on the top
476 # DEPRECATED # context['topmenu_items'] = topmenu_items('my_account', self.request)
477 # DEPRECATED # # so we can sho who is logged
478 # DEPRECATED # context['username'] = the_user(self.request)
479 # DEPRECATED # context.update(page.prelude_env())
480 # DEPRECATED # return context
483 class PlatformsView(TemplateView):
484 template_name = "platforms.html"
486 def get_context_data(self, **kwargs):
487 page = Page(self.request)
489 #network_query = Query().get('local:platform').filter_by('disabled', '==', '0').select('platform','platform_longname','gateway_type')
490 network_query = Query().get('local:platform').select('platform','platform_longname','gateway_type')
491 page.enqueue_query(network_query)
493 page.expose_js_metadata()
494 page.expose_queries()
495 networklist = Hazelnut(
498 domid = 'checkboxes',
499 # this is the query at the core of the slice list
500 query = network_query,
501 query_all = network_query,
503 datatables_options = {
504 # for now we turn off sorting on the checkboxes columns this way
505 # this of course should be automatic in hazelnut
506 'aoColumns' : [None, None, None, None, {'bSortable': False}],
507 'iDisplayLength' : 25,
508 'bLengthChange' : True,
512 # networklist = SimpleList(
516 # query = network_query,
519 context = super(PlatformsView, self).get_context_data(**kwargs)
520 context['person'] = self.request.user
521 context['networks'] = networklist.render(self.request)
523 # XXX This is repeated in all pages
524 # more general variables expected in the template
525 context['title'] = 'Platforms connected to MySlice'
526 # the menu items on the top
527 context['topmenu_items'] = topmenu_items('Platforms', self.request)
528 # so we can sho who is logged
529 context['username'] = the_user(self.request)
531 context.update(page.prelude_env())
537 # View for 1 platform and its details
538 class PlatformView(TemplateView):
539 template_name = "platform.html"
541 def get_context_data(self, **kwargs):
542 page = Page(self.request)
544 for key, value in kwargs.iteritems():
545 print "%s = %s" % (key, value)
546 if key == "platformname":
549 network_query = Query().get('local:platform').filter_by('platform', '==', platformname).select('platform','platform_longname','gateway_type')
550 page.enqueue_query(network_query)
552 page.expose_js_metadata()
553 page.expose_queries()
554 networklist = Hazelnut(
557 domid = 'checkboxes',
558 # this is the query at the core of the slice list
559 query = network_query,
560 query_all = network_query,
562 datatables_options = {
563 # for now we turn off sorting on the checkboxes columns this way
564 # this of course should be automatic in hazelnut
565 'aoColumns' : [None, None, None, None, {'bSortable': False}],
566 'iDisplayLength' : 25,
567 'bLengthChange' : True,
571 # networklist = SimpleList(
575 # query = network_query,
578 context = super(PlatformView, self).get_context_data(**kwargs)
579 context['person'] = self.request.user
580 context['networks'] = networklist.render(self.request)
582 # XXX This is repeated in all pages
583 # more general variables expected in the template
584 context['title'] = 'Platforms connected to MySlice'
585 # the menu items on the top
586 context['topmenu_items'] = topmenu_items('Platforms', self.request)
587 # so we can sho who is logged
588 context['username'] = the_user(self.request)
590 context.update(page.prelude_env())
596 #class for my_account
597 class AccountView(TemplateView):
598 template_name = "my_account.html"
600 #This view requires login
601 @method_decorator(login_required)
602 def dispatch(self, *args, **kwargs):
603 return super(AccountView, self).dispatch(*args, **kwargs)
606 def get_context_data(self, **kwargs):
607 page = Page(self.request)
609 #network_query = Query().get('local:platform').filter_by('disabled', '==', '0').select('platform','platform_longname','gateway_type')
610 network_query = Query().get('local:user').select('user_id','email','config')
611 page.enqueue_query(network_query)
613 page.expose_js_metadata()
614 page.expose_queries()
616 userlist = SimpleList(
620 query = network_query,
623 context = super(AccountView, self).get_context_data(**kwargs)
624 context['person'] = self.request.user
625 context['users'] = userlist.render(self.request)
627 # XXX This is repeated in all pages
628 # more general variables expected in the template
629 context['title'] = 'Platforms connected to MySlice'
630 # the menu items on the top
631 context['topmenu_items'] = topmenu_items('My Account', self.request)
632 # so we can sho who is logged
633 context['username'] = the_user(self.request)
635 context.update(page.prelude_env())
644 # View for my_account form
645 #def my_account(request):
646 # return render(request, 'my_account.html', {
648 # 'topmenu_items': topmenu_items('My Account', request),
649 # 'username': the_user (request)
654 #my_acc form value processing
655 def acc_process(request):
656 # getting the user_id from the session [now hardcoded]
657 get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
658 # getting user info from manifold
659 if 'submit_name' in request.POST:
660 edited_first_name = request.POST['fname']
661 edited_last_name = request.POST['lname']
662 #email = 'test_email@gmail.com'
663 #password = 'test_pp'
664 #message = 'F_Name: %s L_name: %s dummy_pp: %s' % (first_name, last_name, password)
667 # insert into DB [needed for registration page]
668 #approach borrowed from register view
669 #new_user = PendingUser.objects.create_inactive_user(edited_first_name, edited_last_name, email, password, site)
670 #conventional approach
671 #b = PendingUser(first_name=edited_first_name, last_name=edited_last_name)
674 # select and update [will be used throughout this view]
675 # select the logged in user [for the moment hard coded]
676 #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
677 # update first and last name
678 get_user.first_name = edited_first_name
679 get_user.last_name = edited_last_name
682 return HttpResponse('Sucess: First Name and Last Name Updated!')
683 elif 'submit_pass' in request.POST:
684 edited_password = request.POST['password']
685 # select the logged in user [for the moment hard coded]
686 #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
688 get_user.password = edited_password
690 return HttpResponse('Success: Password Changed!!')
691 elif 'generate' in request.POST:
692 # Generate public and private keys using SFA Library
693 from sfa.trust.certificate import Keypair
694 k = Keypair(create=True)
695 public_key = k.get_pubkey_string()
696 private_key = k.as_pem()
701 # def blank_callback():
702 # "Replace the default dashes"
706 # Rand.rand_seed (os.urandom (KEY_LENGTH))
707 # # Generate key pair
708 # key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
709 # # Create memory buffers
710 # pri_mem = BIO.MemoryBuffer()
711 # pub_mem = BIO.MemoryBuffer()
712 # # Save keys to buffers
713 # key.save_key_bio(pri_mem, None)
714 # key.save_pub_key_bio(pub_mem)
717 # public_key = pub_mem.getvalue()
718 # private_key = pri_mem.getvalue()
719 private_key = ''.join(private_key.split())
720 public_key = "ssh-rsa " + public_key
722 keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
723 # keypair = re.sub("\r", "", keypair)
724 # keypair = re.sub("\n", "\\n", keypair)
725 # #keypair = keypair.rstrip('\r\n')
726 # keypair = ''.join(keypair.split())
727 get_user.keypair = keypair
729 return HttpResponse('Success: New Keypair Generated! %s' % keypair)
731 elif 'upload_key' in request.POST:
732 up_file = request.FILES['pubkey']
733 file_content = up_file.read()
734 file_name = up_file.name
735 file_extension = os.path.splitext(file_name)[1]
736 allowed_extension = ['.pub','.txt']
737 if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
738 file_content = '{"user_public_key":"'+ file_content +'"}'
739 file_content = re.sub("\r", "", file_content)
740 file_content = re.sub("\n", "\\n",file_content)
741 file_content = ''.join(file_content.split())
742 get_user.keypair = file_content
744 return HttpResponse('Success: Publickey uploaded! Old records overwritten')
746 return HttpResponse('Please upload a valid RSA public key [.txt or .pub].')
749 message = 'You submitted an empty form.'
750 return HttpResponse(message)
752 def register_4m_f4f(request):
755 authorities_query = Query.get('authority').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc']).select('name', 'authority_hrn')
756 #authorities_query = Query.get('authority').select('authority_hrn')
757 authorities = execute_query(request, authorities_query)
759 if request.method == 'POST':
760 #get_email = PendingUser.objects.get(email)
761 reg_fname = request.POST.get('firstname', '')
762 reg_lname = request.POST.get('lastname', '')
763 reg_aff = request.POST.get('affiliation','')
764 reg_auth = request.POST.get('authority_hrn', '')
765 reg_email = request.POST.get('email','').lower()
767 #POST value validation
768 if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
769 errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
770 #return HttpResponse("Only Letters, Numbers, - and _ allowd in First Name")
771 #return render(request, 'register_4m_f4f.html')
772 if (re.search(r'^[\w+\s.@+-]+$', reg_lname) == None):
773 errors.append('Last Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
774 #return HttpResponse("Only Letters, Numbers, - and _ is allowed in Last name")
775 #return render(request, 'register_4m_f4f.html')
776 if (re.search(r'^[\w+\s.@+-]+$', reg_aff) == None):
777 errors.append('Affiliation may contain only letters, numbers, spaces and @/./+/-/_ characters.')
778 #return HttpResponse("Only Letters, Numbers and _ is allowed in Affiliation")
779 #return render(request, 'register_4m_f4f.html')
780 # XXX validate authority hrn !!
781 if PendingUser.objects.filter(email__iexact=reg_email):
782 errors.append('Email already registered.Please provide a new email address.')
783 #return HttpResponse("Email Already exists")
784 #return render(request, 'register_4m_f4f.html')
785 if 'generate' in request.POST['question']:
786 # Generate public and private keys using SFA Library
787 from sfa.trust.certificate import Keypair
788 k = Keypair(create=True)
789 public_key = k.get_pubkey_string()
790 private_key = k.as_pem()
794 # #from M2Crypto import Rand, RSA, BIO
798 # def blank_callback():
799 # "Replace the default dashes"
803 # Rand.rand_seed (os.urandom (KEY_LENGTH))
804 # # Generate key pair
805 # key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
806 # # Create memory buffers
807 # pri_mem = BIO.MemoryBuffer()
808 # pub_mem = BIO.MemoryBuffer()
809 # # Save keys to buffers
810 # key.save_key_bio(pri_mem, None)
811 # key.save_pub_key_bio(pub_mem)
813 # public_key = pub_mem.getvalue()
814 # private_key = pri_mem.getvalue()
816 private_key = ''.join(private_key.split())
817 public_key = "ssh-rsa " + public_key
819 keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
820 # keypair = re.sub("\r", "", keypair)
821 # keypair = re.sub("\n", "\\n", keypair)
822 # #keypair = keypair.rstrip('\r\n')
823 # keypair = ''.join(keypair.split())
825 up_file = request.FILES['user_public_key']
826 file_content = up_file.read()
827 file_name = up_file.name
828 file_extension = os.path.splitext(file_name)[1]
829 allowed_extension = ['.pub','.txt']
830 if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
831 keypair = '{"user_public_key":"'+ file_content +'"}'
832 keypair = re.sub("\r", "", keypair)
833 keypair = re.sub("\n", "\\n",keypair)
834 keypair = ''.join(keypair.split())
836 errors.append('Please upload a valid RSA public key [.txt or .pub].')
838 #b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff,
839 # email=reg_email, password=request.POST['password'], keypair=keypair)
842 b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff,
843 authority_hrn=reg_auth,
844 email=reg_email, password=request.POST['password'], keypair=keypair)
846 return render(request, 'user_register_complete.html')
848 return render(request, 'register_4m_f4f.html',{
849 'topmenu_items': topmenu_items('Register', request),
851 'firstname': request.POST.get('firstname', ''),
852 'lastname': request.POST.get('lastname', ''),
853 'affiliation': request.POST.get('affiliation', ''),
854 'authority_hrn': request.POST.get('authority_hrn', ''),
855 'email': request.POST.get('email', ''),
856 'password': request.POST.get('password', ''),
857 'authorities': authorities
861 # view for contact form
862 def contact(request):
863 if request.method == 'POST': # If the form has been submitted...
864 form = ContactForm(request.POST) # A form bound to the POST data
865 if form.is_valid(): # All validation rules pass
866 # Process the data in form.cleaned_data
867 first_name = form.cleaned_data['first_name']
868 last_name = form.cleaned_data['last_name']
869 affiliation = form.cleaned_data['affiliation']
870 subject = form.cleaned_data['subject']
871 message = form.cleaned_data['message']
872 email = form.cleaned_data['email'] # email of the sender
873 cc_myself = form.cleaned_data['cc_myself']
875 recipients = ['yasin.upmc@gmail.com']
877 recipients.append(email)
879 from django.core.mail import send_mail
880 send_mail("Onelab user submitted a query ", [first_name,last_name,affiliation,subject,message], email, recipients)
881 return render(request,'contact_sent.html') # Redirect after POST
883 form = ContactForm() # An unbound form
885 return render(request, 'contact.html', {
887 'topmenu_items': topmenu_items('Contact Us', request),
888 'username': the_user (request)
893 def slice_request(request):
894 if request.method == 'POST': # If the form has been submitted...
895 form = SliceRequestForm(request.POST) # A form bound to the POST data
896 if form.is_valid(): # All validation rules pass
897 # Process the data in form.cleaned_data
898 slice_name = form.cleaned_data['slice_name']
899 number_of_nodes = form.cleaned_data['number_of_nodes']
900 type_of_nodes = form.cleaned_data['type_of_nodes']
901 purpose = form.cleaned_data['purpose']
902 email = form.cleaned_data['email'] # email of the sender
903 cc_myself = form.cleaned_data['cc_myself']
905 recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
907 recipients.append(email)
909 from django.core.mail import send_mail
910 send_mail("Onelab New Slice request form submitted", [slice_name,number_of_nodes,type_of_nodes,purpose], email, recipients)
911 return render(request,'slicereq_recvd.html') # Redirect after POST
913 form = SliceRequestForm() # An unbound form
916 # template_env['form'] = form
917 # template_env['topmenu_items'] = topmenu_items('Request a slice', request)
918 # template_env['unfold1_main'] = render(request, 'slice_request_.html', {
921 # from django.shortcuts import render_to_response
922 # from django.template import RequestContext
923 # return render_to_response ('view-unfold1.html',template_env,
924 # context_instance=RequestContext(request))
926 return render(request, 'slice_request.html', {
928 'topmenu_items': topmenu_items('Request a slice', request),
929 'username': the_user (request)
933 class PresViewView(TemplateView):
934 template_name = "view-unfold1.html"
936 def get_context_data(self, **kwargs):
938 page = Page(self.request)
940 pres_view = PresView(page = page)
942 context = super(PresViewView, self).get_context_data(**kwargs)
944 #context['ALL_STATIC'] = "all_static"
945 context['unfold1_main'] = pres_view.render(self.request)
947 # XXX This is repeated in all pages
948 # more general variables expected in the template
949 context['title'] = 'Test view that combines various plugins'
950 # the menu items on the top
951 context['topmenu_items'] = topmenu_items('PresView', self.request)
952 # so we can sho who is logged
953 context['username'] = the_user(self.request)
955 prelude_env = page.prelude_env()
956 context.update(prelude_env)
960 def json_me(config_file,type):
962 for ligne in config_file:
963 if not ligne.startswith('#'):
964 args = ligne.split(';')
965 json_answer += str('{ "name": "' + args[0] + '" ,"id":"' + args[1] + '" ,"descriptif":"' + args[2]+'"')
967 json_answer += str(',"contraints":')
969 json_answer += str('""')
971 json_answer += str(args[3])
972 json_answer += str('},')
973 return json_answer[:-1]
976 DIR = '/var/myslice/'
977 STATIC = '%s/config_method_static' % DIR
978 DYNAMIC = '%s/config_method_dynamic' % DIR
979 ANIMATION = '%s/config_method_animation' % DIR
981 def pres_view_methods(request, type):
985 elif type =="static":
986 config = open(STATIC, "r")
987 json_answer = str('{ "options": [')
988 json_answer += str(json_me(config,"static"))
989 json_answer += str('] }')
991 elif type =="dynamic":
992 config = open(DYNAMIC, "r")
993 json_answer = str('{ "options": [')
994 json_answer += str(json_me(config,"dynamic"))
995 json_answer += str('] }')
997 elif type =="animation":
998 config = open(ANIMATION, "r")
999 json_answer = str('{ "options": [')
1000 json_answer += str(json_me(config,"animation"))
1001 json_answer += str('] }')
1004 config = open(STATIC, "r")
1005 json_answer = str('{ "static": [')
1006 json_answer += str(json_me(config,"static"))
1007 json_answer += str('],')
1008 json_answer += str('"dynamic": [')
1010 config = open(DYNAMIC, "r")
1011 json_answer += str(json_me(config,"dynamic"))
1012 json_answer += str('],')
1013 json_answer += str('"animation": [')
1015 config = open(ANIMATION, "r")
1016 json_answer += str(json_me(config,"animation"))
1017 json_answer += str('] }')
1021 return HttpResponse (json_answer, mimetype="application/json")
1023 def pres_view_animation(request, constraints, id):
1025 # sites crees depuis 2008
1026 # static.py?contraints=']date_created':1262325600&id='name_id"'
1028 # method = request.getvalue('method') #ex : GetSites
1029 #constraints = "']date_created':1262325600"
1035 # method = 'GetSites'#request.getvalue('method') #ex : GetSites
1036 # constraints = {}#request.getvalue('constraints') // nul = {}
1037 # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
1039 config_file = open(ANIMATION, "r")
1040 for ligne in config_file:
1041 if not ligne.startswith('#'):
1042 ligne = ligne.split('\n')
1043 first = ligne[0].split(';')
1044 if (str(first[1]) == str(id)):
1048 #Les print_method, print_option sont definis par le client (js)
1049 #Les animations acceptent que les connexions anonymous
1050 # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
1051 args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
1054 #Creation d'un objet event
1058 "print_options": event.print_options,
1059 "print_method": event.print_method,
1060 "message": event.data
1065 json_answer = json.dumps(cmd)
1066 return HttpResponse (json_answer, mimetype="application/json")
1068 def pres_view_static(request, constraints, id):
1069 #constraints = "']date_created':1262325600"
1072 # method = 'GetSites'#request.getvalue('method') #ex : GetSites
1073 # constraints = {}#request.getvalue('constraints') // nul = {}
1074 # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
1076 config_file = open(STATIC, "r")
1077 for ligne in config_file:
1078 if not ligne.startswith('#'):
1079 ligne = ligne.split('\n')
1080 first = ligne[0].split(';')
1081 if (str(first[1]) == str(id)):
1085 #Les print_method, print_option sont definis par le client (js)
1086 #Les animations acceptent que les connexions anonymous
1087 # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
1088 args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
1091 #Creation d'un objet event
1095 "print_options": event.print_options,
1096 "print_method": event.print_method,
1097 "message": event.data
1102 json_answer = json.dumps(cmd)
1103 return HttpResponse (json_answer, mimetype="application/json")
1105 class ValidatePendingView(TemplateView):
1106 template_name = "validate_pending.html"
1108 def get_context_data(self, **kwargs):
1109 # We might have slices on different registries with different user accounts
1110 # We note that this portal could be specific to a given registry, to which we register users, but i'm not sure that simplifies things
1111 # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
1113 #messages.info(self.request, 'You have logged in')
1114 page = Page(self.request)
1116 ctx_my_authorities = {}
1117 ctx_delegation_authorities = {}
1120 # The user need to be logged in
1121 if the_user(self.request):
1122 # Who can a PI validate:
1123 # His own authorities + those he has credentials for.
1124 # In MySlice we need to look at credentials also.
1127 # XXX This will have to be asynchroneous. Need to implement barriers,
1128 # for now it will be sufficient to have it working statically
1130 # get user_id to later on query accounts
1131 # XXX Having real query plan on local tables would simplify all this
1132 # XXX $user_email is still not available for local tables
1133 #user_query = Query().get('local:user').filter_by('email', '==', '$user_email').select('user_id')
1134 user_query = Query().get('local:user').filter_by('email', '==', the_user(self.request)).select('user_id')
1135 user, = execute_query(self.request, user_query)
1136 user_id = user['user_id']
1138 # Query manifold to learn about available SFA platforms for more information
1139 # In general we will at least have the portal
1140 # For now we are considering all registries
1141 all_authorities = []
1143 sfa_platforms_query = Query().get('local:platform').filter_by('gateway_type', '==', 'sfa').select('platform_id', 'platform', 'auth_type')
1144 sfa_platforms = execute_query(self.request, sfa_platforms_query)
1145 for sfa_platform in sfa_platforms:
1146 print "SFA PLATFORM > ", sfa_platform['platform']
1147 if not 'auth_type' in sfa_platform:
1149 auth = sfa_platform['auth_type']
1150 if not auth in all_authorities:
1151 all_authorities.append(auth)
1152 platform_ids.append(sfa_platform['platform_id'])
1154 # We can check on which the user has authoritity credentials = PI rights
1155 credential_authorities = set()
1156 credential_authorities_expired = set()
1158 # User account on these registries
1159 user_accounts_query = Query.get('local:account').filter_by('user_id', '==', user_id).filter_by('platform_id', 'included', platform_ids).select('config')
1160 user_accounts = execute_query(self.request, user_accounts_query)
1162 #print user_accounts
1164 for user_account in user_accounts:
1165 config = json.loads(user_account['config'])
1167 if 'authority_credentials' in config:
1168 for authority_hrn, credential in config['authority_credentials'].items():
1169 #if credential is not expired:
1170 credential_authorities.add(authority_hrn)
1172 # credential_authorities_expired.add(authority_hrn)
1173 if 'delegated_authority_credentials' in config:
1174 for authority_hrn, credential in config['delegated_authority_credentials'].items():
1175 #if credential is not expired:
1176 credential_authorities.add(authority_hrn)
1178 # credential_authorities_expired.add(authority_hrn)
1180 print 'credential_authorities =', credential_authorities
1181 print 'credential_authorities_expired =', credential_authorities_expired
1183 # ** Where am I a PI **
1184 # For this we need to ask SFA (of all authorities) = PI function
1185 pi_authorities_query = Query.get('user').filter_by('user_hrn', '==', '$user_hrn').select('pi_authorities')
1186 pi_authorities_tmp = execute_query(self.request, pi_authorities_query)
1187 pi_authorities = set()
1188 for pa in pi_authorities_tmp:
1189 pi_authorities |= set(pa['pi_authorities'])
1191 print "pi_authorities =", pi_authorities
1193 # My authorities + I have a credential
1194 pi_credential_authorities = pi_authorities & credential_authorities
1195 pi_no_credential_authorities = pi_authorities - credential_authorities - credential_authorities_expired
1196 pi_expired_credential_authorities = pi_authorities & credential_authorities_expired
1197 # Authorities I've been delegated PI rights
1198 pi_delegation_credential_authorities = credential_authorities - pi_authorities
1199 pi_delegation_expired_authorities = credential_authorities_expired - pi_authorities
1201 print "pi_credential_authorities =", pi_credential_authorities
1202 print "pi_no_credential_authorities =", pi_no_credential_authorities
1203 print "pi_expired_credential_authorities =", pi_expired_credential_authorities
1204 print "pi_delegation_credential_authorities = ", pi_delegation_credential_authorities
1205 print "pi_delegation_expired_authorities = ", pi_delegation_expired_authorities
1207 # Summary intermediary
1208 pi_my_authorities = pi_credential_authorities | pi_no_credential_authorities | pi_expired_credential_authorities
1209 pi_delegation_authorities = pi_delegation_credential_authorities | pi_delegation_expired_authorities
1212 print "pi_my_authorities = ", pi_my_authorities
1213 print "pi_delegation_authorities = ", pi_delegation_authorities
1216 queried_pending_authorities = pi_my_authorities | pi_delegation_authorities
1218 print "queried_pending_authorities = ", queried_pending_authorities
1220 # Pending requests + authorities
1221 #pending_users = PendingUser.objects.filter(authority_hrn__in = queried_pending_authorities).all()
1222 #pending_slices = PendingSlice.objects.filter(authority_hrn__in = queried_pending_authorities).all()
1223 pending_users = PendingUser.objects.all()
1224 pending_slices = PendingSlice.objects.all()
1226 # Dispatch requests and build the proper structure for the template:
1228 print "pending users =", pending_users
1229 print "pending slices =", pending_slices
1231 for user in pending_users:
1232 auth_hrn = user.authority_hrn
1235 request['type'] = 'user'
1236 request['id'] = 'TODO' # XXX in DB ?
1237 request['timestamp'] = 'TODO' # XXX in DB ?
1238 request['details'] = "%s %s <%s>" % (user.first_name, user.last_name, user.email)
1240 if auth_hrn in pi_my_authorities:
1241 dest = ctx_my_authorities
1243 # define the css class
1244 if auth_hrn in pi_credential_authorities:
1245 request['allowed'] = 'allowed'
1246 elif auth_hrn in pi_expired_credential_authorities:
1247 request['allowed'] = 'expired'
1248 else: # pi_no_credential_authorities
1249 request['allowed'] = 'denied'
1251 elif auth_hrn in pi_delegation_authorities:
1252 dest = ctx_delegation_authorities
1254 if auth_hrn in pi_delegation_credential_authorities:
1255 request['allowed'] = 'allowed'
1256 else: # pi_delegation_expired_authorities
1257 request['allowed'] = 'expired'
1262 if not auth_hrn in dest:
1264 print "auth_hrn [%s] was added %r" % (auth_hrn, request)
1265 dest[auth_hrn].append(request)
1267 for slice in pending_slices:
1268 auth_hrn = slice.authority_hrn
1270 auth_hrn = "ple.upmc" # XXX HARDCODED
1273 request['type'] = 'slice'
1274 request['id'] = 'TODO' # XXX in DB ?
1275 request['timestamp'] = 'TODO' # XXX in DB ?
1276 request['details'] = "Number of nodes: %d -- Type of nodes: %s<br/>%s" % ('TODO', 'TODO', 'TODO') # XXX
1277 if auth_hrn in pi_my_authorities:
1278 dest = ctx_my_authorities
1280 # define the css class
1281 if auth_hrn in pi_credential_authorities:
1282 request['allowed'] = 'allowed'
1283 elif auth_hrn in pi_expired_credential_authorities:
1284 request['allowed'] = 'expired'
1285 else: # pi_no_credential_authorities
1286 request['allowed'] = 'denied'
1288 elif auth_hrn in pi_delegation_authorities:
1289 dest = ctx_delegation_authorities
1291 if auth_hrn in pi_delegation_credential_authorities:
1292 request['allowed'] = 'allowed'
1293 else: # pi_delegation_expired_authorities
1294 request['allowed'] = 'expired'
1296 if not auth_hrn in dest:
1298 dest[auth_hrn].append(request)
1300 context = super(ValidatePendingView, self).get_context_data(**kwargs)
1301 context['my_authorities'] = ctx_my_authorities
1302 context['delegation_authorities'] = ctx_delegation_authorities
1304 # XXX This is repeated in all pages
1305 # more general variables expected in the template
1306 context['title'] = 'Test view that combines various plugins'
1307 # the menu items on the top
1308 context['topmenu_items'] = topmenu_items('Dashboard', self.request)
1309 # so we can sho who is logged
1310 context['username'] = the_user(self.request)
1312 # XXX We need to prepare the page for queries
1313 #context.update(page.prelude_env())