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


Reply via email to