summaryrefslogtreecommitdiff
path: root/classes
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2021-11-10 20:44:51 +0300
committerAndrew Dolgov <[email protected]>2021-11-10 20:44:51 +0300
commit9e8d69739f21e5ac85977d57a2a6c961e318c26e (patch)
tree0fc52f7be644b5f86e236cc7cb8f4dc4351da8f9 /classes
parent7a52560e4e3b0652d32645b60ae13e4904f606bc (diff)
add two helper account access levels:
- read only - can't subscribe to more feeds, feed updates are skipped - disabled - can't login define used access levels as UserHelper constants and refactor code to use them instead of hardcoded numbers
Diffstat (limited to 'classes')
-rwxr-xr-xclasses/feeds.php7
-rw-r--r--classes/handler/administrative.php2
-rwxr-xr-xclasses/pref/feeds.php12
-rw-r--r--classes/pref/prefs.php16
-rwxr-xr-xclasses/rpc.php7
-rwxr-xr-xclasses/rssutils.php19
-rw-r--r--classes/userhelper.php19
7 files changed, 66 insertions, 16 deletions
diff --git a/classes/feeds.php b/classes/feeds.php
index 987123a21..cd2633ffb 100755
--- a/classes/feeds.php
+++ b/classes/feeds.php
@@ -1027,10 +1027,17 @@ class Feeds extends Handler_Protected {
* 5 - Couldn't download the URL content.
* 6 - Content is an invalid XML.
* 7 - Error while creating feed database entry.
+ * 8 - Permission denied (ACCESS_LEVEL_READONLY).
*/
static function _subscribe($url, $cat_id = 0,
$auth_login = '', $auth_pass = '') : array {
+ $user = ORM::for_table("ttrss_users")->find_one($_SESSION['uid']);
+
+ if ($user && $user->access_level == UserHelper::ACCESS_LEVEL_READONLY) {
+ return ["code" => 8];
+ }
+
$pdo = Db::pdo();
$url = UrlHelper::validate($url);
diff --git a/classes/handler/administrative.php b/classes/handler/administrative.php
index 52dfed8b7..f2f5b36ba 100644
--- a/classes/handler/administrative.php
+++ b/classes/handler/administrative.php
@@ -2,7 +2,7 @@
class Handler_Administrative extends Handler_Protected {
function before($method) {
if (parent::before($method)) {
- if (($_SESSION["access_level"] ?? 0) >= 10) {
+ if (($_SESSION["access_level"] ?? 0) >= UserHelper::ACCESS_LEVEL_ADMIN) {
return true;
}
}
diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php
index 95bbcd190..ac0874259 100755
--- a/classes/pref/feeds.php
+++ b/classes/pref/feeds.php
@@ -538,6 +538,8 @@ class Pref_Feeds extends Handler_Protected {
$local_purge_intervals = [ T_nsprintf('%d day', '%d days', $purge_interval, $purge_interval) ];
}
+ $user = ORM::for_table("ttrss_users")->find_one($_SESSION["uid"]);
+
print json_encode([
"feed" => $row,
"cats" => [
@@ -550,6 +552,9 @@ class Pref_Feeds extends Handler_Protected {
"update" => $local_update_intervals,
"purge" => $local_purge_intervals,
],
+ "user" => [
+ "access_level" => $user->access_level
+ ],
"lang" => [
"enabled" => Config::get(Config::DB_TYPE) == "pgsql",
"default" => get_pref(Prefs::DEFAULT_SEARCH_LANGUAGE),
@@ -1207,6 +1212,13 @@ class Pref_Feeds extends Handler_Protected {
$login = clean($_REQUEST['login']);
$pass = clean($_REQUEST['pass']);
+ $user = ORM::for_table('ttrss_users')->find_one($_SESSION["uid"]);
+
+ // TODO: we should return some kind of error code to frontend here
+ if ($user->access_level == UserHelper::ACCESS_LEVEL_READONLY) {
+ return false;
+ }
+
$csth = $this->pdo->prepare("SELECT id FROM ttrss_feeds
WHERE feed_url = ? AND owner_uid = ?");
diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php
index c47a99469..c45d6d6ea 100644
--- a/classes/pref/prefs.php
+++ b/classes/pref/prefs.php
@@ -813,7 +813,7 @@ class Pref_Prefs extends Handler_Protected {
usort($rv, function($a, $b) { return strcmp($a["name"], $b["name"]); });
- print json_encode(['plugins' => $rv, 'is_admin' => $_SESSION['access_level'] >= 10]);
+ print json_encode(['plugins' => $rv, 'is_admin' => $_SESSION['access_level'] >= UserHelper::ACCESS_LEVEL_ADMIN]);
}
function index_plugins() {
@@ -890,7 +890,7 @@ class Pref_Prefs extends Handler_Protected {
<?= \Controls\button_tag(\Controls\icon("refresh"), "", ["title" => __("Reload"), "onclick" => "Helpers.Plugins.reload()"]) ?>
- <?php if ($_SESSION["access_level"] >= 10) { ?>
+ <?php if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN) { ?>
<?php if (Config::get(Config::CHECK_FOR_UPDATES) && Config::get(Config::CHECK_FOR_PLUGIN_UPDATES)) { ?>
<button class='alt-warning' dojoType='dijit.form.Button' onclick="Helpers.Plugins.update()">
@@ -1152,7 +1152,7 @@ class Pref_Prefs extends Handler_Protected {
}
function uninstallPlugin() {
- if ($_SESSION["access_level"] >= 10) {
+ if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN) {
$plugin_name = basename(clean($_REQUEST['plugin']));
$status = 0;
@@ -1167,7 +1167,7 @@ class Pref_Prefs extends Handler_Protected {
}
function installPlugin() {
- if ($_SESSION["access_level"] >= 10 && Config::get(Config::ENABLE_PLUGIN_INSTALLER)) {
+ if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN && Config::get(Config::ENABLE_PLUGIN_INSTALLER)) {
$plugin_name = basename(clean($_REQUEST['plugin']));
$all_plugins = $this->_get_available_plugins();
$plugin_dir = dirname(dirname(__DIR__)) . "/plugins.local";
@@ -1252,18 +1252,18 @@ class Pref_Prefs extends Handler_Protected {
}
private function _get_available_plugins() {
- if ($_SESSION["access_level"] >= 10 && Config::get(Config::ENABLE_PLUGIN_INSTALLER)) {
+ if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN && Config::get(Config::ENABLE_PLUGIN_INSTALLER)) {
return json_decode(UrlHelper::fetch(['url' => 'https://tt-rss.org/plugins.json']), true);
}
}
function getAvailablePlugins() {
- if ($_SESSION["access_level"] >= 10) {
+ if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN) {
print json_encode($this->_get_available_plugins());
}
}
function checkForPluginUpdates() {
- if ($_SESSION["access_level"] >= 10 && Config::get(Config::CHECK_FOR_UPDATES) && Config::get(Config::CHECK_FOR_PLUGIN_UPDATES)) {
+ if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN && Config::get(Config::CHECK_FOR_UPDATES) && Config::get(Config::CHECK_FOR_PLUGIN_UPDATES)) {
$plugin_name = $_REQUEST["name"] ?? "";
$root_dir = dirname(dirname(__DIR__)); # we're in classes/pref/
@@ -1279,7 +1279,7 @@ class Pref_Prefs extends Handler_Protected {
}
function updateLocalPlugins() {
- if ($_SESSION["access_level"] >= 10) {
+ if ($_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN) {
$plugins = explode(",", $_REQUEST["plugins"] ?? "");
# we're in classes/pref/
diff --git a/classes/rpc.php b/classes/rpc.php
index b6c4a5fc9..0432ed2d3 100755
--- a/classes/rpc.php
+++ b/classes/rpc.php
@@ -299,7 +299,8 @@ class RPC extends Handler_Protected {
ttrss_feeds f, ttrss_users u LEFT JOIN ttrss_user_prefs2 p ON
(p.owner_uid = u.id AND profile IS NULL AND pref_name = 'DEFAULT_UPDATE_INTERVAL')
WHERE
- f.owner_uid = u.id
+ f.owner_uid = u.id AND
+ u.access_level NOT IN (".sprintf("%d, %d", UserHelper::ACCESS_LEVEL_DISABLED, UserHelper::ACCESS_LEVEL_READONLY).")
$owner_check_qpart
$update_limit_qpart
$updstart_thresh_qpart
@@ -403,7 +404,7 @@ class RPC extends Handler_Protected {
$git_timestamp = $version["timestamp"] ?? false;
$git_commit = $version["commit"] ?? false;
- if (Config::get(Config::CHECK_FOR_UPDATES) && $_SESSION["access_level"] >= 10 && $git_timestamp) {
+ if (Config::get(Config::CHECK_FOR_UPDATES) && $_SESSION["access_level"] >= UserHelper::ACCESS_LEVEL_ADMIN && $git_timestamp) {
$content = @UrlHelper::fetch(["url" => "https://tt-rss.org/version.json"]);
if ($content) {
@@ -510,7 +511,7 @@ class RPC extends Handler_Protected {
$data['cdm_expanded'] = get_pref(Prefs::CDM_EXPANDED);
$data["labels"] = Labels::get_all($_SESSION["uid"]);
- if (Config::get(Config::LOG_DESTINATION) == 'sql' && $_SESSION['access_level'] >= 10) {
+ if (Config::get(Config::LOG_DESTINATION) == 'sql' && $_SESSION['access_level'] >= UserHelper::ACCESS_LEVEL_ADMIN) {
if (Config::get(Config::DB_TYPE) == 'pgsql') {
$log_interval = "created_at > NOW() - interval '1 hour'";
} else {
diff --git a/classes/rssutils.php b/classes/rssutils.php
index 87e52ba42..927a6c251 100755
--- a/classes/rssutils.php
+++ b/classes/rssutils.php
@@ -123,7 +123,8 @@ class RSSUtils {
ttrss_feeds f, ttrss_users u LEFT JOIN ttrss_user_prefs2 p ON
(p.owner_uid = u.id AND profile IS NULL AND pref_name = 'DEFAULT_UPDATE_INTERVAL')
WHERE
- f.owner_uid = u.id
+ f.owner_uid = u.id AND
+ u.access_level NOT IN (".sprintf("%d, %d", UserHelper::ACCESS_LEVEL_DISABLED, UserHelper::ACCESS_LEVEL_READONLY).")
$login_thresh_qpart
$update_limit_qpart
$updstart_thresh_qpart
@@ -163,7 +164,8 @@ class RSSUtils {
FROM ttrss_feeds f, ttrss_users u LEFT JOIN ttrss_user_prefs2 p ON
(p.owner_uid = u.id AND profile IS NULL AND pref_name = 'DEFAULT_UPDATE_INTERVAL')
WHERE
- f.owner_uid = u.id
+ f.owner_uid = u.id AND
+ u.access_level NOT IN (".sprintf("%d, %d", UserHelper::ACCESS_LEVEL_DISABLED, UserHelper::ACCESS_LEVEL_READONLY).")
AND feed_url = :feed
$login_thresh_qpart
$update_limit_qpart
@@ -352,6 +354,19 @@ class RSSUtils {
if (!$feed_language) $feed_language = mb_strtolower(get_pref(Prefs::DEFAULT_SEARCH_LANGUAGE, $feed_obj->owner_uid));
if (!$feed_language) $feed_language = 'simple';
+ $user = ORM::for_table('ttrss_users')->find_one($feed_obj->owner_uid);
+
+ if ($user) {
+ if ($user->access_level == UserHelper::ACCESS_LEVEL_READONLY) {
+ Debug::log("error: denied update for $feed: permission denied by owner access level");
+ return false;
+ }
+ } else {
+ // this would indicate database corruption of some kind
+ Debug::log("error: owner not found for feed: $feed");
+ return false;
+ }
+
} else {
Debug::log("error: feeds table record not found for feed: $feed");
return false;
diff --git a/classes/userhelper.php b/classes/userhelper.php
index 1cdd320a1..ea714b76b 100644
--- a/classes/userhelper.php
+++ b/classes/userhelper.php
@@ -17,6 +17,21 @@ class UserHelper {
self::HASH_ALGO_SHA1
];
+ /** forbidden to login */
+ const ACCESS_LEVEL_DISABLED = -2;
+
+ /** can't subscribe to new feeds, feeds are not updated */
+ const ACCESS_LEVEL_READONLY = -1;
+
+ /** no restrictions, regular user */
+ const ACCESS_LEVEL_USER = 0;
+
+ /** not used, same as regular user */
+ const ACCESS_LEVEL_POWERUSER = 5;
+
+ /** has administrator permissions */
+ const ACCESS_LEVEL_ADMIN = 10;
+
static function authenticate(string $login = null, string $password = null, bool $check_only = false, string $service = null) {
if (!Config::get(Config::SINGLE_USER_MODE)) {
$user_id = false;
@@ -41,7 +56,7 @@ class UserHelper {
$user = ORM::for_table('ttrss_users')->find_one($user_id);
- if ($user) {
+ if ($user && $user->access_level != self::ACCESS_LEVEL_DISABLED) {
$_SESSION["uid"] = $user_id;
$_SESSION["auth_module"] = $auth_module;
$_SESSION["name"] = $user->login;
@@ -68,7 +83,7 @@ class UserHelper {
$_SESSION["uid"] = 1;
$_SESSION["name"] = "admin";
- $_SESSION["access_level"] = 10;
+ $_SESSION["access_level"] = self::ACCESS_LEVEL_ADMIN;
$_SESSION["hide_hello"] = true;
$_SESSION["hide_logout"] = true;