diff options
Diffstat (limited to 'classes/pref/users.php')
-rw-r--r-- | classes/pref/users.php | 151 |
1 files changed, 71 insertions, 80 deletions
diff --git a/classes/pref/users.php b/classes/pref/users.php index 13f808cb3..2e3dc4b67 100644 --- a/classes/pref/users.php +++ b/classes/pref/users.php @@ -1,24 +1,22 @@ <?php class Pref_Users extends Handler_Administrative { function csrf_ignore($method) { - $csrf_ignored = array("index"); - - return array_search($method, $csrf_ignored) !== false; + return $method == "index"; } function edit() { - global $access_level_names; - - $id = (int)clean($_REQUEST["id"]); + $user = ORM::for_table('ttrss_users') + ->select_expr("id,login,access_level,email,full_name,otp_enabled") + ->find_one((int)$_REQUEST["id"]) + ->as_array(); - $sth = $this->pdo->prepare("SELECT id, login, access_level, email FROM ttrss_users WHERE id = ?"); - $sth->execute([$id]); + global $access_level_names; - if ($row = $sth->fetch(PDO::FETCH_ASSOC)) { + if ($user) { print json_encode([ - "user" => $row, - "access_level_names" => $access_level_names - ]); + "user" => $user, + "access_level_names" => $access_level_names + ]); } } @@ -106,31 +104,32 @@ class Pref_Users extends Handler_Administrative { } function editSave() { - $login = clean($_REQUEST["login"]); - $uid = clean($_REQUEST["id"]); - $access_level = (int) clean($_REQUEST["access_level"]); - $email = clean($_REQUEST["email"]); + $id = (int)$_REQUEST['id']; $password = clean($_REQUEST["password"]); + $user = ORM::for_table('ttrss_users')->find_one($id); - // no blank usernames - if (!$login) return; + if ($user) { + $login = clean($_REQUEST["login"]); - // forbid renaming admin - if ($uid == 1) $login = "admin"; + if ($id == 1) $login = "admin"; + if (!$login) return; - if ($password) { - $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); - $pwd_hash = encrypt_password($password, $salt, true); - $pass_query_part = "pwd_hash = ".$this->pdo->quote($pwd_hash).", - salt = ".$this->pdo->quote($salt).","; - } else { - $pass_query_part = ""; - } + $user->login = mb_strtolower($login); + $user->access_level = (int) clean($_REQUEST["access_level"]); + $user->email = clean($_REQUEST["email"]); + $user->otp_enabled = checkbox_to_sql_bool($_REQUEST["otp_enabled"]); - $sth = $this->pdo->prepare("UPDATE ttrss_users SET $pass_query_part login = LOWER(?), - access_level = ?, email = ?, otp_enabled = false WHERE id = ?"); - $sth->execute([$login, $access_level, $email, $uid]); + // force new OTP secret when next enabled + if (Config::get_schema_version() >= 143 && !$user->otp_enabled) { + $user->otp_secret = null; + } + + $user->save(); + } + if ($password) { + UserHelper::reset_password($id, false, $password); + } } function remove() { @@ -152,24 +151,25 @@ class Pref_Users extends Handler_Administrative { function add() { $login = clean($_REQUEST["login"]); - $tmp_user_pwd = make_password(); - $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); - $pwd_hash = encrypt_password($tmp_user_pwd, $salt, true); if (!$login) return; // no blank usernames if (!UserHelper::find_user_by_login($login)) { - $sth = $this->pdo->prepare("INSERT INTO ttrss_users - (login,pwd_hash,access_level,last_login,created, salt) - VALUES (LOWER(?), ?, 0, null, NOW(), ?)"); - $sth->execute([$login, $pwd_hash, $salt]); + $new_password = make_password(); - if ($new_uid = UserHelper::find_user_by_login($login)) { + $user = ORM::for_table('ttrss_users')->create(); - print T_sprintf("Added user %s with password %s", - $login, $tmp_user_pwd); + $user->salt = UserHelper::get_salt(); + $user->login = mb_strtolower($login); + $user->pwd_hash = UserHelper::hash_password($new_password, $user->salt); + $user->access_level = 0; + $user->created = Db::NOW(); + $user->save(); + if ($new_uid = UserHelper::find_user_by_login($login)) { + print T_sprintf("Added user %s with password %s", + $login, $new_password); } else { print T_sprintf("Could not create user %s", $login); } @@ -200,11 +200,10 @@ class Pref_Users extends Handler_Administrative { $sort = "login"; } - $sort = $this->_validate_field($sort, - ["login", "access_level", "created", "num_feeds", "created", "last_login"], "login"); + if (!in_array($sort, ["login", "access_level", "created", "num_feeds", "created", "last_login"])) + $sort = "login"; if ($sort != "login") $sort = "$sort DESC"; - ?> <div dojoType='dijit.layout.BorderContainer' gutters='false'> @@ -249,42 +248,41 @@ class Pref_Users extends Handler_Administrative { <table width='100%' class='users-list' id='users-list'> - <tr class='title'> - <td align='center' width='5%'> </td> - <td width='20%'><a href='#' onclick="Users.reload('login')"><?= ('Login') ?></a></td> - <td width='20%'><a href='#' onclick="Users.reload('access_level')"><?= ('Access Level') ?></a></td> - <td width='10%'><a href='#' onclick="Users.reload('num_feeds')"><?= ('Subscribed feeds') ?></a></td> - <td width='20%'><a href='#' onclick="Users.reload('created')"><?= ('Registered') ?></a></td> - <td width='20%'><a href='#' onclick="Users.reload('last_login')"><?= ('Last login') ?></a></td> + <tr> + <th></th> + <th><a href='#' onclick="Users.reload('login')"><?= ('Login') ?></a></th> + <th><a href='#' onclick="Users.reload('access_level')"><?= ('Access Level') ?></a></th> + <th><a href='#' onclick="Users.reload('num_feeds')"><?= ('Subscribed feeds') ?></a></th> + <th><a href='#' onclick="Users.reload('created')"><?= ('Registered') ?></a></th> + <th><a href='#' onclick="Users.reload('last_login')"><?= ('Last login') ?></a></th> </tr> <?php - $sth = $this->pdo->prepare("SELECT - tu.id, - login,access_level,email, - ".SUBSTRING_FOR_DATE."(last_login,1,16) as last_login, - ".SUBSTRING_FOR_DATE."(created,1,16) as created, - (SELECT COUNT(id) FROM ttrss_feeds WHERE owner_uid = tu.id) AS num_feeds - FROM - ttrss_users tu - WHERE - (:search = '' OR login LIKE :search) AND tu.id > 0 - ORDER BY $sort"); - $sth->execute([":search" => $user_search ? "%$user_search%" : ""]); - - while ($row = $sth->fetch()) { ?> - - <tr data-row-id='<?= $row["id"] ?>' onclick='Users.edit(<?= $row["id"] ?>)' title="<?= __('Click to edit') ?>"> - <td align='center'> + $users = ORM::for_table('ttrss_users') + ->table_alias('u') + ->left_outer_join("ttrss_feeds", ["owner_uid", "=", "u.id"], 'f') + ->select_expr('u.*,COUNT(f.id) AS num_feeds') + ->where_like("login", $user_search ? "%$user_search%" : "%") + ->order_by_expr($sort) + ->group_by_expr('u.id') + ->find_many(); + + foreach ($users as $user) { ?> + + <tr data-row-id='<?= $user["id"] ?>' onclick='Users.edit(<?= $user["id"] ?>)' title="<?= __('Click to edit') ?>"> + <td class='checkbox'> <input onclick='Tables.onRowChecked(this); event.stopPropagation();' dojoType='dijit.form.CheckBox' type='checkbox'> </td> - <td><i class='material-icons'>person</i> <?= htmlspecialchars($row["login"]) ?></td> - <td><?= $access_level_names[$row["access_level"]] ?></td> - <td><?= $row["num_feeds"] ?></td> - <td><?= TimeHelper::make_local_datetime($row["created"], false) ?></td> - <td><?= TimeHelper::make_local_datetime($row["last_login"], false) ?></td> + <td width='30%'> + <i class='material-icons'>person</i> + <strong><?= htmlspecialchars($user["login"]) ?></strong> + </td> + <td><?= $access_level_names[$user["access_level"]] ?></td> + <td><?= $user["num_feeds"] ?></td> + <td class='text-muted'><?= TimeHelper::make_local_datetime($user["created"], false) ?></td> + <td class='text-muted'><?= TimeHelper::make_local_datetime($user["last_login"], false) ?></td> </tr> <?php } ?> </table> @@ -294,11 +292,4 @@ class Pref_Users extends Handler_Administrative { <?php } - private function _validate_field($string, $allowed, $default = "") { - if (in_array($string, $allowed)) - return $string; - else - return $default; - } - } |