diff --git a/go.mod b/go.mod index 6f5eaed403..61dceb0c8c 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( code.forgejo.org/go-chi/binding v1.0.1 code.forgejo.org/go-chi/cache v1.0.1 code.forgejo.org/go-chi/captcha v1.0.2 - code.forgejo.org/go-chi/session v1.0.2 + code.forgejo.org/go-chi/session v1.0.3 code.gitea.io/sdk/gitea v0.21.0 code.superseriousbusiness.org/exif-terminator v0.11.1 code.superseriousbusiness.org/go-jpeg-image-structure/v2 v2.3.0 diff --git a/go.sum b/go.sum index 97aed9a2ae..3de4a64b0d 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,8 @@ code.forgejo.org/go-chi/cache v1.0.1 h1:w6IsDcPbeEnEYZn7M2HJe3/3/Ehtcw/72VjcVK7+ code.forgejo.org/go-chi/cache v1.0.1/go.mod h1:K3aQSyRIN4xiuqV1kanfQ6O4ToDpzDpY3bNOyGjFe3U= code.forgejo.org/go-chi/captcha v1.0.2 h1:vyHDPXkpjDv8bLO9NqtWzZayzstD/WpJ5xwEkAaqZGQ= code.forgejo.org/go-chi/captcha v1.0.2/go.mod h1:lxiPLcJ76UCZHoH31/Wbum4GUi2NgjfFZLrJkKv1lLE= -code.forgejo.org/go-chi/session v1.0.2 h1:pG+AXre9L9VXJmTaADXkmeEPuRalhmBXyv6tG2Rvjcc= -code.forgejo.org/go-chi/session v1.0.2/go.mod h1:HnEGyBny7WPzCiVLP2vzL5ssma+3gCSl/vLpuVNYrqc= +code.forgejo.org/go-chi/session v1.0.3 h1:ByJ9c/UC0AU57hxiGl53TXh+NdBOBwK/bhZ9jyadEwE= +code.forgejo.org/go-chi/session v1.0.3/go.mod h1:xzGtFrV/agCJoZCUhFDlqAr1he6BrAdqlaprKOB1W90= code.forgejo.org/xorm/xorm v1.3.9-forgejo.8 h1:dsSKm2nus0NhHsqYxeuB3Gldk6TtlusD1CBGV6V1SS0= code.forgejo.org/xorm/xorm v1.3.9-forgejo.8/go.mod h1:A7sFd3BFmRp20h6drSsCXgQRQdF8Vz8HuCSrzFS3m90= code.gitea.io/sdk/gitea v0.21.0 h1:69n6oz6kEVHRo1+APQQyizkhrZrLsTLXey9142pfkD4= diff --git a/modules/session/db.go b/modules/session/db.go index eea7e2136e..57f658dfd6 100644 --- a/modules/session/db.go +++ b/modules/session/db.go @@ -84,6 +84,11 @@ func (s *DBStore) Flush() error { return nil } +// True if no keys have been set +func (s *DBStore) Empty() bool { + return len(s.data) == 0 +} + // DBProvider represents a DB session provider implementation. type DBProvider struct { maxLifetime int64 diff --git a/modules/session/redis.go b/modules/session/redis.go index cf84ef21d9..1e8c61da8b 100644 --- a/modules/session/redis.go +++ b/modules/session/redis.go @@ -103,6 +103,11 @@ func (s *RedisStore) Flush() error { return nil } +// True if no keys have been set +func (s *RedisStore) Empty() bool { + return len(s.data) == 0 +} + // RedisProvider represents a redis session provider implementation. type RedisProvider struct { c nosql.RedisClient diff --git a/modules/session/virtual.go b/modules/session/virtual.go index 1986ba64ad..fea7d11a44 100644 --- a/modules/session/virtual.go +++ b/modules/session/virtual.go @@ -76,7 +76,10 @@ func (o *VirtualSessionProvider) Exist(sid string) bool { func (o *VirtualSessionProvider) Destroy(sid string) error { o.lock.Lock() defer o.lock.Unlock() - return o.provider.Destroy(sid) + if o.provider.Exist(sid) { + return o.provider.Destroy(sid) + } + return nil } // Regenerate regenerates a session store from old session ID to new one. @@ -195,3 +198,8 @@ func (s *VirtualStore) Flush() error { s.data = make(map[any]any) return nil } + +// True if no keys have been set +func (s *VirtualStore) Empty() bool { + return len(s.data) == 0 +} diff --git a/routers/common/middleware.go b/routers/common/middleware.go index 7bc4890a43..5c8283e247 100644 --- a/routers/common/middleware.go +++ b/routers/common/middleware.go @@ -118,5 +118,6 @@ func Sessioner() func(next http.Handler) http.Handler { Secure: setting.SessionConfig.Secure, SameSite: setting.SessionConfig.SameSite, Domain: setting.SessionConfig.Domain, + DeferSetCookie: true, }) } diff --git a/tests/integration/create_no_session_test.go b/tests/integration/create_no_session_test.go index 375add7014..fc9c38cabd 100644 --- a/tests/integration/create_no_session_test.go +++ b/tests/integration/create_no_session_test.go @@ -6,7 +6,6 @@ package integration import ( "net/http" "net/http/httptest" - "os" "path/filepath" "testing" @@ -31,8 +30,9 @@ func getSessionID(t *testing.T, resp *httptest.ResponseRecorder) string { found = true } } - assert.True(t, found) - assert.NotEmpty(t, sessionID) + if found { + assert.NotEmpty(t, sessionID) + } return sessionID } @@ -40,18 +40,6 @@ func sessionFile(tmpDir, sessionID string) string { return filepath.Join(tmpDir, sessionID[0:1], sessionID[1:2], sessionID) } -func sessionFileExist(t *testing.T, tmpDir, sessionID string) bool { - sessionFile := sessionFile(tmpDir, sessionID) - _, err := os.Lstat(sessionFile) - if err != nil { - if os.IsNotExist(err) { - return false - } - require.NoError(t, err) - } - return true -} - func TestSessionFileCreation(t *testing.T) { defer tests.PrepareTestEnv(t)() defer test.MockProtect(&setting.SessionConfig.ProviderConfig)() @@ -82,7 +70,7 @@ func TestSessionFileCreation(t *testing.T) { sessionID := getSessionID(t, resp) // We're not logged in so there should be no session - assert.False(t, sessionFileExist(t, tmpDir, sessionID)) + assert.Empty(t, sessionID) }) t.Run("CreateSessionOnLogin", func(t *testing.T) { defer tests.PrintCurrentTest(t)() @@ -92,7 +80,7 @@ func TestSessionFileCreation(t *testing.T) { sessionID := getSessionID(t, resp) // We're not logged in so there should be no session - assert.False(t, sessionFileExist(t, tmpDir, sessionID)) + assert.Empty(t, sessionID) req = NewRequestWithValues(t, "POST", "/user/login", map[string]string{ "user_name": "user2",