Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically set cookie secure attribute, remove COOKIE_SECURE option #26953

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1744,9 +1744,6 @@ LEVEL = Info
;; Session cookie name
;COOKIE_NAME = i_like_gitea
;;
;; If you use session in https only, default is false
;COOKIE_SECURE = false
;;
;; Session GC time interval in seconds, default is 86400 (1 day)
;GC_INTERVAL_TIME = 86400
;;
Expand Down
1 change: 0 additions & 1 deletion docs/content/administration/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,6 @@ and

- `PROVIDER`: **memory**: Session engine provider \[memory, file, redis, redis-cluster, db, mysql, couchbase, memcache, postgres\]. Setting `db` will reuse the configuration in `[database]`
- `PROVIDER_CONFIG`: **data/sessions**: For file, the root path; for db, empty (database config will be used); for others, the connection string. Relative paths will be made absolute against _`AppWorkPath`_.
- `COOKIE_SECURE`: **false**: Enable this to force using HTTPS for all session access.
- `COOKIE_NAME`: **i\_like\_gitea**: The name of the cookie used for the session ID.
- `GC_INTERVAL_TIME`: **86400**: GC interval in seconds.
- `SESSION_LIFE_TIME`: **86400**: Session life time in seconds, default is 86400 (1 day)
Expand Down
1 change: 0 additions & 1 deletion docs/content/administration/config-cheat-sheet.zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,6 @@ Gitea 创建以下非唯一队列:

