From e3cba2b450bdde8725e31567f761ca9aaa63230a Mon Sep 17 00:00:00 2001 From: Savetheinternet Date: Sun, 3 Jul 2011 23:05:14 +1000 Subject: [PATCH] per-board moderators --- inc/display.php | 38 ++++++++--------- inc/mod.php | 22 ++++++++-- install.php | 6 ++- install.sql | 1 + mod.php | 106 +++++++++++++++++++++++++++++++++++++----------- 5 files changed, 126 insertions(+), 47 deletions(-) diff --git a/inc/display.php b/inc/display.php index 91577af0..3a9fc577 100644 --- a/inc/display.php +++ b/inc/display.php @@ -241,29 +241,29 @@ $built = ''; if($this->mod) { // Mod controls (on posts) - $built .= ''; // Delete - if($this->mod['type'] >= $config['mod']['delete']) + if(hasPermission($config['mod']['delete'], $board['uri'], $this->mod)) $built .= ' ' . confirmLink($config['mod']['link_delete'], 'Delete', 'Are you sure you want to delete this?', $board['uri'] . '/delete/' . $this->id); // Delete all posts by IP - if($this->mod['type'] >= $config['mod']['deletebyip']) + if(hasPermission($config['mod']['deletebyip'], $board['uri'], $this->mod)) $built .= ' ' . confirmLink($config['mod']['link_deletebyip'], 'Delete all posts by IP', 'Are you sure you want to delete all posts by IP?', $board['uri'] . '/deletebyip/' . $this->id); // Ban - if($this->mod['type'] >= $config['mod']['ban']) + if(hasPermission($config['mod']['ban'], $board['uri'], $this->mod)) $built .= ' ' . $config['mod']['link_ban'] . ''; // Ban & Delete - if($this->mod['type'] >= $config['mod']['bandelete']) + if(hasPermission($config['mod']['bandelete'], $board['uri'], $this->mod)) $built .= ' ' . $config['mod']['link_bandelete'] . ''; // Delete file (keep post) - if(!empty($this->file) && $this->mod['type'] >= $config['mod']['deletefile']) + if(!empty($this->file) && hasPermission($config['mod']['deletefile'], $board['uri'], $this->mod)) $built .= ' ' . $config['mod']['link_deletefile'] . ''; - $built .= ''; + if(!empty($built)) + $built = '' . $built . ''; } return $built; } @@ -309,7 +309,7 @@ . (!empty($this->capcode) ? capcode($this->capcode) : ''); // IP Address - if($this->mod && $this->mod['type'] >= $config['mod']['show_ip']) { + if($this->mod && hasPermission($config['mod']['show_ip'], $board['uri'], $this->mod)) { $built .= ' [' . $this->ip . ']'; } @@ -436,43 +436,42 @@ $built = ''; if($this->mod) { // Mod controls (on posts) - $built .= ''; - // Delete - if($this->mod['type'] >= $config['mod']['delete']) + if(hasPermission($config['mod']['delete'], $board['uri'], $this->mod)) $built .= ' ' . confirmLink($config['mod']['link_delete'], 'Delete', 'Are you sure you want to delete this?', $board['uri'] . '/delete/' . $this->id); // Delete all posts by IP - if($this->mod['type'] >= $config['mod']['deletebyip']) + if(hasPermission($config['mod']['deletebyip'], $board['uri'], $this->mod)) $built .= ' ' . confirmLink($config['mod']['link_deletebyip'], 'Delete all posts by IP', 'Are you sure you want to delete all posts by IP?', $board['uri'] . '/deletebyip/' . $this->id); // Ban - if($this->mod['type'] >= $config['mod']['ban']) + if(hasPermission($config['mod']['ban'], $board['uri'], $this->mod)) $built .= ' ' . $config['mod']['link_ban'] . ''; // Ban & Delete - if($this->mod['type'] >= $config['mod']['bandelete']) + if(hasPermission($config['mod']['bandelete'], $board['uri'], $this->mod)) $built .= ' ' . $config['mod']['link_bandelete'] . ''; // Delete file (keep post) - if(!empty($this->file) && $this->file != 'deleted' && $this->mod['type'] >= $config['mod']['deletefile']) + if(!empty($this->file) && $this->file != 'deleted' && hasPermission($config['mod']['deletefile'], $board['uri'], $this->mod)) $built .= ' ' . $config['mod']['link_deletefile'] . ''; // Sticky - if($this->mod['type'] >= $config['mod']['sticky']) + if(hasPermission($config['mod']['sticky'], $board['uri'], $this->mod)) if($this->sticky) $built .= ' ' . $config['mod']['link_desticky'] . ''; else $built .= ' ' . $config['mod']['link_sticky'] . ''; // Lock - if($this->mod['type'] >= $config['mod']['lock']) + if(hasPermission($config['mod']['lock'], $board['uri'], $this->mod)) if($this->locked) $built .= ' ' . $config['mod']['link_unlock'] . ''; else $built .= ' ' . $config['mod']['link_lock'] . ''; - $built .= ''; + if(!empty($built)) + $built = '' . $built . ''; } return $built; } @@ -534,7 +533,8 @@ . (!empty($this->capcode) ? capcode($this->capcode) : ''); // IP Address - if($this->mod && $this->mod['type'] >= $config['mod']['show_ip']) { + + if($this->mod && hasPermission($config['mod']['show_ip'], $board['uri'], $this->mod)) { $built .= ' [' . $this->ip . ']'; } diff --git a/inc/mod.php b/inc/mod.php index 78351ba7..0acb3864 100644 --- a/inc/mod.php +++ b/inc/mod.php @@ -14,6 +14,21 @@ return substr(base64_encode(sha1(rand() . time(), true)), 0, $length); } + function hasPermission($action = null, $board = null, $_mod = null) { + if(isset($_mod)) + $mod = &$_mod; + else + global $mod; + + if(isset($action) && $mod['type'] < $action) + return false; + + if(isset($board) && !in_array($board, $mod['boards'])) + return false; + + return true; + } + function login($username, $password, $makehash=true) { global $mod; @@ -22,7 +37,7 @@ $password = sha1($password); } - $query = prepare("SELECT `id`,`type` FROM `mods` WHERE `username` = :username AND `password` = :password LIMIT 1"); + $query = prepare("SELECT `id`,`type`,`boards` FROM `mods` WHERE `username` = :username AND `password` = :password LIMIT 1"); $query->bindValue(':username', $username); $query->bindValue(':password', $password); $query->execute() or error(db_error($query)); @@ -33,7 +48,8 @@ 'type' => $user['type'], 'username' => $username, 'password' => $password, - 'hash' => isset($_SESSION['mod']['hash']) ? $_SESSION['mod']['hash'] : mkhash() + 'hash' => isset($_SESSION['mod']['hash']) ? $_SESSION['mod']['hash'] : mkhash(), + 'boards' => explode(',', $user['boards']) ); } else return false; } @@ -230,4 +246,4 @@ ''; } -?> \ No newline at end of file +?> diff --git a/install.php b/install.php index a9e6b2e6..d9aafd2f 100644 --- a/install.php +++ b/install.php @@ -1,6 +1,6 @@ bindValue(':id', $match[1], PDO::PARAM_INT); @@ -484,7 +484,7 @@ header('Location: ?/noticeboard', true, $config['redirect_http']); } elseif(preg_match('/^\/noticeboard$/', $query)) { - if($mod['type'] < $config['mod']['noticeboard']) error($config['error']['noaccess']); + if(!hasPermission($config['mod']['noticeboard'])) error($config['error']['noaccess']); $body = ''; @@ -553,7 +553,7 @@ ) ); } elseif(preg_match('/^\/news\/delete\/(\d+)$/', $query, $match)) { - if($mod['type'] < $config['mod']['noticeboard_delete']) error($config['error']['noaccess']); + if(!hasPermission($config['mod']['noticeboard_delete'])) error($config['error']['noaccess']); $query = prepare("DELETE FROM `news` WHERE `id` = :id"); $query->bindValue(':id', $match[1], PDO::PARAM_INT); @@ -744,7 +744,7 @@ ); } } elseif(preg_match('/^\/new_PM\/(\d+)(\/(\d+))?$/', $query, $match)) { - if($mod['type'] < $config['mod']['create_pm']) error($config['error']['noaccess']); + if(!hasPermission($config['mod']['create_pm'])) error($config['error']['noaccess']); $to = &$match[1]; @@ -826,7 +826,7 @@ ); } } elseif(preg_match('/^\/search$/', $query)) { - if($mod['type'] < $config['mod']['search']) error($config['error']['noaccess']); + if(!hasPermission($config['mod']['search'])) error($config['error']['noaccess']); $body = '

Search

' . '

' . @@ -920,9 +920,9 @@ ) ); } elseif(preg_match('/^\/users$/', $query)) { - if($mod['type'] < $config['mod']['manageusers']) error($config['error']['noaccess']); + if(!hasPermission($config['mod']['manageusers'])) error($config['error']['noaccess']); - $body = ''; + $body = '
IDUsernameTypeLast action
'; $query = query("SELECT *, (SELECT `time` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `last`, (SELECT `text` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `action` FROM `mods` ORDER BY `type` DESC,`id`") or error(db_error()); while($_mod = $query->fetch()) { @@ -940,6 +940,10 @@ $type . '' . + '' . + '' . + '' . '
IDUsernameTypeBoardsLast action
' . + str_replace(',', ', ', $_mod['boards']) . + '' . ($_mod['last'] ? '' . ago($_mod['last']) . '' @@ -982,7 +986,7 @@ ) ); } elseif(preg_match('/^\/users\/new$/', $query)) { - if($mod['type'] < $config['mod']['createusers']) error($config['error']['noaccess']); + if(!hasPermission($config['mod']['createusers'])) error($config['error']['noaccess']); if(isset($_POST['username']) && isset($_POST['password'])) { if(!isset($_POST['type'])) { @@ -1002,15 +1006,36 @@ error(sprintf($config['error']['modexists'], $_mod['id'])); } - $query = prepare("INSERT INTO `mods` VALUES (NULL, :username, :password, :type)"); + $boards = Array(); + foreach($_POST as $name => $null) { + if(preg_match('/^board_(\w+)/', $name, $m)) + $boards[] = $m[1]; + } + $boards = implode(',', $boards); + + $query = prepare("INSERT INTO `mods` VALUES (NULL, :username, :password, :type, :boards)"); $query->bindValue(':username', $_POST['username']); $query->bindValue(':password', sha1($_POST['password'])); $query->bindValue(':type', $_POST['type'], PDO::PARAM_INT); + $query->bindValue(':boards', $boards); $query->execute() or error(db_error($query)); modLog('Create a new user: "' . $_POST['username'] . '"'); } + $__boards = '
    '; + $boards = listBoards(); + foreach($boards as &$_board) { + $__boards .= '
  • ' . + ' ' . + '' . + '
  • '; + } + $__boards .= '
'; + $body = '
New user' . // Begin form @@ -1025,6 +1050,7 @@ '
' . '
' . '
Boards' . $__boards . '
' . '' . @@ -1044,7 +1070,7 @@ if(isset($matches[2])) { if($matches[3] == 'delete') { - if($mod['type'] < $config['mod']['deleteusers']) error($config['error']['noaccess']); + if(!hasPermission($config['mod']['deleteusers'])) error($config['error']['noaccess']); $query = prepare("DELETE FROM `mods` WHERE `id` = :id"); $query->bindValue(':id', $modID, PDO::PARAM_INT); @@ -1053,7 +1079,7 @@ modLog('Deleted user #' . $modID); } else { // Promote/demote - if($mod['type'] < $config['mod']['promoteusers']) error($config['error']['noaccess']); + if(!hasPermission($config['mod']['promoteusers'])) error($config['error']['noaccess']); if($matches[3] == 'promote') { $query = prepare("UPDATE `mods` SET `type` = `type` + 1 WHERE `type` != :admin AND `id` = :id"); @@ -1069,7 +1095,7 @@ header('Location: ?/users', true, $config['redirect_http']); } else { // Edit user - if($mod['type'] < $config['mod']['editusers'] && $mod['type'] < $config['mod']['change_password']) error($config['error']['noaccess']); + if(!hasPermission($config['mod']['editusers']) || !hasPermission($config['mod']['change_password'])) error($config['error']['noaccess']); $query = prepare("SELECT * FROM `mods` WHERE `id` = :id"); $query->bindValue(':id', $modID, PDO::PARAM_INT); @@ -1084,8 +1110,16 @@ if((isset($_POST['username']) && isset($_POST['password'])) || (isset($change_password_only) && isset($_POST['password']))) { if(!isset($change_password_only)) { - $query = prepare("UPDATE `mods` SET `username` = :username WHERE `id` = :id"); - $query->bindValue(':username', $_POST['username']); + $boards = Array(); + foreach($_POST as $name => $null) { + if(preg_match('/^board_(\w+)/', $name, $m)) + $boards[] = $m[1]; + } + $boards = implode(',', $boards); + + $query = prepare("UPDATE `mods` SET `username` = :username, `boards` = :boards WHERE `id` = :id"); + $query->bindValue(':username', $_POST['username'], PDO::PARAM_STR); + $query->bindValue(':boards', $boards, PDO::PARAM_STR); $query->bindValue(':id', $modID, PDO::PARAM_INT); $query->execute() or error(db_error($query)); modLog('Edited login details for user "' . $_mod['username'] . '"'); @@ -1114,6 +1148,24 @@ } } + $__boards = '

    '; + $boards = listBoards(); + $_mod['boards'] = explode(',', $_mod['boards']); + foreach($boards as &$_board) { + $__boards .= '
  • ' . + ' ' . + '' . + '
  • '; + } + $__boards .= '
'; + $body = '
Edit user' . // Begin form @@ -1129,6 +1181,11 @@ '' . 'Password (new; optional)' . + + (isset($change_password_only) ? '' : + 'Boards' . $__boards . '' + ) . + '' . '' . @@ -1751,10 +1808,11 @@ // Redirect header('Location: ?/' . sprintf($config['board_path'], $boardName) . $config['file_index'], true, $config['redirect_http']); } elseif(preg_match('/^\/' . $regex['board'] . '(un)?lock\/(\d+)$/', $query, $matches)) { - if($mod['type'] < $config['mod']['lock']) error($config['error']['noaccess']); // Lock/Unlock $boardName = &$matches[1]; + if(!hasPermission($config['mod']['lock'], $boardName)) error($config['error']['noaccess']); + $post = &$matches[3]; // Open board if(!openBoard($boardName)) @@ -1817,7 +1875,7 @@ header('Location: ?/' . sprintf($config['board_path'], $boardName) . $config['file_index'], true, $config['redirect_http']); } elseif(preg_match('/^\/ban$/', $query)) { - if($mod['type'] < $config['mod']['ban']) error($config['error']['noaccess']); + if(!hasPermission($config['mod']['ban'])) error($config['error']['noaccess']); // Ban page if(isset($_POST['new_ban'])) { @@ -1888,7 +1946,7 @@ $query->execute() or error(db_error($query)); // Delete too - if($mod['type'] >= $config['mod']['delete'] && isset($_POST['delete']) && isset($_POST['board'])) { + if(isset($_POST['delete']) && isset($_POST['board']) && hasPermission($config['mod']['delete'], $_POST['board'])) { openBoard($_POST['board']); $post = round($_POST['delete']); @@ -1938,12 +1996,14 @@ header('Location: ?/', true, $config['redirect_http']); } } elseif(preg_match('/^\/' . $regex['board'] . 'ban(&delete)?\/(\d+)$/', $query, $matches)) { - if($mod['type'] < $config['mod']['ban']) error($config['error']['noaccess']); + // Ban by post $boardName = &$matches[1]; + if(!hasPermission($config['mod']['ban'], $boardName)) error($config['error']['noaccess']); + $delete = isset($matches[2]) && $matches[2] == '&delete'; - if($delete && $mod['type'] < $config['mod']['delete']) error($config['error']['noaccess']); + if($delete && !hasPermission($config['mod']['delete'], $boardName)) error($config['error']['noaccess']); $post = $matches[3]; // Open board @@ -1970,7 +2030,7 @@ ) ); } elseif(preg_match('/^\/IP\/(\d+\.\d+\.\d+\.\d+|' . $config['ipv6_regex'] . ')\/deletenote\/(?P\d+)$/', $query, $matches)) { - if($mod['type'] < $config['mod']['remove_notes']) error($config['error']['noaccess']); + if(!hasPermission($config['mod']['remove_notes'])) error($config['error']['noaccess']); $ip = $matches[1]; $id = $matches['id'];