diff options
-rw-r--r-- | database.php | 82 | ||||
-rw-r--r-- | denied.php | 12 | ||||
-rw-r--r-- | index.php | 5 | ||||
-rw-r--r-- | motion.php | 211 | ||||
-rw-r--r-- | motions.php | 83 | ||||
-rw-r--r-- | proxy.php | 157 | ||||
-rw-r--r-- | styles.css | 28 | ||||
-rw-r--r-- | vote.php | 107 |
8 files changed, 685 insertions, 0 deletions
diff --git a/database.php b/database.php new file mode 100644 index 0000000..be20eb0 --- /dev/null +++ b/database.php @@ -0,0 +1,82 @@ +<?php + $board = "cacert-board@lists.cacert.org"; + class DB { + function __construct() { + $this->dbh = new PDO("sqlite:".dirname(__FILE__)."/database.sqlite"); + $this->statement = array(); + $this->statement['list decisions'] = $this->dbh->prepare("SELECT decisions.id, decisions.tag, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.quorum, decisions.majority, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id ORDER BY proposed DESC LIMIT 10 OFFSET 10 * (:page - 1);"); + $this->statement['closed decisions'] = $this->dbh->prepare("SELECT decisions.id, decisions.tag, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.quorum, decisions.majority, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.status=0 AND datetime('now','utc') > datetime(due);"); + $this->statement['get decision'] = $this->dbh->prepare("SELECT decisions.id, decisions.tag, decisions.proponent, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.quorum, decisions.majority, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.id=:decision;"); + $this->statement['get new decision'] = $this->dbh->prepare("SELECT decisions.id, decisions.tag, decisions.proponent, voters.name AS proposer, decisions.proposed, decisions.title, decisions.content, decisions.quorum, decisions.majority, decisions.status, decisions.due, decisions.modified, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=1) AS ayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=-1) AS nayes, (SELECT COUNT(*) FROM votes WHERE decision=decisions.id AND vote=0) AS abstains FROM decisions, voters WHERE decisions.proponent=voters.id AND decisions.id=last_insert_rowid();"); + $this->statement['get voter'] = $this->dbh->prepare("SELECT voters.id, voters.name FROM voters, emails WHERE voters.id=emails.voter AND emails.address=? AND voters.enabled=1"); + $this->statement['get voter by id'] = $this->dbh->prepare("SELECT voters.id, voters.name FROM voters WHERE id=:id;"); + $this->statement['get voters'] = $this->dbh->prepare("SELECT voters.id, voters.name FROM voters WHERE voters.enabled=1 ORDER BY name ASC;"); + $this->statement['del vote'] = $this->dbh->prepare("DELETE FROM votes WHERE decision=:decision AND voter=:voter;"); + $this->statement['do vote'] = $this->dbh->prepare("INSERT INTO votes (decision, voter, vote, voted, notes) VALUES (:decision, :voter, :vote, datetime('now','utc'), :notes);"); + $this->statement['stats'] = $this->dbh->prepare("SELECT (SELECT COUNT(*) FROM voters WHERE enabled=1) AS voters;"); + $this->statement['create decision'] = $this->dbh->prepare("INSERT INTO decisions (proposed, proponent, title, content, quorum, majority, status, due, modified) VALUES (datetime('now','utc'), :proponent, :title, :content, :quorum, :majority, 0, datetime('now','utc', :due), datetime('now','utc'));"); + $this->statement['post create'] = $this->dbh->prepare(" UPDATE decisions SET tag='m' || strftime('%Y%m%d','now') || '.' || id WHERE id=last_insert_rowid();"); + $this->statement['update decision'] = $this->dbh->prepare("UPDATE decisions SET proposed=datetime('now','utc'), proponent=:proponent, title=:title, content=:content, quorum=:quorum, majority=:majority, status=0, due=datetime('now','utc',:due), modified=datetime('now','utc') WHERE id=:id;"); + $this->statement['close decision'] = $this->dbh->prepare("UPDATE decisions SET status=:status, modified=datetime('now','utc') WHERE id=:decision"); + } + function getStatement($name) { + return $this->statement[$name]; + } + function closeVotes() { + $stmt = $this->getStatement("closed decisions"); + $upd = $this->getStatement("close decision"); + if ($stmt->execute()) { + while ($decision = $stmt->fetch()) { + $votes = $decision['ayes'] + $decision['nayes'] + $decision['abstains']; + if ($votes < $decision['quorum']) { + $decision['status'] = -1; + } else { + $votes = $decision['ayes'] + $decision['nayes']; + if (($decision['ayes'] / $votes) >= ($decision['majority'] / 100)) { + $decision['status'] = 1; + } else { + $decision['status'] = -1; + } + } + $upd->bindParam(":decision",$decision['id']); + $upd->bindParam(":status",$decision['status']); + $upd->execute(); + $state = $decision['status']==1?"accepted":"declined"; + $tag = $decision['tag']; + $title = $decision['title']; + $content = $decision['content']; + $quorum = $decision['quorum']; + $majority = $decision['majority']; + $ayes = $decision['ayes']; + $nayes = $decision['nayes']; + $abstains = $decision['abstains']; + $percent = $decision['ayes'] * 100 / $decision['ayes']+$decision['nayes']; + $body = <<<BODY +Dear Board, + +The motion with the identifier $tag has been $state. + +Motion: + $title + $content + +Votes: + Quorum: $quorum + Majority: $majority% + + Ayes: $ayes + Nayes: $nayes + Abstentions: $abstains + + Percentage: $percent% + +Kind regards, +the voting system. + +BODY; + mail($board,"Re: ".$decision['tag']." - ".$decision['title'],$body); + } + } + } + } +?>
\ No newline at end of file diff --git a/denied.php b/denied.php new file mode 100644 index 0000000..9bb72d6 --- /dev/null +++ b/denied.php @@ -0,0 +1,12 @@ +<html> + <head> + <title>CAcert Board Decisions</title> + <meta http-equiv="Content-Type" content="text/html; charset='UTF-8'" /> + <link rel="stylesheet" type="text/css" href="styles.css" /> + </head> + <body> + <b>You are not authorized to act here!</b><br/> + <i>If you think this is in error, please contact the administrator</i> + <i>If you don't know who that is, it is definitely not an error ;)</i> + </body> +</html>
\ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..3363496 --- /dev/null +++ b/index.php @@ -0,0 +1,5 @@ +<?php + header("HTTP/1.0 301 Redirect"); + header("Location: motions.php"); + exit(); +?>
\ No newline at end of file diff --git a/motion.php b/motion.php new file mode 100644 index 0000000..515e25c --- /dev/null +++ b/motion.php @@ -0,0 +1,211 @@ +<?php + if ($_SERVER['HTTPS'] != 'on') { + header("HTTP/1.0 302 Redirect"); + header("Location: https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); + exit(); + } + $user = $_SERVER['REMOTE_USER']; + require_once("database.php"); + $db = new DB(); + $stmt = $db->getStatement("get voter"); + $stmt->execute(array($user)); + if (!($user = $stmt->fetch())) { + header("HTTP/1.0 302 Redirect"); + header("Location: denied.php"); + exit(); + } + $db->getStatement("stats")->execute(); + $stats = $db->getStatement("stats")->fetch(); + function htmlesc($string) { + $string = preg_replace('/&/',"&",$string); + $string = preg_replace('/</',"<",$string); + $string = preg_replace('/>/',">",$string); + echo $string; + } +?> +<html> + <head> + <title>CAcert Board Decisions</title> + <meta http-equiv="Content-Type" content="text/html; charset='UTF-8'" /> + <link rel="stylesheet" type="text/css" href="styles.css" /> + </head> + <body> + <?php + if ($_REQUEST['action'] == "store") { + if (is_numeric($_REQUEST['motion'])) { + $stmt = $db->getStatement("update decision"); + $stmt->bindParam(":id",$_POST['motion']); + $stmt->bindParam(":proponent",$_POST['proponent']); + $stmt->bindParam(":title",$_POST['title']); + $stmt->bindParam(":content",$_POST['content']); + $stmt->bindParam(":quorum",$_POST['quorum']); + $stmt->bindParam(":majority",$_POST['majority']); + $stmt->bindParam(":due",$_POST['due']); + if ($stmt->execute()) { + ?> + <b>The motion has been proposed!</b><br/> + <a href="motions.php">Back to motions</a><br/> + <br/> + <br/> + <?php + $decision = $db->getStatement("get decision")->execute(array($_POST['motion']))?$db->getStatement("get decision")->fetch():array(); + $name = $user['name']; + $tag = $decision['tag']; + $title = $decision['title']; + $content =$decision['content']; + $due = $decision['due']." UTC"; + $quorum = $decision['quorum']; + $majority = $decision['majority']; + $voteurl = "https://".$_SERVER['HTTP_HOST'].":".$_SERVER['SERVER_PORT'].preg_replace('/motion\.php/','vote.php',$_SERVER['REQUEST_URI'])."?motion=".$decision['id']; + $body = <<<BODY +Dear Board, + +$name has modified motion $tag to the following: + +$title +$content + +To pass a minimum of $quorum votes and a $majority% acceptance will be required. +Voting will close $due. + +To vote please choose: + +Aye: $voteurl&vote=1 +Naye: $voteurl&vote=-1 +Abstain: $voteurl&vote=0 + +Please be aware, that if you have voted already your votr is still registered and valid. +If this modification has an impact on how you wish to vote, you are responsible for voting +again. + +Kind regards, +the voting system +BODY; + mail($board,"Re: $tag - $title",$body); + } else { + ?> + <b>The motion has NOT been proposed!</b><br/> + <a href="motions.php">Back to motions</a><br/> + <i><?php echo join("<br/>\n",$stmt->errorInfo()); ?></i><br/> + <br/> + <br/> + <?php + } + } else { + $stmt = $db->getStatement("create decision"); + $stmt->bindParam(":proponent",$_POST['proponent']); + $stmt->bindParam(":title",$_POST['title']); + $stmt->bindParam(":content",$_POST['content']); + $stmt->bindParam(":quorum",$_POST['quorum']); + $stmt->bindParam(":majority",$_POST['majority']); + $stmt->bindParam(":due",$_POST['due']); + if ($stmt->execute()) { + $db->getStatement("post create")->execute(); + ?> + <b>The motion has been proposed!</b><br/> + <a href="motions.php">Back to motions</a><br/> + <br/> + <br/> + <?php + $decision = $db->getStatement("get new decision")->execute()?$db->getStatement("get new decision")->fetch():array(); + $name = $user['name']; + $tag = $decision['tag']; + $title = $decision['title']; + $content =$decision['content']; + $due = $decision['due']." UTC"; + $quorum = $decision['quorum']; + $majority = $decision['majority']; + $voteurl = "https://".$_SERVER['HTTP_HOST'].":".$_SERVER['SERVER_PORT'].preg_replace('/motion\.php/','vote.php',$_SERVER['REQUEST_URI'])."?motion=".$decision['id']; + $body = <<<BODY +Dear Board, + +$name has made the following motion: + +$title +$content + +To pass a minimum of $quorum votes and a $majority% acceptance will be required. +Voting will close $due. + +To vote please choose: + +Aye: $voteurl&vote=1 +Naye: $voteurl&vote=-1 +Abstain: $voteurl&vote=0 + +Kind regards, +the voting system +BODY; + mail($board,"$tag - $title",$body); + } else { + ?> + <b>The motion has NOT been proposed!</b><br/> + <a href="motions.php">Back to motions</a><br/> + <i><?php echo join("<br/>\n",$stmt->errorInfo()); ?></i><br/> + <br/> + <br/> + <?php + } + } + + } + if (is_numeric($_REQUEST['motion'])) { + $stmt = $db->getStatement("get decision"); + if ($stmt->execute(array($_REQUEST['motion']))) { + $motion = $stmt->fetch(); + } + if (!is_numeric($motion['id'])) { + $motion = array(); + foreach (array("title","content","quorum","majority") as $column) { + $motion[$column] = ""; + } + $motion["proponent"] = $user['id']; + $motion["proposer"] = $user['name']; + } + } else { + $motion = array(); + foreach (array("title","content","quorum","majority") as $column) { + $motion[$column] = ""; + } + $motion["proponent"] = $user['id']; + $motion["proposer"] = $user['name']; + } + ?> + <form <?php if (is_numeric($_REQUEST['motion'])) { echo(" action=\"?\""); } ?> method="POST"> + <input type="hidden" name="action" value="store" /> + <?php + if (is_numeric($_REQUEST['motion'])) { + ?><input type="hidden" name="motion" value="<?php echo($_REQUEST["motion"]); ?>" /><?php + } + ?> + <table> + <tr><td>ID:</td><td><?php htmlesc($motion['tag']); ?></td></tr> + <tr><td>Proponent:</td><td><?php htmlesc($motion['proposer']); ?><input type="hidden" name="proponent" value="<?php htmlesc($user['id']); ?>"></td></tr> + <tr><td>Proposed:</td><td><?php htmlesc($motion['proposed']); ?> UTC</td></tr> + <tr><td>Title:</td><td><input name="title" value="<?php htmlesc($motion['title'])?>"></td></tr> + <tr><td>Text:</td><td><textarea name="content"><?php htmlesc($motion['content'])?></textarea></td></tr> + <tr><td>Quorum:</td><td><select name="quorum"> + <option value="<?php echo(ceil($stats["voters"])); ?>" <?php if($motion['quorum'] == $stats["voters"]) { echo(" selected=\"selected\""); } ?>>100% Votes (<?php echo($stats["voters"]); ?>)</option> + <option value="<?php echo(ceil($stats["voters"] / 2)); ?>" <?php if($motion['quorum'] == ceil($stats["voters"] / 2)) { echo(" selected=\"selected\""); } ?>>50% Votes (<?php echo(ceil($stats["voters"] / 2)); ?>)</option> + <option value="2" <?php if($motion['quorum'] == 2) { echo(" selected=\"selected\""); } ?>>2 Votes</option> + <option value="1" <?php if($motion['quorum'] == 1) { echo(" selected=\"selected\""); } ?>>1 Vote</option> + </select></td></tr> + <tr><td>Majority:</td><td><select name="majority"> + <option value="50" <?php if($motion['majority'] == 50) { echo(" selected=\"selected\""); } ?>>50%</option> + <option value="67" <?php if($motion['majority'] == 67) { echo(" selected=\"selected\""); } ?>>67%</option> + <option value="75" <?php if($motion['majority'] == 75) { echo(" selected=\"selected\""); } ?>>75%</option> + <option value="100" <?php if($motion['majority'] == 100) { echo(" selected=\"selected\""); } ?>>100%</option> + </td></tr> + <tr><td rowspan="2">Due:</td><td><?php echo($motion['due'])?> UTC</td></tr> + <tr><td><select name="due"> + <option value="+3 days">In 3 Days</option> + <option value="+7 days">In 1 Week</option> + <option value="+14 days">In 2 Weeks</option> + </select></td></tr> + <tr><td> </td><td><input type="submit" value="Propose" /></td></tr> + </table> + </form> + <br/> + <a href="motions.php">Back to motions</a> + </body> +</html> diff --git a/motions.php b/motions.php new file mode 100644 index 0000000..27d1632 --- /dev/null +++ b/motions.php @@ -0,0 +1,83 @@ +<?php + require_once("database.php"); + $db = new DB(); + $db->closeVotes(); + $page = is_numeric($_REQUEST['page'])?$_REQUEST['page']:1; +?> +<html> + <head> + <title>CAcert Board Decisions</title> + <meta http-equiv="Content-Type" content="text/html; charset='UTF-8'" /> + <link rel="stylesheet" type="text/css" href="styles.css" /> + </head> + <body> + <table class="list"> + <tr> + <th>Status</th> + <th>Motion</th> + <th>Actions</th> + </tr> + <?php + $stmt = $db->getStatement("list decisions"); + $stmt->execute(array($page)); + $items = 0; + while ($row = $stmt->fetch()) { + $items++; + ?><tr> + <td class="<?php switch($row['status']) { case 0: echo "pending"; break; case 1: echo "approved"; break; case -1: echo "declined"; break; }?>"> + <?php + switch($row['status']) { + case 0: echo "Pending<br/><i>".$row['due']." UTC</i>"; break; + case 1: echo "Approved<br/><i>".$row['modified']." UTC</i>"; break; + case -1: echo "Declined<br/><i>".$row['modified']." UTC</i>"; break; + } + ?> + </td> + <td> + <i><?php echo $row['tag'] ?></i><br/> + <b><?php echo $row['title']; ?></b><br/> + <pre><?php echo $row['content']; ?></pre> + <br/> + <i>Due: <?php echo($row['due']); ?> UTC</i><br/> + <i>Proposed: <?php echo($row['proposer']); ?> (<?php echo($row['proposed']); ?> UTC)</i><br/> + <i>Required Votes: <?php echo($row['quorum']); ?></i><br/> + <i>Majority: <?php echo($row['majority']); ?>%</i><br/> + <i>Aye|Naye|Abstain: <?php echo($row['ayes']); ?>|<?php echo($row['nayes']); ?>|<?php echo($row['abstains']); ?></i><br/> + </td><?php + ?><td class="actions"> + <?php + if ($row['status'] == 0) { + ?> + <ul> + <li><a href="vote.php?motion=<?php echo($row['id']); ?>&vote=1">Aye</a></li> + <li><a href="vote.php?motion=<?php echo($row['id']); ?>&vote=0">Abstain</a></li> + <li><a href="vote.php?motion=<?php echo($row['id']); ?>&vote=-1">Naye</a></li> + <li><a href="proxy.php?motion=<?php echo($row['id']); ?>">Proxy Vote</a></li> + <li><a href="motion.php?motion=<?php echo($row['id']); ?>">Modify</a></li> + </ul> + <?php + } else { + ?> + + <?php + } + ?> + </td> + </tr><?php + } + ?> + <tr> + <td colspan="2" class="navigation"> + <?php if ($page>1) { ?><a href="?page=<?php echo($page-1); ?>"><</a><?php } else { ?> <?php } ?> + + <?php if ($items>9) { ?><a href="?page=<?php echo($page+1); ?>">></a><?php } else { ?> <?php } ?> + </td> + <td class="actions"> + <ul> + <li><a href="motion.php">New Motion</a></li> + </ul> + </td> + </tr> + </table> + </body> +</html> diff --git a/proxy.php b/proxy.php new file mode 100644 index 0000000..77bcc89 --- /dev/null +++ b/proxy.php @@ -0,0 +1,157 @@ +<?php + if ($_SERVER['HTTPS'] != 'on') { + header("HTTP/1.0 302 Redirect"); + header("Location: https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); + exit(); + } + $user = $_SERVER['REMOTE_USER']; + require_once("database.php"); + $db = new DB(); + $stmt = $db->getStatement("get voter"); + $stmt->execute(array($user)); + if (!($user = $stmt->fetch())) { + header("HTTP/1.0 302 Redirect"); + header("Location: denied.php"); + exit(); + } +?> +<html> + <head> + <title>CAcert Board Decisions</title> + <meta http-equiv="Content-Type" content="text/html; charset='UTF-8'" /> + <link rel="stylesheet" type="text/css" href="styles.css" /> + </head> + <body> +<?php + if (!is_numeric($_REQUEST['motion'])) { +?> + <b>This is not a valid motion!</b><br/> + <a href="motions.php">Back to motions</a><br/> +<?php + } else { + $stmt = $db->getStatement("get decision"); + $stmt->bindParam(":decision",$_REQUEST['motion']); + if ($stmt->execute() && ($decision=$stmt->fetch()) && ($decision['status'] == 0)) { + if (is_numeric($_POST['voter']) && is_numeric($_POST['vote']) && is_numeric($_REQUEST['motion']) && ($_POST['justification'] != "")) { + $stmt = $db->getStatement("del vote"); + $stmt->bindParam(":voter",$_REQUEST['voter']); + $stmt->bindParam(":decision",$_REQUEST['motion']); + if ($stmt->execute()) { + $stmt = $db->getStatement("do vote"); + $stmt->bindParam(":voter",$_REQUEST['voter']); + $stmt->bindParam(":decision",$_REQUEST['motion']); + $stmt->bindParam(":vote",$_REQUEST['vote']); + $notes = "Proxy-Vote by ".$user['name']."\n\n".$_REQUEST['justification']."\n\n".$_SERVER['SSL_CLIENT_CERT']; + $stmt->bindParam(":notes",$notes); + if ($stmt->execute()) { + ?> + <b>The vote has been registered.</b><br/> + <a href="motions.php">Back to motions</a> + <?php + $stmt = $db->getStatement("get voter by id"); + $stmt->bindParam(":id",$_REQUEST['voter']); + if ($stmt->execute() && ($voter=$stmt->fetch())) { + $voter = $voter['name']; + } else { + $voter = "Voter: ".$_REQUEST['voter']; + } + $name = $user['name']; + $justification = $_REQUEST['justification']; + $vote = ''; + switch($_REQUEST['vote']) { + case 1 : $vote='Aye'; break; + case -1: $vote='Naye'; break; + default: $vote='Abstain'; break; + } + $tag = $decision['tag']; + $title = $decision['title']; + $content = $decision['content']; + $due = $decision['due']." UTC"; + $body = <<<BODY +Dear Board, + +$name has just registered a proxy vote of $vote for $voter on motion $tag. + +The justification for this was: +$justification + +Motion: +$title +$content + +Kind regards, +the vote system + +BODY; + mail($board,"Re: $tag - $title",$body); + } else { + ?> + <b>The vote has NOT been registered.</b><br/> + <a href="motions.php">Back to motions</a> + <i><?php echo join("<br/>\n",$stmt->errorInfo()); ?></i> + <?php + } + } else { + ?> + <b>The vote has NOT been registered.</b><br/> + <a href="motions.php">Back to motions</a> + <i><?php echo join("<br/>\n",$stmt->errorInfo()); ?></i> + <?php + } + } else { + $stmt = $db->getStatement("get voters"); + if ($stmt->execute() && ($voters = $stmt->fetchAll())) { +?> + <form method="POST" action="?motion=<?php echo($_REQUEST['motion']); ?>"> + <table> + <tr> + <th>Voter</th><th>Vote</th> + </tr> + <tr> + <td><select name="voter"><?php + foreach ($voters as $voter) { +?> + <option value="<?php echo($voter['id']); ?>"<?php if ($voter['id'] == $_POST['voter']) { echo(" selected=\"selected\""); } ?>><?php echo($voter['name']); ?></option> +<?php + } + ?></select></td> + <td><select name="vote"> + <option value="1"<?php if (1 == $_POST['voter']) { echo(" selected=\"selected\""); } ?>>Aye</option> + <option value="0"<?php if (0 == $_POST['voter']) { echo(" selected=\"selected\""); } ?>>Abstain</option> + <option value="-1"<?php if (-1 == $_POST['voter']) { echo(" selected=\"selected\""); } ?>>Naye</option> + </select></td> + </tr> + <tr> + <th colspan="2">Justification:</th> + </tr> + <tr> + <td colspan="2"><textarea name="justification"><?php echo($_POST['justification']); ?></textarea></td> + </tr> + <tr> + <td colspan="2"><input type="submit" value="Proxy Vote" /></td> + </tr> + </table> + </form> +<?php + } else { +?> + <b>Could not retrieve voters!</b><br/> + <a href="motions.php">Back to motions</a><br/> + <i><?php echo join("<br/>\n",$stmt->errorInfo()); ?></i> +<?php + } + } +?> + +<?php + } else { +?> + <b>This is not a valid motion!</b><br/> + <a href="motions.php">Back to motions</a><br/> + <i><?php echo join("<br/>\n",$stmt->errorInfo()); ?></i> +<?php + } + } +?> + </body> +</html> diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..0610148 --- /dev/null +++ b/styles.css @@ -0,0 +1,28 @@ +html, body, th, td { + font-family: Verdana, Arial, Sans-Serif; + font-size:10px; +} +table, tr, td, th { + vertical-align:top; + border:1px solid black; + border-collapse: collapse; +} +td.navigation { + text-align:center; +} +td.approved { + color:green; +} +td.declined { + color:red; +} +td.pending { + color:blue; +} +textarea { + width:400px; + height:150px; +} +input { + width:400px; +} diff --git a/vote.php b/vote.php new file mode 100644 index 0000000..b357cf1 --- /dev/null +++ b/vote.php @@ -0,0 +1,107 @@ +<?php + if ($_SERVER['HTTPS'] != 'on') { + header("HTTP/1.0 302 Redirect"); + header("Location: https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); + exit(); + } + $user = $_SERVER['REMOTE_USER']; + require_once("database.php"); + $db = new DB(); + $stmt = $db->getStatement("get voter"); + $stmt->execute(array($user)); + if (!($user = $stmt->fetch())) { + header("HTTP/1.0 302 Redirect"); + header("Location: denied.php"); + exit(); + } +?> +<html> + <head> + <title>CAcert Board Decisions</title> + <meta http-equiv="Content-Type" content="text/html; charset='UTF-8'" /> + <link rel="stylesheet" type="text/css" href="styles.css" /> + </head> + <body> + <?php + if (is_numeric($_REQUEST['motion']) && is_numeric($_REQUEST['vote'])) { + $stmt = $db->getStatement("get decision"); + $stmt->bindParam(":decision",$_REQUEST['motion']); + if ($stmt->execute() && ($decision=$stmt->fetch())) { + if ($decision['status'] == 0) { + $stmt = $db->getStatement("del vote"); + $stmt->bindParam(":voter",$user['id']); + $stmt->bindParam(":decision",$_REQUEST['motion']); + if ($stmt->execute()) { + $stmt = $db->getStatement("do vote"); + $stmt->bindParam(":voter",$user['id']); + $stmt->bindParam(":decision",$_REQUEST['motion']); + $stmt->bindParam(":vote",$_REQUEST['vote']); + $notes="Direct Vote\n\n".$_SERVER['SSL_CLIENT_CERT']; + $stmt->bindParam(":notes",$notes); + if ($stmt->execute()) { + ?> + <b>Your vote has been registered.</b><br/> + <a href="motions.php">Back to motions</a> + <?php + $name = $user['name']; + $vote = ''; + switch($_REQUEST['vote']) { + case 1 : $vote='Aye'; break; + case -1: $vote='Naye'; break; + default: $vote='Abstain'; break; + } + $tag = $decision['tag']; + $title = $decision['title']; + $content = $decision['content']; + $due = $decision['due']." UTC"; + $body = <<<BODY +Dear Board, + +$name has just voted $vote on motion $tag. + +Motion: + $title + $content + +Kind regards, +the vote system + +BODY; + mail($board,"Re: $tag - $title",$body); + } else { + ?> + <b>Your vote has NOT been registered.</b><br/> + <a href="motions.php">Back to motions</a> + <i><?php echo join("<br/>\n",$stmt->errorInfo()); ?></i> + <?php + } + } else { + ?> + <b>Your vote has NOT been registered.</b><br/> + <a href="motions.php">Back to motions</a> + <i><?php echo join("<br/>\n",$stmt->errorInfo()); ?></i> + <?php + } + } else { + ?> + <b>Your vote has NOT been registered.</b><br/> + <b>Voting is alread closed!</b><br/> + <a href="motions.php">Back to motions</a> + <?php + } + } else { + ?> + <b>Your vote has NOT been registered.</b><br/> + <b>Could not find the motion to be voted!</b><br/> + <a href="motions.php">Back to motions</a> + <?php + } + } else { + ?> + <b>This call is not a valid vote!</b><br/> + <a href="motions.php">Back to motions</a> + <?php + } + ?> + </body> +</html>
\ No newline at end of file |