aboutsummaryrefslogtreecommitdiffstats
path: root/modules/web/middleware/cookie.go
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2023-04-14 03:45:33 +0800
committerGitHub <noreply@github.com>2023-04-13 15:45:33 -0400
commit5b9557aef59b190c55de9ea218bf51152bc04786 (patch)
treed77004c983875886a00acd1561a74b8c3d5ce682 /modules/web/middleware/cookie.go
parentb7221bec34fd49495234a18c26e4f5d81483e102 (diff)
downloadgitea-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.go192
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())
+ }
+}