diff --git a/modules/context/context.go b/modules/context/context.go index 311186e64..896169484 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 20ea1e24a..236d66bd1 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 6edcb914b..d44939f50 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 c784d7e1e..04435dd88 100644 --- a/routers/user/auth_openid.go +++ b/routers/user/auth_openid.go @@ -49,12 +49,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 d63f84afd..4c5cbf508 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()) }