Commit a8ac2004 authored by Lukas Fleischer's avatar Lukas Fleischer
Browse files

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's avatarLukas Fleischer <lfleischer@archlinux.org>
parent 6892ec77
......@@ -379,3 +379,23 @@ CREATE TABLE Bans (
BanTS TIMESTAMP NOT NULL,
PRIMARY KEY (IPAddress)
) ENGINE = InnoDB;
-- Terms and Conditions
--
CREATE TABLE Terms (
ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
Description VARCHAR(255) NOT NULL,
URL VARCHAR(8000) NOT NULL,
Revision INTEGER UNSIGNED NOT NULL DEFAULT 1,
PRIMARY KEY (ID)
) ENGINE = InnoDB;
-- Terms and Conditions accepted by users
--
CREATE TABLE AcceptedTerms (
UsersID INTEGER UNSIGNED NOT NULL,
TermsID INTEGER UNSIGNED NOT NULL,
Revision INTEGER UNSIGNED NOT NULL DEFAULT 0,
FOREIGN KEY (UsersID) REFERENCES Users(ID) ON DELETE CASCADE,
FOREIGN KEY (TermsID) REFERENCES Terms(ID) ON DELETE CASCADE
) ENGINE = InnoDB;
......@@ -15,3 +15,23 @@ UPDATE PackageDepends
---
ALTER TABLE PackageComments ADD COLUMN RenderedComment TEXT NOT NULL;
---
3. Add Terms and AcceptedTerms tables:
---
CREATE TABLE Terms (
ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
Description VARCHAR(255) NOT NULL,
URL VARCHAR(8000) NOT NULL,
Revision INTEGER UNSIGNED NOT NULL DEFAULT 1,
PRIMARY KEY (ID)
) ENGINE = InnoDB;
CREATE TABLE AcceptedTerms (
UsersID INTEGER UNSIGNED NOT NULL,
TermsID INTEGER UNSIGNED NOT NULL,
Revision INTEGER UNSIGNED NOT NULL DEFAULT 0,
FOREIGN KEY (UsersID) REFERENCES Users(ID) ON DELETE CASCADE,
FOREIGN KEY (TermsID) REFERENCES Terms(ID) ON DELETE CASCADE
) ENGINE = InnoDB;
---
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . '../lib');
include_once("aur.inc.php");
$uid = uid_from_sid($_COOKIE["AURSID"]);
if (isset($_POST["accept"]) && $_POST["accept"]) {
accept_terms($uid, $_POST["rev"]);
header("Location: " . get_uri('/'));
}
$terms = fetch_updated_terms($uid);
if (!$terms) {
header("Location: " . get_uri('/'));
}
html_header('AUR ' . __("Terms of Service"));
?>
<div id="dev-login" class="box">
<h2>AUR <?= __('Terms of Service') ?></h2>
<?php if (isset($_COOKIE["AURSID"])): ?>
<form method="post" action="<?= get_uri('/tos') ?>">
<fieldset>
<p>
<?= __("Logged-in as: %s", '<strong>' . username_from_sid($_COOKIE["AURSID"]) . '</strong>'); ?>
</p>
<p>
<?= __("The following documents have been updated. Please review them carefully:"); ?>
</p>
<ul>
<?php foreach($terms as $row): ?>
<li><a href="<?= htmlspecialchars(sprintf($row["URL"], $row["Revision"]), ENT_QUOTES) ?>"><?= htmlspecialchars($row["Description"]) ?></a> (<?= __('revision %d', $row["Revision"]) ?>)</li>
<?php endforeach; ?>
</ul>
<p>
<?php foreach($terms as $row): ?>
<input type="hidden" name="rev[<?= $row["ID"] ?>]" value="<?= $row["Revision"] ?>" />
<?php endforeach; ?>
<input type="checkbox" name="accept" /> <?= __("I accept the terms and conditions above."); ?>
</p>
<p>
<input type="submit" name="submit" value="<?= __("Continue") ?>" />
</p>
</fieldset>
</form>
<?php endif; ?>
</div>
<?php
html_footer(AURWEB_VERSION);
......@@ -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);
}
}
......@@ -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
*
......
......@@ -16,6 +16,7 @@ $ROUTES = array(
'/passreset' => 'passreset.php',
'/rpc' => 'rpc.php',
'/rss' => 'rss.php',
'/tos' => 'tos.php',
'/tu' => 'tu.php',
'/addvote' => 'addvote.php',
);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment