You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@steve.apache.org by hu...@apache.org on 2015/03/24 12:36:26 UTC

svn commit: r1668848 - in /steve/trunk/pysteve: lib/election.py www/cgi-bin/rest_admin.py www/htdocs/admin/edit_election.html www/htdocs/css/steve_interactive.css www/htdocs/js/steve_rest.js

Author: humbedooh
Date: Tue Mar 24 11:36:26 2015
New Revision: 1668848

URL: http://svn.apache.org/r1668848
Log:
- Add checksums to issues
- Add feature for cuing monitors before an election starts
- Send checksums to monitors when an election has been closed.

Modified:
    steve/trunk/pysteve/lib/election.py
    steve/trunk/pysteve/www/cgi-bin/rest_admin.py
    steve/trunk/pysteve/www/htdocs/admin/edit_election.html
    steve/trunk/pysteve/www/htdocs/css/steve_interactive.css
    steve/trunk/pysteve/www/htdocs/js/steve_rest.js

Modified: steve/trunk/pysteve/lib/election.py
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/lib/election.py?rev=1668848&r1=1668847&r2=1668848&view=diff
==============================================================================
--- steve/trunk/pysteve/lib/election.py (original)
+++ steve/trunk/pysteve/lib/election.py Tue Mar 24 11:36:26 2015
@@ -69,10 +69,13 @@ def getIssue(electionID, issueID):
     issuepath = os.path.join(homedir, "issues", electionID, issueID) + ".json"
     issuedata = None
     if os.path.isfile(issuepath):
+        ihash = ""
         with open(issuepath, "r") as f:
             data = f.read()
+            ihash = hashlib.sha224(data).hexdigest()
             f.close()
             issuedata = json.loads(data)
+        issuedata['hash'] = ihash
         issuedata['id'] = issueID
         issuedata['APIURL'] = "https://%s/steve/voter/view/%s/%s" % (config.get("general", "rooturl"), electionID, issueID)
         issuedata['prettyURL'] = "https://%s/steve/ballot?%s/%s" % (config.get("general", "rooturl"), electionID, issueID)
