Add support for Terms of Service documents

This allows for adding Terms of Service documents to the database that
registered users need to accept before using the AUR. A revision field
can be used to indicate whether a document was updated. If it is
increased, all users are again asked to accept the new terms.

Signed-off-by: Lukas Fleischer <lfleischer@archlinux.org>
This commit is contained in:
Lukas Fleischer 2017-04-27 09:24:11 +02:00
parent 6892ec7791
commit a8ac2004d3
6 changed files with 188 additions and 0 deletions

View file

@ -1325,3 +1325,77 @@ function notify($params) {
return proc_close($p);
}
/*
* Obtain a list of terms a given user has not yet accepted.
*
* @param int $uid The ID of the user to obtain terms for.
*
* @return array A list of terms the user has not yet accepted.
*/
function fetch_updated_terms($uid) {
$dbh = DB::connect();
$q = "SELECT ID, Terms.Revision, Description, URL ";
$q .= "FROM Terms LEFT JOIN AcceptedTerms ";
$q .= "ON AcceptedTerms.TermsID = Terms.ID ";
$q .= "AND AcceptedTerms.UsersID = " . intval($uid) . " ";
$q .= "WHERE AcceptedTerms.Revision IS NULL OR ";
$q .= "AcceptedTerms.Revision < Terms.Revision";
$result = $dbh->query($q);
if ($result) {
return $result->fetchAll();
} else {
return array();
}
}
/*
* Accept a list of given terms.
*
* @param int $uid The ID of the user to accept the terms.
* @param array $termrev An array mapping each term to the accepted revision.
*
* @return void
*/
function accept_terms($uid, $termrev) {
$dbh = DB::connect();
$q = "SELECT TermsID, Revision FROM AcceptedTerms ";
$q .= "WHERE UsersID = " . intval($uid);
$result = $dbh->query($q);
if (!$result) {
return;
}
$termrev_update = array();
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
$id = $row['TermsID'];
if (!array_key_exists($id, $termrev)) {
continue;
}
if ($row['Revision'] < $termrev[$id]) {
$termrev_update[$id] = $termrev[$id];
}
}
$termrev_add = array_diff_key($termrev, $termrev_update);
foreach ($termrev_add as $id => $rev) {
$q = "INSERT INTO AcceptedTerms (TermsID, UsersID, Revision) ";
$q .= "VALUES (" . intval($id) . ", " . intval($uid) . ", ";
$q .= intval($rev) . ")";
$dbh->exec($q);
}
foreach ($termrev_update as $id => $rev) {
$q = "UPDATE AcceptedTerms ";
$q .= "SET Revision = " . intval($rev) . " ";
$q .= "WHERE TermsID = " . intval($id) . " AND ";
$q .= "UsersID = " . intval($uid);
$dbh->exec($q);
}
}

View file

@ -22,6 +22,7 @@ include_once('timezone.inc.php');
set_tz();
check_sid();
check_tos();
/**
* Check if a visitor is logged in
@ -91,6 +92,28 @@ function check_sid() {
return;
}
/**
* Redirect user to the Terms of Service agreement if there are updated terms.
*
* @return void
*/
function check_tos() {
if (!isset($_COOKIE["AURSID"])) {
return;
}
$path = $_SERVER['PATH_INFO'];
$route = get_route($path);
if (!$route || $route == "tos.php") {
return;
}
if (count(fetch_updated_terms(uid_from_sid($_COOKIE["AURSID"]))) > 0) {
header('Location: ' . get_uri('/tos'));
exit();
}
}
/**
* Verify the supplied CSRF token matches expected token
*

View file

@ -16,6 +16,7 @@ $ROUTES = array(
'/passreset' => 'passreset.php',
'/rpc' => 'rpc.php',
'/rss' => 'rss.php',
'/tos' => 'tos.php',
'/tu' => 'tu.php',
'/addvote' => 'addvote.php',
);