diff --git a/inc/config.php b/inc/config.php
index d19af058..03df743d 100644
--- a/inc/config.php
+++ b/inc/config.php
@@ -123,6 +123,7 @@
$config['error']['noaccess'] = 'You don\'t have permission to do that.';
$config['error']['invalidpost'] = 'That post doesn\'t exist…';
$config['error']['404'] = 'Page not found.';
+ $config['error']['modexists'] = 'That mod already exists!';
// How many reports you can create in the same request.
$config['report_limit'] = 2;
@@ -299,6 +300,16 @@
$config['mod']['manageboards'] = ADMIN;
// Delete a board
$config['mod']['deleteboard'] = ADMIN;
+ // List/manage users
+ $config['mod']['manageusers'] = MOD;
+ // Promote/demote users
+ $config['mod']['promoteusers'] = ADMIN;
+ // Edit any users' login information
+ $config['mod']['editusers'] = ADMIN;
+ // Delete a user
+ $config['mod']['deleteusers'] = ADMIN;
+ // Create a user
+ $config['mod']['createusers'] = ADMIN;
// Mod links (full HTML)
// Correspond to above permission directives
diff --git a/inc/functions.php b/inc/functions.php
index 3840e03b..8b8b2b59 100644
--- a/inc/functions.php
+++ b/inc/functions.php
@@ -865,7 +865,7 @@
$body = utf8tohtml($body, true);
if($config['wiki_markup']) {
- $body = preg_replace("/(^|\n)==(.+?)==\n?/m", "
$2
", $body);
+ $body = preg_replace("/(^|\n)==(.+?)==\n?/m", "$2", $body);
$body = preg_replace("/'''(.+?)'''/m", "$1", $body);
$body = preg_replace("/''(.+?)''/m", "$1", $body);
$body = preg_replace("/\*\*(.+?)\*\*/m", "$1", $body);
diff --git a/mod.php b/mod.php
index 0f3aeeda..f22e6985 100644
--- a/mod.php
+++ b/mod.php
@@ -90,6 +90,9 @@
if($mod['type'] >= $config['mod']['view_banlist']) {
$fieldset['Administration'] .= 'Ban list';
}
+ if($mod['type'] >= $config['mod']['manageusers']) {
+ $fieldset['Administration'] .= 'Manage users';
+ }
if($mod['type'] >= $config['mod']['show_config']) {
$fieldset['Administration'] .= 'Show configuration';
}
@@ -109,7 +112,212 @@
//,'mod'=>true /* All 'mod' does, at this point, is put the "Return to dashboard" link in. */
)
);
+ } elseif(preg_match('/^\/users$/', $query)) {
+ $body = '';
+
+ echo Element('page.html', Array(
+ 'index'=>$config['root'],
+ 'title'=>'Manage users',
+ 'body'=>$body
+ ,'mod'=>true
+ )
+ );
+ } elseif(preg_match('/^\/users\/new$/', $query)) {
+ if($mod['type'] < $config['mod']['createusers']) error($config['error']['noaccess']);
+
+ if(isset($_POST['username']) && isset($_POST['password'])) {
+ if(!isset($_POST['type'])) {
+ error(sprintf($config['error']['required'], 'type'));
+ }
+
+ if($_POST['type'] != ADMIN && $_POST['type'] != MOD && $_POST['type'] != JANITOR) {
+ error(sprintf($config['error']['invalidfield'], 'type'));
+ }
+
+ // Check if already exists
+ $query = prepare("SELECT `id` FROM `mods` WHERE `username` = :username");
+ $query->bindValue(':username', $_POST['username']);
+ $query->execute() or error(db_error($query));
+
+ if($_mod = $query->fetch()) {
+ error(sprintf($config['error']['modexists'], $_mod['id']));
+ }
+
+ $query = prepare("INSERT INTO `mods` VALUES (NULL, :username, :password, :type)");
+ $query->bindValue(':username', $_POST['username']);
+ $query->bindValue(':password', sha1($_POST['password']));
+ $query->bindValue(':type', $_POST['type'], PDO::PARAM_INT);
+ $query->execute() or error(db_error($query));
+ }
+
+ $body = '';
+
+ echo Element('page.html', Array(
+ 'index'=>$config['root'],
+ 'title'=>'New user',
+ 'body'=>$body
+ ,'mod'=>true
+ )
+ );
+ } elseif(preg_match('/^\/users\/(\d+)(\/(promote|demote|delete))?$/', $query, $matches)) {
+ $modID = $matches[1];
+
+ if(isset($matches[2])) {
+ if($matches[3] == 'delete') {
+ if($mod['type'] < $config['mod']['deleteusers']) error($config['error']['noaccess']);
+
+ $query = prepare("DELETE FROM `mods` WHERE `id` = :id");
+ $query->bindValue(':id', $modID, PDO::PARAM_INT);
+ $query->execute() or error(db_error($query));
+ } else {
+ // Promote/demote
+ if($mod['type'] < $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");
+ $query->bindValue(':admin', ADMIN, PDO::PARAM_INT);
+ } else {
+ $query = prepare("UPDATE `mods` SET `type` = `type` - 1 WHERE `type` != :janitor AND `id` = :id");
+ $query->bindValue(':janitor', JANITOR, PDO::PARAM_INT);
+ }
+
+ $query->bindValue(':id', $modID, PDO::PARAM_INT);
+ $query->execute() or error(db_error($query));
+ }
+ header('Location: ?/users', true, $config['redirect_http']);
+ } else {
+ // Edit user
+ if($mod['type'] < $config['mod']['editusers']) error($config['error']['noaccess']);
+
+ $query = prepare("SELECT * FROM `mods` WHERE `id` = :id");
+ $query->bindValue(':id', $modID, PDO::PARAM_INT);
+ $query->execute() or error(db_error($query));
+
+ if(!$_mod = $query->fetch()) {
+ error($config['error']['404']);
+ }
+
+ if(isset($_POST['username']) && isset($_POST['password'])) {
+ $query = prepare("UPDATE `mods` SET `username` = :username WHERE `id` = :id");
+ $query->bindValue(':username', $_POST['username']);
+ $query->bindValue(':id', $modID, PDO::PARAM_INT);
+ $query->execute() or error(db_error($query));
+
+ if(!empty($_POST['password'])) {
+ $query = prepare("UPDATE `mods` SET `password` = :password WHERE `id` = :id");
+ $query->bindValue(':password', sha1($_POST['password']));
+ $query->bindValue(':id', $modID, PDO::PARAM_INT);
+ $query->execute() or error(db_error($query));
+ }
+
+ // Refresh
+ $query = prepare("SELECT * FROM `mods` WHERE `id` = :id");
+ $query->bindValue(':id', $modID, PDO::PARAM_INT);
+ $query->execute() or error(db_error($query));
+
+ $_mod = $query->fetch();
+ }
+
+ $body = '';
+
+ echo Element('page.html', Array(
+ 'index'=>$config['root'],
+ 'title'=>'Edit user',
+ 'body'=>$body
+ ,'mod'=>true
+ )
+ );
+ }
} elseif(preg_match('/^\/reports$/', $query)) {
+ if($mod['type'] < $config['mod']['reports']) error($config['error']['noaccess']);
+
$body = '';
$reports = 0;
diff --git a/style.css b/style.css
index 13ad2c56..dc60e5ed 100644
--- a/style.css
+++ b/style.css
@@ -251,6 +251,12 @@ div.ban p {
div.ban p.reason {
font-weight: bold;
}
+span.heading {
+ color: #AF0A0F;
+ font-size: 11pt;
+ font-weight: bold;
+ display: block;
+}
span.spoiler {
background: black;
color: black;