From: Jordan Augé Date: Wed, 28 Aug 2013 08:41:36 +0000 (+0200) Subject: improved request validation X-Git-Tag: myslice-0.2-1~42 X-Git-Url: http://git.onelab.eu/?p=myslice.git;a=commitdiff_plain;h=26d84333b968352f844b47740021dd2a2fcafa41 improved request validation --- diff --git a/manifold/manifoldapi.py b/manifold/manifoldapi.py index 81a2caf6..e7d6a1bc 100644 --- a/manifold/manifoldapi.py +++ b/manifold/manifoldapi.py @@ -74,5 +74,10 @@ def execute_query(request, query): print "-"*80 result = manifold_api.forward(query.to_dict()) if result['code'] == 2: - raise Exception, 'Error running query' + raise Exception, 'Error running query: %r' % result + + # XXX Handle errors + #Error running query: {'origin': [0, 'XMLRPCAPI'], 'code': 2, 'description': 'No such session: No row was found for one()', 'traceback': 'Traceback (most recent call last):\n File "/usr/local/lib/python2.7/dist-packages/manifold/core/xmlrpc_api.py", line 68, in xmlrpc_forward\n user = Auth(auth).check()\n File "/usr/local/lib/python2.7/dist-packages/manifold/auth/__init__.py", line 245, in check\n return self.auth_method.check()\n File "/usr/local/lib/python2.7/dist-packages/manifold/auth/__init__.py", line 95, in check\n raise AuthenticationFailure, "No such session: %s" % e\nAuthenticationFailure: No such session: No row was found for one()\n', 'type': 2, 'ts': None, 'value': None} + + return result['value'] diff --git a/portal/actions.py b/portal/actions.py new file mode 100644 index 00000000..16ddaa18 --- /dev/null +++ b/portal/actions.py @@ -0,0 +1,180 @@ +from django.http import HttpResponse +from manifold.core.query import Query +from manifold.manifoldapi import execute_query +from portal.models import PendingUser, PendingSlice +import json + +# Get the list of authorities + +def authority_get_pis(authority_hrn): + query = Query.get('authority').filter_by('authority_hrn', '==', authority_hrn).select('pi_users') + results = execute_query(query) + if not results: + raise Exception, "Authority not found: %s" % authority_hrn + result, = results + return result['pi_users'] + +def authority_get_pi_emails(authority_hrn): + user_hrns = authority_get_pis(authority_hrn) + + query = Query.get('user').filter_by('user_hrn', 'included', user_hrns).select('user_email') + results = execute_query(query) + + return [result['user_email'] for result in results] + +# SFA add record (user, slice) + +def sfa_add_user(user_params): + # sfi.py add --xrn=fed4fire.upmc.timur_friedman --type=user --key=/root/.sfi/timur.pub --email=timur.friedman@lip6.fr --extra=first_name=Timur --extra=last_name=Friedman --extra=enabled=true + # user_params: xrn type key email + first_name last_name enabled + query = Query.create('user').set(user_params).select('user_hrn') + results = execute_query(query) + if not results: + raise Exception, "Failed creating SFA user: %s" % user_params['user_hrn'] + result, = results + return result['user_hrn'] + +def sfa_add_slice(slice_params): + pass + +# Propose hrn + +def manifold_add_user(user_params): + # user_params: email, password + query = Query.create('local:user').set(user_params).select('email') + results = execute_query(query) + if not results: + raise Exception, "Failed creating manifold user: %s" % user_params['email'] + result, = results + return result['email'] + +def manifold_add_account(account_params): + query = Query.create('local:account').set(account_params).select(['user', 'platform']) + results = execute_query(query) + if not results: + raise Exception, "Failed creating manifold account on platform %s for user: %s" % (account_params['platform'], account_params['user']) + result, = results + return (result['user'], result['platform']) + +def make_request_user(user): + request = {} + request['type'] = 'user' + request['id'] = user.id + request['timestamp'] = 'TODO' # XXX in DB ? + request['authority_hrn'] = user.authority_hrn + request['first_name'] = user.first_name + request['last_name'] = user.last_name + request['email'] = user.email + return request + +def make_request_slice(slice): + request = {} + request['type'] = 'slice' + request['id'] = slice.id + request['timestamp'] = 'TODO' # XXX in DB ? + request['authority_hrn'] = slice.authority_hrn + request['number_of_nodes'] = slice.number_of_nodes + request['type_of_nodes'] = slice.type_of_nodes + request['purpose'] = slice.purpose + return request + +def make_requests(pending_users, pending_slices): + print "pending users =", pending_users + print "pending slices =", pending_slices + + requests = [] + for user in pending_users: + requests.append(make_request_user(user)) + for slice in pending_slices: + requests.append(make_request_slice(slice)) + return requests + +def get_request_by_id(ids): + sorted_ids = { 'user': [], 'slice': [] } + for type__id in ids: + type, id = type__id.split('__') + sorted_ids[type].append(id) + + if not ids: + pending_users = PendingUser.objects.all() + pending_slices = PendingSlice.objects.all() + else: + pending_users = PendingUser.objects.filter(id__in=sorted_ids['user']).all() + pending_slices = PendingSlice.objects.filter(id__in=sorted_ids['slice']).all() + + return make_requests(pending_users, pending_slices) + +def get_request_by_authority(authority_hrns): + if not authority_hrns: + pending_users = PendingUser.objects.all() + pending_slices = PendingSlice.objects.all() + else: + pending_users = PendingUser.objects.filter(authority_hrn__in=authority_hrns).all() + pending_slices = PendingSlice.objects.filter(authority_hrn__in=authority_hrns).all() + + return make_requests(pending_users, pending_slices) + +SFA_USER_KEYS = ['xrn', 'type', 'key', 'first_name', 'last_name', 'email'] +SFA_SLICE_KEYS = [] +MANIFOLD_USER_KEYS = ['email', 'password'] +MANIFOLD_ACCOUNT_KEYS = [] + +def portal_validate_request(request_ids): + status = {} + + if not isinstance(request_ids, list): + request_ids = [request_ids] + + requests = get_request_by_id(request_ids) + for request in requests: + # type, id, timestamp, details, allowed -- MISSING: authority_hrn + # CAREFUL about details + # user : first name, last name, email, password, keypair + # slice : number of nodes, type of nodes, purpose + + request_status = {} + + if request['type'] == 'user': + try: + sfa_user_params = { key: request[key] for key in SFA_USER_KEYS } + sfa_user_params['enabled'] = True + # XXX # sfa_add_user(sfa_user_params) + request_status['SFA user'] = {'status': True } + except Exception, e: + request_status['SFA user'] = {'status': False, 'description': str(e)} + + try: + manifold_user_params = { key: request[key] for key in MANIFOLD_USER_KEYS } + # XXX # manifold_add_user(manifold_user_params) + request_status['MySlice user'] = {'status': True } + except Exception, e: + request_status['MySlice user'] = {'status': False, 'description': str(e)} + + # XXX + #manifold_account_params = { key: request[key] for key in MANIFOLD_ACCOUNT_KEYS } + #manifold_add_account(manifold_account_params) + request_status['MySlice testbed accounts'] = {'status': False } + + elif request['type'] == 'slice': + try: + sfa_slice_params = { key: request[key] for key in SFA_SLICE_KEYS } + # XXX # sfa_add_slice(sfa_slice_params) + request_status['SFA slice'] = {'status': True } + except Exception, e: + request_status['SFA slice'] = {'status': False, 'description': str(e)} + + status['%s__%s' % (request['type'], request['id'])] = request_status + + # XXX remove from database succeeded actions + + return status + + +def validate_action(*args, **kwargs): + ids = filter(None, kwargs['id'].split('/')) + status = portal_validate_request(ids) + json_answer = json.dumps(status) + return HttpResponse (json_answer, mimetype="application/json") + +# Django and ajax +# http://djangosnippets.org/snippets/942/ diff --git a/portal/forms.py b/portal/forms.py index 46a60bd4..7abc0e41 100644 --- a/portal/forms.py +++ b/portal/forms.py @@ -105,12 +105,12 @@ from django.utils.translation import ugettext_lazy as _ # DEPRECATED # # DEPRECATED # class Meta: # DEPRECATED # model = PendingUser - -class SliceRequestForm(forms.ModelForm): - slice_name = forms.CharField( widget=forms.TextInput ) - class Meta: - model = PendingSlice - +# DEPRECATED # +# DEPRECATED #class SliceRequestForm(forms.ModelForm): +# DEPRECATED # slice_name = forms.CharField( widget=forms.TextInput ) +# DEPRECATED # class Meta: +# DEPRECATED # model = PendingSlice +# DEPRECATED # # DEPRECATED #class RegisterUserStep2Form(forms.ModelForm): # DEPRECATED # class Meta: # DEPRECATED # model = PendingUser @@ -126,10 +126,29 @@ class ContactForm(forms.Form): class SliceRequestForm(forms.Form): slice_name = forms.CharField() + authority_hrn = forms.ChoiceField(choices=[(1, 'un')]) number_of_nodes = forms.DecimalField() type_of_nodes = forms.CharField() purpose = forms.CharField(widget=forms.Textarea) email = forms.EmailField() cc_myself = forms.BooleanField(required=False) + def __init__(self, *args, **kwargs): + initial = kwargs.get('initial', {}) + authority_hrn = initial.get('authority_hrn', None) + + # set just the initial value + # in the real form needs something like this {'authority_hrn':'a'} + # but in this case you want {'authority_hrn':('a', 'letter_a')} + if authority_hrn: + kwargs['initial']['authority_hrn'] = authority_hrn[0] + + # create the form + super(SliceRequestForm, self).__init__(*args, **kwargs) + + # self.fields only exist after, so a double validation is needed + if authority_hrn:# and authority_hrn[0] not in (c[0] for c in authority_hrn): + # XXX This does not work, the choicefield is not updated... + #self.fields['authority_hrn'].choices.extend(authority_hrn) + self.fields['authority_hrn'] = forms.ChoiceField( choices=authority_hrn) diff --git a/portal/migrations/0003_extend_slice.py b/portal/migrations/0003_extend_slice.py new file mode 100644 index 00000000..24370980 --- /dev/null +++ b/portal/migrations/0003_extend_slice.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'PendingSlice.number_of_nodes' + db.add_column(u'portal_pendingslice', 'number_of_nodes', + self.gf('django.db.models.fields.TextField')(default=0), + keep_default=False) + + # Adding field 'PendingSlice.type_of_nodes' + db.add_column(u'portal_pendingslice', 'type_of_nodes', + self.gf('django.db.models.fields.TextField')(default='NA'), + keep_default=False) + + # Adding field 'PendingSlice.purpose' + db.add_column(u'portal_pendingslice', 'purpose', + self.gf('django.db.models.fields.TextField')(default='NA'), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'PendingSlice.number_of_nodes' + db.delete_column(u'portal_pendingslice', 'number_of_nodes') + + # Deleting field 'PendingSlice.type_of_nodes' + db.delete_column(u'portal_pendingslice', 'type_of_nodes') + + # Deleting field 'PendingSlice.purpose' + db.delete_column(u'portal_pendingslice', 'purpose') + + + models = { + u'portal.institution': { + 'Meta': {'object_name': 'Institution'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.TextField', [], {}) + }, + u'portal.pendingslice': { + 'Meta': {'object_name': 'PendingSlice'}, + 'authority_hrn': ('django.db.models.fields.TextField', [], {'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'number_of_nodes': ('django.db.models.fields.TextField', [], {'default': '0'}), + 'purpose': ('django.db.models.fields.TextField', [], {'default': "'NA'"}), + 'slice_name': ('django.db.models.fields.TextField', [], {}), + 'type_of_nodes': ('django.db.models.fields.TextField', [], {'default': "'NA'"}) + }, + u'portal.pendinguser': { + 'Meta': {'object_name': 'PendingUser'}, + 'affiliation': ('django.db.models.fields.TextField', [], {}), + 'authority_hrn': ('django.db.models.fields.TextField', [], {}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'first_name': ('django.db.models.fields.TextField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'keypair': ('django.db.models.fields.TextField', [], {}), + 'last_name': ('django.db.models.fields.TextField', [], {}), + 'password': ('django.db.models.fields.TextField', [], {}) + } + } + + complete_apps = ['portal'] \ No newline at end of file diff --git a/portal/models.py b/portal/models.py index a16e3307..9a414ba5 100644 --- a/portal/models.py +++ b/portal/models.py @@ -309,5 +309,8 @@ class PendingUser(models.Model): class PendingSlice(models.Model): - slice_name = models.TextField() - authority_hrn = models.TextField(null=True) + slice_name = models.TextField() + authority_hrn = models.TextField(null=True) + number_of_nodes = models.TextField(default=0) + type_of_nodes = models.TextField(default='NA') + purpose = models.TextField(default='NA') diff --git a/portal/static/css/validate_pending.css b/portal/static/css/validate_pending.css index 4ed27e14..d0a7a568 100644 --- a/portal/static/css/validate_pending.css +++ b/portal/static/css/validate_pending.css @@ -5,7 +5,7 @@ position:relative; } -.portal_validate_request .slice { +.portal_validate_request.slice { background-image: url(../img/slice-icon.png); } @@ -13,7 +13,7 @@ background-image: url(../img/user-icon.png); } -.portal_validate_request .authority { +.portal_validate_request.authority { background-image: url(../img/authority-icon.png); } @@ -23,21 +23,33 @@ } .portal_validate_request .id { - position: relative; + position: absolute; left: 5%; } -.portal_validate_request .timestamp { - position: relative; - left: 10%; + +.portal_validate_request .authority { + position: absolute; + left: 7%; } + .portal_validate_request .details { - position: relative; - left: 20%; + position: absolute; + left: 15%; +} + +.portal_validate_request .timestamp { + position: absolute; + left: 50%; +} + +.portal_validate_request .status { + position: absolute; + left: 65%; } .portal_validate_request input { - position: relative; - left: 40%; + position: absolute; + left: 60%; } .portal_validate_request.even { diff --git a/portal/templates/slice_request_email.txt b/portal/templates/slice_request_email.txt new file mode 100644 index 00000000..ef46a04c --- /dev/null +++ b/portal/templates/slice_request_email.txt @@ -0,0 +1,9 @@ +NEW SLICE REQUEST + +slice name : {{slice_name}} +number of nodes : {{number_of_nodes}} +type of nodes : {{type_of_nodes}} +purpose : {{purpose}} +email : {{email}} +cc myself : {{cc_myself}} + diff --git a/portal/templates/user_request_email.txt b/portal/templates/user_request_email.txt new file mode 100644 index 00000000..3e18d0e9 --- /dev/null +++ b/portal/templates/user_request_email.txt @@ -0,0 +1,9 @@ +NEW USER REQUEST + +first_name : {{first_name}} +last_name : {{last_name}} +authority_hrn: {{authority_hrn}} +keypair : {{keypair}} +email : {{email}} +cc myself : {{cc_myself}} + diff --git a/portal/templates/validate_pending.html b/portal/templates/validate_pending.html index dd7d5c27..74176ea3 100644 --- a/portal/templates/validate_pending.html +++ b/portal/templates/validate_pending.html @@ -2,6 +2,47 @@ {% block head %} + {% endblock %} {% block unfold1_main %} @@ -19,9 +60,20 @@ {{ request.type }} {{ request.id }} {{ request.timestamp }} - {{ request.details }} + {{ request.authority_hrn }} + + {% if request.type == 'user' %} + First name: {{request.first_name}} -- Last name: {{request.last_name}} -- Email: {{request.email}} + {% else %} + {% if request.type == 'slice' %} + Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}} + {% else %} {# authority #} + TODO + {% endif %} + {% endif %} + {% if request.allowed == 'allowed' %} - + {% else %} {% if request.allowed == 'expired' %} expired @@ -29,6 +81,7 @@ denied {% endif %} {% endif %} + {% endfor %} {% endfor %} @@ -49,7 +102,7 @@ {{ request.timestamp }} {{ request.details }} {% if request.allowed == 'allowed' %} - + {% else %} {% if request.allowed == 'expired' %} expired @@ -57,10 +110,13 @@ denied {% endif %} {% endif %} + {% endfor %} {% endfor %} {% endif %} + + {% endblock %} diff --git a/portal/urls.py b/portal/urls.py index 2887388a..31c8908e 100644 --- a/portal/urls.py +++ b/portal/urls.py @@ -55,6 +55,9 @@ urlpatterns = patterns('', url(r'^slice_request/?$', views.slice_request), # Validate pending requests url(r'^validate/?$', ValidatePendingView.as_view()), + # http://stackoverflow.com/questions/2360179/django-urls-how-to-pass-a-list-of-items-via-clean-urls + # (r'^validate_action/(?P[^/]+)/(?P\w+)/?$', 'portal.views.pres_view_static'), + (r'^validate_action(?P(?:/\w+)+)/?$', 'portal.actions.validate_action'), url(r'^pres_view/?$', PresViewView.as_view(), name='pres_view'), (r'^methods/(?P\w+)/?$', 'portal.views.pres_view_methods'), diff --git a/portal/views.py b/portal/views.py index ac4e7b81..87f6cb69 100644 --- a/portal/views.py +++ b/portal/views.py @@ -27,6 +27,8 @@ from django.contrib import messages from django.views.generic import View from django.views.generic.base import TemplateView from django.shortcuts import render +from django.template.loader import render_to_string +from django.core.mail import send_mail from plugins.lists.simplelist import SimpleList from plugins.hazelnut import Hazelnut @@ -38,6 +40,7 @@ from portal import signals from portal.forms import SliceRequestForm, ContactForm from portal.util import RegistrationView, ActivationView from portal.models import PendingUser, PendingSlice +from portal.actions import authority_get_pi_emails, get_request_by_authority from manifold.core.query import Query from manifold.manifoldapi import execute_query from unfold.page import Page @@ -690,6 +693,8 @@ def register_4m_f4f(request): authorities = execute_query(request, authorities_query) if request.method == 'POST': + # We shall use a form here + #get_email = PendingUser.objects.get(email) reg_fname = request.POST.get('firstname', '') reg_lname = request.POST.get('lastname', '') @@ -763,10 +768,35 @@ def register_4m_f4f(request): # email=reg_email, password=request.POST['password'], keypair=keypair) #b.save() if not errors: - b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff, - authority_hrn=reg_auth, - email=reg_email, password=request.POST['password'], keypair=keypair) + b = PendingUser( + first_name=reg_fname, + last_name=reg_lname, + affiliation=reg_aff, + authority_hrn=reg_auth, + email=reg_email, + password=request.POST['password'], + keypair=keypair + ) b.save() + + # Send email + ctx = { + first_name : reg_fname, + last_name : reg_lname, + affiliation : reg_aff, + authority_hrn: reg_auth, + email : reg_email, + keypair : keypair, + cc_myself : True # form.cleaned_data['cc_myself'] + } + + recipients = authority_get_pi_emails(authority_hrn) + if ctx['cc_myself']: + recipients.append(ctx['email']) + + msg = render_to_string('user_request_email.txt', ctx) + send_mail("Onelab New User request submitted", msg, email, recipients) + return render(request, 'user_register_complete.html') return render(request, 'register_4m_f4f.html',{ @@ -796,6 +826,7 @@ def contact(request): email = form.cleaned_data['email'] # email of the sender cc_myself = form.cleaned_data['cc_myself'] + #recipients = authority_get_pi_emails(authority_hrn) recipients = ['yasin.upmc@gmail.com'] if cc_myself: recipients.append(email) @@ -815,26 +846,54 @@ def contact(request): def slice_request(request): - if request.method == 'POST': # If the form has been submitted... - form = SliceRequestForm(request.POST) # A form bound to the POST data - if form.is_valid(): # All validation rules pass - # Process the data in form.cleaned_data - slice_name = form.cleaned_data['slice_name'] + errors = [] + + authorities_query = Query.get('authority').filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc']).select('name', 'authority_hrn') + #authorities_query = Query.get('authority').select('authority_hrn') + authorities = execute_query(request, authorities_query) + + authority_hrn_tuple = [] + for authority in authorities: + authority_hrn_tuple.append((authority['authority_hrn'], authority['name'])) + authority_hrn_initial = {'authority_hrn': authority_hrn_tuple} + + # request.POST or None ? + if request.method == 'POST': + # The form has been submitted + form = SliceRequestForm(request.POST, initial=authority_hrn_initial) + + if form.is_valid(): + slice_name = form.cleaned_data['slice_name'] + authority_hrn = form.cleaned_data['authority_hrn'] number_of_nodes = form.cleaned_data['number_of_nodes'] - type_of_nodes = form.cleaned_data['type_of_nodes'] - purpose = form.cleaned_data['purpose'] + type_of_nodes = form.cleaned_data['type_of_nodes'] + purpose = form.cleaned_data['purpose'] + + s = PendingSlice( + slice_name = slice_name, + authority_hrn = authority_hrn, + number_of_nodes = number_of_nodes, + type_of_nodes = type_of_nodes, + purpose = purpose + ) + s.save() + + # All validation rules pass; process data in form.cleaned_data + # slice_name, number_of_nodes, type_of_nodes, purpose email = form.cleaned_data['email'] # email of the sender cc_myself = form.cleaned_data['cc_myself'] - recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr'] + # The recipients are the PI of the authority + recipients = authority_get_pi_emails(authority_hrn) + #recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr'] if cc_myself: recipients.append(email) + msg = render_to_string('slice_request_email.txt', form.cleaned_data) + send_mail("Onelab New Slice request form submitted", msg, email, recipients) - from django.core.mail import send_mail - send_mail("Onelab New Slice request form submitted", [slice_name,number_of_nodes,type_of_nodes,purpose], email, recipients) return render(request,'slicereq_recvd.html') # Redirect after POST else: - form = SliceRequestForm() # An unbound form + form = SliceRequestForm(initial=authority_hrn_initial) # template_env = {} # template_env['form'] = form @@ -1140,26 +1199,10 @@ class ValidatePendingView(TemplateView): queried_pending_authorities = pi_my_authorities | pi_delegation_authorities print "----" print "queried_pending_authorities = ", queried_pending_authorities - - # Pending requests + authorities - #pending_users = PendingUser.objects.filter(authority_hrn__in = queried_pending_authorities).all() - #pending_slices = PendingSlice.objects.filter(authority_hrn__in = queried_pending_authorities).all() - pending_users = PendingUser.objects.all() - pending_slices = PendingSlice.objects.all() - - # Dispatch requests and build the proper structure for the template: - - print "pending users =", pending_users - print "pending slices =", pending_slices - - for user in pending_users: - auth_hrn = user.authority_hrn - request = {} - request['type'] = 'user' - request['id'] = 'TODO' # XXX in DB ? - request['timestamp'] = 'TODO' # XXX in DB ? - request['details'] = "%s %s <%s>" % (user.first_name, user.last_name, user.email) + requests = get_request_by_authority(queried_pending_authorities) + for request in requests: + auth_hrn = request['authority_hrn'] if auth_hrn in pi_my_authorities: dest = ctx_my_authorities @@ -1182,45 +1225,11 @@ class ValidatePendingView(TemplateView): else: continue - - if not auth_hrn in dest: - dest[auth_hrn] = [] - print "auth_hrn [%s] was added %r" % (auth_hrn, request) - dest[auth_hrn].append(request) - - for slice in pending_slices: - auth_hrn = slice.authority_hrn - if not auth_hrn: - auth_hrn = "ple.upmc" # XXX HARDCODED - - request = {} - request['type'] = 'slice' - request['id'] = 'TODO' # XXX in DB ? - request['timestamp'] = 'TODO' # XXX in DB ? - request['details'] = "Number of nodes: %d -- Type of nodes: %s
%s" % ('TODO', 'TODO', 'TODO') # XXX - if auth_hrn in pi_my_authorities: - dest = ctx_my_authorities - - # define the css class - if auth_hrn in pi_credential_authorities: - request['allowed'] = 'allowed' - elif auth_hrn in pi_expired_credential_authorities: - request['allowed'] = 'expired' - else: # pi_no_credential_authorities - request['allowed'] = 'denied' - - elif auth_hrn in pi_delegation_authorities: - dest = ctx_delegation_authorities - if auth_hrn in pi_delegation_credential_authorities: - request['allowed'] = 'allowed' - else: # pi_delegation_expired_authorities - request['allowed'] = 'expired' - if not auth_hrn in dest: dest[auth_hrn] = [] dest[auth_hrn].append(request) - + context = super(ValidatePendingView, self).get_context_data(**kwargs) context['my_authorities'] = ctx_my_authorities context['delegation_authorities'] = ctx_delegation_authorities