From bd9ed96da50de283485a4e274b414b7dd1d22ba6 Mon Sep 17 00:00:00 2001
From: zeripath <art27@cantab.net>
Date: Tue, 28 May 2019 07:18:40 +0100
Subject: [PATCH] Install page - Handle invalid administrator username better
 (#7060)

* Install page - detect invalid admin username before installing

* Also fix #6954
---
 options/locale/locale_en-US.ini |  4 +++
 routers/install.go              | 48 ++++++++++++++++++++++++---------
 2 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index d2079415d0..a691232cff 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -94,6 +94,10 @@ sqlite_helper = File path for the SQLite3 database.<br>Enter an absolute path if
 err_empty_db_path = The SQLite3 database path cannot be empty.
 no_admin_and_disable_registration = You cannot disable user self-registration without creating an administrator account.
 err_empty_admin_password = The administrator password cannot be empty.
+err_empty_admin_email = The administrator email cannot be empty.
+err_admin_name_is_reserved = Administrator Username is invalid, username is reserved
+err_admin_name_pattern_not_allowed = Administrator Username is invalid, username is pattern is not allowed
+err_admin_name_is_invalid = Administrator Username is invalid
 
 general_title = General Settings
 app_name = Site Title
diff --git a/routers/install.go b/routers/install.go
index cc8be065a8..c95abebea7 100644
--- a/routers/install.go
+++ b/routers/install.go
@@ -215,18 +215,42 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) {
 		return
 	}
 
-	// Check admin password.
-	if len(form.AdminName) > 0 && len(form.AdminPasswd) == 0 {
-		ctx.Data["Err_Admin"] = true
-		ctx.Data["Err_AdminPasswd"] = true
-		ctx.RenderWithErr(ctx.Tr("install.err_empty_admin_password"), tplInstall, form)
-		return
-	}
-	if form.AdminPasswd != form.AdminConfirmPasswd {
-		ctx.Data["Err_Admin"] = true
-		ctx.Data["Err_AdminPasswd"] = true
-		ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplInstall, form)
-		return
+	// Check admin user creation
+	if len(form.AdminName) > 0 {
+		// Ensure AdminName is valid
+		if err := models.IsUsableUsername(form.AdminName); err != nil {
+			ctx.Data["Err_Admin"] = true
+			ctx.Data["Err_AdminName"] = true
+			if models.IsErrNameReserved(err) {
+				ctx.RenderWithErr(ctx.Tr("install.err_admin_name_is_reserved"), tplInstall, form)
+				return
+			} else if models.IsErrNamePatternNotAllowed(err) {
+				ctx.RenderWithErr(ctx.Tr("install.err_admin_name_pattern_not_allowed"), tplInstall, form)
+				return
+			}
+			ctx.RenderWithErr(ctx.Tr("install.err_admin_name_is_invalid"), tplInstall, form)
+			return
+		}
+		// Check Admin email
+		if len(form.AdminEmail) == 0 {
+			ctx.Data["Err_Admin"] = true
+			ctx.Data["Err_AdminEmail"] = true
+			ctx.RenderWithErr(ctx.Tr("install.err_empty_admin_email"), tplInstall, form)
+			return
+		}
+		// Check admin password.
+		if len(form.AdminPasswd) == 0 {
+			ctx.Data["Err_Admin"] = true
+			ctx.Data["Err_AdminPasswd"] = true
+			ctx.RenderWithErr(ctx.Tr("install.err_empty_admin_password"), tplInstall, form)
+			return
+		}
+		if form.AdminPasswd != form.AdminConfirmPasswd {
+			ctx.Data["Err_Admin"] = true
+			ctx.Data["Err_AdminPasswd"] = true
+			ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplInstall, form)
+			return
+		}
 	}
 
 	if form.AppURL[len(form.AppURL)-1] != '/' {