diff --git a/allauthdemo/polls/views.py b/allauthdemo/polls/views.py index cd0a48f..562a980 100755 --- a/allauthdemo/polls/views.py +++ b/allauthdemo/polls/views.py @@ -253,14 +253,16 @@ def event_trustee_setup(request, event_id): email_key = event.keys.filter(key=access_key) if email_key.exists() and event.users_trustees.filter(email=email_key[0].user.email).exists(): if TrusteeKey.objects.filter(event=event, user=email_key[0].user).exists(): - messages.add_message(request, messages.WARNING, 'You have already submitted your key for this event') - return HttpResponseRedirect(reverse("user_home")) + return render(request, "polls/event_setup.html", {"is_trustee": True, + "can_submit": False, + "access_denied_reason": "You have already submitted your public key for this event. Thank you!" + }) if request.method == "POST": form = EventSetupForm(request.POST) # If form data is valid, create a TrusteeKey object with the supplied public key if form.is_valid(): - public_key = request.POST["public_key"] + public_key = request.POST.get("public_key") key = TrusteeKey.objects.get_or_create(event=event, user=email_key[0].user)[0] key.key = public_key key.save() @@ -280,11 +282,18 @@ def event_trustee_setup(request, event_id): return HttpResponseRedirect(reverse("user_home")) else: form = EventSetupForm() - return render(request, "polls/event_setup.html", {"event": event, "form": form, "user_email": email_key[0].user.email}) + return render(request, "polls/event_setup.html", {"event": event, + "form": form, + "user_email": email_key[0].user.email, + "is_trustee": True, + "can_submit": True + }) - #if no key or is invalid? - messages.add_message(request, messages.WARNING, 'You do not have permission to access: ' + request.path) - return HttpResponseRedirect(reverse("user_home")) + else: + return render(request, "polls/event_setup.html", {"is_trustee": False, + "can_submit": False, + "access_denied_reason": "You do not have permission to access this page." + }) def event_end(request, event_id): @@ -311,11 +320,10 @@ def event_trustee_decrypt(request, event_id): if email_key.exists() and event.users_trustees.filter(email=trustee.email).exists(): if PartialBallotDecryption.objects.filter(event=event, user=trustee).count() == event.total_num_opts(): - - warning_msg = 'You have already provided your decryption key for this event - Thank You' - messages.add_message(request, messages.WARNING, warning_msg) - - return HttpResponseRedirect(reverse("user_home")) + return render(request, "polls/event_decrypt.html", {"is_trustee": True, + "can_submit": False, + "access_denied_reason": "You have already submitted your partial decryptions for this event. Thank you!" + }) elif request.method == "GET": # Get the Trustee's original PK - used in the template for SK validation trustee_pk = TrusteeKey.objects.get(event=event, user=trustee).key @@ -344,7 +352,9 @@ def event_trustee_decrypt(request, event_id): "event": event, "user_email": trustee.email, "trustee_pk": trustee_pk, - "poll_ciphers": poll_ciphers + "poll_ciphers": poll_ciphers, + "is_trustee": True, + "can_submit": True }) elif request.method == "POST": @@ -359,7 +369,7 @@ def event_trustee_decrypt(request, event_id): input_name = str("") input_name = "poll-" + str(i) + "-cipher-" + str(j) - part_dec = request.POST[input_name] + part_dec = request.POST.get(input_name) PartialBallotDecryption.objects.create(event=event, poll=polls[i], @@ -381,8 +391,10 @@ def event_trustee_decrypt(request, event_id): return HttpResponseRedirect(reverse("user_home")) # Without an access key, the client does not have permission to access this page - messages.add_message(request, messages.WARNING, 'You do not have permission to decrypt this Event.') - return HttpResponseRedirect(reverse("user_home")) + return render(request, "polls/event_decrypt.html", {"is_trustee": False, + "can_submit": False, + "access_denied_reason": "You don't have permission to access this page." + }) def manage_questions(request, event_id): diff --git a/allauthdemo/templates/bases/bootstrap-jquery.html b/allauthdemo/templates/bases/bootstrap-jquery.html index 59279ac..a4679ac 100755 --- a/allauthdemo/templates/bases/bootstrap-jquery.html +++ b/allauthdemo/templates/bases/bootstrap-jquery.html @@ -22,6 +22,7 @@ + @@ -66,73 +67,6 @@ } - function getBytes(arr) { - for(var i = 0; i < arr.length; i++) { - arr[i] = parseInt(arr[i]); - } - - return new Uint8Array(arr); - } - - //new function - demosEncrypt.decryptSubmitCiphers = function() { - - }; - - //new function - demosEncrypt.generateKeys = function() { - var parameter = $("#event-param").val(); - var tempParams = JSON.parse(JSON.parse(parameter).crypto); - //the full objects need to be initalised as per the library, then copy the values we need into it - //I follow Bingsheng's code as to what objects are used in the parameter object - var ctx = new CTX("BN254CX"); //new context we can use - var n = new ctx.BIG(); - var g1 = new ctx.ECP(); - var g2 = new ctx.ECP2(); - - //copying the values - n.copy(tempParams.n); - g1.copy(tempParams.g1); - g2.copy(tempParams.g2); - - var params = { - n:n, - g1:g1, - g2:g2 - } - - var PKbytes = []; - var SKbytes = []; - - var keypair = keyGen(params); - keypair.PK.toBytes(PKbytes); - keypair.SK.toBytes(SKbytes); - - var PKB64Encoded = ""; - for(let i = 0; i < PKbytes.length; i++) { - PKB64Encoded += btoa(PKbytes[i]); - } - - var SKB64Encoded = ""; - for(let j = 0; j < SKbytes.length; j++) { - SKB64Encoded += btoa(SKbytes[j]); - } - - $('input#public-key').val(PKB64Encoded); - $('input#secret-key').val(SKB64Encoded); - - //mostly code from before here - var blob = new Blob([SKB64Encoded], {type : 'text/plain'}); - - var dlBtn = $('a#download-btn'); - var url = URL.createObjectURL(blob); - var fileName = $(dlBtn).attr("href", url); - - $(dlBtn).attr("download", "sk-{% block sk-file-name %}{% endblock %}".replace(/[\W]/g, "-")); - $(dlBtn).attr("disabled", false); - $("#public-submit").attr("disabled", false); - } - //these other functions might not be used //I don't think this is used demosEncrypt.downloadSecretKey = function() { diff --git a/allauthdemo/templates/polls/event_decrypt.html b/allauthdemo/templates/polls/event_decrypt.html index 808011e..d2959ad 100755 --- a/allauthdemo/templates/polls/event_decrypt.html +++ b/allauthdemo/templates/polls/event_decrypt.html @@ -4,77 +4,86 @@ {% block sk-file-name %}{{ event.title|safe }}{% endblock %} {% block content %} - +{% if is_trustee and can_submit %} + + +
+

Trustee Event Decryption for Event '{{ event.title }}'

+
+
+
Upload your Secret Key as '{{ user_email }}'
+
+ + + +
- - -
-
-
Encrypted Event Data
-
-
- {% csrf_token %} - {% for opts_ciphers in poll_ciphers %} - {% for cipher in opts_ciphers %} - +
+
Encrypted Event Data
+
+ + {% csrf_token %} + {% for opts_ciphers in poll_ciphers %} + {% for cipher in opts_ciphers %} + +
+ {% endfor %}
{% endfor %} -
- {% endfor %} - - + + +
-
- - - - + + + +{% else %} +
+ +
+{% endif %} {% endblock %} diff --git a/allauthdemo/templates/polls/event_setup.html b/allauthdemo/templates/polls/event_setup.html index 81d4ce5..87be9f8 100755 --- a/allauthdemo/templates/polls/event_setup.html +++ b/allauthdemo/templates/polls/event_setup.html @@ -6,34 +6,66 @@ {% block content %} -
-

Trustee Event Setup for Event '{{ event.title }}'

-
-

Key Generation For: {{ user_email }}

-
-
-
Step 1: Generate and Download Your Secret Key
-
- - - -
-
Step 2: Submit Your Public Key
-
- {% load crispy_forms_tags %} -
- {% crispy form %} -

Ensure your secret key is backed up before submitting.

