From 2a660a1de17daf58b8f7d58dea4b82b107b47536 Mon Sep 17 00:00:00 2001
From: zeripath <art27@cantab.net>
Date: Tue, 18 Dec 2018 17:05:48 +0000
Subject: [PATCH] Support reverse proxy providing email (#5554)

This PR implements #2347
---
 custom/conf/app.ini.sample                    |  2 ++
 .../doc/advanced/config-cheat-sheet.en-us.md  |  4 ++++
 modules/auth/auth.go                          |  9 +++++++-
 modules/setting/setting.go                    | 22 +++++++++++--------
 routers/admin/admin.go                        |  1 +
 5 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample
index bcf633b630..0b24bf3414 100644
--- a/custom/conf/app.ini.sample
+++ b/custom/conf/app.ini.sample
@@ -261,6 +261,7 @@ COOKIE_USERNAME = gitea_awesome
 COOKIE_REMEMBER_NAME = gitea_incredible
 ; Reverse proxy authentication header name of user name
 REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER
+REVERSE_PROXY_AUTHENTICATION_EMAIL = X-WEBAUTH-EMAIL
 ; The minimum password length for new Users
 MIN_PASSWORD_LENGTH = 6
 ; Set to true to allow users to import local server paths
@@ -323,6 +324,7 @@ ENABLE_NOTIFY_MAIL = false
 ; More detail: https://github.com/gogits/gogs/issues/165
 ENABLE_REVERSE_PROXY_AUTHENTICATION = false
 ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false
+ENABLE_REVERSE_PROXY_EMAIL = false
 ; Enable captcha validation for registration
 ENABLE_CAPTCHA = false
 ; Type of captcha you want to use. Options: image, recaptcha
diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
index 4c1b219fca..0fe6219572 100644
--- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md
+++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
@@ -160,6 +160,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
    information.
 - `REVERSE_PROXY_AUTHENTICATION_USER`: **X-WEBAUTH-USER**: Header name for reverse proxy
    authentication.
+- `REVERSE_PROXY_AUTHENTICATION_EMAIL`: **X-WEBAUTH-EMAIL**: Header name for reverse proxy
+   authentication provided email.
 - `DISABLE_GIT_HOOKS`: **false**: Set to `true` to prevent all users (including admin) from creating custom
    git hooks.
 - `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
@@ -188,6 +190,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
 - `ENABLE_REVERSE_PROXY_AUTHENTICATION`: **false**: Enable this to allow reverse proxy authentication.
 - `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: **false**: Enable this to allow auto-registration
    for reverse authentication.
+- `ENABLE_REVERSE_PROXY_EMAIL`: **false**: Enable this to allow to auto-registration with a
+   provided email rather than a generated email.
 - `ENABLE_CAPTCHA`: **false**: Enable this to use captcha validation for registration.
 - `CAPTCHA_TYPE`: **image**: \[image, recaptcha\]
 - `RECAPTCHA_SECRET`: **""**: Go to https://www.google.com/recaptcha/admin to get a secret for recaptcha.
diff --git a/modules/auth/auth.go b/modules/auth/auth.go
index 0d703084da..4b0d4559c9 100644
--- a/modules/auth/auth.go
+++ b/modules/auth/auth.go
@@ -105,9 +105,16 @@ func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool)
 
 				// Check if enabled auto-registration.
 				if setting.Service.EnableReverseProxyAutoRegister {
+					email := gouuid.NewV4().String() + "@localhost"
+					if setting.Service.EnableReverseProxyEmail {
+						webAuthEmail := ctx.Req.Header.Get(setting.ReverseProxyAuthEmail)
+						if len(webAuthEmail) > 0 {
+							email = webAuthEmail
+						}
+					}
 					u := &models.User{
 						Name:     webAuthUser,
-						Email:    gouuid.NewV4().String() + "@localhost",
+						Email:    email,
 						Passwd:   webAuthUser,
 						IsActive: true,
 					}
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index f7da6baac4..c10f165c8e 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -157,15 +157,16 @@ var (
 	}
 
 	// Security settings
-	InstallLock          bool
-	SecretKey            string
-	LogInRememberDays    int
-	CookieUserName       string
-	CookieRememberName   string
-	ReverseProxyAuthUser string
-	MinPasswordLength    int
-	ImportLocalPaths     bool
-	DisableGitHooks      bool
+	InstallLock           bool
+	SecretKey             string
+	LogInRememberDays     int
+	CookieUserName        string
+	CookieRememberName    string
+	ReverseProxyAuthUser  string
+	ReverseProxyAuthEmail string
+	MinPasswordLength     int
+	ImportLocalPaths      bool
+	DisableGitHooks       bool
 
 	// Database settings
 	UseSQLite3    bool
@@ -950,6 +951,7 @@ func NewContext() {
 	CookieUserName = sec.Key("COOKIE_USERNAME").MustString("gitea_awesome")
 	CookieRememberName = sec.Key("COOKIE_REMEMBER_NAME").MustString("gitea_incredible")
 	ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER")
+	ReverseProxyAuthEmail = sec.Key("REVERSE_PROXY_AUTHENTICATION_EMAIL").MustString("X-WEBAUTH-EMAIL")
 	MinPasswordLength = sec.Key("MIN_PASSWORD_LENGTH").MustInt(6)
 	ImportLocalPaths = sec.Key("IMPORT_LOCAL_PATHS").MustBool(false)
 	DisableGitHooks = sec.Key("DISABLE_GIT_HOOKS").MustBool(false)
@@ -1216,6 +1218,7 @@ var Service struct {
 	EnableNotifyMail                        bool
 	EnableReverseProxyAuth                  bool
 	EnableReverseProxyAutoRegister          bool
+	EnableReverseProxyEmail                 bool
 	EnableCaptcha                           bool
 	CaptchaType                             string
 	RecaptchaSecret                         string
@@ -1247,6 +1250,7 @@ func newService() {
 	Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool()
 	Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
 	Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
+	Service.EnableReverseProxyEmail = sec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool()
 	Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false)
 	Service.CaptchaType = sec.Key("CAPTCHA_TYPE").MustString(ImageCaptcha)
 	Service.RecaptchaSecret = sec.Key("RECAPTCHA_SECRET").MustString("")
diff --git a/routers/admin/admin.go b/routers/admin/admin.go
index 9b18847d6c..7d98e1af36 100644
--- a/routers/admin/admin.go
+++ b/routers/admin/admin.go
@@ -215,6 +215,7 @@ func Config(ctx *context.Context) {
 	ctx.Data["LogRootPath"] = setting.LogRootPath
 	ctx.Data["ScriptType"] = setting.ScriptType
 	ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser
+	ctx.Data["ReverseProxyAuthEmail"] = setting.ReverseProxyAuthEmail
 
 	ctx.Data["SSH"] = setting.SSH