- `PROVIDER`: **memory**:会话存储引擎 \[memory, file, redis, redis-cluster, db, mysql, couchbase, memcache, postgres\]。设置为 `db` 将会重用 `[database]` 的配置信息。
- `PROVIDER_CONFIG`: **data/sessions**:对于文件,为根路径;对于 db,为空(将使用数据库配置);对于其他引擎,为连接字符串。相对路径将根据 _`AppWorkPath`_ 绝对化。
- `COOKIE_SECURE`: **false**:启用此选项以强制在所有会话访问中使用 HTTPS。
- `COOKIE_NAME`: **i\_like\_gitea**:用于会话 ID 的 cookie 名称。
- `GC_INTERVAL_TIME`: **86400**:GC 间隔时间,以秒为单位。
- `SESSION_LIFE_TIME`: **86400**:会话生命周期,以秒为单位,默认为 86400(1 天)。
Expand Down
26 changes: 13 additions & 13 deletions modules/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,6 @@ func NewWebContext(base *Base, render Render, session session.Store) *Context {
// Contexter initializes a classic context for a request.
func Contexter() func(next http.Handler) http.Handler {
rnd := templates.HTMLRenderer()
csrfOpts := CsrfOptions{
Secret: setting.SecretKey,
Cookie: setting.CSRFCookieName,
SetCookie: true,
Secure: setting.SessionConfig.Secure,
CookieHTTPOnly: setting.CSRFCookieHTTPOnly,
Header: "X-Csrf-Token",
CookieDomain: setting.SessionConfig.Domain,
CookiePath: setting.SessionConfig.CookiePath,
SameSite: setting.SessionConfig.SameSite,
}
if !setting.IsProd {
CsrfTokenRegenerationInterval = 5 * time.Second // in dev, re-generate the tokens more aggressively for debug purpose
}
Expand All @@ -166,6 +155,17 @@ func Contexter() func(next http.Handler) http.Handler {
ctx.Base.AppendContextValue(WebContextKey, ctx)
ctx.Base.AppendContextValueFunc(git.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })

csrfOpts := CsrfOptions{
Secret: setting.SecretKey,
Cookie: setting.CSRFCookieName,
SetCookie: true,
Secure: middleware.GetCookieSecure(ctx.Req),
Header: "X-Csrf-Token",
CookieDomain: setting.SessionConfig.Domain,
CookiePath: setting.SessionConfig.CookiePath,
CookieHTTPOnly: setting.CSRFCookieHTTPOnly,
SameSite: setting.SessionConfig.SameSite,
}
ctx.Csrf = PrepareCSRFProtector(csrfOpts, ctx)

// Get the last flash message from cookie
Expand All @@ -185,9 +185,9 @@ func Contexter() func(next http.Handler) http.Handler {
// if there are new messages in the ctx.Flash, write them into cookie
ctx.Resp.Before(func(resp ResponseWriter) {
if val := ctx.Flash.Encode(); val != "" {
middleware.SetSiteCookie(ctx.Resp, CookieNameFlash, val, 0)
middleware.SetSiteCookie(ctx.Resp, ctx.Req, CookieNameFlash, val, 0)
} else if lastFlashCookie != "" {
middleware.SetSiteCookie(ctx.Resp, CookieNameFlash, "", -1)
middleware.SetSiteCookie(ctx.Resp, ctx.Req, CookieNameFlash, "", -1)
}
})

Expand Down
4 changes: 2 additions & 2 deletions modules/context/context_cookie.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ func removeSessionCookieHeader(w http.ResponseWriter) {
// SetSiteCookie convenience function to set most cookies consistently
// CSRF and a few others are the exception here
func (ctx *Context) SetSiteCookie(name, value string, maxAge int) {
middleware.SetSiteCookie(ctx.Resp, name, value, maxAge)
middleware.SetSiteCookie(ctx.Resp, ctx.Req, name, value, maxAge)
}

// DeleteSiteCookie convenience function to delete most cookies consistently
// CSRF and a few others are the exception here
func (ctx *Context) DeleteSiteCookie(name string) {
middleware.SetSiteCookie(ctx.Resp, name, "", -1)
middleware.SetSiteCookie(ctx.Resp, ctx.Req, name, "", -1)
}

// GetSiteCookie returns given cookie value from request header.
Expand Down
3 changes: 0 additions & 3 deletions modules/setting/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ var SessionConfig = struct {
Gclifetime int64
// Max life time in seconds. Default is whatever GC interval time is.
Maxlifetime int64
// Use HTTPS only. Default is false.
Secure bool
// Cookie domain name. Default is empty.
Domain string
// SameSite declares if your cookie should be restricted to a first-party or same-site context. Valid strings are "none", "lax", "strict". Default is "lax"
Expand All @@ -50,7 +48,6 @@ func loadSessionFrom(rootCfg ConfigProvider) {
}
SessionConfig.CookieName = sec.Key("COOKIE_NAME").MustString("i_like_gitea")
SessionConfig.CookiePath = AppSubURL + "/" // there was a bug, old code only set CookePath=AppSubURL, no trailing slash
SessionConfig.Secure = sec.Key("COOKIE_SECURE").MustBool(false)
SessionConfig.Gclifetime = sec.Key("GC_INTERVAL_TIME").MustInt64(86400)
SessionConfig.Maxlifetime = sec.Key("SESSION_LIFE_TIME").MustInt64(86400)
SessionConfig.Domain = sec.Key("DOMAIN").String()
Expand Down
23 changes: 17 additions & 6 deletions modules/web/middleware/cookie.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import (
)

// SetRedirectToCookie convenience function to set the RedirectTo cookie consistently
func SetRedirectToCookie(resp http.ResponseWriter, value string) {
SetSiteCookie(resp, "redirect_to", value, 0)
func SetRedirectToCookie(resp http.ResponseWriter, req *http.Request, value string) {
SetSiteCookie(resp, req, "redirect_to", value, 0)
}

// DeleteRedirectToCookie convenience function to delete most cookies consistently
func DeleteRedirectToCookie(resp http.ResponseWriter) {
SetSiteCookie(resp, "redirect_to", "", -1)
func DeleteRedirectToCookie(resp http.ResponseWriter, req *http.Request) {
SetSiteCookie(resp, req, "redirect_to", "", -1)
}

// GetSiteCookie returns given cookie value from request header.
Expand All @@ -32,15 +32,26 @@ func GetSiteCookie(req *http.Request, name string) string {
return val
}

// GetCookieSecure returns whether the "Secure" attribute on a cookie should be set
func GetCookieSecure(req *http.Request) bool {
forwardedProto := req.Header.Get("x-forwarded-proto")
if forwardedProto != "" {
return forwardedProto == "https"
} else {
return req.TLS != nil
}
}

// SetSiteCookie returns given cookie value from request header.
func SetSiteCookie(resp http.ResponseWriter, name, value string, maxAge int) {
func SetSiteCookie(resp http.ResponseWriter, req *http.Request, name, value string, maxAge int) {

silverwind marked this conversation as resolved.
Show resolved Hide resolved
cookie := &http.Cookie{
Name: name,
Value: url.QueryEscape(value),
MaxAge: maxAge,
Path: setting.SessionConfig.CookiePath,
Domain: setting.SessionConfig.Domain,
Secure: setting.SessionConfig.Secure,
Secure: GetCookieSecure(req),
HttpOnly: true,
SameSite: setting.SessionConfig.SameSite,
}
Expand Down
10 changes: 5 additions & 5 deletions modules/web/middleware/locale.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,19 @@ func Locale(resp http.ResponseWriter, req *http.Request) translation.Locale {
}

if changeLang {
SetLocaleCookie(resp, lang, 1<<31-1)
SetLocaleCookie(resp, req, lang, 1<<31-1)
}

return translation.NewLocale(lang)
}

// SetLocaleCookie convenience function to set the locale cookie consistently
func SetLocaleCookie(resp http.ResponseWriter, lang string, maxAge int) {
SetSiteCookie(resp, "lang", lang, maxAge)
func SetLocaleCookie(resp http.ResponseWriter, req *http.Request, lang string, maxAge int) {
SetSiteCookie(resp, req, "lang", lang, maxAge)
}

// DeleteLocaleCookie convenience function to delete the locale cookie consistently
// Setting the lang cookie will trigger the middleware to reset the language to previous state.
func DeleteLocaleCookie(resp http.ResponseWriter) {
SetSiteCookie(resp, "lang", "", -1)
func DeleteLocaleCookie(resp http.ResponseWriter, req *http.Request) {
SetSiteCookie(resp, req, "lang", "", -1)
}
1 change: 0 additions & 1 deletion options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3109,7 +3109,6 @@ config.provider_config = Provider Config
config.cookie_name = Cookie Name
config.gc_interval_time = GC Interval Time
config.session_life_time = Session Life Time
config.https_only = HTTPS Only
config.cookie_life_time = Cookie Life Time

config.picture_config = Picture and Avatar Configuration
Expand Down
27 changes: 16 additions & 11 deletions routers/common/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,20 @@ func stripSlashesMiddleware(next http.Handler) http.Handler {
}

func Sessioner() func(next http.Handler) http.Handler {
return session.Sessioner(session.Options{
Provider: setting.SessionConfig.Provider,
ProviderConfig: setting.SessionConfig.ProviderConfig,
CookieName: setting.SessionConfig.CookieName,
CookiePath: setting.SessionConfig.CookiePath,
Gclifetime: setting.SessionConfig.Gclifetime,
Maxlifetime: setting.SessionConfig.Maxlifetime,
Secure: setting.SessionConfig.Secure,
SameSite: setting.SessionConfig.SameSite,
Domain: setting.SessionConfig.Domain,
})
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
handler := session.Sessioner(session.Options{
Provider: setting.SessionConfig.Provider,
ProviderConfig: setting.SessionConfig.ProviderConfig,
CookieName: setting.SessionConfig.CookieName,
CookiePath: setting.SessionConfig.CookiePath,
Gclifetime: setting.SessionConfig.Gclifetime,
Maxlifetime: setting.SessionConfig.Maxlifetime,
Secure: middleware.GetCookieSecure(req),
SameSite: setting.SessionConfig.SameSite,
Domain: setting.SessionConfig.Domain,
})
handler(next).ServeHTTP(resp, req)
})
}
Copy link
Member Author

@silverwind silverwind Sep 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure this usage is correct, but it appears to work.

Copy link
Contributor

@wxiaoguang wxiaoguang Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "next" call is right, but the Sessioner is not designed to be used like this. eg: It starts a GC goroutine for every session.Sessioner() call.

The sessioner expects there should be only one instance for all requests.

Copy link
Member Author

@silverwind silverwind Sep 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is suboptimal, I think the only other option is to let sessioner accept a func for the Secure attribute as well, or add a autoSecure option. Or look for alternative sessioners that are more flexible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not only suboptimal, it breaks the Sessioner's design and would cause bugs. The Sessioner also has many internal states, it expects the only one instance do "Init" (eg: connect to redis) and do session management (eg: Lock, GC).

Although we could make some changes to make a Sessioner work with dynamic Cookie Secure option, but I think it's too complex to do that, and "dynamic Cookie Secure" doesn't seem really bring enough benefit.

The mentioned "AppURL + COOKIE_SECURE option" should be simple enough and I don't see any problem by doing that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not just cookie secure. If the backend wants for example to reconstruct the original URL a client used (for example for audit log), XFP is required for that as well.

Maybe I'll look into sessioner accepting a function (typecheck with Reflect), that seems the simplest option.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the backend wants for example to reconstruct the original URL a client used (for example for audit log), XFP is required for that as well.

Just use AppURL, in many cases, the backend doesn't have the HTTP request context.

So, AppURL should always be correct.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless the app runs on multiple URLs :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless the app runs on multiple URLs :)

Yup, but the AppURL should also be correct in this case, otherwise the nofication/mail/webhook would stop working.

As long as the AppURL should be always right, then just use it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
1 change: 0 additions & 1 deletion routers/web/admin/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ func Config(ctx *context.Context) {
sessionCfg.CookiePath = realSession.CookiePath
sessionCfg.Gclifetime = realSession.Gclifetime
sessionCfg.Maxlifetime = realSession.Maxlifetime
sessionCfg.Secure = realSession.Secure
sessionCfg.Domain = realSession.Domain
}
sessionCfg.ProviderConfig = shadowPassword(sessionCfg.Provider, sessionCfg.ProviderConfig)
Expand Down
16 changes: 8 additions & 8 deletions routers/web/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func resetLocale(ctx *context.Context, u *user_model.User) error {
}
}

middleware.SetLocaleCookie(ctx.Resp, u.Language, 0)
middleware.SetLocaleCookie(ctx.Resp, ctx.Req, u.Language, 0)

if ctx.Locale.Language() != u.Language {
ctx.Locale = middleware.Locale(ctx.Resp, ctx.Req)
Expand All @@ -123,13 +123,13 @@ func checkAutoLogin(ctx *context.Context) bool {

redirectTo := ctx.FormString("redirect_to")
if len(redirectTo) > 0 {
middleware.SetRedirectToCookie(ctx.Resp, redirectTo)
middleware.SetRedirectToCookie(ctx.Resp, ctx.Req, redirectTo)
} else {
redirectTo = ctx.GetSiteCookie("redirect_to")
}

if isSucceed {
middleware.DeleteRedirectToCookie(ctx.Resp)
middleware.DeleteRedirectToCookie(ctx.Resp, ctx.Req)
ctx.RedirectToFirst(redirectTo, setting.AppSubURL+string(setting.LandingPageURL))
return true
}
Expand Down Expand Up @@ -323,7 +323,7 @@ func handleSignInFull(ctx *context.Context, u *user_model.User, remember, obeyRe
}
}

middleware.SetLocaleCookie(ctx.Resp, u.Language, 0)
middleware.SetLocaleCookie(ctx.Resp, ctx.Req, u.Language, 0)

if ctx.Locale.Language() != u.Language {
ctx.Locale = middleware.Locale(ctx.Resp, ctx.Req)
Expand All @@ -340,7 +340,7 @@ func handleSignInFull(ctx *context.Context, u *user_model.User, remember, obeyRe
}

if redirectTo := ctx.GetSiteCookie("redirect_to"); len(redirectTo) > 0 && !utils.IsExternalURL(redirectTo) {
middleware.DeleteRedirectToCookie(ctx.Resp)
middleware.DeleteRedirectToCookie(ctx.Resp, ctx.Req)
if obeyRedirect {
ctx.RedirectToFirst(redirectTo)
}
Expand Down Expand Up @@ -371,7 +371,7 @@ func HandleSignOut(ctx *context.Context) {
ctx.DeleteSiteCookie(setting.CookieUserName)
ctx.DeleteSiteCookie(setting.CookieRememberName)
ctx.Csrf.DeleteCookie(ctx)
middleware.DeleteRedirectToCookie(ctx.Resp)
middleware.DeleteRedirectToCookie(ctx.Resp, ctx.Req)
}

// SignOut sign out from login status
Expand Down Expand Up @@ -400,7 +400,7 @@ func SignUp(ctx *context.Context) {

redirectTo := ctx.FormString("redirect_to")
if len(redirectTo) > 0 {
middleware.SetRedirectToCookie(ctx.Resp, redirectTo)
middleware.SetRedirectToCookie(ctx.Resp, ctx.Req, redirectTo)
}

ctx.HTML(http.StatusOK, tplSignUp)
Expand Down Expand Up @@ -735,7 +735,7 @@ func handleAccountActivation(ctx *context.Context, user *user_model.User) {

ctx.Flash.Success(ctx.Tr("auth.account_activated"))
if redirectTo := ctx.GetSiteCookie("redirect_to"); len(redirectTo) > 0 {
middleware.DeleteRedirectToCookie(ctx.Resp)
middleware.DeleteRedirectToCookie(ctx.Resp, ctx.Req)
ctx.RedirectToFirst(redirectTo)
return
}
Expand Down
4 changes: 2 additions & 2 deletions routers/web/auth/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ func SignInOAuth(ctx *context.Context) {

redirectTo := ctx.FormString("redirect_to")
if len(redirectTo) > 0 {
middleware.SetRedirectToCookie(ctx.Resp, redirectTo)
middleware.SetRedirectToCookie(ctx.Resp, ctx.Req, redirectTo)
}

// try to do a direct callback flow, so we don't authenticate the user again but use the valid accesstoken to get the user
Expand Down Expand Up @@ -1163,7 +1163,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model
}

if redirectTo := ctx.GetSiteCookie("redirect_to"); len(redirectTo) > 0 {
middleware.DeleteRedirectToCookie(ctx.Resp)
middleware.DeleteRedirectToCookie(ctx.Resp, ctx.Req)
ctx.RedirectToFirst(redirectTo)
return
}
Expand Down
4 changes: 2 additions & 2 deletions routers/web/auth/openid.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ func SignInOpenID(ctx *context.Context) {

redirectTo := ctx.FormString("redirect_to")
if len(redirectTo) > 0 {
middleware.SetRedirectToCookie(ctx.Resp, redirectTo)
middleware.SetRedirectToCookie(ctx.Resp, ctx.Req, redirectTo)
} else {
redirectTo = ctx.GetSiteCookie("redirect_to")
}

if isSucceed {
middleware.DeleteRedirectToCookie(ctx.Resp)
middleware.DeleteRedirectToCookie(ctx.Resp, ctx.Req)
ctx.RedirectToFirst(redirectTo)
return
}
Expand Down
2 changes: 1 addition & 1 deletion routers/web/auth/password.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ func MustChangePasswordPost(ctx *context.Context) {
log.Trace("User updated password: %s", u.Name)

if redirectTo := ctx.GetSiteCookie("redirect_to"); len(redirectTo) > 0 && !utils.IsExternalURL(redirectTo) {
middleware.DeleteRedirectToCookie(ctx.Resp)
middleware.DeleteRedirectToCookie(ctx.Resp, ctx.Req)
ctx.RedirectToFirst(redirectTo)
return
}
Expand Down
2 changes: 1 addition & 1 deletion routers/web/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func Home(ctx *context.Context) {
} else if ctx.Doer.MustChangePassword {
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI())
middleware.SetRedirectToCookie(ctx.Resp, ctx.Req, setting.AppSubURL+ctx.Req.URL.RequestURI())
ctx.Redirect(setting.AppSubURL + "/user/settings/change_password")
} else {
user.Dashboard(ctx)
Expand Down
2 changes: 1 addition & 1 deletion routers/web/user/setting/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ func UpdateUserLang(ctx *context.Context) {
}

// Update the language to the one we just set
middleware.SetLocaleCookie(ctx.Resp, ctx.Doer.Language, 0)
middleware.SetLocaleCookie(ctx.Resp, ctx.Req, ctx.Doer.Language, 0)

log.Trace("User settings updated: %s", ctx.Doer.Name)
ctx.Flash.Success(translation.NewLocale(ctx.Doer.Language).Tr("settings.update_language_success"))
Expand Down
2 changes: 1 addition & 1 deletion services/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func handleSignIn(resp http.ResponseWriter, req *http.Request, sess SessionStore
}
}

middleware.SetLocaleCookie(resp, user.Language, 0)
middleware.SetLocaleCookie(resp, req, user.Language, 0)

// Clear whatever CSRF has right now, force to generate a new one
if ctx := gitea_context.GetWebContext(req); ctx != nil {
Expand Down
6 changes: 3 additions & 3 deletions services/auth/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func VerifyAuthWithOptions(options *VerifyOptions) func(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
if ctx.Req.URL.Path != "/user/events" {
middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI())
middleware.SetRedirectToCookie(ctx.Resp, ctx.Req, setting.AppSubURL+ctx.Req.URL.RequestURI())
}
ctx.Redirect(setting.AppSubURL + "/user/settings/change_password")
return
Expand Down Expand Up @@ -136,7 +136,7 @@ func VerifyAuthWithOptions(options *VerifyOptions) func(ctx *context.Context) {
if options.SignInRequired {
if !ctx.IsSigned {
if ctx.Req.URL.Path != "/user/events" {
middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI())
middleware.SetRedirectToCookie(ctx.Resp, ctx.Req, setting.AppSubURL+ctx.Req.URL.RequestURI())
}
ctx.Redirect(setting.AppSubURL + "/user/login")
return
Expand All @@ -151,7 +151,7 @@ func VerifyAuthWithOptions(options *VerifyOptions) func(ctx *context.Context) {
if !options.SignOutRequired && !ctx.IsSigned &&
len(ctx.GetSiteCookie(setting.CookieUserName)) > 0 {
if ctx.Req.URL.Path != "/user/events" {
middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI())
middleware.SetRedirectToCookie(ctx.Resp, ctx.Req, setting.AppSubURL+ctx.Req.URL.RequestURI())
}
ctx.Redirect(setting.AppSubURL + "/user/login")
return
Expand Down
Loading
Loading