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.manifoldapi import execute_query
47 from manifold.core.query import 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 # View for 1 platform and its details
56 class PlatformView(TemplateView):
57 template_name = "platform.html"
59 def get_context_data(self, **kwargs):
60 page = Page(self.request)
62 for key, value in kwargs.iteritems():
63 print "%s = %s" % (key, value)
64 if key == "platformname":
67 network_query = Query().get('local:platform').filter_by('platform', '==', platformname).select('platform','platform_longname','gateway_type')
68 page.enqueue_query(network_query)
70 page.expose_js_metadata()
72 networklist = Hazelnut(
76 # this is the query at the core of the slice list
77 query = network_query,
78 query_all = network_query,
80 datatables_options = {
81 # for now we turn off sorting on the checkboxes columns this way
82 # this of course should be automatic in hazelnut
83 'aoColumns' : [None, None, None, None, {'bSortable': False}],
84 'iDisplayLength' : 25,
85 'bLengthChange' : True,
89 # networklist = SimpleList(
93 # query = network_query,
96 context = super(PlatformView, self).get_context_data(**kwargs)
97 context['person'] = self.request.user
98 context['networks'] = networklist.render(self.request)
100 # XXX This is repeated in all pages
101 # more general variables expected in the template
102 context['title'] = 'Platforms connected to MySlice'
103 # the menu items on the top
104 context['topmenu_items'] = topmenu_items('Platforms', self.request)
105 # so we can sho who is logged
106 context['username'] = the_user(self.request)
108 context.update(page.prelude_env())
114 #class for my_account
115 class AccountView(TemplateView):
116 template_name = "my_account.html"
118 #This view requires login
119 @method_decorator(login_required)
120 def dispatch(self, *args, **kwargs):
121 return super(AccountView, self).dispatch(*args, **kwargs)
124 def get_context_data(self, **kwargs):
125 #page = Page(self.request)
127 user_query = Query().get('local:user').select('config','email')
128 user_details = execute_query(self.request, user_query)
130 # not always found in user_details...
132 for user_detail in user_details:
133 #email = user_detail['email']
134 if user_detail['config']:
135 config = json.loads(user_detail['config'])
137 platform_query = Query().get('local:platform').select('platform_id','platform')
138 account_query = Query().get('local:account').select('user_id','platform_id','auth_type','config')
139 platform_details = execute_query(self.request, platform_query)
140 account_details = execute_query(self.request, account_query)
142 # initial assignment needed for users having no account
147 platform_name_list = []
148 account_type_list = []
151 for account_detail in account_details:
152 for platform_detail in platform_details:
153 if platform_detail['platform_id'] == account_detail['platform_id']:
154 platform_name = platform_detail['platform']
155 account_type = account_detail['auth_type']
156 account_config = json.loads(account_detail['config'])
157 # a bit more pythonic
158 account_usr_hrn = account_config.get('user_hrn','N/A')
159 account_pub_key = account_config.get('user_public_key','N/A')
161 platform_name_list.append(platform_name)
162 account_type_list.append(account_type)
163 usr_hrn_list.append(account_usr_hrn)
164 pub_key_list.append(account_pub_key)
166 # combining 4 lists into 1 [to render in the template]
167 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)]
171 context = super(AccountView, self).get_context_data(**kwargs)
172 context['data'] = lst
173 context['person'] = self.request.user
174 context ['firstname'] = config.get('firstname',"?")
175 context ['lastname'] = config.get('lastname',"?")
176 context ['fullname'] = context['firstname'] +' '+ context['lastname']
177 context ['authority'] = config.get('authority',"Unknown Authority")
178 #context['users'] = userlist.render(self.request)
180 # XXX This is repeated in all pages
181 # more general variables expected in the template
182 context['title'] = 'Platforms connected to MySlice'
183 # the menu items on the top
184 context['topmenu_items'] = topmenu_items('My Account', self.request)
185 # so we can sho who is logged
186 context['username'] = the_user(self.request)
187 # context ['firstname'] = config['firstname']
188 #context.update(page.prelude_env())
192 #my_acc form value processing
193 def account_process(request):
194 user_query = Query().get('local:user').select('password','config')
195 user_details = execute_query(request, user_query)
197 if 'submit_name' in request.POST:
198 edited_first_name = request.POST['fname']
199 edited_last_name = request.POST['lname']
202 for user_config in user_details:
203 #email = user_detail['email']
204 if user_config['config']:
205 config = json.loads(user_config['config'])
206 config['firstname'] = edited_first_name
207 config['lastname'] = edited_last_name
208 config['authority'] = config.get('authority','Unknown Authority')
209 updated_config = json.dumps(config)
211 # updating config local:user in manifold
212 user_params = { 'config': updated_config}
213 manifold_update_user(request,user_params)
214 # this will be depricated, we will show the success msg in same page
215 return HttpResponse('Sucess: First Name and Last Name Updated!')
216 elif 'submit_pass' in request.POST:
217 edited_password = request.POST['password']
219 for user_pass in user_details:
220 user_pass['password'] = edited_password
221 #updating password in local:user
222 user_params = { 'password': user_pass['password']}
223 manifold_update_user(request,user_params)
225 return HttpResponse('Success: Password Changed!!')
226 elif 'generate' in request.POST:
227 # Generate public and private keys using SFA Library
228 from sfa.trust.certificate import Keypair
229 k = Keypair(create=True)
230 public_key = k.get_pubkey_string()
231 private_key = k.as_pem()
232 private_key = ''.join(private_key.split())
233 public_key = "ssh-rsa " + public_key
235 keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
236 # keypair = re.sub("\r", "", keypair)
237 # keypair = re.sub("\n", "\\n", keypair)
238 # #keypair = keypair.rstrip('\r\n')
239 # keypair = ''.join(keypair.split())
240 get_user.keypair = keypair
242 return HttpResponse('Success: New Keypair Generated! %s' % keypair)
244 elif 'upload_key' in request.POST:
245 up_file = request.FILES['pubkey']
246 file_content = up_file.read()
247 file_name = up_file.name
248 file_extension = os.path.splitext(file_name)[1]
249 allowed_extension = ['.pub','.txt']
250 if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
251 file_content = '{"user_public_key":"'+ file_content +'"}'
252 file_content = re.sub("\r", "", file_content)
253 file_content = re.sub("\n", "\\n",file_content)
254 file_content = ''.join(file_content.split())
255 get_user.keypair = file_content
257 return HttpResponse('Success: Publickey uploaded! Old records overwritten')
259 return HttpResponse('Please upload a valid RSA public key [.txt or .pub].')
262 message = 'You submitted an empty form.'
263 return HttpResponse(message)
265 def register_4m_f4f(request):
268 authorities_query = Query.get('authority').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc']).select('name', 'authority_hrn')
269 #authorities_query = Query.get('authority').select('authority_hrn')
270 authorities = execute_query(request, authorities_query)
272 if request.method == 'POST':
273 # We shall use a form here
275 #get_email = PendingUser.objects.get(email)
276 reg_fname = request.POST.get('firstname', '')
277 reg_lname = request.POST.get('lastname', '')
278 reg_aff = request.POST.get('affiliation','')
279 reg_auth = request.POST.get('authority_hrn', '')
280 reg_email = request.POST.get('email','').lower()
282 #POST value validation
283 if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
284 errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
285 #return HttpResponse("Only Letters, Numbers, - and _ allowd in First Name")
286 #return render(request, 'register_4m_f4f.html')
287 if (re.search(r'^[\w+\s.@+-]+$', reg_lname) == None):
288 errors.append('Last Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
289 #return HttpResponse("Only Letters, Numbers, - and _ is allowed in Last name")
290 #return render(request, 'register_4m_f4f.html')
291 if (re.search(r'^[\w+\s.@+-]+$', reg_aff) == None):
292 errors.append('Affiliation may contain only letters, numbers, spaces and @/./+/-/_ characters.')
293 #return HttpResponse("Only Letters, Numbers and _ is allowed in Affiliation")
294 #return render(request, 'register_4m_f4f.html')
295 # XXX validate authority hrn !!
296 if PendingUser.objects.filter(email__iexact=reg_email):
297 errors.append('Email already registered.Please provide a new email address.')
298 #return HttpResponse("Email Already exists")
299 #return render(request, 'register_4m_f4f.html')
300 if 'generate' in request.POST['question']:
301 # Generate public and private keys using SFA Library
302 from sfa.trust.certificate import Keypair
303 k = Keypair(create=True)
304 public_key = k.get_pubkey_string()
305 private_key = k.as_pem()
306 private_key = ''.join(private_key.split())
307 public_key = "ssh-rsa " + public_key
309 keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
310 # keypair = re.sub("\r", "", keypair)
311 # keypair = re.sub("\n", "\\n", keypair)
312 # #keypair = keypair.rstrip('\r\n')
313 # keypair = ''.join(keypair.split())
315 up_file = request.FILES['user_public_key']
316 file_content = up_file.read()
317 file_name = up_file.name
318 file_extension = os.path.splitext(file_name)[1]
319 allowed_extension = ['.pub','.txt']
320 if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
321 keypair = '{"user_public_key":"'+ file_content +'"}'
322 keypair = re.sub("\r", "", keypair)
323 keypair = re.sub("\n", "\\n",keypair)
324 keypair = ''.join(keypair.split())
326 errors.append('Please upload a valid RSA public key [.txt or .pub].')
328 #b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff,
329 # email=reg_email, password=request.POST['password'], keypair=keypair)
333 first_name=reg_fname,
336 authority_hrn=reg_auth,
338 password=request.POST['password'],
345 first_name : reg_fname,
346 last_name : reg_lname,
347 affiliation : reg_aff,
348 authority_hrn: reg_auth,
351 cc_myself : True # form.cleaned_data['cc_myself']
354 recipients = authority_get_pi_emails(authority_hrn)
356 recipients.append(ctx['email'])
358 msg = render_to_string('user_request_email.txt', ctx)
359 send_mail("Onelab New User request submitted", msg, email, recipients)
361 return render(request, 'user_register_complete.html')
363 return render(request, 'register_4m_f4f.html',{
364 'topmenu_items': topmenu_items('Register', request),
366 'firstname': request.POST.get('firstname', ''),
367 'lastname': request.POST.get('lastname', ''),
368 'affiliation': request.POST.get('affiliation', ''),
369 'authority_hrn': request.POST.get('authority_hrn', ''),
370 'email': request.POST.get('email', ''),
371 'password': request.POST.get('password', ''),
372 'authorities': authorities
376 # view for contact form
377 def contact(request):
378 if request.method == 'POST': # If the form has been submitted...
379 form = ContactForm(request.POST) # A form bound to the POST data
380 if form.is_valid(): # All validation rules pass
381 # Process the data in form.cleaned_data
382 first_name = form.cleaned_data['first_name']
383 last_name = form.cleaned_data['last_name']
384 affiliation = form.cleaned_data['affiliation']
385 subject = form.cleaned_data['subject']
386 message = form.cleaned_data['message']
387 email = form.cleaned_data['email'] # email of the sender
388 cc_myself = form.cleaned_data['cc_myself']
390 #recipients = authority_get_pi_emails(authority_hrn)
391 recipients = ['yasin.upmc@gmail.com']
393 recipients.append(email)
395 from django.core.mail import send_mail
396 send_mail("Onelab user submitted a query ", [first_name,last_name,affiliation,subject,message], email, recipients)
397 return render(request,'contact_sent.html') # Redirect after POST
399 form = ContactForm() # An unbound form
401 return render(request, 'contact.html', {
403 'topmenu_items': topmenu_items('Contact Us', request),
404 'username': the_user (request)
409 def slice_request(request):
412 authorities_query = Query.get('authority').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc']).select('name', 'authority_hrn')
413 #authorities_query = Query.get('authority').select('authority_hrn')
414 authorities = execute_query(request, authorities_query)
416 authority_hrn_tuple = []
417 for authority in authorities:
418 authority_hrn_tuple.append((authority['authority_hrn'], authority['name']))
419 authority_hrn_initial = {'authority_hrn': authority_hrn_tuple}
421 # request.POST or None ?
422 if request.method == 'POST':
423 # The form has been submitted
424 form = SliceRequestForm(request.POST, initial=authority_hrn_initial)
427 slice_name = form.cleaned_data['slice_name']
428 authority_hrn = form.cleaned_data['authority_hrn']
429 number_of_nodes = form.cleaned_data['number_of_nodes']
430 type_of_nodes = form.cleaned_data['type_of_nodes']
431 purpose = form.cleaned_data['purpose']
434 slice_name = slice_name,
435 authority_hrn = authority_hrn,
436 number_of_nodes = number_of_nodes,
437 type_of_nodes = type_of_nodes,
442 # All validation rules pass; process data in form.cleaned_data
443 # slice_name, number_of_nodes, type_of_nodes, purpose
444 email = form.cleaned_data['email'] # email of the sender
445 cc_myself = form.cleaned_data['cc_myself']
447 # The recipients are the PI of the authority
448 recipients = authority_get_pi_emails(authority_hrn)
449 #recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
451 recipients.append(email)
452 msg = render_to_string('slice_request_email.txt', form.cleaned_data)
453 send_mail("Onelab New Slice request form submitted", msg, email, recipients)
455 return render(request,'slicereq_recvd.html') # Redirect after POST
457 form = SliceRequestForm(initial=authority_hrn_initial)
460 # template_env['form'] = form
461 # template_env['topmenu_items'] = topmenu_items('Request a slice', request)
462 # template_env['unfold1_main'] = render(request, 'slice_request_.html', {
465 # from django.shortcuts import render_to_response
466 # from django.template import RequestContext
467 # return render_to_response ('view-unfold1.html',template_env,
468 # context_instance=RequestContext(request))
470 return render(request, 'slice_request.html', {
472 'topmenu_items': topmenu_items('Request a slice', request),
473 'username': the_user (request)
477 class PresViewView(TemplateView):
478 template_name = "view-unfold1.html"
480 def get_context_data(self, **kwargs):
482 page = Page(self.request)
484 pres_view = PresView(page = page)
486 context = super(PresViewView, self).get_context_data(**kwargs)
488 #context['ALL_STATIC'] = "all_static"
489 context['unfold1_main'] = pres_view.render(self.request)
491 # XXX This is repeated in all pages
492 # more general variables expected in the template
493 context['title'] = 'Test view that combines various plugins'
494 # the menu items on the top
495 context['topmenu_items'] = topmenu_items('PresView', self.request)
496 # so we can sho who is logged
497 context['username'] = the_user(self.request)
499 prelude_env = page.prelude_env()
500 context.update(prelude_env)
504 def json_me(config_file,type):
506 for ligne in config_file:
507 if not ligne.startswith('#'):
508 args = ligne.split(';')
509 json_answer += str('{ "name": "' + args[0] + '" ,"id":"' + args[1] + '" ,"descriptif":"' + args[2]+'"')
511 json_answer += str(',"contraints":')
513 json_answer += str('""')
515 json_answer += str(args[3])
516 json_answer += str('},')
517 return json_answer[:-1]
520 DIR = '/var/myslice/'
521 STATIC = '%s/config_method_static' % DIR
522 DYNAMIC = '%s/config_method_dynamic' % DIR
523 ANIMATION = '%s/config_method_animation' % DIR
525 def pres_view_methods(request, type):
529 elif type =="static":
530 config = open(STATIC, "r")
531 json_answer = str('{ "options": [')
532 json_answer += str(json_me(config,"static"))
533 json_answer += str('] }')
535 elif type =="dynamic":
536 config = open(DYNAMIC, "r")
537 json_answer = str('{ "options": [')
538 json_answer += str(json_me(config,"dynamic"))
539 json_answer += str('] }')
541 elif type =="animation":
542 config = open(ANIMATION, "r")
543 json_answer = str('{ "options": [')
544 json_answer += str(json_me(config,"animation"))
545 json_answer += str('] }')
548 config = open(STATIC, "r")
549 json_answer = str('{ "static": [')
550 json_answer += str(json_me(config,"static"))
551 json_answer += str('],')
552 json_answer += str('"dynamic": [')
554 config = open(DYNAMIC, "r")
555 json_answer += str(json_me(config,"dynamic"))
556 json_answer += str('],')
557 json_answer += str('"animation": [')
559 config = open(ANIMATION, "r")
560 json_answer += str(json_me(config,"animation"))
561 json_answer += str('] }')
565 return HttpResponse (json_answer, mimetype="application/json")
567 def pres_view_animation(request, constraints, id):
569 # sites crees depuis 2008
570 # static.py?contraints=']date_created':1262325600&id='name_id"'
572 # method = request.getvalue('method') #ex : GetSites
573 #constraints = "']date_created':1262325600"
579 # method = 'GetSites'#request.getvalue('method') #ex : GetSites
580 # constraints = {}#request.getvalue('constraints') // nul = {}
581 # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
583 config_file = open(ANIMATION, "r")
584 for ligne in config_file:
585 if not ligne.startswith('#'):
586 ligne = ligne.split('\n')
587 first = ligne[0].split(';')
588 if (str(first[1]) == str(id)):
592 #Les print_method, print_option sont definis par le client (js)
593 #Les animations acceptent que les connexions anonymous
594 # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
595 args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
598 #Creation d'un objet event
602 "print_options": event.print_options,
603 "print_method": event.print_method,
604 "message": event.data
609 json_answer = json.dumps(cmd)
610 return HttpResponse (json_answer, mimetype="application/json")
612 def pres_view_static(request, constraints, id):
613 #constraints = "']date_created':1262325600"
616 # method = 'GetSites'#request.getvalue('method') #ex : GetSites
617 # constraints = {}#request.getvalue('constraints') // nul = {}
618 # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
620 config_file = open(STATIC, "r")
621 for ligne in config_file:
622 if not ligne.startswith('#'):
623 ligne = ligne.split('\n')
624 first = ligne[0].split(';')
625 if (str(first[1]) == str(id)):
629 #Les print_method, print_option sont definis par le client (js)
630 #Les animations acceptent que les connexions anonymous
631 # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
632 args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
635 #Creation d'un objet event
639 "print_options": event.print_options,
640 "print_method": event.print_method,
641 "message": event.data
646 json_answer = json.dumps(cmd)
647 return HttpResponse (json_answer, mimetype="application/json")
649 class ValidatePendingView(TemplateView):
650 template_name = "validate_pending.html"
652 def get_context_data(self, **kwargs):
653 # We might have slices on different registries with different user accounts
654 # 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
655 # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
657 #messages.info(self.request, 'You have logged in')
658 page = Page(self.request)
660 ctx_my_authorities = {}
661 ctx_delegation_authorities = {}
664 # The user need to be logged in
665 if the_user(self.request):
666 # Who can a PI validate:
667 # His own authorities + those he has credentials for.
668 # In MySlice we need to look at credentials also.
671 # XXX This will have to be asynchroneous. Need to implement barriers,
672 # for now it will be sufficient to have it working statically
674 # get user_id to later on query accounts
675 # XXX Having real query plan on local tables would simplify all this
676 # XXX $user_email is still not available for local tables
677 #user_query = Query().get('local:user').filter_by('email', '==', '$user_email').select('user_id')
678 user_query = Query().get('local:user').filter_by('email', '==', the_user(self.request)).select('user_id')
679 user, = execute_query(self.request, user_query)
680 user_id = user['user_id']
682 # Query manifold to learn about available SFA platforms for more information
683 # In general we will at least have the portal
684 # For now we are considering all registries
687 sfa_platforms_query = Query().get('local:platform').filter_by('gateway_type', '==', 'sfa').select('platform_id', 'platform', 'auth_type')
688 sfa_platforms = execute_query(self.request, sfa_platforms_query)
689 for sfa_platform in sfa_platforms:
690 print "SFA PLATFORM > ", sfa_platform['platform']
691 if not 'auth_type' in sfa_platform:
693 auth = sfa_platform['auth_type']
694 if not auth in all_authorities:
695 all_authorities.append(auth)
696 platform_ids.append(sfa_platform['platform_id'])
698 # We can check on which the user has authoritity credentials = PI rights
699 credential_authorities = set()
700 credential_authorities_expired = set()
702 # User account on these registries
703 user_accounts_query = Query.get('local:account').filter_by('user_id', '==', user_id).filter_by('platform_id', 'included', platform_ids).select('config')
704 user_accounts = execute_query(self.request, user_accounts_query)
708 for user_account in user_accounts:
709 config = json.loads(user_account['config'])
711 if 'authority_credentials' in config:
712 for authority_hrn, credential in config['authority_credentials'].items():
713 #if credential is not expired:
714 credential_authorities.add(authority_hrn)
716 # credential_authorities_expired.add(authority_hrn)
717 if 'delegated_authority_credentials' in config:
718 for authority_hrn, credential in config['delegated_authority_credentials'].items():
719 #if credential is not expired:
720 credential_authorities.add(authority_hrn)
722 # credential_authorities_expired.add(authority_hrn)
724 print 'credential_authorities =', credential_authorities
725 print 'credential_authorities_expired =', credential_authorities_expired
727 # ** Where am I a PI **
728 # For this we need to ask SFA (of all authorities) = PI function
729 pi_authorities_query = Query.get('user').filter_by('user_hrn', '==', '$user_hrn').select('pi_authorities')
730 pi_authorities_tmp = execute_query(self.request, pi_authorities_query)
731 pi_authorities = set()
732 for pa in pi_authorities_tmp:
733 pi_authorities |= set(pa['pi_authorities'])
735 print "pi_authorities =", pi_authorities
737 # My authorities + I have a credential
738 pi_credential_authorities = pi_authorities & credential_authorities
739 pi_no_credential_authorities = pi_authorities - credential_authorities - credential_authorities_expired
740 pi_expired_credential_authorities = pi_authorities & credential_authorities_expired
741 # Authorities I've been delegated PI rights
742 pi_delegation_credential_authorities = credential_authorities - pi_authorities
743 pi_delegation_expired_authorities = credential_authorities_expired - pi_authorities
745 print "pi_credential_authorities =", pi_credential_authorities
746 print "pi_no_credential_authorities =", pi_no_credential_authorities
747 print "pi_expired_credential_authorities =", pi_expired_credential_authorities
748 print "pi_delegation_credential_authorities = ", pi_delegation_credential_authorities
749 print "pi_delegation_expired_authorities = ", pi_delegation_expired_authorities
751 # Summary intermediary
752 pi_my_authorities = pi_credential_authorities | pi_no_credential_authorities | pi_expired_credential_authorities
753 pi_delegation_authorities = pi_delegation_credential_authorities | pi_delegation_expired_authorities
756 print "pi_my_authorities = ", pi_my_authorities
757 print "pi_delegation_authorities = ", pi_delegation_authorities
760 queried_pending_authorities = pi_my_authorities | pi_delegation_authorities
762 print "queried_pending_authorities = ", queried_pending_authorities
764 requests = get_request_by_authority(queried_pending_authorities)
765 for request in requests:
766 auth_hrn = request['authority_hrn']
768 if auth_hrn in pi_my_authorities:
769 dest = ctx_my_authorities
771 # define the css class
772 if auth_hrn in pi_credential_authorities:
773 request['allowed'] = 'allowed'
774 elif auth_hrn in pi_expired_credential_authorities:
775 request['allowed'] = 'expired'
776 else: # pi_no_credential_authorities
777 request['allowed'] = 'denied'
779 elif auth_hrn in pi_delegation_authorities:
780 dest = ctx_delegation_authorities
782 if auth_hrn in pi_delegation_credential_authorities:
783 request['allowed'] = 'allowed'
784 else: # pi_delegation_expired_authorities
785 request['allowed'] = 'expired'
790 if not auth_hrn in dest:
792 dest[auth_hrn].append(request)
794 context = super(ValidatePendingView, self).get_context_data(**kwargs)
795 context['my_authorities'] = ctx_my_authorities
796 context['delegation_authorities'] = ctx_delegation_authorities
798 # XXX This is repeated in all pages
799 # more general variables expected in the template
800 context['title'] = 'Test view that combines various plugins'
801 # the menu items on the top
802 context['topmenu_items'] = topmenu_items('Dashboard', self.request)
803 # so we can sho who is logged
804 context['username'] = the_user(self.request)
806 # XXX We need to prepare the page for queries
807 #context.update(page.prelude_env())