diff options
Diffstat (limited to 'modules/context/context_cookie.go')
-rw-r--r-- | modules/context/context_cookie.go | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/modules/context/context_cookie.go b/modules/context/context_cookie.go new file mode 100644 index 0000000000..5cb4ea0aca --- /dev/null +++ b/modules/context/context_cookie.go @@ -0,0 +1,105 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package context + +import ( + "encoding/hex" + "net/http" + "strconv" + "strings" + + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/web/middleware" + + "github.com/minio/sha256-simd" + "golang.org/x/crypto/pbkdf2" +) + +const CookieNameFlash = "gitea_flash" + +func removeSessionCookieHeader(w http.ResponseWriter) { + cookies := w.Header()["Set-Cookie"] + w.Header().Del("Set-Cookie") + for _, cookie := range cookies { + if strings.HasPrefix(cookie, setting.SessionConfig.CookieName+"=") { + continue + } + w.Header().Add("Set-Cookie", cookie) + } +} + +// 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) +} + +// 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) +} + +// GetSiteCookie returns given cookie value from request header. +func (ctx *Context) GetSiteCookie(name string) string { + return middleware.GetSiteCookie(ctx.Req, name) +} + +// GetSuperSecureCookie returns given cookie value from request header with secret string. +func (ctx *Context) GetSuperSecureCookie(secret, name string) (string, bool) { + val := ctx.GetSiteCookie(name) + return ctx.CookieDecrypt(secret, val) +} + +// CookieDecrypt returns given value from with secret string. +func (ctx *Context) CookieDecrypt(secret, val string) (string, bool) { + if val == "" { + return "", false + } + + text, err := hex.DecodeString(val) + if err != nil { + return "", false + } + + key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New) + text, err = util.AESGCMDecrypt(key, text) + return string(text), err == nil +} + +// SetSuperSecureCookie sets given cookie value to response header with secret string. +func (ctx *Context) SetSuperSecureCookie(secret, name, value string, maxAge int) { + text := ctx.CookieEncrypt(secret, value) + ctx.SetSiteCookie(name, text, maxAge) +} + +// CookieEncrypt encrypts a given value using the provided secret +func (ctx *Context) CookieEncrypt(secret, value string) string { + key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New) + text, err := util.AESGCMEncrypt(key, []byte(value)) + if err != nil { + panic("error encrypting cookie: " + err.Error()) + } + + return hex.EncodeToString(text) +} + +// GetCookieInt returns cookie result in int type. +func (ctx *Context) GetCookieInt(name string) int { + r, _ := strconv.Atoi(ctx.GetSiteCookie(name)) + return r +} + +// GetCookieInt64 returns cookie result in int64 type. +func (ctx *Context) GetCookieInt64(name string) int64 { + r, _ := strconv.ParseInt(ctx.GetSiteCookie(name), 10, 64) + return r +} + +// GetCookieFloat64 returns cookie result in float64 type. +func (ctx *Context) GetCookieFloat64(name string) float64 { + v, _ := strconv.ParseFloat(ctx.GetSiteCookie(name), 64) + return v +} |