summaryrefslogtreecommitdiffstats
path: root/web/lib
diff options
context:
space:
mode:
authorLukas Fleischer <lfleischer@archlinux.org>2017-02-26 10:30:16 +0100
committerLukas Fleischer <lfleischer@archlinux.org>2017-02-26 10:30:16 +0100
commit69f7eb115a0a48d4d2808708bcfef9eaf292f64c (patch)
treee8e4ac633b88099b6836ba3f637b0ab2b1d6a472 /web/lib
parentfdd932ff8d5e5899cfeae9a8b29011fa2cf9d439 (diff)
parent5fd417d70154470d145c83a4b60693c8d877b016 (diff)
downloadaur-69f7eb115a0a48d4d2808708bcfef9eaf292f64c.tar.gz
aur-69f7eb115a0a48d4d2808708bcfef9eaf292f64c.tar.xz
Merge branch 'master' into maint
Diffstat (limited to 'web/lib')
-rw-r--r--web/lib/DB.class.php24
-rw-r--r--web/lib/acctfuncs.inc.php190
-rw-r--r--web/lib/aur.inc.php64
-rw-r--r--web/lib/aurjson.class.php4
-rw-r--r--web/lib/confparser.inc.php6
-rw-r--r--web/lib/pkgbasefuncs.inc.php20
-rw-r--r--web/lib/pkgfuncs.inc.php152
-rw-r--r--web/lib/pkgreqfuncs.inc.php22
-rw-r--r--web/lib/timezone.inc.php60
-rw-r--r--web/lib/translator.inc.php2
-rw-r--r--web/lib/version.inc.php2
11 files changed, 280 insertions, 266 deletions
diff --git a/web/lib/DB.class.php b/web/lib/DB.class.php
index b538e0d3..dfdbbf96 100644
--- a/web/lib/DB.class.php
+++ b/web/lib/DB.class.php
@@ -17,20 +17,30 @@ class DB {
public static function connect() {
if (self::$dbh === null) {
try {
- $dsn_prefix = config_get('database', 'dsn_prefix');
+ $backend = config_get('database', 'backend');
$host = config_get('database', 'host');
$socket = config_get('database', 'socket');
$name = config_get('database', 'name');
$user = config_get('database', 'user');
$password = config_get('database', 'password');
- $dsn = $dsn_prefix .
- ':host=' . $host .
- ';unix_socket=' . $socket .
- ';dbname=' . $name;
+ if ($backend == "mysql") {
+ $dsn = $backend .
+ ':host=' . $host .
+ ';unix_socket=' . $socket .
+ ';dbname=' . $name;
+
+ self::$dbh = new PDO($dsn, $user, $password);
+ self::$dbh->exec("SET NAMES 'utf8' COLLATE 'utf8_general_ci';");
+ } else if ($backend == "sqlite") {
+ $dsn = $backend .
+ ":" . $name;
+
+ self::$dbh = new PDO($dsn, null, null);
+ } else {
+ die("Error - " . $backend . " is not supported by aurweb");
+ }
- self::$dbh = new PDO($dsn, $user, $password);
- self::$dbh->exec("SET NAMES 'utf8' COLLATE 'utf8_general_ci';");
} catch (PDOException $e) {
die('Error - Could not connect to AUR database');
}
diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php
index 172b9621..d0a7ff94 100644
--- a/web/lib/acctfuncs.inc.php
+++ b/web/lib/acctfuncs.inc.php
@@ -1,5 +1,4 @@
<?php
-
/**
* Determine if an HTTP request variable is set
*
@@ -52,6 +51,7 @@ function html_format_pgp_fingerprint($fingerprint) {
* @param string $C The confirmed password value of the displayed user
* @param string $R The real name of the displayed user
* @param string $L The language preference of the displayed user
+ * @param string $TZ The timezone preference of the displayed user
* @param string $HP The homepage of the displayed user
* @param string $I The IRC nickname of the displayed user
* @param string $K The PGP key fingerprint of the displayed user
@@ -66,9 +66,13 @@ function html_format_pgp_fingerprint($fingerprint) {
* @return void
*/
function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R="",
- $L="",$HP="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="") {
+ $L="",$TZ="",$HP="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="") {
global $SUPPORTED_LANGS;
+ if ($TZ == "") {
+ $TZ = config_get("options", "default_timezone");
+ }
+
include("account_edit_form.php");
return;
}
@@ -88,6 +92,7 @@ function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R=""
* @param string $C The confirmed password for the user
* @param string $R The real name of the user
* @param string $L The language preference of the user
+ * @param string $TZ The timezone preference of the user
* @param string $HP The homepage of the displayed user
* @param string $I The IRC nickname of the user
* @param string $K The PGP fingerprint of the user
@@ -102,7 +107,7 @@ function display_account_form($A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",$R=""
* @return array Boolean indicating success and message to be printed
*/
function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C="",
- $R="",$L="",$HP="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="") {
+ $R="",$L="",$TZ="",$HP="",$I="",$K="",$PK="",$J="",$CN="",$UN="",$ON="",$UID=0,$N="") {
global $SUPPORTED_LANGS;
$error = '';
@@ -200,6 +205,9 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C=""
if (!$error && !array_key_exists($L, $SUPPORTED_LANGS)) {
$error = __("Language is not currently supported.");
}
+ if (!$error && !array_key_exists($TZ, generate_timezone_list())) {
+ $error = __("Timezone is not currently supported.");
+ }
if (!$error) {
/*
* Check whether the user name is available.
@@ -264,13 +272,12 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C=""
if ($TYPE == "new") {
/* Create an unprivileged user. */
- $salt = generate_salt();
if (empty($P)) {
$send_resetkey = true;
$email = $E;
} else {
$send_resetkey = false;
- $P = salted_hash($P, $salt);
+ $P = password_hash($P, PASSWORD_DEFAULT);
}
$U = $dbh->quote($U);
$E = $dbh->quote($E);
@@ -278,13 +285,14 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C=""
$salt = $dbh->quote($salt);
$R = $dbh->quote($R);
$L = $dbh->quote($L);
+ $TZ = $dbh->quote($TZ);
$HP = $dbh->quote($HP);
$I = $dbh->quote($I);
$K = $dbh->quote(str_replace(" ", "", $K));
$q = "INSERT INTO Users (AccountTypeID, Suspended, ";
- $q.= "InactivityTS, Username, Email, Passwd, Salt, ";
- $q.= "RealName, LangPreference, Homepage, IRCNick, PGPKey) ";
- $q.= "VALUES (1, 0, 0, $U, $E, $P, $salt, $R, $L, ";
+ $q.= "InactivityTS, Username, Email, Passwd , ";
+ $q.= "RealName, LangPreference, Timezone, Homepage, IRCNick, PGPKey) ";
+ $q.= "VALUES (1, 0, 0, $U, $E, $P, $R, $L, $TZ ";
$q.= "$HP, $I, $K)";
$result = $dbh->exec($q);
if (!$result) {
@@ -341,12 +349,12 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C=""
$q.= ", HideEmail = 0";
}
if ($P) {
- $salt = generate_salt();
- $hash = salted_hash($P, $salt);
- $q .= ", Passwd = '$hash', Salt = '$salt'";
+ $hash = password_hash($P, PASSWORD_DEFAULT);
+ $q .= ", Passwd = " . $dbh->quote($hash);
}
$q.= ", RealName = " . $dbh->quote($R);
$q.= ", LangPreference = " . $dbh->quote($L);
+ $q.= ", Timezone = " . $dbh->quote($TZ);
$q.= ", Homepage = " . $dbh->quote($HP);
$q.= ", IRCNick = " . $dbh->quote($I);
$q.= ", PGPKey = " . $dbh->quote(str_replace(" ", "", $K));
@@ -359,6 +367,20 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$H="",$P="",$C=""
$ssh_key_result = account_set_ssh_keys($UID, $ssh_keys, $ssh_fingerprints);
+ if (isset($_COOKIE["AURTZ"]) && ($_COOKIE["AURTZ"] != $TZ)) {
+ /* set new cookie for timezone */
+ $timeout = intval(config_get("options", "persistent_cookie_timeout"));
+ $cookie_time = time() + $timeout;
+ setcookie("AURTZ", $TZ, $cookie_time, "/");
+ }
+
+ if (isset($_COOKIE["AURLANG"]) && ($_COOKIE["AURLANG"] != $L)) {
+ /* set new cookie for language */
+ $timeout = intval(config_get("options", "persistent_cookie_timeout"));
+ $cookie_time = time() + $timeout;
+ setcookie("AURLANG", $L, $cookie_time, "/");
+ }
+
if ($result === false || $ssh_key_result === false) {
$message = __("No changes were made to the account, %s%s%s.",
"<strong>", htmlspecialchars($U,ENT_QUOTES), "</strong>");
@@ -504,19 +526,24 @@ function try_login() {
if (user_suspended($userID)) {
$login_error = __('Account suspended');
return array('SID' => '', 'error' => $login_error);
- } elseif (passwd_is_empty($userID)) {
- $login_error = __('Your password has been reset. ' .
- 'If you just created a new account, please ' .
- 'use the link from the confirmation email ' .
- 'to set an initial password. Otherwise, ' .
- 'please request a reset key on the %s' .
- 'Password Reset%s page.', '<a href="' .
- htmlspecialchars(get_uri('/passreset')) . '">',
- '</a>');
- return array('SID' => '', 'error' => $login_error);
- } elseif (!valid_passwd($userID, $_REQUEST['passwd'])) {
- $login_error = __("Bad username or password.");
- return array('SID' => '', 'error' => $login_error);
+ }
+
+ switch (check_passwd($userID, $_REQUEST['passwd'])) {
+ case -1:
+ $login_error = __('Your password has been reset. ' .
+ 'If you just created a new account, please ' .
+ 'use the link from the confirmation email ' .
+ 'to set an initial password. Otherwise, ' .
+ 'please request a reset key on the %s' .
+ 'Password Reset%s page.', '<a href="' .
+ htmlspecialchars(get_uri('/passreset')) . '">',
+ '</a>');
+ return array('SID' => '', 'error' => $login_error);
+ case 0:
+ $login_error = __("Bad username or password.");
+ return array('SID' => '', 'error' => $login_error);
+ case 1:
+ break;
}
$logged_in = 0;
@@ -543,7 +570,7 @@ function try_login() {
$new_sid = new_sid();
$q = "INSERT INTO Sessions (UsersID, SessionID, LastUpdateTS)"
- ." VALUES (" . $userID . ", '" . $new_sid . "', UNIX_TIMESTAMP())";
+ ." VALUES (" . $userID . ", '" . $new_sid . "', " . strval(time()) . ")";
$result = $dbh->exec($q);
/* Query will fail if $new_sid is not unique. */
@@ -560,7 +587,7 @@ function try_login() {
return array('SID' => $new_sid, 'error' => $login_error);
}
- $q = "UPDATE Users SET LastLogin = UNIX_TIMESTAMP(), ";
+ $q = "UPDATE Users SET LastLogin = " . strval(time()) . ", ";
$q.= "LastLoginIPAddress = " . $dbh->quote($_SERVER['REMOTE_ADDR']) . " ";
$q.= "WHERE ID = $userID";
$dbh->exec($q);
@@ -597,7 +624,7 @@ function try_login() {
function is_ipbanned() {
$dbh = DB::connect();
- $q = "SELECT * FROM Bans WHERE IPAddress = " . $dbh->quote(ip2long($_SERVER['REMOTE_ADDR']));
+ $q = "SELECT * FROM Bans WHERE IPAddress = " . $dbh->quote($_SERVER['REMOTE_ADDR']);
$result = $dbh->query($q);
return ($result->fetchColumn() ? true : false);
@@ -638,7 +665,7 @@ function valid_username($user) {
function open_user_proposals($user) {
$dbh = DB::connect();
$q = "SELECT * FROM TU_VoteInfo WHERE User = " . $dbh->quote($user) . " ";
- $q.= "AND End > UNIX_TIMESTAMP()";
+ $q.= "AND End > " . strval(time());
$result = $dbh->query($q);
return ($result->fetchColumn() ? true : false);
@@ -665,7 +692,7 @@ function add_tu_proposal($agenda, $user, $votelength, $quorum, $submitteruid) {
$q = "INSERT INTO TU_VoteInfo (Agenda, User, Submitted, End, Quorum, ";
$q.= "SubmitterID, ActiveTUs) VALUES ";
$q.= "(" . $dbh->quote($agenda) . ", " . $dbh->quote($user) . ", ";
- $q.= "UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + " . $dbh->quote($votelength);
+ $q.= strval(time()) . ", " . strval(time()) . " + " . $dbh->quote($votelength);
$q.= ", " . $dbh->quote($quorum) . ", " . $submitteruid . ", ";
$q.= $active_tus . ")";
$result = $dbh->exec($q);
@@ -712,18 +739,18 @@ function send_resetkey($email, $welcome=false) {
/**
* Change a user's password in the database if reset key and e-mail are correct
*
- * @param string $hash New MD5 hash of a user's password
- * @param string $salt New salt for the user's password
+ * @param string $password The new password
* @param string $resetkey Code e-mailed to a user to reset a password
* @param string $email E-mail address of the user resetting their password
*
* @return string|void Redirect page if successful, otherwise return error message
*/
-function password_reset($hash, $salt, $resetkey, $email) {
+function password_reset($password, $resetkey, $email) {
+ $hash = password_hash($password, PASSWORD_DEFAULT);
+
$dbh = DB::connect();
- $q = "UPDATE Users ";
- $q.= "SET Passwd = '$hash', ";
- $q.= "Salt = '$salt', ";
+ $q = "UPDATE Users SET ";
+ $q.= "Passwd = " . $dbh->quote($hash) . ", ";
$q.= "ResetKey = '' ";
$q.= "WHERE ResetKey != '' ";
$q.= "AND ResetKey = " . $dbh->quote($resetkey) . " ";
@@ -754,75 +781,48 @@ function good_passwd($passwd) {
/**
* Determine if the password is correct and salt it if it hasn't been already
*
- * @param string $userID The user ID to check the password against
+ * @param int $user_id The user ID to check the password against
* @param string $passwd The password the visitor sent
*
- * @return bool True if password was correct and properly salted, otherwise false
+ * @return int Positive if password is correct, negative if password is unset
*/
-function valid_passwd($userID, $passwd) {
+function check_passwd($user_id, $passwd) {
$dbh = DB::connect();
- if ($passwd == "") {
- return false;
- }
-
- /* Get salt for this user. */
- $salt = get_salt($userID);
- if ($salt) {
- $q = "SELECT ID FROM Users ";
- $q.= "WHERE ID = " . $userID . " ";
- $q.= "AND Passwd = " . $dbh->quote(salted_hash($passwd, $salt));
- $result = $dbh->query($q);
- if (!$result) {
- return false;
- }
-
- $row = $result->fetch(PDO::FETCH_NUM);
- return ($row[0] > 0);
- } else {
- /* Check password without using salt. */
- $q = "SELECT ID FROM Users ";
- $q.= "WHERE ID = " . $userID . " ";
- $q.= "AND Passwd = " . $dbh->quote(md5($passwd));
- $result = $dbh->query($q);
- if (!$result) {
- return false;
- }
- $row = $result->fetch(PDO::FETCH_NUM);
- if (!$row[0]) {
- return false;
- }
+ /* Get password hash and salt. */
+ $q = "SELECT Passwd, Salt FROM Users WHERE ID = " . intval($user_id);
+ $result = $dbh->query($q);
+ if (!$result) {
+ return 0;
+ }
+ $row = $result->fetch(PDO::FETCH_ASSOC);
+ if (!$row) {
+ return 0;
+ }
+ $hash = $row['Passwd'];
+ $salt = $row['Salt'];
+ if (!$hash) {
+ return -1;
+ }
- /* Password correct, but salt it first! */
- if (!save_salt($userID, $passwd)) {
- trigger_error("Unable to salt user's password;" .
- " ID " . $userID, E_USER_WARNING);
- return false;
+ /* Verify the password hash. */
+ if (!password_verify($passwd, $hash)) {
+ /* Invalid password, fall back to MD5. */
+ if (md5($salt . $passwd) != $hash) {
+ return 0;
}
-
- return true;
}
-}
-/**
- * Determine if a user's password is empty
- *
- * @param string $uid The user ID to check for an empty password
- *
- * @return bool True if the user's password is empty, otherwise false
- */
-function passwd_is_empty($uid) {
- $dbh = DB::connect();
-
- $q = "SELECT * FROM Users WHERE ID = " . $dbh->quote($uid) . " ";
- $q .= "AND Passwd = " . $dbh->quote('');
- $result = $dbh->query($q);
+ /* Password correct, migrate the hash if necessary. */
+ if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
+ $hash = password_hash($passwd, PASSWORD_DEFAULT);
- if ($result->fetchColumn()) {
- return true;
- } else {
- return false;
+ $q = "UPDATE Users SET Passwd = " . $dbh->quote($hash) . " ";
+ $q.= "WHERE ID = " . intval($user_id);
+ $dbh->query($q);
}
+
+ return 1;
}
/**
@@ -978,7 +978,7 @@ function clear_expired_sessions() {
$dbh = DB::connect();
$timeout = config_get_int('options', 'login_timeout');
- $q = "DELETE FROM Sessions WHERE LastUpdateTS < (UNIX_TIMESTAMP() - " . $timeout . ")";
+ $q = "DELETE FROM Sessions WHERE LastUpdateTS < (" . strval(time()) . " - " . $timeout . ")";
$dbh->query($q);
return;
@@ -1086,7 +1086,7 @@ function last_votes_list() {
$q = "SELECT UserID, MAX(VoteID) AS LastVote FROM TU_Votes, ";
$q .= "TU_VoteInfo, Users WHERE TU_VoteInfo.ID = TU_Votes.VoteID AND ";
- $q .= "TU_VoteInfo.End < UNIX_TIMESTAMP() AND ";
+ $q .= "TU_VoteInfo.End < " . strval(time()) . " AND ";
$q .= "Users.ID = TU_Votes.UserID AND (Users.AccountTypeID = 2 OR Users.AccountTypeID = 4) ";
$q .= "GROUP BY UserID ORDER BY LastVote DESC, UserName ASC";
$result = $dbh->query($q);
diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php
index 9015ae8f..d58df406 100644
--- a/web/lib/aur.inc.php
+++ b/web/lib/aur.inc.php
@@ -18,6 +18,9 @@ include_once("cachefuncs.inc.php");
include_once("confparser.inc.php");
include_once("credentials.inc.php");
+include_once('timezone.inc.php');
+set_tz();
+
/**
* Check if a visitor is logged in
*
@@ -38,7 +41,7 @@ function check_sid() {
# the visitor is logged in, try and update the session
#
$dbh = DB::connect();
- $q = "SELECT LastUpdateTS, UNIX_TIMESTAMP() FROM Sessions ";
+ $q = "SELECT LastUpdateTS, " . strval(time()) . " FROM Sessions ";
$q.= "WHERE SessionID = " . $dbh->quote($_COOKIE["AURSID"]);
$result = $dbh->query($q);
$row = $result->fetch(PDO::FETCH_NUM);
@@ -77,7 +80,7 @@ function check_sid() {
# This keeps 'remembered' sessions from being
# overwritten.
if ($last_update < time() + $timeout) {
- $q = "UPDATE Sessions SET LastUpdateTS = UNIX_TIMESTAMP() ";
+ $q = "UPDATE Sessions SET LastUpdateTS = " . strval(time()) . " ";
$q.= "WHERE SessionID = " . $dbh->quote($_COOKIE["AURSID"]);
$dbh->exec($q);
}
@@ -535,63 +538,6 @@ function mkurl($append) {
}
/**
- * Determine a user's salt from the database
- *
- * @param string $user_id The user ID of the user trying to log in
- *
- * @return string|void Return the salt for the requested user, otherwise void
- */
-function get_salt($user_id) {
- $dbh = DB::connect();
- $q = "SELECT Salt FROM Users WHERE ID = " . $user_id;
- $result = $dbh->query($q);
- if ($result) {
- $row = $result->fetch(PDO::FETCH_NUM);
- return $row[0];
- }
- return;
-}
-
-/**
- * Save a user's salted password in the database
- *
- * @param string $user_id The user ID of the user who is salting their password
- * @param string $passwd The password of the user logging in
- */
-function save_salt($user_id, $passwd) {
- $dbh = DB::connect();
- $salt = generate_salt();
- $hash = salted_hash($passwd, $salt);
- $q = "UPDATE Users SET Salt = " . $dbh->quote($salt) . ", ";
- $q.= "Passwd = " . $dbh->quote($hash) . " WHERE ID = " . $user_id;
- return $dbh->exec($q);
-}
-
-/**
- * Generate a string to be used for salting passwords
- *
- * @return string MD5 hash of concatenated random number and current time
- */
-function generate_salt() {
- return md5(uniqid(mt_rand(), true));
-}
-
-/**
- * Combine salt and password to form a hash
- *
- * @param string $passwd User plaintext password
- * @param string $salt MD5 hash to be used as user salt
- *
- * @return string The MD5 hash of the concatenated salt and user password
- */
-function salted_hash($passwd, $salt) {
- if (strlen($salt) != 32) {
- trigger_error('Salt does not look like an md5 hash', E_USER_WARNING);
- }
- return md5($salt . $passwd);
-}
-
-/**
* Get a package comment
*
* @param int $comment_id The ID of the comment
diff --git a/web/lib/aurjson.class.php b/web/lib/aurjson.class.php
index 3bd9179c..e07522d4 100644
--- a/web/lib/aurjson.class.php
+++ b/web/lib/aurjson.class.php
@@ -387,7 +387,7 @@ class AurJSON {
if ($search_by === 'name' || $search_by === 'name-desc') {
if (strlen($keyword_string) < 2) {
- return $this->json_error('Query arg too small');
+ return $this->json_error('Query arg too small.');
}
$keyword_string = $this->dbh->quote("%" . addcslashes($keyword_string, '%_') . "%");
@@ -441,7 +441,7 @@ class AurJSON {
$names = $args['names'];
if (!$ids && !$names) {
- return $this->json_error('Invalid query arguments');
+ return $this->json_error('Invalid query arguments.');
}
$where_condition = "";
diff --git a/web/lib/confparser.inc.php b/web/lib/confparser.inc.php
index 789300e1..e7128be6 100644
--- a/web/lib/confparser.inc.php
+++ b/web/lib/confparser.inc.php
@@ -4,7 +4,11 @@ function config_load() {
global $AUR_CONFIG;
if (!isset($AUR_CONFIG)) {
- $AUR_CONFIG = parse_ini_file("/etc/aurweb/config", true, INI_SCANNER_RAW);
+ $path = getenv('AUR_CONFIG');
+ if (!$path) {
+ $path = "/etc/aurweb/config";
+ }
+ $AUR_CONFIG = parse_ini_file($path, true, INI_SCANNER_RAW);
}
}
diff --git a/web/lib/pkgbasefuncs.inc.php b/web/lib/pkgbasefuncs.inc.php
index b0827844..57b307d8 100644
--- a/web/lib/pkgbasefuncs.inc.php
+++ b/web/lib/pkgbasefuncs.inc.php
@@ -98,7 +98,7 @@ function pkgbase_add_comment($base_id, $uid, $comment) {
$q = "INSERT INTO PackageComments ";
$q.= "(PackageBaseID, UsersID, Comments, CommentTS) VALUES (";
$q.= intval($base_id) . ", " . $uid . ", ";
- $q.= $dbh->quote($comment) . ", UNIX_TIMESTAMP())";
+ $q.= $dbh->quote($comment) . ", " . strval(time()) . ")";
$dbh->exec($q);
$comment_id = $dbh->lastInsertId();
@@ -144,7 +144,7 @@ function pkgbase_pin_comment($unpin=false) {
$dbh = DB::connect();
$q = "UPDATE PackageComments ";
if (!$unpin) {
- $q.= "SET PinnedTS = UNIX_TIMESTAMP() ";
+ $q.= "SET PinnedTS = " . strval(time()) . " ";
} else {
$q.= "SET PinnedTS = 0 ";
}
@@ -395,7 +395,7 @@ function pkgbase_flag($base_ids, $comment) {
$dbh = DB::connect();
$q = "UPDATE PackageBases SET ";
- $q.= "OutOfDateTS = UNIX_TIMESTAMP(), FlaggerUID = " . $uid . ", ";
+ $q.= "OutOfDateTS = " . strval(time()) . ", FlaggerUID = " . $uid . ", ";
$q.= "FlaggerComment = " . $dbh->quote($comment) . " ";
$q.= "WHERE ID IN (" . implode(",", $base_ids) . ") ";
$q.= "AND OutOfDateTS IS NULL";
@@ -680,15 +680,15 @@ function pkgbase_adopt ($base_ids, $action=true, $via) {
$comaintainers = pkgbase_get_comaintainers($base_id);
if (count($comaintainers) > 0) {
- $uid = uid_from_username($comaintainers[0]);
+ $comaintainer_uid = uid_from_username($comaintainers[0]);
$comaintainers = array_diff($comaintainers, array($comaintainers[0]));
pkgbase_set_comaintainers($base_id, $comaintainers);
} else {
- $uid = "NULL";
+ $comaintainer_uid = "NULL";
}
$q = "UPDATE PackageBases ";
- $q.= "SET MaintainerUID = " . $uid . " ";
+ $q.= "SET MaintainerUID = " . $comaintainer_uid . " ";
$q.= "WHERE ID = " . $base_id;
$dbh->exec($q);
}
@@ -749,12 +749,12 @@ function pkgbase_vote ($base_ids, $action=true) {
$first = 0;
$vote_ids = $pid;
if ($action) {
- $vote_clauses = "($uid, $pid, UNIX_TIMESTAMP())";
+ $vote_clauses = "($uid, $pid, " . strval(time()) . ")";
}
} else {
$vote_ids .= ", $pid";
if ($action) {
- $vote_clauses .= ", ($uid, $pid, UNIX_TIMESTAMP())";
+ $vote_clauses .= ", ($uid, $pid, " . strval(time()) . ")";
}
}
}
@@ -972,7 +972,7 @@ function pkgbase_delete_comment($undelete=false) {
$q = "UPDATE PackageComments ";
$q.= "SET DelUsersID = ".$uid.", ";
- $q.= "DelTS = UNIX_TIMESTAMP() ";
+ $q.= "DelTS = " . strval(time()) . " ";
$q.= "WHERE ID = ".intval($comment_id);
$dbh->exec($q);
return array(true, __("Comment has been deleted."));
@@ -1005,7 +1005,7 @@ function pkgbase_edit_comment($comment) {
$q = "UPDATE PackageComments ";
$q.= "SET EditedUsersID = ".$uid.", ";
$q.= "Comments = ".$dbh->quote($comment).", ";
- $q.= "EditedTS = UNIX_TIMESTAMP() ";
+ $q.= "EditedTS = " . strval(time()) . " ";
$q.= "WHERE ID = ".intval($comment_id);
$dbh->exec($q);
return array(true, __("Comment has been edited."));
diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php
index 4b0fdbac..adb21f66 100644
--- a/web/lib/pkgfuncs.inc.php
+++ b/web/lib/pkgfuncs.inc.php
@@ -481,17 +481,19 @@ function pkg_rel_html($name, $cond, $arch) {
*
* @param string $url The URL of the source
* @param string $arch The source architecture
+ * @param string $package The name of the package
*
* @return string The HTML code of the label to display
*/
-function pkg_source_link($url, $arch) {
+function pkg_source_link($url, $arch, $package) {
$url = explode('::', $url);
$parsed_url = parse_url($url[0]);
if (isset($parsed_url['scheme']) || isset($url[1])) {
$link = '<a href="' . htmlspecialchars((isset($url[1]) ? $url[1] : $url[0]), ENT_QUOTES) . '">' . htmlspecialchars($url[0]) . '</a>';
} else {
- $link = htmlspecialchars($url[0]);
+ $file_url = sprintf(config_get('options', 'source_file_uri'), htmlspecialchars($url[0]), $package);
+ $link = '<a href="' . $file_url . '">' . htmlspecialchars($url[0]) . '</a>';
}
if ($arch) {
@@ -642,52 +644,16 @@ function pkg_display_details($id=0, $row, $SID="") {
}
}
-/* pkg_search_page(SID)
- * outputs the body of search/search results page
- *
- * parameters:
- * SID - current Session ID
- * preconditions:
- * package search page has been accessed
- * request variables have not been sanitized
- *
- * request vars:
- * O - starting result number
- * PP - number of search hits per page
- * K - package search string
- * SO - search hit sort order:
- * values: a - ascending
- * d - descending
- * SB - sort search hits by:
- * values: n - package name
- * v - number of votes
- * m - maintainer username
- * SeB- property that search string (K) represents
- * values: n - package name
- * nd - package name & description
- * b - package base name
- * N - package name (exact match)
- * B - package base name (exact match)
- * k - package keyword(s)
- * m - package maintainer's username
- * s - package submitter's username
- * do_Orphans - boolean. whether to search packages
- * without a maintainer
- *
- *
- * These two are actually handled in packages.php.
- *
- * IDs- integer array of ticked packages' IDs
- * action - action to be taken on ticked packages
- * values: do_Flag - Flag out-of-date
- * do_UnFlag - Remove out-of-date flag
- * do_Adopt - Adopt
- * do_Disown - Disown
- * do_Delete - Delete
- * do_Notify - Enable notification
- * do_UnNotify - Disable notification
+/**
+ * Output the body of the search results page
+ *
+ * @param array $params Search parameters
+ * @param bool $show_headers True if statistics should be included
+ * @param string $SID The session ID of the visitor
+ *
+ * @return int The total number of packages matching the query
*/
-function pkg_search_page($SID="") {
+function pkg_search_page($params, $show_headers=true, $SID="") {
$dbh = DB::connect();
/*
@@ -698,16 +664,16 @@ function pkg_search_page($SID="") {
$myuid = uid_from_sid($SID);
/* Sanitize paging variables. */
- if (isset($_GET['O'])) {
- $_GET['O'] = max(intval($_GET['O']), 0);
+ if (isset($params['O'])) {
+ $params['O'] = max(intval($params['O']), 0);
} else {
- $_GET['O'] = 0;
+ $params['O'] = 0;
}
- if (isset($_GET["PP"])) {
- $_GET["PP"] = bound(intval($_GET["PP"]), 50, 250);
+ if (isset($params["PP"])) {
+ $params["PP"] = bound(intval($params["PP"]), 50, 250);
} else {
- $_GET["PP"] = 50;
+ $params["PP"] = 50;
}
/*
@@ -741,60 +707,75 @@ function pkg_search_page($SID="") {
$q_where = 'WHERE PackageBases.PackagerUID IS NOT NULL ';
- if (isset($_GET['K'])) {
- if (isset($_GET["SeB"]) && $_GET["SeB"] == "m") {
+ if (isset($params['K'])) {
+ if (isset($params["SeB"]) && $params["SeB"] == "m") {
/* Search by maintainer. */
- $q_where .= "AND Users.Username = " . $dbh->quote($_GET['K']) . " ";
- }
- elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "s") {
+ $q_where .= "AND Users.Username = " . $dbh->quote($params['K']) . " ";
+ }
+ elseif (isset($params["SeB"]) && $params["SeB"] == "c") {
+ /* Search by co-maintainer. */
+ $q_where .= "AND EXISTS (SELECT * FROM PackageComaintainers ";
+ $q_where .= "INNER JOIN Users ON Users.ID = PackageComaintainers.UsersID ";
+ $q_where .= "WHERE PackageComaintainers.PackageBaseID = PackageBases.ID ";
+ $q_where .= "AND Users.Username = " . $dbh->quote($params['K']) . ")";
+ }
+ elseif (isset($params["SeB"]) && $params["SeB"] == "M") {
+ /* Search by maintainer and co-maintainer. */
+ $q_where .= "AND (Users.Username = " . $dbh->quote($params['K']) . " ";
+ $q_where .= "OR EXISTS (SELECT * FROM PackageComaintainers ";
+ $q_where .= "INNER JOIN Users ON Users.ID = PackageComaintainers.UsersID ";
+ $q_where .= "WHERE PackageComaintainers.PackageBaseID = PackageBases.ID ";
+ $q_where .= "AND Users.Username = " . $dbh->quote($params['K']) . "))";
+ }
+ elseif (isset($params["SeB"]) && $params["SeB"] == "s") {
/* Search by submitter. */
- $q_where .= "AND SubmitterUID = " . intval(uid_from_username($_GET['K'])) . " ";
+ $q_where .= "AND SubmitterUID = " . intval(uid_from_username($params['K'])) . " ";
}
- elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "n") {
+ elseif (isset($params["SeB"]) && $params["SeB"] == "n") {
/* Search by name. */
- $K = "%" . addcslashes($_GET['K'], '%_') . "%";
+ $K = "%" . addcslashes($params['K'], '%_') . "%";
$q_where .= "AND (Packages.Name LIKE " . $dbh->quote($K) . ") ";
}
- elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "b") {
+ elseif (isset($params["SeB"]) && $params["SeB"] == "b") {
/* Search by package base name. */
- $K = "%" . addcslashes($_GET['K'], '%_') . "%";
+ $K = "%" . addcslashes($params['K'], '%_') . "%";
$q_where .= "AND (PackageBases.Name LIKE " . $dbh->quote($K) . ") ";
}
- elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "k") {
+ elseif (isset($params["SeB"]) && $params["SeB"] == "k") {
/* Search by keywords. */
- $q_where .= construct_keyword_search($dbh, false);
+ $q_where .= construct_keyword_search($dbh, $params['K'], false);
}
- elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "N") {
+ elseif (isset($params["SeB"]) && $params["SeB"] == "N") {
/* Search by name (exact match). */
- $q_where .= "AND (Packages.Name = " . $dbh->quote($_GET['K']) . ") ";
+ $q_where .= "AND (Packages.Name = " . $dbh->quote($params['K']) . ") ";
}
- elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "B") {
+ elseif (isset($params["SeB"]) && $params["SeB"] == "B") {
/* Search by package base name (exact match). */
- $q_where .= "AND (PackageBases.Name = " . $dbh->quote($_GET['K']) . ") ";
+ $q_where .= "AND (PackageBases.Name = " . $dbh->quote($params['K']) . ") ";
}
else {
/* Keyword search (default). */
- $q_where .= construct_keyword_search($dbh, true);
+ $q_where .= construct_keyword_search($dbh, $params['K'], true);
}
}
- if (isset($_GET["do_Orphans"])) {
+ if (isset($params["do_Orphans"])) {
$q_where .= "AND MaintainerUID IS NULL ";
}
- if (isset($_GET['outdated'])) {
- if ($_GET['outdated'] == 'on') {
+ if (isset($params['outdated'])) {
+ if ($params['outdated'] == 'on') {
$q_where .= "AND OutOfDateTS IS NOT NULL ";
}
- elseif ($_GET['outdated'] == 'off') {
+ elseif ($params['outdated'] == 'off') {
$q_where .= "AND OutOfDateTS IS NULL ";
}
}
- $order = (isset($_GET["SO"]) && $_GET["SO"] == 'd') ? 'DESC' : 'ASC';
+ $order = (isset($params["SO"]) && $params["SO"] == 'd') ? 'DESC' : 'ASC';
$q_sort = "ORDER BY ";
- $sort_by = isset($_GET["SB"]) ? $_GET["SB"] : '';
+ $sort_by = isset($params["SB"]) ? $params["SB"] : '';
switch ($sort_by) {
case 'v':
$q_sort .= "NumVotes " . $order . ", ";
@@ -827,7 +808,7 @@ function pkg_search_page($SID="") {
}
$q_sort .= " Packages.Name " . $order . " ";
- $q_limit = "LIMIT ".$_GET["PP"]." OFFSET ".$_GET["O"];
+ $q_limit = "LIMIT ".$params["PP"]." OFFSET ".$params["O"];
$q = $q_select . $q_from . $q_from_extra . $q_where . $q_sort . $q_limit;
$q_total = "SELECT COUNT(*) " . $q_from . $q_where;
@@ -843,7 +824,7 @@ function pkg_search_page($SID="") {
}
if ($result && $total > 0) {
- if (isset($_GET["SO"]) && $_GET["SO"] == "d"){
+ if (isset($params["SO"]) && $params["SO"] == "d"){
$SO_next = "a";
}
else {
@@ -852,10 +833,10 @@ function pkg_search_page($SID="") {
}
/* Calculate the results to use. */
- $first = $_GET['O'] + 1;
+ $first = $params['O'] + 1;
/* Calculation of pagination links. */
- $per_page = ($_GET['PP'] > 0) ? $_GET['PP'] : 50;
+ $per_page = ($params['PP'] > 0) ? $params['PP'] : 50;
$current = ceil($first / $per_page);
$pages = ceil($total / $per_page);
$templ_pages = array();
@@ -880,8 +861,6 @@ function pkg_search_page($SID="") {
$templ_pages[__('Last') . ' &raquo;'] = ($pages - 1) * $per_page;
}
- include('pkg_search_form.php');
-
$searchresults = array();
if ($result) {
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
@@ -891,24 +870,25 @@ function pkg_search_page($SID="") {
include('pkg_search_results.php');
- return;
+ return $total;
}
/**
* Construct the WHERE part of the sophisticated keyword search
*
* @param handle $dbh Database handle
- * @param boolean $namedesc Search name and description fields
+ * @param string $keywords The search term
+ * @param bool $namedesc Search name and description fields
*
* @return string WHERE part of the SQL clause
*/
-function construct_keyword_search($dbh, $namedesc) {
+function construct_keyword_search($dbh, $keywords, $namedesc) {
$count = 0;
$where_part = "";
$q_keywords = "";
$op = "";
- foreach (str_getcsv($_GET['K'], ' ') as $term) {
+ foreach (str_getcsv($keywords, ' ') as $term) {
if ($term == "") {
continue;
}
diff --git a/web/lib/pkgreqfuncs.inc.php b/web/lib/pkgreqfuncs.inc.php
index 8ceac8df..774ebe7e 100644
--- a/web/lib/pkgreqfuncs.inc.php
+++ b/web/lib/pkgreqfuncs.inc.php
@@ -19,10 +19,12 @@ function pkgreq_count() {
*
* @param int $offset The index of the first request to return
* @param int $limit The maximum number of requests to return
+ * @param int $uid Only return packages affecting the given user
+ * @param int $from Do not return packages older than the given date
*
- * @return array List of pacakge requests with details
+ * @return array List of package requests with details
*/
-function pkgreq_list($offset, $limit) {
+function pkgreq_list($offset, $limit, $uid=false, $from=false) {
$dbh = DB::connect();
$q = "SELECT PackageRequests.ID, ";
@@ -35,6 +37,18 @@ function pkgreq_list($offset, $limit) {
$q.= "FROM PackageRequests INNER JOIN RequestTypes ON ";
$q.= "RequestTypes.ID = PackageRequests.ReqTypeID ";
$q.= "INNER JOIN Users ON Users.ID = PackageRequests.UsersID ";
+
+ if ($uid || $from) {
+ $q.= "WHERE ";
+ if ($uid) {
+ $q.= "(PackageRequests.UsersID = " . intval($uid). " ";
+ $q.= "OR Users.ID = " . intval($uid) . ") AND ";
+ }
+ if ($from) {
+ $q.= "RequestTS >= " . intval($from). " ";
+ }
+ }
+
$q.= "ORDER BY Open DESC, RequestTS DESC ";
$q.= "LIMIT " . $limit . " OFFSET " . $offset;
@@ -149,7 +163,7 @@ function pkgreq_file($ids, $type, $merge_into, $comments) {
$q.= "UsersID, Comments, RequestTS) VALUES (" . $type_id . ", ";
$q.= $base_id . ", " . $dbh->quote($pkgbase_name) . ", ";
$q.= $dbh->quote($merge_into) . ", " . $uid . ", ";
- $q.= $dbh->quote($comments) . ", UNIX_TIMESTAMP())";
+ $q.= $dbh->quote($comments) . ", " . strval(time()) . ")";
$dbh->exec($q);
$request_id = $dbh->lastInsertId();
@@ -172,7 +186,7 @@ function pkgreq_file($ids, $type, $merge_into, $comments) {
* maintainer will not be included in the Cc list of the
* request notification email.
*/
- $out_of_date_time = gmdate("Y-m-d", intval($details["OutOfDateTS"]));
+ $out_of_date_time = date("Y-m-d", intval($details["OutOfDateTS"]));
pkgreq_close($request_id, "accepted",
"The package base has been flagged out-of-date " .
"since " . $out_of_date_time . ".", true);
diff --git a/web/lib/timezone.inc.php b/web/lib/timezone.inc.php
new file mode 100644
index 00000000..9fb24331
--- /dev/null
+++ b/web/lib/timezone.inc.php
@@ -0,0 +1,60 @@
+<?php
+set_include_path(get_include_path() . PATH_SEPARATOR . '../lib');
+
+/**
+ * Generate an associative of the PHP timezones and display text.
+ *
+ * @return array PHP Timezone => Displayed Description
+ */
+function generate_timezone_list() {
+ $php_timezones = DateTimeZone::listIdentifiers(DateTimeZone::ALL);
+
+ $offsets = array();
+ foreach ($php_timezones as $timezone) {
+ $tz = new DateTimeZone($timezone);
+ $offset = $tz->getOffset(new DateTime());
+ $offsets[$timezone] = "(UTC" . ($offset < 0 ? "-" : "+") . gmdate("H:i", abs($offset)) .
+ ") " . $timezone;
+ }
+
+ asort($offsets);
+ return $offsets;
+}
+
+/**
+ * Set the timezone for the user.
+ *
+ * @return null
+ */
+function set_tz() {
+ $timezones = generate_timezone_list();
+ $update_cookie = false;
+
+ if (isset($_COOKIE["AURTZ"])) {
+ $timezone = $_COOKIE["AURTZ"];
+ } elseif (isset($_COOKIE["AURSID"])) {
+ $dbh = DB::connect();
+ $q = "SELECT Timezone FROM Users, Sessions ";
+ $q .= "WHERE Users.ID = Sessions.UsersID ";
+ $q .= "AND Sessions.SessionID = ";
+ $q .= $dbh->quote($_COOKIE["AURSID"]);
+ $result = $dbh->query($q);
+
+ if ($result) {
+ $timezone = $result->fetchColumn(0);
+ }
+
+ $update_cookie = true;
+ }
+
+ if (!isset($timezone) || !array_key_exists($timezone, $timezones)) {
+ $timezone = config_get("options", "default_timezone");
+ }
+ date_default_timezone_set($timezone);
+
+ if ($update_cookie) {
+ $timeout = intval(config_get("options", "persistent_cookie_timeout"));
+ $cookie_time = time() + $timeout;
+ setcookie("AURTZ", $timezone, $cookie_time, "/");
+ }
+}
diff --git a/web/lib/translator.inc.php b/web/lib/translator.inc.php
index d53bd530..58648c41 100644
--- a/web/lib/translator.inc.php
+++ b/web/lib/translator.inc.php
@@ -106,7 +106,7 @@ function set_lang() {
$dbh = DB::connect();
$q = "SELECT LangPreference FROM Users, Sessions ";
$q.= "WHERE Users.ID = Sessions.UsersID ";
- $q.= "AND Sessions.SessionID = '";
+ $q.= "AND Sessions.SessionID = ";
$q.= $dbh->quote($_COOKIE["AURSID"]);
$result = $dbh->query($q);
diff --git a/web/lib/version.inc.php b/web/lib/version.inc.php
index dcf5666e..e18873e3 100644
--- a/web/lib/version.inc.php
+++ b/web/lib/version.inc.php
@@ -1,3 +1,3 @@
<?php
-define("AURWEB_VERSION", "v4.4.1");
+define("AURWEB_VERSION", "v4.5.0");