View to enter a private key that will be encrypted and saved into the user session.

Util functions to encrypt/decrypt the private key.
Decorator to redirect to the private key input view if there is no key defined in the user session.
Templatetag 'decrypt' that decrypts text using the private key provided to the templatetag.
Fixes 
 - Legacy-Id: 5335
This commit is contained in:
Emilio A. Sánchez López 2013-01-30 16:48:19 +00:00
parent 20320ea9ff
commit 9b00517449
8 changed files with 127 additions and 6 deletions

View file

@ -1,3 +1,7 @@
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.utils.http import urlquote
from ietf.ietfauth.decorators import passes_test_decorator, has_role
from ietf.nomcom.utils import get_nomcom_by_year
@ -16,3 +20,15 @@ def member_required(role=None):
return nomcom.group.is_member(user)
return False
return passes_test_decorator(_is_nomcom_member, 'Restricted to NomCom %s' % role)
def private_key_required(view_func):
def inner(request, *args, **kwargs):
year = kwargs.get('year', None)
if not year:
raise Exception, 'View decorated with private_key_required must receive a year argument'
if not 'NOMCOM_PRIVATE_KEY_%s' % year in request.session:
return HttpResponseRedirect('%s?back_to=%s' % (reverse('nomcom_private_key', None, args=(year, )), urlquote(request.get_full_path())))
else:
return view_func(request, *args, **kwargs)
return inner

View file

@ -440,3 +440,10 @@ class PositionForm(BaseNomcomForm, forms.ModelForm):
def save(self, *args, **kwargs):
self.instance.nomcom = self.nomcom
super(PositionForm, self).save(*args, **kwargs)
class PrivateKeyForm(BaseNomcomForm, forms.Form):
key = forms.CharField(label='Private key', widget=forms.Textarea(), required=False)
fieldsets = [('Private key', ('key',))]

View file

@ -1,7 +1,12 @@
import os
import tempfile
from django import template
from django.conf import settings
from ietf.ietfauth.decorators import has_role
from ietf.nomcom.utils import get_nomcom_by_year
from ietf.utils.pipe import pipe
register = template.Library()
@ -14,3 +19,25 @@ def is_chair(user, year):
if has_role(user, "Secretariat"):
return True
return nomcom.group.is_chair(user)
@register.filter
def decrypt(string, key=None):
if not key:
return '<-Encripted text [No private key provided]->'
encrypted_file = tempfile.NamedTemporaryFile(delete=False)
encrypted_file.write(string)
encrypted_file.close()
command = "%s smime -decrypt -in %s -inkey /dev/stdin"
code, out, error = pipe(command % (settings.OPENSSL_COMMAND,
encrypted_file.name), key)
os.unlink(encrypted_file.name)
if error:
return '<-Encripted text [Your private key is invalid]->'
return out

View file

@ -4,6 +4,7 @@ from ietf.nomcom.forms import EditChairForm, EditChairFormPreview, \
urlpatterns = patterns('ietf.nomcom.views',
url(r'^(?P<year>\d{4})/private/$', 'private_index', name='nomcom_private_index'),
url(r'^(?P<year>\d{4})/private/key/$', 'private_key', name='nomcom_private_key'),
url(r'^(?P<year>\d{4})/private/nominate/$', 'private_nominate', name='nomcom_private_nominate'),
url(r'^(?P<year>\d{4})/private/merge/$', 'private_merge', name='nomcom_private_merge'),
url(r'^(?P<year>\d{4})/private/edit-members/$', EditMembersFormPreview(EditMembersForm), name='nomcom_edit_members'),

View file

@ -1,8 +1,10 @@
from django.shortcuts import get_object_or_404
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404
from ietf.person.models import Email
from ietf.dbtemplate.models import DBTemplate
from ietf.person.models import Email
from ietf.utils.pipe import pipe
MAIN_NOMCOM_TEMPLATE_PATH = '/nomcom/defaults/'
QUESTIONNAIRE_TEMPLATE = 'position/questionnaire.txt'
@ -85,3 +87,27 @@ def initialize_requirements_for_position(position):
variables=template.variables,
type_id=template.type_id,
content=template.content)
def retrieve_nomcom_private_key(request, year):
private_key = request.session.get('NOMCOM_PRIVATE_KEY_%s' % year, None)
if not private_key:
return private_key
command = "%s bf -d -in /dev/stdin -k \"%s\" -a"
code, out, error = pipe(command % (settings.OPENSSL_COMMAND,
settings.SECRET_KEY), private_key)
return out
def store_nomcom_private_key(request, year, private_key):
if not private_key:
request.session['NOMCOM_PRIVATE_KEY_%s' % year] = ''
else:
command = "%s bf -e -in /dev/stdin -k \"%s\" -a"
code, out, error = pipe(command % (settings.OPENSSL_COMMAND,
settings.SECRET_KEY), private_key)
if error:
out = ''
request.session['NOMCOM_PRIVATE_KEY_%s' % year] = out

View file

@ -9,11 +9,13 @@ from django.utils import simplejson
from ietf.dbtemplate.models import DBTemplate
from ietf.dbtemplate.views import template_edit
from ietf.nomcom.decorators import member_required
from ietf.nomcom.decorators import member_required, private_key_required
from ietf.nomcom.forms import (EditPublicKeyForm, NominateForm, MergeForm,
NomComTemplateForm, PositionForm)
NomComTemplateForm, PositionForm, PrivateKeyForm)
from ietf.nomcom.models import Position
from ietf.nomcom.utils import get_nomcom_by_year, HOME_TEMPLATE
from ietf.nomcom.utils import (get_nomcom_by_year, HOME_TEMPLATE,
retrieve_nomcom_private_key,
store_nomcom_private_key)
def index(request, year):
@ -27,6 +29,28 @@ def index(request, year):
'template': template}, RequestContext(request))
@member_required(role='member')
def private_key(request, year):
nomcom = get_nomcom_by_year(year)
private_key = retrieve_nomcom_private_key(request, year)
back_url = request.GET.get('back_to', reverse('nomcom_private_index', None, args=(year, )))
if request.method == 'POST':
form = PrivateKeyForm(data=request.POST)
if form.is_valid():
store_nomcom_private_key(request, year, form.cleaned_data.get('key', ''))
return HttpResponseRedirect(back_url)
else:
form = PrivateKeyForm(initial={'key': private_key})
return render_to_response('nomcom/private_key.html',
{'nomcom': nomcom,
'year': year,
'back_url': back_url,
'form': form,
'private_key': private_key,
'selected': 'private_key'}, RequestContext(request))
@member_required(role='member')
def private_index(request, year):
nomcom = get_nomcom_by_year(year)

View file

@ -9,7 +9,8 @@
<div class="ietf-navset">
{% if selected == "index" %}<span class="selected">List of nominees</span>{% else %}<a href="{% url nomcom_private_index year %}">List of nominees</a>{% endif %} |
{% if selected == "nominate" %}<span class="selected">Nominate</span>{% else %}<a href="{% url nomcom_private_nominate year %}">Nominate</a>{% endif %} |
{% if user|is_chair:year %}
{% if selected == "private_key" %}<span class="selected">Private key</span>{% else %}<a href="{% url nomcom_private_key year %}">Private key</a>{% endif %}
{% if user|is_chair:year %} |
{% if selected == "merge" %}<span class="selected">Merge nominee email addr</span>{% else %}<a href="{% url nomcom_private_merge year %}">Merge nominee email addr</a>{% endif %} |
{% if selected == "edit_members" %}<span class="selected">Nomcom members</span>{% else %}<a href="{% url nomcom_edit_members year %}">Nomcom members</a>{% endif %} |
{% if selected == "edit_publickey" %}<span class="selected">Public key</span>{% else %}<a href="{% url nomcom_edit_publickey year %}">Public key</a>{% endif %} |

View file

@ -0,0 +1,19 @@
{% extends "nomcom/nomcom_private_base.html" %}
{% block subtitle %}- Enter private key{% endblock %}
{% block nomcom_content %}
<h2>Enter private key</h2>
<p>In order to access the {{ nomcom.group }} data you have to enter your private key. Please paste it in the text area below.</p>
<p>If you don't have a private key, please contact the group chair. You can leave the key empty and continue navigation without access to the encrypted data.</p>
<form enctype="multipart/form-data" action="" method="post">{% csrf_token %}
<table>
{{ form }}
</table>
<p><input type="submit" value="Enter key" /></p>
</form>
{% endblock %}