Compare commits

...

3 Commits

Author SHA1 Message Date
wxiaoguang
64cc691b7f
Fix safari cookie session bug (#24772)
Partically backport #24330

Related: #24176

Maybe fix #24770
2023-05-18 09:10:23 +08:00
Giteabot
1bad05da3d
Fix missed table name on iterate lfs meta objects (#24768) (#24774)
Backport #24768 by @lunny

Fix #24763

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-05-17 20:35:20 +02:00
Giteabot
57f520e7e5
Make mailer SMTP check have timed context (#24751) (#24759)
Backport #24751 by @wxiaoguang

Make mailer SMTP check have timed context

Otherwise Gitea may block for long time if the DNS request blocks.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2023-05-17 06:08:39 -04:00
4 changed files with 54 additions and 8 deletions

View File

@ -390,7 +390,7 @@ func IterateLFSMetaObjectsForRepo(ctx context.Context, repoID int64, f func(cont
for { for {
beans := make([]*CountLFSMetaObject, 0, batchSize) beans := make([]*CountLFSMetaObject, 0, batchSize)
sess := engine.Select("`lfs_meta_object`.*, COUNT(`l1`.oid) AS `count`"). sess := engine.Table("lfs_meta_object").Select("`lfs_meta_object`.*, COUNT(`l1`.oid) AS `count`").
Join("INNER", "`lfs_meta_object` AS l1", "`lfs_meta_object`.oid = `l1`.oid"). Join("INNER", "`lfs_meta_object` AS l1", "`lfs_meta_object`.oid = `l1`.oid").
Where("`lfs_meta_object`.repository_id = ?", repoID) Where("`lfs_meta_object`.repository_id = ?", repoID)
if !opts.OlderThan.IsZero() { if !opts.OlderThan.IsZero() {

View File

@ -473,6 +473,17 @@ func (ctx *Context) JSON(status int, content interface{}) {
} }
} }
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)
}
}
// Redirect redirects the request // Redirect redirects the request
func (ctx *Context) Redirect(location string, status ...int) { func (ctx *Context) Redirect(location string, status ...int) {
code := http.StatusSeeOther code := http.StatusSeeOther
@ -480,6 +491,15 @@ func (ctx *Context) Redirect(location string, status ...int) {
code = status[0] code = status[0]
} }
if strings.Contains(location, "://") || strings.HasPrefix(location, "//") {
// Some browsers (Safari) have buggy behavior for Cookie + Cache + External Redirection, eg: /my-path => https://other/path
// 1. the first request to "/my-path" contains cookie
// 2. some time later, the request to "/my-path" doesn't contain cookie (caused by Prevent web tracking)
// 3. Gitea's Sessioner doesn't see the session cookie, so it generates a new session id, and returns it to browser
// 4. then the browser accepts the empty session, then the user is logged out
// So in this case, we should remove the session cookie from the response header
removeSessionCookieHeader(ctx.Resp)
}
http.Redirect(ctx.Resp, ctx.Req, location, code) http.Redirect(ctx.Resp, ctx.Req, location, code)
} }

View File

@ -0,0 +1,24 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package context
import (
"net/http"
"net/http/httptest"
"testing"
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
func TestRemoveSessionCookieHeader(t *testing.T) {
w := httptest.NewRecorder()
w.Header().Add("Set-Cookie", (&http.Cookie{Name: setting.SessionConfig.CookieName, Value: "foo"}).String())
w.Header().Add("Set-Cookie", (&http.Cookie{Name: "other", Value: "bar"}).String())
assert.Len(t, w.Header().Values("Set-Cookie"), 2)
removeSessionCookieHeader(w)
assert.Len(t, w.Header().Values("Set-Cookie"), 1)
assert.Contains(t, "other=bar", w.Header().Get("Set-Cookie"))
}

View File

@ -4,6 +4,7 @@
package setting package setting
import ( import (
"context"
"net" "net"
"net/mail" "net/mail"
"strings" "strings"
@ -198,7 +199,7 @@ func loadMailerFrom(rootCfg ConfigProvider) {
ips := tryResolveAddr(MailService.SMTPAddr) ips := tryResolveAddr(MailService.SMTPAddr)
if MailService.Protocol == "smtp" { if MailService.Protocol == "smtp" {
for _, ip := range ips { for _, ip := range ips {
if !ip.IsLoopback() { if !ip.IP.IsLoopback() {
log.Warn("connecting over insecure SMTP protocol to non-local address is not recommended") log.Warn("connecting over insecure SMTP protocol to non-local address is not recommended")
break break
} }
@ -258,20 +259,21 @@ func loadNotifyMailFrom(rootCfg ConfigProvider) {
log.Info("Notify Mail Service Enabled") log.Info("Notify Mail Service Enabled")
} }
func tryResolveAddr(addr string) []net.IP { func tryResolveAddr(addr string) []net.IPAddr {
if strings.HasPrefix(addr, "[") && strings.HasSuffix(addr, "]") { if strings.HasPrefix(addr, "[") && strings.HasSuffix(addr, "]") {
addr = addr[1 : len(addr)-1] addr = addr[1 : len(addr)-1]
} }
ip := net.ParseIP(addr) ip := net.ParseIP(addr)
if ip != nil { if ip != nil {
ips := make([]net.IP, 1) return []net.IPAddr{{IP: ip}}
ips[0] = ip
return ips
} }
ips, err := net.LookupIP(addr)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
ips, err := net.DefaultResolver.LookupIPAddr(ctx, addr)
if err != nil { if err != nil {
log.Warn("could not look up mailer.SMTP_ADDR: %v", err) log.Warn("could not look up mailer.SMTP_ADDR: %v", err)
return make([]net.IP, 0) return nil
} }
return ips return ips
} }