diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2023-04-14 03:45:33 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-13 15:45:33 -0400 |
commit | 5b9557aef59b190c55de9ea218bf51152bc04786 (patch) | |
tree | d77004c983875886a00acd1561a74b8c3d5ce682 /modules/web/middleware/cookie.go | |
parent | b7221bec34fd49495234a18c26e4f5d81483e102 (diff) | |
download | gitea-5b9557aef59b190c55de9ea218bf51152bc04786.tar.gz gitea-5b9557aef59b190c55de9ea218bf51152bc04786.zip |
Refactor cookie (#24107)
Close #24062
At the beginning, I just wanted to fix the warning mentioned by #24062
But, the cookie code really doesn't look good to me, so clean up them.
Complete the TODO on `SetCookie`:
> TODO: Copied from gitea.com/macaron/macaron and should be improved
after macaron removed.
Diffstat (limited to 'modules/web/middleware/cookie.go')
-rw-r--r-- | modules/web/middleware/cookie.go | 192 |
1 files changed, 26 insertions, 166 deletions
diff --git a/modules/web/middleware/cookie.go b/modules/web/middleware/cookie.go index 7c1aaf6daf..621640895b 100644 --- a/modules/web/middleware/cookie.go +++ b/modules/web/middleware/cookie.go @@ -7,184 +7,23 @@ package middleware import ( "net/http" "net/url" - "time" + "strings" "code.gitea.io/gitea/modules/setting" ) -// MaxAge sets the maximum age for a provided cookie -func MaxAge(maxAge int) func(*http.Cookie) { - return func(c *http.Cookie) { - c.MaxAge = maxAge - } -} - -// Path sets the path for a provided cookie -func Path(path string) func(*http.Cookie) { - return func(c *http.Cookie) { - c.Path = path - } -} - -// Domain sets the domain for a provided cookie -func Domain(domain string) func(*http.Cookie) { - return func(c *http.Cookie) { - c.Domain = domain - } -} - -// Secure sets the secure setting for a provided cookie -func Secure(secure bool) func(*http.Cookie) { - return func(c *http.Cookie) { - c.Secure = secure - } -} - -// HTTPOnly sets the HttpOnly setting for a provided cookie -func HTTPOnly(httpOnly bool) func(*http.Cookie) { - return func(c *http.Cookie) { - c.HttpOnly = httpOnly - } -} - -// Expires sets the expires and rawexpires for a provided cookie -func Expires(expires time.Time) func(*http.Cookie) { - return func(c *http.Cookie) { - c.Expires = expires - c.RawExpires = expires.Format(time.UnixDate) - } -} - -// SameSite sets the SameSite for a provided cookie -func SameSite(sameSite http.SameSite) func(*http.Cookie) { - return func(c *http.Cookie) { - c.SameSite = sameSite - } -} - -// NewCookie creates a cookie -func NewCookie(name, value string, maxAge int) *http.Cookie { - return &http.Cookie{ - Name: name, - Value: value, - HttpOnly: true, - Path: setting.SessionConfig.CookiePath, - Domain: setting.SessionConfig.Domain, - MaxAge: maxAge, - Secure: setting.SessionConfig.Secure, - } -} - // SetRedirectToCookie convenience function to set the RedirectTo cookie consistently func SetRedirectToCookie(resp http.ResponseWriter, value string) { - SetCookie(resp, "redirect_to", value, - 0, - setting.AppSubURL, - "", - setting.SessionConfig.Secure, - true, - SameSite(setting.SessionConfig.SameSite)) + SetSiteCookie(resp, "redirect_to", value, 0) } // DeleteRedirectToCookie convenience function to delete most cookies consistently func DeleteRedirectToCookie(resp http.ResponseWriter) { - SetCookie(resp, "redirect_to", "", - -1, - setting.AppSubURL, - "", - setting.SessionConfig.Secure, - true, - SameSite(setting.SessionConfig.SameSite)) + SetSiteCookie(resp, "redirect_to", "", -1) } -// DeleteCSRFCookie convenience function to delete SessionConfigPath cookies consistently -func DeleteCSRFCookie(resp http.ResponseWriter) { - SetCookie(resp, setting.CSRFCookieName, "", - -1, - setting.SessionConfig.CookiePath, - setting.SessionConfig.Domain) // FIXME: Do we need to set the Secure, httpOnly and SameSite values too? -} - -// SetCookie set the cookies. (name, value, lifetime, path, domain, secure, httponly, expires, {sameSite, ...}) -// TODO: Copied from gitea.com/macaron/macaron and should be improved after macaron removed. -func SetCookie(resp http.ResponseWriter, name, value string, others ...interface{}) { - cookie := http.Cookie{} - cookie.Name = name - cookie.Value = url.QueryEscape(value) - - if len(others) > 0 { - switch v := others[0].(type) { - case int: - cookie.MaxAge = v - case int64: - cookie.MaxAge = int(v) - case int32: - cookie.MaxAge = int(v) - case func(*http.Cookie): - v(&cookie) - } - } - - cookie.Path = "/" - if len(others) > 1 { - if v, ok := others[1].(string); ok && len(v) > 0 { - cookie.Path = v - } else if v, ok := others[1].(func(*http.Cookie)); ok { - v(&cookie) - } - } - - if len(others) > 2 { - if v, ok := others[2].(string); ok && len(v) > 0 { - cookie.Domain = v - } else if v, ok := others[2].(func(*http.Cookie)); ok { - v(&cookie) - } - } - - if len(others) > 3 { - switch v := others[3].(type) { - case bool: - cookie.Secure = v - case func(*http.Cookie): - v(&cookie) - default: - if others[3] != nil { - cookie.Secure = true - } - } - } - - if len(others) > 4 { - if v, ok := others[4].(bool); ok && v { - cookie.HttpOnly = true - } else if v, ok := others[4].(func(*http.Cookie)); ok { - v(&cookie) - } - } - - if len(others) > 5 { - if v, ok := others[5].(time.Time); ok { - cookie.Expires = v - cookie.RawExpires = v.Format(time.UnixDate) - } else if v, ok := others[5].(func(*http.Cookie)); ok { - v(&cookie) - } - } - - if len(others) > 6 { - for _, other := range others[6:] { - if v, ok := other.(func(*http.Cookie)); ok { - v(&cookie) - } - } - } - - resp.Header().Add("Set-Cookie", cookie.String()) -} - -// GetCookie returns given cookie value from request header. -func GetCookie(req *http.Request, name string) string { +// GetSiteCookie returns given cookie value from request header. +func GetSiteCookie(req *http.Request, name string) string { cookie, err := req.Cookie(name) if err != nil { return "" @@ -192,3 +31,24 @@ func GetCookie(req *http.Request, name string) string { val, _ := url.QueryUnescape(cookie.Value) return val } + +// SetSiteCookie returns given cookie value from request header. +func SetSiteCookie(resp http.ResponseWriter, name, value string, maxAge int) { + cookie := &http.Cookie{ + Name: name, + Value: url.QueryEscape(value), + MaxAge: maxAge, + Path: setting.SessionConfig.CookiePath, + Domain: setting.SessionConfig.Domain, + Secure: setting.SessionConfig.Secure, + HttpOnly: true, + SameSite: setting.SessionConfig.SameSite, + } + resp.Header().Add("Set-Cookie", cookie.String()) + if maxAge < 0 { + // There was a bug in "setting.SessionConfig.CookiePath" code, the old default value of it was empty "". + // So we have to delete the cookie on path="" again, because some old code leaves cookies on path="". + cookie.Path = strings.TrimSuffix(setting.SessionConfig.CookiePath, "/") + resp.Header().Add("Set-Cookie", cookie.String()) + } +} |