From 7b2b900e13612f565051c64374b788b0c8a82751 Mon Sep 17 00:00:00 2001
From: Lauris BH <lauris@nix.lv>
Date: Thu, 15 Mar 2018 23:13:34 +0200
Subject: [PATCH] Refactor and simplify redirect to url (#3674)

---
 modules/context/context.go  | 21 +++++++++++++++++++++
 routers/repo/repo.go        |  6 +-----
 routers/user/auth.go        | 12 ++++--------
 routers/user/auth_openid.go |  8 ++------
 routers/user/profile.go     |  6 +-----
 5 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/modules/context/context.go b/modules/context/context.go
index ea26184397..7f9193f821 100644
--- a/modules/context/context.go
+++ b/modules/context/context.go
@@ -9,6 +9,7 @@ import (
 	"html/template"
 	"io"
 	"net/http"
+	"net/url"
 	"path"
 	"strings"
 	"time"
@@ -75,6 +76,26 @@ func (ctx *Context) HasValue(name string) bool {
 	return ok
 }
 
+// RedirectToFirst redirects to first not empty URL
+func (ctx *Context) RedirectToFirst(location ...string) {
+	for _, loc := range location {
+		if len(loc) == 0 {
+			continue
+		}
+
+		u, err := url.Parse(loc)
+		if err != nil || (u.Scheme != "" && !strings.HasPrefix(strings.ToLower(loc), strings.ToLower(setting.AppURL))) {
+			continue
+		}
+
+		ctx.Redirect(loc)
+		return
+	}
+
+	ctx.Redirect(setting.AppSubURL + "/")
+	return
+}
+
 // HTML calls Context.HTML and converts template name to string.
 func (ctx *Context) HTML(status int, name base.TplName) {
 	log.Debug("Template: %s", name)
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index 20ea1e24a2..236d66bd1f 100644
--- a/routers/repo/repo.go
+++ b/routers/repo/repo.go
@@ -307,11 +307,7 @@ func Action(ctx *context.Context) {
 		return
 	}
 
-	redirectTo := ctx.Query("redirect_to")
-	if len(redirectTo) == 0 {
-		redirectTo = ctx.Repo.RepoLink
-	}
-	ctx.Redirect(redirectTo)
+	ctx.RedirectToFirst(ctx.Query("redirect_to"), ctx.Repo.RepoLink)
 }
 
 // Download download an archive of a repository
diff --git a/routers/user/auth.go b/routers/user/auth.go
index 6edcb914b1..d44939f50d 100644
--- a/routers/user/auth.go
+++ b/routers/user/auth.go
@@ -93,12 +93,8 @@ func checkAutoLogin(ctx *context.Context) bool {
 	}
 
 	if isSucceed {
-		if len(redirectTo) > 0 {
-			ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
-			ctx.Redirect(redirectTo)
-		} else {
-			ctx.Redirect(setting.AppSubURL + string(setting.LandingPageURL))
-		}
+		ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
+		ctx.RedirectToFirst(redirectTo, setting.AppSubURL+string(setting.LandingPageURL))
 		return true
 	}
 
@@ -350,7 +346,7 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR
 	if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
 		ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
 		if obeyRedirect {
-			ctx.Redirect(redirectTo)
+			ctx.RedirectToFirst(redirectTo)
 		}
 		return
 	}
@@ -439,7 +435,7 @@ func handleOAuth2SignIn(u *models.User, gothUser goth.User, ctx *context.Context
 
 			if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
 				ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
-				ctx.Redirect(redirectTo)
+				ctx.RedirectToFirst(redirectTo)
 				return
 			}
 
diff --git a/routers/user/auth_openid.go b/routers/user/auth_openid.go
index 7df40bcc98..9fe3424aae 100644
--- a/routers/user/auth_openid.go
+++ b/routers/user/auth_openid.go
@@ -50,12 +50,8 @@ func SignInOpenID(ctx *context.Context) {
 	}
 
 	if isSucceed {
-		if len(redirectTo) > 0 {
-			ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
-			ctx.Redirect(redirectTo)
-		} else {
-			ctx.Redirect(setting.AppSubURL + "/")
-		}
+		ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
+		ctx.RedirectToFirst(redirectTo)
 		return
 	}
 
diff --git a/routers/user/profile.go b/routers/user/profile.go
index d63f84afd3..4c5cbf5081 100644
--- a/routers/user/profile.go
+++ b/routers/user/profile.go
@@ -271,9 +271,5 @@ func Action(ctx *context.Context) {
 		return
 	}
 
-	redirectTo := ctx.Query("redirect_to")
-	if len(redirectTo) == 0 {
-		redirectTo = u.HomeLink()
-	}
-	ctx.Redirect(redirectTo)
+	ctx.RedirectToFirst(ctx.Query("redirect_to"), u.HomeLink())
 }