@ -45,6 +45,8 @@ import (
"golang.org/x/crypto/pbkdf2"
)
const CookieNameFlash = "gitea_flash"
// Render represents a template render
type Render interface {
TemplateLookup ( tmpl string ) ( * template . Template , error )
@ -60,7 +62,7 @@ type Context struct {
Render Render
translation . Locale
Cache cache . Cache
c srf CSRFProtector
C srf CSRFProtector
Flash * middleware . Flash
Session session . Store
@ -478,38 +480,26 @@ func (ctx *Context) Redirect(location string, status ...int) {
http . Redirect ( ctx . Resp , ctx . Req , location , code )
}
// Set Cookie convenience function to set most cookies consistently
// Set Site Cookie convenience function to set most cookies consistently
// CSRF and a few others are the exception here
func ( ctx * Context ) SetCookie ( name , value string , expiry int ) {
middleware . SetCookie ( ctx . Resp , name , value ,
expiry ,
setting . AppSubURL ,
setting . SessionConfig . Domain ,
setting . SessionConfig . Secure ,
true ,
middleware . SameSite ( setting . SessionConfig . SameSite ) )
func ( ctx * Context ) SetSiteCookie ( name , value string , maxAge int ) {
middleware . SetSiteCookie ( ctx . Resp , name , value , maxAge )
}
// Delete Cookie convenience function to delete most cookies consistently
// DeleteSiteCookie convenience function to delete most cookies consistently
// CSRF and a few others are the exception here
func ( ctx * Context ) DeleteCookie ( name string ) {
middleware . SetCookie ( ctx . Resp , name , "" ,
- 1 ,
setting . AppSubURL ,
setting . SessionConfig . Domain ,
setting . SessionConfig . Secure ,
true ,
middleware . SameSite ( setting . SessionConfig . SameSite ) )
func ( ctx * Context ) DeleteSiteCookie ( name string ) {
middleware . SetSiteCookie ( ctx . Resp , name , "" , - 1 )
}
// Get Cookie returns given cookie value from request header.
func ( ctx * Context ) Get Cookie( name string ) string {
return middleware . Get Cookie( ctx . Req , name )
// 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 . Get Cookie( name )
val := ctx . Get Site Cookie( name )
return ctx . CookieDecrypt ( secret , val )
}
@ -530,10 +520,9 @@ func (ctx *Context) CookieDecrypt(secret, val string) (string, bool) {
}
// SetSuperSecureCookie sets given cookie value to response header with secret string.
func ( ctx * Context ) SetSuperSecureCookie ( secret , name , value string , expiry int ) {
func ( ctx * Context ) SetSuperSecureCookie ( secret , name , value string , maxAge int ) {
text := ctx . CookieEncrypt ( secret , value )
ctx . SetCookie ( name , text , expiry )
ctx . SetSiteCookie ( name , text , maxAge )
}
// CookieEncrypt encrypts a given value using the provided secret
@ -549,19 +538,19 @@ func (ctx *Context) CookieEncrypt(secret, value string) string {
// GetCookieInt returns cookie result in int type.
func ( ctx * Context ) GetCookieInt ( name string ) int {
r , _ := strconv . Atoi ( ctx . Get Cookie( name ) )
r , _ := strconv . Atoi ( ctx . Get Site Cookie( name ) )
return r
}
// GetCookieInt64 returns cookie result in int64 type.
func ( ctx * Context ) GetCookieInt64 ( name string ) int64 {
r , _ := strconv . ParseInt ( ctx . Get Cookie( name ) , 10 , 64 )
r , _ := strconv . ParseInt ( ctx . Get Site Cookie( name ) , 10 , 64 )
return r
}
// GetCookieFloat64 returns cookie result in float64 type.
func ( ctx * Context ) GetCookieFloat64 ( name string ) float64 {
v , _ := strconv . ParseFloat ( ctx . Get Cookie( name ) , 64 )
v , _ := strconv . ParseFloat ( ctx . Get Site Cookie( name ) , 64 )
return v
}
@ -659,7 +648,10 @@ func WithContext(req *http.Request, ctx *Context) *http.Request {
// GetContext retrieves install context from request
func GetContext ( req * http . Request ) * Context {
return req . Context ( ) . Value ( contextKey ) . ( * Context )
if ctx , ok := req . Context ( ) . Value ( contextKey ) . ( * Context ) ; ok {
return ctx
}
return nil
}
// GetContextUser returns context user
@ -726,13 +718,13 @@ func Contexter(ctx context.Context) func(next http.Handler) http.Handler {
ctx . Data [ "Context" ] = & ctx
ctx . Req = WithContext ( req , & ctx )
ctx . c srf = PrepareCSRFProtector ( csrfOpts , & ctx )
ctx . C srf = PrepareCSRFProtector ( csrfOpts , & ctx )
// Get flash.
flashCookie := ctx . GetCookie ( "macaron_flash" )
vals , _ := url . ParseQuery ( flashCookie)
if len ( vals ) > 0 {
f : = & middleware . Flash {
// Get the last flash message from cookie
lastFlashCookie := middleware . GetSiteCookie ( ctx . Req , CookieNameFlash )
if vals , _ := url . ParseQuery ( lastFlashCookie) ; len ( vals ) > 0 {
// store last Flash message into the template data, to render it
ctx. Data [ "Flash" ] = & middleware . Flash {
DataStore : & ctx ,
Values : vals ,
ErrorMsg : vals . Get ( "error" ) ,
@ -740,40 +732,18 @@ func Contexter(ctx context.Context) func(next http.Handler) http.Handler {
InfoMsg : vals . Get ( "info" ) ,
WarningMsg : vals . Get ( "warning" ) ,
}
ctx . Data [ "Flash" ] = f
}
f := & middleware . Flash {
DataStore : & ctx ,
Values : url . Values { } ,
ErrorMsg : "" ,
WarningMsg : "" ,
InfoMsg : "" ,
SuccessMsg : "" ,
}
// prepare an empty Flash message for current request
ctx . Flash = & middleware . Flash { DataStore : & ctx , Values : url . Values { } }
ctx . Resp . Before ( func ( resp ResponseWriter ) {
if flash := f . Encode ( ) ; len ( flash ) > 0 {
middleware . SetCookie ( resp , "macaron_flash" , flash , 0 ,
setting . SessionConfig . CookiePath ,
middleware . Domain ( setting . SessionConfig . Domain ) ,
middleware . HTTPOnly ( true ) ,
middleware . Secure ( setting . SessionConfig . Secure ) ,
middleware . SameSite ( setting . SessionConfig . SameSite ) ,
)
return
if val := ctx . Flash . Encode ( ) ; val != "" {
middleware . SetSiteCookie ( ctx . Resp , CookieNameFlash , val , 0 )
} else if lastFlashCookie != "" {
middleware . SetSiteCookie ( ctx . Resp , CookieNameFlash , "" , - 1 )
}
middleware . SetCookie ( ctx . Resp , "macaron_flash" , "" , - 1 ,
setting . SessionConfig . CookiePath ,
middleware . Domain ( setting . SessionConfig . Domain ) ,
middleware . HTTPOnly ( true ) ,
middleware . Secure ( setting . SessionConfig . Secure ) ,
middleware . SameSite ( setting . SessionConfig . SameSite ) ,
)
} )
ctx . Flash = f
// If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid.
if ctx . Req . Method == "POST" && strings . Contains ( ctx . Req . Header . Get ( "Content-Type" ) , "multipart/form-data" ) {
if err := ctx . Req . ParseMultipartForm ( setting . Attachment . MaxSize << 20 ) ; err != nil && ! strings . Contains ( err . Error ( ) , "EOF" ) { // 32MB max size
@ -785,7 +755,7 @@ func Contexter(ctx context.Context) func(next http.Handler) http.Handler {
httpcache . SetCacheControlInHeader ( ctx . Resp . Header ( ) , 0 , "no-transform" )
ctx . Resp . Header ( ) . Set ( ` X-Frame-Options ` , setting . CORSConfig . XFrameOptions )
ctx . Data [ "CsrfToken" ] = ctx . c srf. GetToken ( )
ctx . Data [ "CsrfToken" ] = ctx . C srf. GetToken ( )
ctx . Data [ "CsrfTokenHtml" ] = template . HTML ( ` <input type="hidden" name="_csrf" value=" ` + ctx . Data [ "CsrfToken" ] . ( string ) + ` "> ` )
// FIXME: do we really always need these setting? There should be someway to have to avoid having to always set these