From 72638acac3dd6c25cdf707e316e735f4d8ceeec1 Mon Sep 17 00:00:00 2001
From: Tobias Diekershoff <tobias.diekershoff@gmx.net>
Date: Fri, 6 Jul 2018 15:32:56 +0200
Subject: [PATCH 1/2] admins can forbid some nicknames from being registered

---
 mod/admin.php                 |  5 +++++
 src/Model/User.php            | 29 +++++++++++++++++++++++++++++
 view/templates/admin/site.tpl |  1 +
 3 files changed, 35 insertions(+)

diff --git a/mod/admin.php b/mod/admin.php
index b43baa4433..f12ec5e3b2 100644
--- a/mod/admin.php
+++ b/mod/admin.php
@@ -975,6 +975,7 @@ function admin_page_site_post(App $a)
 
 	$allowed_sites		=	((x($_POST,'allowed_sites'))		? notags(trim($_POST['allowed_sites']))		: '');
 	$allowed_email		=	((x($_POST,'allowed_email'))		? notags(trim($_POST['allowed_email']))		: '');
+	$forbidden_nicknames	=	((x($_POST,'forbidden_nicknames'))	? strtolower(notags(trim($_POST['forbidden_nicknames'])))		: '');
 	$no_oembed_rich_content = x($_POST,'no_oembed_rich_content');
 	$allowed_oembed		=	((x($_POST,'allowed_oembed'))		? notags(trim($_POST['allowed_oembed']))		: '');
 	$block_public		=	((x($_POST,'block_public'))		? True						: False);
@@ -1143,6 +1144,7 @@ function admin_page_site_post(App $a)
 	Config::set('config', 'register_text', $register_text);
 	Config::set('system', 'allowed_sites', $allowed_sites);
 	Config::set('system', 'allowed_email', $allowed_email);
+	Config::set('system', 'forbidden_nicknames', $forbidden_nicknames);
 	Config::set('system', 'no_oembed_rich_content', $no_oembed_rich_content);
 	Config::set('system', 'allowed_oembed', $allowed_oembed);
 	Config::set('system', 'block_public', $block_public);
@@ -1349,6 +1351,8 @@ function admin_page_site(App $a)
 	if ($optimize_max_tablesize <= 0) {
 		$optimize_max_tablesize = -1;
 	}
+	// Default list of forbidden names, classic role names from RFC 2142
+	$default_forbidden_nicknames = 'info, marketing, sales, support, abuse, noc, security, postmaster, hostmaster, usenet, news, webmaster, www, uucp, ftp, root, sysop';
 
 	$t = get_markup_template('admin/site.tpl');
 	return replace_macros($t, [
@@ -1388,6 +1392,7 @@ function admin_page_site(App $a)
 		'$register_policy'	=> ['register_policy', L10n::t("Register policy"), $a->config['register_policy'], "", $register_choices],
 		'$daily_registrations'	=> ['max_daily_registrations', L10n::t("Maximum Daily Registrations"), Config::get('system', 'max_daily_registrations'), L10n::t("If registration is permitted above, this sets the maximum number of new user registrations to accept per day.  If register is set to closed, this setting has no effect.")],
 		'$register_text'	=> ['register_text', L10n::t("Register text"), $a->config['register_text'], L10n::t("Will be displayed prominently on the registration page. You can use BBCode here.")],
+		'$forbidden_nicknames' => ['forbidden_nicknames', L10n::t('Forbidden Nicknames'), Config::get('system', 'forbidden_nicknames', $default_forbidden_nicknames), L10n::t('Comma separated list of nicknames that are forbidden from registration. Preset is a list of role names according RFC 2142.')],
 		'$abandon_days'		=> ['abandon_days', L10n::t('Accounts abandoned after x days'), Config::get('system','account_abandon_days'), L10n::t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')],
 		'$allowed_sites'	=> ['allowed_sites', L10n::t("Allowed friend domains"), Config::get('system','allowed_sites'), L10n::t("Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains")],
 		'$allowed_email'	=> ['allowed_email', L10n::t("Allowed email domains"), Config::get('system','allowed_email'), L10n::t("Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains")],
diff --git a/src/Model/User.php b/src/Model/User.php
index 6754f22070..f1fa32f48d 100644
--- a/src/Model/User.php
+++ b/src/Model/User.php
@@ -304,6 +304,32 @@ class User
 		return dba::update('user', $fields, ['uid' => $uid]);
 	}
 
+	/**
+	 * @brief Checks if a nickname is in the list of the forbidden nicknames
+	 *
+	 * Check if a nickname is forbidden from registration on the node by the
+	 * admin. Forbidden nicknames (e.g. role namess) can be configured in the
+	 * admin panel.
+	 *
+	 * @param string $nickname The nickname that should be checked
+	 * @return boolean True is the nickname is blocked on the node
+	 */
+	public static function isNicknameBlocked($nickname)
+	{
+		$forbidden_nicknames = Config::get('system', 'forbidden_nicknames', '');
+		// if the config variable is empty return false
+		if (!x($forbidden_nicknames)) {
+			return false;
+		}
+		// check if the nickname is in the list of blocked nicknames
+		$forbidden = explode(',', $forbidden_nicknames);
+		if (in_array(strtolower($nickname), $forbidden)) {
+			return true;
+		}
+		// else return false
+		return false;
+	}
+
 	/**
 	 * @brief Catch-all user creation function
 	 *
@@ -417,6 +443,9 @@ class User
 		if (!valid_email($email) || !Network::isEmailDomainValid($email)) {
 			throw new Exception(L10n::t('Not a valid email address.'));
 		}
+		if (self::isNicknameBlocked($nickname)) {
+			throw new Exception(L10n::t('The nickname was blocked from registration by the nodes admin.'));
+		}
 
 		if (Config::get('system', 'block_extended_register', false) && dba::exists('user', ['email' => $email])) {
 			throw new Exception(L10n::t('Cannot use that email.'));
diff --git a/view/templates/admin/site.tpl b/view/templates/admin/site.tpl
index 0b46aa9919..31b3b68ca2 100644
--- a/view/templates/admin/site.tpl
+++ b/view/templates/admin/site.tpl
@@ -78,6 +78,7 @@
 	<h3>{{$corporate}}</h3>
 	{{include file="field_input.tpl" field=$allowed_sites}}
 	{{include file="field_input.tpl" field=$allowed_email}}
+	{{include file="field_input.tpl" field=$forbidden_nicknames}}
 	{{include file="field_checkbox.tpl" field=$no_oembed_rich_content}}
 	{{include file="field_input.tpl" field=$allowed_oembed}}
 	{{include file="field_checkbox.tpl" field=$block_public}}

From a49e09430886057b3c00fcdb3ac0ec58cc97f6eb Mon Sep 17 00:00:00 2001
From: Tobias Diekershoff <tobias.diekershoff@gmx.net>
Date: Fri, 6 Jul 2018 15:49:27 +0200
Subject: [PATCH 2/2] added forgotten trim

---
 src/Model/User.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/Model/User.php b/src/Model/User.php
index f1fa32f48d..dc5702b605 100644
--- a/src/Model/User.php
+++ b/src/Model/User.php
@@ -323,6 +323,7 @@ class User
 		}
 		// check if the nickname is in the list of blocked nicknames
 		$forbidden = explode(',', $forbidden_nicknames);
+		$forbidden = array_map('trim', $forbidden);
 		if (in_array(strtolower($nickname), $forbidden)) {
 			return true;
 		}