From 9ca28b8fa49ee78bcea545f71d2970277702ba8b Mon Sep 17 00:00:00 2001 From: phibel Date: Wed, 3 Oct 2018 17:36:33 +0200 Subject: [PATCH 1/6] FIX user can transfer his moderator permissions from one forum to an other forum I am working further on the moderator permissions and discovered that my previous commit 692509f is a bad solution. Because the moderator submits the threadId and postID for the post who he wants to delete. This threadId was used to check the moderator permissions of the postId. So if a moderator has only permissions for one forum, he could change the transmitted threadId in an other forum to get there also moderator permisssions... Sorry that I did not noticed this glitch before I made the previous commit. :-/ --- e107_plugins/forum/forum_class.php | 48 +++++++++++++------ .../shortcodes/batch/view_shortcodes.php | 2 +- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/e107_plugins/forum/forum_class.php b/e107_plugins/forum/forum_class.php index 0f81a11e9..5990e4822 100644 --- a/e107_plugins/forum/forum_class.php +++ b/e107_plugins/forum/forum_class.php @@ -366,30 +366,48 @@ class e107forum exit; } - - + + + /** + * get user ids with moderator permissions for the given $postId + * @param $postId id of a forum post + * @return an array with user ids how have moderator permissions for the $postId + */ + public function getModeratorUserIdsByPostId($postId) + { + $sql = e107::getDb(); + $query = "SELECT f.forum_moderators + FROM #forum AS f + INNER JOIN #forum_thread AS ft ON f.forum_id = ft.thread_forum_id + INNER JOIN #forum_post AS fp ON ft.thread_id = fp.post_thread + WHERE fp.post_id = ". $postId; + if ($sql->gen($query) > 0) + { + $row = $sql->fetch(); + return array_keys($this->forumGetMods($row['forum_moderators'])); + } + return array(); + } + + public function ajaxModerate() { $ret = array('hide' => false, 'msg' => 'unkown', 'status' => 'error'); - $modArray = array(); + $moderatorUserIds = array(); - // get moderator-class for the thread to check permissions of the user - if (isset($_POST['thread'])) + if (isset($_POST['thread']) && is_numeric($_POST['thread'])) { $threadId = intval($_POST['thread']); + } - $sql = e107::getDb(); - $query = "SELECT f.forum_moderators - FROM #forum AS f - INNER JOIN #forum_thread AS ft ON f.forum_id = ft.thread_forum_id - WHERE ft.thread_id = ". $threadId; - $sql->gen($query); - $row = $sql->fetch(); - $modArray = $this->forumGetMods($row[forum_moderators]); + if (isset($_POST['post']) && is_numeric($_POST['post'])) + { + $postId = intval($_POST['post']); + $moderatorUserIds = $this->getModeratorUserIdsByPostId($postId); } // Check if user has moderator permissions for this thread - if(!in_array(USERID, array_keys($modArray))) + if(!in_array(USERID, $moderatorUserIds)) { $ret['msg'] = ''.LAN_FORUM_8030.' '. json_encode($_POST); $ret['hide'] = false; @@ -414,7 +432,7 @@ class e107forum break; case 'deletepost': - if(!$postId = vartrue($_POST['post'])) + if(!$postId) { // echo "No Post"; // exit; diff --git a/e107_plugins/forum/shortcodes/batch/view_shortcodes.php b/e107_plugins/forum/shortcodes/batch/view_shortcodes.php index 956f7db93..d96bde48d 100644 --- a/e107_plugins/forum/shortcodes/batch/view_shortcodes.php +++ b/e107_plugins/forum/shortcodes/batch/view_shortcodes.php @@ -889,7 +889,7 @@ // if(!$this->forum->threadDetermineInitialPost($this->postInfo['post_id'])) if(empty($this->postInfo['thread_start'])) { - $text .= "
  • " . LAN_DELETE . " " . $tp->toGlyph('trash') . "
  • "; + $text .= "
  • " . LAN_DELETE . " " . $tp->toGlyph('trash') . "
  • "; } if($type == 'thread') From 37d086c418664fba4cdc51dbb65b827233898801 Mon Sep 17 00:00:00 2001 From: phibel Date: Wed, 3 Oct 2018 17:38:02 +0200 Subject: [PATCH 2/6] MNT remove debug print --- e107_plugins/forum/forum_class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e107_plugins/forum/forum_class.php b/e107_plugins/forum/forum_class.php index 5990e4822..49fc1c2f5 100644 --- a/e107_plugins/forum/forum_class.php +++ b/e107_plugins/forum/forum_class.php @@ -409,7 +409,7 @@ class e107forum // Check if user has moderator permissions for this thread if(!in_array(USERID, $moderatorUserIds)) { - $ret['msg'] = ''.LAN_FORUM_8030.' '. json_encode($_POST); + $ret['msg'] = ''.LAN_FORUM_8030.''; $ret['hide'] = false; $ret['status'] = 'error'; } From c644a8b9d2f673fca51873df9e83db3bbfc15c18 Mon Sep 17 00:00:00 2001 From: phibel Date: Wed, 3 Oct 2018 17:42:14 +0200 Subject: [PATCH 3/6] FIX check moderator permissions for thread-operations Without admin permissions (member of user class 254) it was not possible to modify threads in the forum. This fix get the forum-moderator permissions by the threadId to modify this thread. --- e107_plugins/forum/forum_class.php | 48 +++++++++++++++++++ e107_plugins/forum/forum_viewforum.php | 12 ++--- .../shortcodes/batch/viewforum_shortcodes.php | 24 +++++----- 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/e107_plugins/forum/forum_class.php b/e107_plugins/forum/forum_class.php index 49fc1c2f5..1af36d6c5 100644 --- a/e107_plugins/forum/forum_class.php +++ b/e107_plugins/forum/forum_class.php @@ -390,6 +390,49 @@ class e107forum } + /** + * get user ids with moderator permissions for the given $threadId + * @param $threadId id of a forum thread + * @return an array with user ids how have moderator permissions for the $threadId + */ + public function getModeratorUserIdsByThreadId($threadId) + { + // get moderator-class for the thread to check permissions of the user + $sql = e107::getDb(); + $query = "SELECT f.forum_moderators + FROM #forum AS f + INNER JOIN #forum_thread AS ft ON f.forum_id = ft.thread_forum_id + WHERE ft.thread_id = ". $threadId; + if ($sql->gen($query) > 0) + { + $row = $sql->fetch(); + return array_keys($this->forumGetMods($row['forum_moderators'])); + } + return array(); + } + + + /** + * get user ids with moderator permissions for the given $forumId + * @param $forumId id of a forum + * @return an array with user ids how have moderator permissions for the $forumId + */ + public function getModeratorUserIdsByForumId($forumId) + { + // get moderator-class for the thread to check permissions of the user + $sql = e107::getDb(); + $query = "SELECT f.forum_moderators + FROM #forum AS f + WHERE f.forum_id = ". $forumId; + if ($sql->gen($query) > 0) + { + $row = $sql->fetch(); + return array_keys($this->forumGetMods($row['forum_moderators'])); + } + return array(); + } + + public function ajaxModerate() { $ret = array('hide' => false, 'msg' => 'unkown', 'status' => 'error'); @@ -398,8 +441,13 @@ class e107forum if (isset($_POST['thread']) && is_numeric($_POST['thread'])) { $threadId = intval($_POST['thread']); + $moderatorUserIds = $this->getModeratorUserIdsByThreadId($threadId); } + /* If both, a thread-operation and a post-operation is submitted, the + * thread-permissions MUST be overwritten by the post-permissions! + * Otherwise it is possible that a moderator can transfer his + * permissions from one forum to another forum, where he has no permissions. */ if (isset($_POST['post']) && is_numeric($_POST['post'])) { $postId = intval($_POST['post']); diff --git a/e107_plugins/forum/forum_viewforum.php b/e107_plugins/forum/forum_viewforum.php index e74993d98..5e5dc75ca 100644 --- a/e107_plugins/forum/forum_viewforum.php +++ b/e107_plugins/forum/forum_viewforum.php @@ -200,21 +200,15 @@ if(!empty($forumInfo['forum_description'])) ), 250, '...')); } -//define('MODERATOR', $forum_info['forum_moderators'] != '' && check_class($forum_info['forum_moderators'])); -//$modArray = $forum->forum_getmods($forum_info['forum_moderators']); +$moderatorUserIds = $forum->getModeratorUserIdsByForumId($forumId); +define('MODERATOR', (USER && in_array(USERID, $moderatorUserIds))); -// $thread??? -$modArray = $forum->forumGetMods($thread->forum_info['forum_moderators']); -define('MODERATOR', (USER && is_array($modArray) && in_array(USERID, array_keys($modArray)))); - -//----$message = ''; if (MODERATOR) { if ($_POST) { require_once(e_PLUGIN.'forum/forum_mod.php'); -//-- $message = forum_thread_moderate($_POST); - $forumSCvars['message']=forum_thread_moderate($_POST); + $forumSCvars['message'] = forum_thread_moderate($_POST); } } diff --git a/e107_plugins/forum/shortcodes/batch/viewforum_shortcodes.php b/e107_plugins/forum/shortcodes/batch/viewforum_shortcodes.php index b0d60be22..e869e3b22 100644 --- a/e107_plugins/forum/shortcodes/batch/viewforum_shortcodes.php +++ b/e107_plugins/forum/shortcodes/batch/viewforum_shortcodes.php @@ -971,18 +971,18 @@ function sc_adminoptions() { - /*-- - if(!deftrue('BOOTSTRAP')) - { - return $this->sc_admin_icons; - } - if (MODERATOR) - { - return fadminoptions($this->var); - } - return ''; - --*/ - return (!deftrue('BOOTSTRAP') ? $this->sc_admin_icons() : ((MODERATOR) ? fadminoptions($this->var) : '')); + if(!deftrue('BOOTSTRAP')) + { + return $this->sc_admin_icons(); + } + else if (MODERATOR) + { + return fadminoptions($this->var); + } + else + { + return ''; + } } From f480064ba47f997094a60df480a46cd6b33ad701 Mon Sep 17 00:00:00 2001 From: phibel Date: Wed, 3 Oct 2018 15:56:37 +0200 Subject: [PATCH 4/6] FIX allow moderators to edit posts from other users --- e107_plugins/forum/forum_post.php | 3 ++- e107_plugins/forum/forum_viewtopic.php | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/e107_plugins/forum/forum_post.php b/e107_plugins/forum/forum_post.php index e9f58c1de..8fc08480d 100644 --- a/e107_plugins/forum/forum_post.php +++ b/e107_plugins/forum/forum_post.php @@ -66,8 +66,9 @@ class forum_post_handler $this->id = (int) $_GET['id']; // forum thread/topic id. $this->post = (int) $_GET['post']; // post ID if needed. - define('MODERATOR', USER && $this->forumObj->isModerator(USERID)); + $moderatorUserIds = $forum->getModeratorUserIdsByPostId($this->post); + define('MODERATOR', (USER && in_array(USERID, $moderatorUserIds))); $this->data = $this->processGet(); diff --git a/e107_plugins/forum/forum_viewtopic.php b/e107_plugins/forum/forum_viewtopic.php index 85d5e5cac..c832b9e4b 100644 --- a/e107_plugins/forum/forum_viewtopic.php +++ b/e107_plugins/forum/forum_viewtopic.php @@ -142,8 +142,12 @@ if (USER && (USERID != $thread->threadInfo['thread_user'] || $thread->threadInfo } define('e_PAGETITLE', strip_tags($tp->toHTML($thread->threadInfo['thread_name'], true, 'no_hook, emotes_off')).' / '.$tp->toHTML($thread->threadInfo['forum_name'], true, 'no_hook, emotes_off').' / '.LAN_FORUM_1001); + $forum->modArray = $forum->forumGetMods($thread->threadInfo['forum_moderators']); -define('MODERATOR', (USER && $forum->isModerator(USERID))); + +/* Check if use has moderator permissions for this thread */ +$moderatorUserIds = $forum->getModeratorUserIdsByThreadId($thread->threadInfo['thread_id']); +define('MODERATOR', (USER && in_array(USERID, $moderatorUserIds))); e107::getScBatch('view', 'forum')->setScVar('forum', $forum); //var_dump(e107::getScBatch('forum', 'forum')); From 38485607524e17ae8487b7b7548c6728e67a10ca Mon Sep 17 00:00:00 2001 From: phibel Date: Sun, 30 Sep 2018 23:17:58 +0200 Subject: [PATCH 5/6] ENH allow user to delete his own post, if it is the last post in the thread --- e107_plugins/forum/forum_class.php | 41 +++++++++++++++++ e107_plugins/forum/forum_viewtopic.php | 46 +++++++++++-------- .../shortcodes/batch/view_shortcodes.php | 11 +++++ 3 files changed, 80 insertions(+), 18 deletions(-) diff --git a/e107_plugins/forum/forum_class.php b/e107_plugins/forum/forum_class.php index 1af36d6c5..7fa410d2e 100644 --- a/e107_plugins/forum/forum_class.php +++ b/e107_plugins/forum/forum_class.php @@ -368,6 +368,47 @@ class e107forum } + /** + * Allow a user to delete their own post, if it is the last post in the thread. + */ + function usersLastPostDeletion() + { + $ret = array('hide' => false, 'msg' => LAN_FORUM_7008, 'status' => 'error'); + $actionAllowed = false; + + if (isset($_POST['post']) && is_numeric($_POST['post'])) + { + $postId = intval($_POST['post']); + $sql = e107::getDb(); + $query = "SELECT fp.post_user + FROM #forum_post AS fp + WHERE fp.post_id = ". $postId; + if ($sql->gen($query) > 0) + { + $row = $sql->fetch(); + if (USERID == $row['post_user']) $actionAllowed = true; + } + } + + if ($actionAllowed && $_POST['action'] == 'deletepost') + { + if ($this->postDelete($postId)) + { + $ret['msg'] = ''.LAN_FORUM_8021.' #'.$postId; + $ret['hide'] = true; + $ret['status'] = 'ok'; + } + else + { + $ret['msg'] = "".LAN_FORUM_8021." #".$postId; + $ret['status'] = 'error'; + } + } + echo json_encode($ret); + exit(); + } + + /** * get user ids with moderator permissions for the given $postId * @param $postId id of a forum post diff --git a/e107_plugins/forum/forum_viewtopic.php b/e107_plugins/forum/forum_viewtopic.php index c832b9e4b..57eb63827 100644 --- a/e107_plugins/forum/forum_viewtopic.php +++ b/e107_plugins/forum/forum_viewtopic.php @@ -69,9 +69,27 @@ if(vartrue($_GET['id']) && isset($_GET['dl'])) exit; } +if (isset($_GET['last'])) +{ + $_GET['f'] = 'last'; +} + +if(isset($_GET['f']) && $_GET['f'] == 'post') +{ + $thread->processFunction(); +} + +$thread->init(); + + +/* Check if use has moderator permissions for this thread */ +$moderatorUserIds = $forum->getModeratorUserIdsByThreadId($thread->threadInfo['thread_id']); +define('MODERATOR', (USER && in_array(USERID, $moderatorUserIds))); + + if(e_AJAX_REQUEST) { - if(varset($_POST['action']) == 'quickreply') + if(varset($_POST['action']) == 'quickreply') { $forum->ajaxQuickReply(); } @@ -85,22 +103,12 @@ if(e_AJAX_REQUEST) { $forum->ajaxModerate(); } - + else if(varset($_POST['action']) == 'deletepost') + { + $forum->usersLastPostDeletion(); + } } - -if (isset($_GET['last'])) -{ - $_GET['f'] = 'last'; -} - -if(isset($_GET['f']) && $_GET['f'] == 'post') -{ - $thread->processFunction(); -} - -$thread->init(); - /* if(isset($_POST['track_toggle'])) @@ -145,9 +153,6 @@ define('e_PAGETITLE', strip_tags($tp->toHTML($thread->threadInfo['thread_name'], $forum->modArray = $forum->forumGetMods($thread->threadInfo['forum_moderators']); -/* Check if use has moderator permissions for this thread */ -$moderatorUserIds = $forum->getModeratorUserIdsByThreadId($thread->threadInfo['thread_id']); -define('MODERATOR', (USER && in_array(USERID, $moderatorUserIds))); e107::getScBatch('view', 'forum')->setScVar('forum', $forum); //var_dump(e107::getScBatch('forum', 'forum')); @@ -485,6 +490,8 @@ $i = $thread->page; $sc->wrapper('forum_viewtopic/end'); $forend = $tp->parseTemplate($FORUMEND, true, $sc); +$lastPostDetectionCounter = count($postList); +$sc->setScVar('thisIsTheLastPost', false); foreach ($postList as $c => $postInfo) { @@ -494,6 +501,9 @@ foreach ($postList as $c => $postInfo) } $loop_uid = (int)$postInfo['post_user']; + $lastPostDetectionCounter--; + if ($lastPostDetectionCounter == 0) $sc->setScVar('thisIsTheLastPost', true); + //---- Orphan $tnum???? $tnum = $i; diff --git a/e107_plugins/forum/shortcodes/batch/view_shortcodes.php b/e107_plugins/forum/shortcodes/batch/view_shortcodes.php index d96bde48d..079e497db 100644 --- a/e107_plugins/forum/shortcodes/batch/view_shortcodes.php +++ b/e107_plugins/forum/shortcodes/batch/view_shortcodes.php @@ -859,6 +859,17 @@ } + // Delete own post, if it is the last in the thread + if($this->thisIsTheLastPost && USER && $this->thread->threadInfo['thread_lastuser'] == USERID) + { + /* only show delete button when post is not the initial post of the topic + * AND if this post is the last post in the thread */ + if($this->thread->threadInfo['thread_active'] && empty($this->postInfo['thread_start']) ) + { + $text .= "
  • " . LAN_DELETE . " " . $tp->toGlyph('trash') . "
  • "; + } + } + if($this->forum->checkperm($this->postInfo['post_forum'], 'post')) { $url = e107::url('forum', 'post') . "?f=quote&id=" . $this->postInfo['post_thread'] . "&post=" . $this->postInfo['post_id']; From e2789872a5381a6a4125bef11d8d94651fe17141 Mon Sep 17 00:00:00 2001 From: phibel Date: Fri, 5 Oct 2018 00:32:33 +0200 Subject: [PATCH 6/6] FIX the database was not updated when a post was deleted Looks like someone was interrupted during work and than it was merged into the repo? Anyway, the needed information are stored in $postInfo[] and not in $row[]. --- e107_plugins/forum/forum_class.php | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/e107_plugins/forum/forum_class.php b/e107_plugins/forum/forum_class.php index 7fa410d2e..41c101e85 100644 --- a/e107_plugins/forum/forum_class.php +++ b/e107_plugins/forum/forum_class.php @@ -2527,27 +2527,24 @@ class e107forum * Delete a Post * @param $postId integer * @param $updateCounts boolean - * + * @return "null" if this post does not exist, "true" if post could deleted, otherwise "false" */ function postDelete($postId, $updateCounts = true) { $postId = (int)$postId; - $e107 = e107::getInstance(); + $sql = e107::getDb(); $deleted = false; $postInfo = $sql->retrieve('forum_post', '*', 'post_id = '.$postId); - //if(!$sql->select('forum_post', '*', 'post_id = '.$postId)) + if(!is_array($postInfo) || empty($postInfo)) { - echo 'NOT FOUND!'; return; + return null; } - - - $row = $sql->fetch(); //delete attachments if they exist - if($row['post_attachments']) + if($postInfo['post_attachments']) { $this->postDeleteAttachments('post', $postId); } @@ -2563,24 +2560,24 @@ class e107forum if($updateCounts) { // decrement user post counts - if ($row['post_user']) + if ($postInfo['post_user']) { - $sql->update('user_extended', 'user_plugin_forum_posts=GREATEST(user_plugin_forum_posts-1,0) WHERE user_extended_id='.$row['post_user']); + $sql->update('user_extended', 'user_plugin_forum_posts=GREATEST(user_plugin_forum_posts-1,0) WHERE user_extended_id='.$postInfo['post_user']); } // update thread with correct reply counts - $sql->update('forum_thread', "thread_total_replies=GREATEST(thread_total_replies-1,0) WHERE thread_id=".$row['post_thread']); + $sql->update('forum_thread', "thread_total_replies=GREATEST(thread_total_replies-1,0) WHERE thread_id=".$postInfo['post_thread']); // update forum with correct thread/reply counts - $sql->update('forum', "forum_replies=GREATEST(forum_replies-1,0) WHERE forum_id=".$row['post_forum']); + $sql->update('forum', "forum_replies=GREATEST(forum_replies-1,0) WHERE forum_id=".$postInfo['post_forum']); // update thread lastpost info - $this->forumUpdateLastpost('thread', $row['post_thread']); + $this->forumUpdateLastpost('thread', $postInfo['post_thread']); // update forum lastpost info - $this->forumUpdateLastpost('forum', $row['post_forum']); + $this->forumUpdateLastpost('forum', $postInfo['post_forum']); } - return $deleted; // return boolean. $threadInfo['thread_total_replies']; + return $deleted; }