- -
+ + + -
-
+{% else %} +
+ +
+{% endif %} {% endblock %} diff --git a/static/js/decrypt_event.js b/static/js/decrypt_event.js index 5255fa7..1563d72 100644 --- a/static/js/decrypt_event.js +++ b/static/js/decrypt_event.js @@ -1,6 +1,7 @@ // -------------- Global vars -------------------- var filesHandleSK = document.getElementById('files_sk_upload'); var CSRF = $( "input[name='csrfmiddlewaretoken']" ).val(); +var partialDecryptions = {}; // -------------- Helper fns -------------------- //SK checking algorithm - If PK and SK matches, it returns True; otherwise, it returns false. @@ -15,6 +16,14 @@ function csrfSafeMethod(method) { return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } +function getBytes(arr) { + for(var i = 0; i < arr.length; i++) { + arr[i] = parseInt(arr[i]); + } + + return new Uint8Array(arr); +} + function getKeyBytes(key, byteArray) { for(let i = 0; i < key.length; i += 4) { let B64EncodedByte = key.substring(i, i + 4); @@ -23,8 +32,8 @@ function getKeyBytes(key, byteArray) { } } -function showDialog(titleTxt, bodyTxt) { - var modalDialog = $('#modalDialog'); +function showDecryptDialog(titleTxt, bodyTxt) { + var modalDialog = $('#EventDecryptionModalDialog'); var title = modalDialog.find('.modal-title'); var body = modalDialog.find('.modal-body'); @@ -79,7 +88,7 @@ function validateSKFromString(SKStr) { return skCheck(ctx, params, sk, pk); } -function decryptSubmitCiphers() { +function decryptSubmit() { var skString = $('#secret-key').val(); if (!skString) { @@ -96,7 +105,6 @@ function decryptSubmitCiphers() { inputs.each(function() { //for each ciphertext to decrypt let input = $(this); - console.log(input.attr('name')); var ciphertext = { C1: null, @@ -116,10 +124,38 @@ function decryptSubmitCiphers() { var bytes = []; partial.D.toBytes(bytes); input.val(bytes.toString()); + + partialDecryptions[input.attr('name')] = bytes.toString(); }); + + submitPartialDecryptions(); } } +function onAfterPartialDecryptionsSend() { + showDecryptDialog('Partial Decryptions Successfully Received', + 'Thank you! You can now close down this page.'); +} + +function submitPartialDecryptions() { + $.ajaxSetup({ + beforeSend: function(xhr, settings) { + if (!csrfSafeMethod(settings.type) && !this.crossDomain) { + xhr.setRequestHeader("X-CSRFToken", CSRF); + } + } + }); + + $.ajax({ + type : "POST", + url : window.location, + data : partialDecryptions, + success : function(){ + onAfterPartialDecryptionsSend(); + } + }); +} + function processFileSKChange(event) { var files = event.target.files; @@ -153,4 +189,9 @@ function processFileSKChange(event) { if(filesHandleSK) { filesHandleSK.addEventListener('change', processFileSKChange, false); -} \ No newline at end of file +} + +$('#EventDecryptionModalDialog').on('hide.bs.modal', function (e) { + // Update page to reflect the fact that the PK submission has taken place + location.reload(); +}); \ No newline at end of file diff --git a/static/js/event_setup.js b/static/js/event_setup.js new file mode 100644 index 0000000..c91ac2c --- /dev/null +++ b/static/js/event_setup.js @@ -0,0 +1,105 @@ +var CSRF = $( "input[name='csrfmiddlewaretoken']" ).val(); + +function csrfSafeMethod(method) { + // these HTTP methods do not require CSRF protection + return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); +} + +function showSetupDialog(titleTxt, bodyTxt) { + var modalDialog = $('#EventSetupModalDialog'); + var title = modalDialog.find('.modal-title'); + var body = modalDialog.find('.modal-body'); + + title.text(titleTxt); + var bodyText = bodyTxt; + + var p = document.createElement("p"); + p.innerHTML = bodyText; + body.empty(); + body.append( p ); + + modalDialog.modal('show'); +} + +function generateKeys() { + var parameter = $("#event-param").val(); + var tempParams = JSON.parse(JSON.parse(parameter).crypto); + //the full objects need to be initalised as per the library, then copy the values we need into it + //I follow Bingsheng's code as to what objects are used in the parameter object + var ctx = new CTX("BN254CX"); //new context we can use + var n = new ctx.BIG(); + var g1 = new ctx.ECP(); + var g2 = new ctx.ECP2(); + + //copying the values + n.copy(tempParams.n); + g1.copy(tempParams.g1); + g2.copy(tempParams.g2); + + var params = { + n:n, + g1:g1, + g2:g2 + } + + var PKbytes = []; + var SKbytes = []; + + var keypair = keyGen(params); + keypair.PK.toBytes(PKbytes); + keypair.SK.toBytes(SKbytes); + + var PKB64Encoded = ""; + for(let i = 0; i < PKbytes.length; i++) { + PKB64Encoded += btoa(PKbytes[i]); + } + + var SKB64Encoded = ""; + for(let j = 0; j < SKbytes.length; j++) { + SKB64Encoded += btoa(SKbytes[j]); + } + + $('input#public-key').val(PKB64Encoded); + $('input#secret-key').val(SKB64Encoded); + + //mostly code from before here + var blob = new Blob([SKB64Encoded], {type : 'text/plain'}); + + var dlBtn = $('a#download-btn'); + var url = URL.createObjectURL(blob); + $(dlBtn).attr("href", url); + + let fileName = "sk-" + EVENT_TITLE.replace(/[\W]/g, "-"); + $(dlBtn).attr("download", fileName); + $(dlBtn).attr("disabled", false); + $("#public-submit").attr("disabled", false); +} + +function onAfterKeySend() { + showSetupDialog('Public Key Successfully Received', + 'Thank you! You can now close down this page.'); +} + +function submitPublicKey() { + $.ajaxSetup({ + beforeSend: function(xhr, settings) { + if (!csrfSafeMethod(settings.type) && !this.crossDomain) { + xhr.setRequestHeader("X-CSRFToken", CSRF); + } + } + }); + + $.ajax({ + type : "POST", + url : window.location, + data : { public_key: $('input#public-key').val() }, + success : function(){ + onAfterKeySend(); + } + }); +} + +$('#EventSetupModalDialog').on('hide.bs.modal', function (e) { + // Update page to reflect the fact that the PK submission has taken place + location.reload(); +}); \ No newline at end of file