2021-01-26 23:36:53 +08:00
// Copyright 2020 The Macaron Authors
2021-01-05 21:05:40 +08:00
// Copyright 2020 The Gitea Authors. All rights reserved.
2022-11-27 13:20:29 -05:00
// SPDX-License-Identifier: MIT
2021-01-05 21:05:40 +08:00
2021-01-30 16:55:53 +08:00
package middleware
2021-01-05 21:05:40 +08:00
import (
"net/http"
"net/url"
2023-04-14 03:45:33 +08:00
"strings"
2021-01-05 21:05:40 +08:00
2024-04-19 12:03:53 +08:00
"code.gitea.io/gitea/modules/session"
2021-01-05 21:05:40 +08:00
"code.gitea.io/gitea/modules/setting"
)
2021-03-07 08:12:43 +00:00
// SetRedirectToCookie convenience function to set the RedirectTo cookie consistently
func SetRedirectToCookie ( resp http . ResponseWriter , value string ) {
2023-04-14 03:45:33 +08:00
SetSiteCookie ( resp , "redirect_to" , value , 0 )
2021-03-07 08:12:43 +00:00
}
// DeleteRedirectToCookie convenience function to delete most cookies consistently
func DeleteRedirectToCookie ( resp http . ResponseWriter ) {
2023-04-14 03:45:33 +08:00
SetSiteCookie ( resp , "redirect_to" , "" , - 1 )
2021-03-07 08:12:43 +00:00
}
2023-04-14 03:45:33 +08:00
// GetSiteCookie returns given cookie value from request header.
func GetSiteCookie ( req * http . Request , name string ) string {
2021-01-26 23:36:53 +08:00
cookie , err := req . Cookie ( name )
if err != nil {
return ""
}
val , _ := url . QueryUnescape ( cookie . Value )
return val
}
2023-04-14 03:45:33 +08:00
// SetSiteCookie returns given cookie value from request header.
func SetSiteCookie ( resp http . ResponseWriter , name , value string , maxAge int ) {
2024-06-11 11:31:23 +08:00
// Previous versions would use a cookie path with a trailing /.
// These are more specific than cookies without a trailing /, so
// we need to delete these if they exist.
deleteLegacySiteCookie ( resp , name )
2023-04-14 03:45:33 +08:00
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 ( ) )
2024-04-14 00:46:56 -04:00
}
2024-04-19 12:03:53 +08:00
// deleteLegacySiteCookie deletes the cookie with the given name at the cookie
2024-04-14 00:46:56 -04:00
// path with a trailing /, which would unintentionally override the cookie.
2024-04-19 12:03:53 +08:00
func deleteLegacySiteCookie ( resp http . ResponseWriter , name string ) {
2024-04-14 00:46:56 -04:00
if setting . SessionConfig . CookiePath == "" || strings . HasSuffix ( setting . SessionConfig . CookiePath , "/" ) {
// If the cookie path ends with /, no legacy cookies will take
// precedence, so do nothing. The exception is that cookies with no
// path could override other cookies, but it's complicated and we don't
// currently handle that.
return
2023-04-14 03:45:33 +08:00
}
2024-04-14 00:46:56 -04:00
cookie := & http . Cookie {
Name : name ,
Value : "" ,
MaxAge : - 1 ,
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 ( ) )
2023-04-14 03:45:33 +08:00
}
2024-04-19 12:03:53 +08:00
func init ( ) {
session . BeforeRegenerateSession = append ( session . BeforeRegenerateSession , func ( resp http . ResponseWriter , _ * http . Request ) {
// Ensure that a cookie with a trailing slash does not take precedence over
// the cookie written by the middleware.
deleteLegacySiteCookie ( resp , setting . SessionConfig . CookieName )
} )
}