@@ -144,6 +147,15 @@ def vote(electionID, issueID, voterID, v
     else:
         raise Exception("No such election")
 
+def getVotes(electionID, issueID):
+    issuepath = os.path.join(homedir, "issues", electionID, issueID) + ".json.votes"
+    if os.path.isfile(issuepath):
+        with open(issuepath, "r") as f:
+            votes = json.loads(f.read())
+            f.close()
+            return votes
+    else:
+        return {}
 
 def invalidate(issueData, vote):
     "Tries to invalidate a vote, returns why if succeeded, None otherwise"
@@ -316,4 +328,18 @@ def stv(candidates, votes, numseats, shu
         winnernames.append(candidates[i]['name'])
 
     # Return the data
-    return winners, winnernames, debug
\ No newline at end of file
+    return winners, winnernames, debug
+
+def getHash(electionID):
+    basedata = getBasedata(electionID)
+    issues = listIssues(electionID)
+    ihash = ""
+    output = []
+    for issue in issues:
+        issuedata = getIssue(electionID, issue)
+        votes = getVotes(electionID, issue)
+        ihash += issuedata['hash']
+        output.append("Issue #%s: %s\n- Checksum: %s\n- Votes cast: %u\n" % (issue, issuedata['title'], issuedata['hash'], len(votes)))
+    tothash = hashlib.sha224(ihash).hexdigest()
+    output.insert(0, ("The following data shows the state of the election data on disk. If any of these checksums change, especially the main checksum, then the election has been edited (rigged?) after invites were sent out.\n\nMain Election Checksum : %s\n\n" % tothash))
+    return tothash, "\n".join(output)

Modified: steve/trunk/pysteve/www/cgi-bin/rest_admin.py
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/cgi-bin/rest_admin.py?rev=1668848&r1=1668847&r2=1668848&view=diff
==============================================================================
--- steve/trunk/pysteve/www/cgi-bin/rest_admin.py (original)
+++ steve/trunk/pysteve/www/cgi-bin/rest_admin.py Tue Mar 24 11:36:26 2015
@@ -411,6 +411,20 @@ else:
             else:
                     response.respond(404, {'message': 'No such election or issue'})
         
+        # Send issue hash to monitors
+        elif action == "debug" and electionID:
+            if election.exists(electionID):
+                basedata = election.getBasedata(electionID)
+                if karma >= 4 or ('owner' in basedata and basedata['owner'] == whoami):
+                    ehash, debug = election.getHash(electionID)
+                    for email in basedata['monitors']:
+                        voter.email(email, "Monitoring update for election #%s" % electionID, debug)
+                    response.respond(200, {'message': "Debug sent to monitors", 'hash': ehash, 'debug': debug})
+                else:
+                    response.respond(403, {'message': "You do not have karma to do this"})
+            else:
+                    response.respond(404, {'message': 'No such election'})
+        
         # Get a temp voter ID for peeking
         elif action == "temp" and electionID:
             if electionID and election.exists(electionID):
@@ -499,6 +513,9 @@ else:
                         if reopen:
                             response.respond(200, {'message': "Election reopened"})
                         else:
+                            ehash, debug = election.getHash(electionID)
+                            for email in basedata['monitors']:
+                                voter.email(email, "Monitoring update for election #%s: Election closed!" % electionID, debug)
                             response.respond(200, {'message': "Election closed"})
                     except Exception as err:
                         response.respond(500, {'message': "Could not close election: %s" % err})

Modified: steve/trunk/pysteve/www/htdocs/admin/edit_election.html
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/htdocs/admin/edit_election.html?rev=1668848&r1=1668847&r2=1668848&view=diff
==============================================================================
--- steve/trunk/pysteve/www/htdocs/admin/edit_election.html (original)
+++ steve/trunk/pysteve/www/htdocs/admin/edit_election.html Tue Mar 24 11:36:26 2015
@@ -25,37 +25,43 @@
             <img style="vertical-align: middle;" src="/images/icon_invite.png"/>
             Invite people
         </a>
-        &nbsp; 
+        
         <a
            href="javascript:void(location.href='add_issue.html'+document.location.search);"
            class="btn-green" title="Click to add an issue to this election">
             <img style="vertical-align: middle;"  src="/images/icon_add.png"/>
             Add an issue
         </a>
-        &nbsp; 
+        
         <a id="closea" href="javascript:void(location.href='close.html'+document.location.search);"
            class="btn-red" title="Click to close this election, preventing further voting">
             <img style="vertical-align: middle;"  src="/images/icon_close.png"/>
             <span id="closex">Close election</span>
         </a>
-        &nbsp; 
+        
         <a href="javascript:void(location.href='edit_basedata.html'+document.location.search);"
            class="btn" title="Edit base data (title etc)">
             <img style="vertical-align: middle;"  src="/images/icon_edit.png"/>
-            Edit election base data
+            Edit base data
         </a>
-        &nbsp; 
+        
         <a href="javascript:void(peekAtElection());"
            class="btn-purple" title="Take a sneek peek at this election as viewed by voters">
             <img style="vertical-align: middle;"  src="/images/icon_view.png"/>
             View election
         </a>
-        &nbsp; 
+        
         <a href="javascript:void(location.href='tally.html'+document.location.search);"
            class="btn-black" title="Do a preliminary tally of all votes">
             <img style="vertical-align: middle;"  src="/images/icon_view.png"/>
             Tally votes
         </a>
+        
+        <a href="javascript:void(primeMonitors());"
+           class="btn-orange" title="Sends the election checksum to monitors. Use this right before you invite people to the election.">
+            <img style="vertical-align: middle;"  src="/images/icon_invite.png"/>
+            Cue monitors
+        </a>
         <br/>
 </fieldset>
 <form>

Modified: steve/trunk/pysteve/www/htdocs/css/steve_interactive.css
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/htdocs/css/steve_interactive.css?rev=1668848&r1=1668847&r2=1668848&view=diff
==============================================================================
--- steve/trunk/pysteve/www/htdocs/css/steve_interactive.css (original)
+++ steve/trunk/pysteve/www/htdocs/css/steve_interactive.css Tue Mar 24 11:36:26 2015
@@ -78,6 +78,28 @@ p {
   transition: 0.3s ease;
 }
 
+.btn-orange {
+  background: #C17E3F !important;
+  border: #C18E3F solid 1px;
+  border-radius: 3px;
+  color: #fff !important;
+  display: inline-block;
+  font-weight: bold;
+  font-size: 14px;
+  padding: 4px 8px;
+  text-decoration: none;
+  text-align: center;
+  min-width: 30px;
+  position: relative;
+  transition: color .1s ease;
+  cursor: pointer;
+  margin-left: 10px;
+}
+.btn-orange:hover {
+  background: #D19E3F !important;
+  transition: 0.3s ease;
+}
+
 .btn-black {
   background: #888888 !important;
   border: #aaaaaa solid 1px;

Modified: steve/trunk/pysteve/www/htdocs/js/steve_rest.js
URL: http://svn.apache.org/viewvc/steve/trunk/pysteve/www/htdocs/js/steve_rest.js?rev=1668848&r1=1668847&r2=1668848&view=diff
==============================================================================
--- steve/trunk/pysteve/www/htdocs/js/steve_rest.js (original)
+++ steve/trunk/pysteve/www/htdocs/js/steve_rest.js Tue Mar 24 11:36:26 2015
@@ -432,6 +432,7 @@ function renderEditBasedata(code, respon
 		obj.appendChild(keyvaluepair("id", "Election ID:", "text", election, true))
 		obj.appendChild(keyvaluepair("type", "Open election?:", "text", response.base_data.open, true))
 		obj.appendChild(keyvaluepair("etitle", "Election title:", "text", response.base_data.title))
+		obj.appendChild(keyvaluepair("etitle", "Monitors:", "text", response.base_data.monitors.join(", "), true))
 		obj.appendChild(document.createElement('hr'))
 		//obj.appendChild(keyvaluepair("description", "Description/statement:", "textarea", edit_i.description))
 		
@@ -939,4 +940,22 @@ function displayIssueYNA(code, response,
 		
 		obj.appendChild(outer)
 	}
+}
+
+
+
+function primeMonitorsCallback(code, response, election) {
+	alert(response.message)
+}
+function primeMonitors() {
+	var l = document.location.search.substr(1).split('/');
+	var election = l[0]
+	
+	
+	postREST("/steve/admin/debug/" + election, {
+		
+	},
+	undefined,
+	primeMonitorsCallback,
+	election)
 }
\ No newline at end of file