From 1c633f7d2612b0150a633821aa0bb28e64e59640 Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Thu, 4 Apr 2024 11:15:13 +0200 Subject: [PATCH 01/26] Bump golang.org/x/net to 0.23.0 Backports: https://github.com/owncloud/ocis/pull/8773 Fixes #8771 --- go.mod | 8 +- go.sum | 16 +- .../x/crypto/internal/poly1305/sum_ppc64le.s | 14 +- vendor/golang.org/x/crypto/ocsp/ocsp.go | 13 +- vendor/golang.org/x/net/http2/frame.go | 31 ++ vendor/golang.org/x/net/http2/pipe.go | 11 +- vendor/golang.org/x/net/http2/server.go | 13 +- vendor/golang.org/x/net/http2/testsync.go | 331 ++++++++++++++++++ vendor/golang.org/x/net/http2/transport.go | 307 ++++++++++++---- vendor/golang.org/x/sys/unix/aliases.go | 2 +- .../x/sys/unix/syscall_darwin_libSystem.go | 2 +- .../golang.org/x/sys/unix/syscall_freebsd.go | 12 +- vendor/golang.org/x/sys/unix/syscall_linux.go | 99 ++++++ .../golang.org/x/sys/unix/zsyscall_linux.go | 10 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 60 ++++ vendor/modules.txt | 8 +- 16 files changed, 832 insertions(+), 105 deletions(-) create mode 100644 vendor/golang.org/x/net/http2/testsync.go diff --git a/go.mod b/go.mod index 209f15f8e6..5e1ae10e6f 100644 --- a/go.mod +++ b/go.mod @@ -95,12 +95,12 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 go.opentelemetry.io/otel/sdk v1.24.0 go.opentelemetry.io/otel/trace v1.24.0 - golang.org/x/crypto v0.19.0 + golang.org/x/crypto v0.21.0 golang.org/x/image v0.15.0 - golang.org/x/net v0.21.0 + golang.org/x/net v0.23.0 golang.org/x/oauth2 v0.17.0 golang.org/x/sync v0.6.0 - golang.org/x/term v0.17.0 + golang.org/x/term v0.18.0 golang.org/x/text v0.14.0 google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe google.golang.org/grpc v1.62.0 @@ -335,7 +335,7 @@ require ( go.uber.org/zap v1.23.0 // indirect golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect diff --git a/go.sum b/go.sum index 0deebeba3a..885f9d7595 100644 --- a/go.sum +++ b/go.sum @@ -2167,8 +2167,8 @@ golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIi golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -2313,8 +2313,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2495,8 +2495,8 @@ golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2513,8 +2513,8 @@ golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s index d2ca5deeb9..b3c1699bff 100644 --- a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s @@ -19,15 +19,14 @@ #define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \ MULLD r0, h0, t0; \ - MULLD r0, h1, t4; \ MULHDU r0, h0, t1; \ + MULLD r0, h1, t4; \ MULHDU r0, h1, t5; \ ADDC t4, t1, t1; \ MULLD r0, h2, t2; \ - ADDZE t5; \ MULHDU r1, h0, t4; \ MULLD r1, h0, h0; \ - ADD t5, t2, t2; \ + ADDE t5, t2, t2; \ ADDC h0, t1, t1; \ MULLD h2, r1, t3; \ ADDZE t4, h0; \ @@ -37,13 +36,11 @@ ADDE t5, t3, t3; \ ADDC h0, t2, t2; \ MOVD $-4, t4; \ - MOVD t0, h0; \ - MOVD t1, h1; \ ADDZE t3; \ - ANDCC $3, t2, h2; \ - AND t2, t4, t0; \ + RLDICL $0, t2, $62, h2; \ + AND t2, t4, h0; \ ADDC t0, h0, h0; \ - ADDE t3, h1, h1; \ + ADDE t3, t1, h1; \ SLD $62, t3, t4; \ SRD $2, t2; \ ADDZE h2; \ @@ -75,6 +72,7 @@ TEXT ·update(SB), $0-32 loop: POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22) + PCALIGN $16 multiply: POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21) ADD $-16, R5 diff --git a/vendor/golang.org/x/crypto/ocsp/ocsp.go b/vendor/golang.org/x/crypto/ocsp/ocsp.go index 4269ed113b..bf2259537d 100644 --- a/vendor/golang.org/x/crypto/ocsp/ocsp.go +++ b/vendor/golang.org/x/crypto/ocsp/ocsp.go @@ -279,21 +279,22 @@ func getOIDFromHashAlgorithm(target crypto.Hash) asn1.ObjectIdentifier { // This is the exposed reflection of the internal OCSP structures. -// The status values that can be expressed in OCSP. See RFC 6960. +// The status values that can be expressed in OCSP. See RFC 6960. +// These are used for the Response.Status field. const ( // Good means that the certificate is valid. - Good = iota + Good = 0 // Revoked means that the certificate has been deliberately revoked. - Revoked + Revoked = 1 // Unknown means that the OCSP responder doesn't know about the certificate. - Unknown + Unknown = 2 // ServerFailed is unused and was never used (see // https://go-review.googlesource.com/#/c/18944). ParseResponse will // return a ResponseError when an error response is parsed. - ServerFailed + ServerFailed = 3 ) -// The enumerated reasons for revoking a certificate. See RFC 5280. +// The enumerated reasons for revoking a certificate. See RFC 5280. const ( Unspecified = 0 KeyCompromise = 1 diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index e2b298d859..43557ab7e9 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -1564,6 +1564,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { if size > remainSize { hdec.SetEmitEnabled(false) mh.Truncated = true + remainSize = 0 return } remainSize -= size @@ -1576,6 +1577,36 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { var hc headersOrContinuation = hf for { frag := hc.HeaderBlockFragment() + + // Avoid parsing large amounts of headers that we will then discard. + // If the sender exceeds the max header list size by too much, + // skip parsing the fragment and close the connection. + // + // "Too much" is either any CONTINUATION frame after we've already + // exceeded the max header list size (in which case remainSize is 0), + // or a frame whose encoded size is more than twice the remaining + // header list bytes we're willing to accept. + if int64(len(frag)) > int64(2*remainSize) { + if VerboseLogs { + log.Printf("http2: header list too large") + } + // It would be nice to send a RST_STREAM before sending the GOAWAY, + // but the structure of the server's frame writer makes this difficult. + return nil, ConnectionError(ErrCodeProtocol) + } + + // Also close the connection after any CONTINUATION frame following an + // invalid header, since we stop tracking the size of the headers after + // an invalid one. + if invalid != nil { + if VerboseLogs { + log.Printf("http2: invalid header: %v", invalid) + } + // It would be nice to send a RST_STREAM before sending the GOAWAY, + // but the structure of the server's frame writer makes this difficult. + return nil, ConnectionError(ErrCodeProtocol) + } + if _, err := hdec.Write(frag); err != nil { return nil, ConnectionError(ErrCodeCompression) } diff --git a/vendor/golang.org/x/net/http2/pipe.go b/vendor/golang.org/x/net/http2/pipe.go index 684d984fd9..3b9f06b962 100644 --- a/vendor/golang.org/x/net/http2/pipe.go +++ b/vendor/golang.org/x/net/http2/pipe.go @@ -77,7 +77,10 @@ func (p *pipe) Read(d []byte) (n int, err error) { } } -var errClosedPipeWrite = errors.New("write on closed buffer") +var ( + errClosedPipeWrite = errors.New("write on closed buffer") + errUninitializedPipeWrite = errors.New("write on uninitialized buffer") +) // Write copies bytes from p into the buffer and wakes a reader. // It is an error to write more data than the buffer can hold. @@ -91,6 +94,12 @@ func (p *pipe) Write(d []byte) (n int, err error) { if p.err != nil || p.breakErr != nil { return 0, errClosedPipeWrite } + // pipe.setBuffer is never invoked, leaving the buffer uninitialized. + // We shouldn't try to write to an uninitialized pipe, + // but returning an error is better than panicking. + if p.b == nil { + return 0, errUninitializedPipeWrite + } return p.b.Write(d) } diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index ae94c6408d..ce2e8b40ee 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -124,6 +124,7 @@ type Server struct { // IdleTimeout specifies how long until idle clients should be // closed with a GOAWAY frame. PING frames are not considered // activity for the purposes of IdleTimeout. + // If zero or negative, there is no timeout. IdleTimeout time.Duration // MaxUploadBufferPerConnection is the size of the initial flow @@ -434,7 +435,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { // passes the connection off to us with the deadline already set. // Write deadlines are set per stream in serverConn.newStream. // Disarm the net.Conn write deadline here. - if sc.hs.WriteTimeout != 0 { + if sc.hs.WriteTimeout > 0 { sc.conn.SetWriteDeadline(time.Time{}) } @@ -924,7 +925,7 @@ func (sc *serverConn) serve() { sc.setConnState(http.StateActive) sc.setConnState(http.StateIdle) - if sc.srv.IdleTimeout != 0 { + if sc.srv.IdleTimeout > 0 { sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) defer sc.idleTimer.Stop() } @@ -1637,7 +1638,7 @@ func (sc *serverConn) closeStream(st *stream, err error) { delete(sc.streams, st.id) if len(sc.streams) == 0 { sc.setConnState(http.StateIdle) - if sc.srv.IdleTimeout != 0 { + if sc.srv.IdleTimeout > 0 { sc.idleTimer.Reset(sc.srv.IdleTimeout) } if h1ServerKeepAlivesDisabled(sc.hs) { @@ -2017,7 +2018,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // similar to how the http1 server works. Here it's // technically more like the http1 Server's ReadHeaderTimeout // (in Go 1.8), though. That's a more sane option anyway. - if sc.hs.ReadTimeout != 0 { + if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) } @@ -2038,7 +2039,7 @@ func (sc *serverConn) upgradeRequest(req *http.Request) { // Disable any read deadline set by the net/http package // prior to the upgrade. - if sc.hs.ReadTimeout != 0 { + if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) } @@ -2116,7 +2117,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream st.flow.conn = &sc.flow // link to conn-level counter st.flow.add(sc.initialStreamSendWindowSize) st.inflow.init(sc.srv.initialStreamRecvWindowSize()) - if sc.hs.WriteTimeout != 0 { + if sc.hs.WriteTimeout > 0 { st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) } diff --git a/vendor/golang.org/x/net/http2/testsync.go b/vendor/golang.org/x/net/http2/testsync.go new file mode 100644 index 0000000000..61075bd16d --- /dev/null +++ b/vendor/golang.org/x/net/http2/testsync.go @@ -0,0 +1,331 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package http2 + +import ( + "context" + "sync" + "time" +) + +// testSyncHooks coordinates goroutines in tests. +// +// For example, a call to ClientConn.RoundTrip involves several goroutines, including: +// - the goroutine running RoundTrip; +// - the clientStream.doRequest goroutine, which writes the request; and +// - the clientStream.readLoop goroutine, which reads the response. +// +// Using testSyncHooks, a test can start a RoundTrip and identify when all these goroutines +// are blocked waiting for some condition such as reading the Request.Body or waiting for +// flow control to become available. +// +// The testSyncHooks also manage timers and synthetic time in tests. +// This permits us to, for example, start a request and cause it to time out waiting for +// response headers without resorting to time.Sleep calls. +type testSyncHooks struct { + // active/inactive act as a mutex and condition variable. + // + // - neither chan contains a value: testSyncHooks is locked. + // - active contains a value: unlocked, and at least one goroutine is not blocked + // - inactive contains a value: unlocked, and all goroutines are blocked + active chan struct{} + inactive chan struct{} + + // goroutine counts + total int // total goroutines + condwait map[*sync.Cond]int // blocked in sync.Cond.Wait + blocked []*testBlockedGoroutine // otherwise blocked + + // fake time + now time.Time + timers []*fakeTimer + + // Transport testing: Report various events. + newclientconn func(*ClientConn) + newstream func(*clientStream) +} + +// testBlockedGoroutine is a blocked goroutine. +type testBlockedGoroutine struct { + f func() bool // blocked until f returns true + ch chan struct{} // closed when unblocked +} + +func newTestSyncHooks() *testSyncHooks { + h := &testSyncHooks{ + active: make(chan struct{}, 1), + inactive: make(chan struct{}, 1), + condwait: map[*sync.Cond]int{}, + } + h.inactive <- struct{}{} + h.now = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC) + return h +} + +// lock acquires the testSyncHooks mutex. +func (h *testSyncHooks) lock() { + select { + case <-h.active: + case <-h.inactive: + } +} + +// waitInactive waits for all goroutines to become inactive. +func (h *testSyncHooks) waitInactive() { + for { + <-h.inactive + if !h.unlock() { + break + } + } +} + +// unlock releases the testSyncHooks mutex. +// It reports whether any goroutines are active. +func (h *testSyncHooks) unlock() (active bool) { + // Look for a blocked goroutine which can be unblocked. + blocked := h.blocked[:0] + unblocked := false + for _, b := range h.blocked { + if !unblocked && b.f() { + unblocked = true + close(b.ch) + } else { + blocked = append(blocked, b) + } + } + h.blocked = blocked + + // Count goroutines blocked on condition variables. + condwait := 0 + for _, count := range h.condwait { + condwait += count + } + + if h.total > condwait+len(blocked) { + h.active <- struct{}{} + return true + } else { + h.inactive <- struct{}{} + return false + } +} + +// goRun starts a new goroutine. +func (h *testSyncHooks) goRun(f func()) { + h.lock() + h.total++ + h.unlock() + go func() { + defer func() { + h.lock() + h.total-- + h.unlock() + }() + f() + }() +} + +// blockUntil indicates that a goroutine is blocked waiting for some condition to become true. +// It waits until f returns true before proceeding. +// +// Example usage: +// +// h.blockUntil(func() bool { +// // Is the context done yet? +// select { +// case <-ctx.Done(): +// default: +// return false +// } +// return true +// }) +// // Wait for the context to become done. +// <-ctx.Done() +// +// The function f passed to blockUntil must be non-blocking and idempotent. +func (h *testSyncHooks) blockUntil(f func() bool) { + if f() { + return + } + ch := make(chan struct{}) + h.lock() + h.blocked = append(h.blocked, &testBlockedGoroutine{ + f: f, + ch: ch, + }) + h.unlock() + <-ch +} + +// broadcast is sync.Cond.Broadcast. +func (h *testSyncHooks) condBroadcast(cond *sync.Cond) { + h.lock() + delete(h.condwait, cond) + h.unlock() + cond.Broadcast() +} + +// broadcast is sync.Cond.Wait. +func (h *testSyncHooks) condWait(cond *sync.Cond) { + h.lock() + h.condwait[cond]++ + h.unlock() +} + +// newTimer creates a new fake timer. +func (h *testSyncHooks) newTimer(d time.Duration) timer { + h.lock() + defer h.unlock() + t := &fakeTimer{ + hooks: h, + when: h.now.Add(d), + c: make(chan time.Time), + } + h.timers = append(h.timers, t) + return t +} + +// afterFunc creates a new fake AfterFunc timer. +func (h *testSyncHooks) afterFunc(d time.Duration, f func()) timer { + h.lock() + defer h.unlock() + t := &fakeTimer{ + hooks: h, + when: h.now.Add(d), + f: f, + } + h.timers = append(h.timers, t) + return t +} + +func (h *testSyncHooks) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { + ctx, cancel := context.WithCancel(ctx) + t := h.afterFunc(d, cancel) + return ctx, func() { + t.Stop() + cancel() + } +} + +func (h *testSyncHooks) timeUntilEvent() time.Duration { + h.lock() + defer h.unlock() + var next time.Time + for _, t := range h.timers { + if next.IsZero() || t.when.Before(next) { + next = t.when + } + } + if d := next.Sub(h.now); d > 0 { + return d + } + return 0 +} + +// advance advances time and causes synthetic timers to fire. +func (h *testSyncHooks) advance(d time.Duration) { + h.lock() + defer h.unlock() + h.now = h.now.Add(d) + timers := h.timers[:0] + for _, t := range h.timers { + t := t // remove after go.mod depends on go1.22 + t.mu.Lock() + switch { + case t.when.After(h.now): + timers = append(timers, t) + case t.when.IsZero(): + // stopped timer + default: + t.when = time.Time{} + if t.c != nil { + close(t.c) + } + if t.f != nil { + h.total++ + go func() { + defer func() { + h.lock() + h.total-- + h.unlock() + }() + t.f() + }() + } + } + t.mu.Unlock() + } + h.timers = timers +} + +// A timer wraps a time.Timer, or a synthetic equivalent in tests. +// Unlike time.Timer, timer is single-use: The timer channel is closed when the timer expires. +type timer interface { + C() <-chan time.Time + Stop() bool + Reset(d time.Duration) bool +} + +// timeTimer implements timer using real time. +type timeTimer struct { + t *time.Timer + c chan time.Time +} + +// newTimeTimer creates a new timer using real time. +func newTimeTimer(d time.Duration) timer { + ch := make(chan time.Time) + t := time.AfterFunc(d, func() { + close(ch) + }) + return &timeTimer{t, ch} +} + +// newTimeAfterFunc creates an AfterFunc timer using real time. +func newTimeAfterFunc(d time.Duration, f func()) timer { + return &timeTimer{ + t: time.AfterFunc(d, f), + } +} + +func (t timeTimer) C() <-chan time.Time { return t.c } +func (t timeTimer) Stop() bool { return t.t.Stop() } +func (t timeTimer) Reset(d time.Duration) bool { return t.t.Reset(d) } + +// fakeTimer implements timer using fake time. +type fakeTimer struct { + hooks *testSyncHooks + + mu sync.Mutex + when time.Time // when the timer will fire + c chan time.Time // closed when the timer fires; mutually exclusive with f + f func() // called when the timer fires; mutually exclusive with c +} + +func (t *fakeTimer) C() <-chan time.Time { return t.c } + +func (t *fakeTimer) Stop() bool { + t.mu.Lock() + defer t.mu.Unlock() + stopped := t.when.IsZero() + t.when = time.Time{} + return stopped +} + +func (t *fakeTimer) Reset(d time.Duration) bool { + if t.c != nil || t.f == nil { + panic("fakeTimer only supports Reset on AfterFunc timers") + } + t.mu.Lock() + defer t.mu.Unlock() + t.hooks.lock() + defer t.hooks.unlock() + active := !t.when.IsZero() + t.when = t.hooks.now.Add(d) + if !active { + t.hooks.timers = append(t.hooks.timers, t) + } + return active +} diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index df578b86c6..ce375c8c75 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -147,6 +147,12 @@ type Transport struct { // waiting for their turn. StrictMaxConcurrentStreams bool + // IdleConnTimeout is the maximum amount of time an idle + // (keep-alive) connection will remain idle before closing + // itself. + // Zero means no limit. + IdleConnTimeout time.Duration + // ReadIdleTimeout is the timeout after which a health check using ping // frame will be carried out if no frame is received on the connection. // Note that a ping response will is considered a received frame, so if @@ -178,6 +184,8 @@ type Transport struct { connPoolOnce sync.Once connPoolOrDef ClientConnPool // non-nil version of ConnPool + + syncHooks *testSyncHooks } func (t *Transport) maxHeaderListSize() uint32 { @@ -302,7 +310,7 @@ type ClientConn struct { readerErr error // set before readerDone is closed idleTimeout time.Duration // or 0 for never - idleTimer *time.Timer + idleTimer timer mu sync.Mutex // guards following cond *sync.Cond // hold mu; broadcast on flow/closed changes @@ -344,6 +352,60 @@ type ClientConn struct { werr error // first write error that has occurred hbuf bytes.Buffer // HPACK encoder writes into this henc *hpack.Encoder + + syncHooks *testSyncHooks // can be nil +} + +// Hook points used for testing. +// Outside of tests, cc.syncHooks is nil and these all have minimal implementations. +// Inside tests, see the testSyncHooks function docs. + +// goRun starts a new goroutine. +func (cc *ClientConn) goRun(f func()) { + if cc.syncHooks != nil { + cc.syncHooks.goRun(f) + return + } + go f() +} + +// condBroadcast is cc.cond.Broadcast. +func (cc *ClientConn) condBroadcast() { + if cc.syncHooks != nil { + cc.syncHooks.condBroadcast(cc.cond) + } + cc.cond.Broadcast() +} + +// condWait is cc.cond.Wait. +func (cc *ClientConn) condWait() { + if cc.syncHooks != nil { + cc.syncHooks.condWait(cc.cond) + } + cc.cond.Wait() +} + +// newTimer creates a new time.Timer, or a synthetic timer in tests. +func (cc *ClientConn) newTimer(d time.Duration) timer { + if cc.syncHooks != nil { + return cc.syncHooks.newTimer(d) + } + return newTimeTimer(d) +} + +// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. +func (cc *ClientConn) afterFunc(d time.Duration, f func()) timer { + if cc.syncHooks != nil { + return cc.syncHooks.afterFunc(d, f) + } + return newTimeAfterFunc(d, f) +} + +func (cc *ClientConn) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { + if cc.syncHooks != nil { + return cc.syncHooks.contextWithTimeout(ctx, d) + } + return context.WithTimeout(ctx, d) } // clientStream is the state for a single HTTP/2 stream. One of these @@ -425,7 +487,7 @@ func (cs *clientStream) abortStreamLocked(err error) { // TODO(dneil): Clean up tests where cs.cc.cond is nil. if cs.cc.cond != nil { // Wake up writeRequestBody if it is waiting on flow control. - cs.cc.cond.Broadcast() + cs.cc.condBroadcast() } } @@ -435,7 +497,7 @@ func (cs *clientStream) abortRequestBodyWrite() { defer cc.mu.Unlock() if cs.reqBody != nil && cs.reqBodyClosed == nil { cs.closeReqBodyLocked() - cc.cond.Broadcast() + cc.condBroadcast() } } @@ -445,10 +507,10 @@ func (cs *clientStream) closeReqBodyLocked() { } cs.reqBodyClosed = make(chan struct{}) reqBodyClosed := cs.reqBodyClosed - go func() { + cs.cc.goRun(func() { cs.reqBody.Close() close(reqBodyClosed) - }() + }) } type stickyErrWriter struct { @@ -537,15 +599,6 @@ func authorityAddr(scheme string, authority string) (addr string) { return net.JoinHostPort(host, port) } -var retryBackoffHook func(time.Duration) *time.Timer - -func backoffNewTimer(d time.Duration) *time.Timer { - if retryBackoffHook != nil { - return retryBackoffHook(d) - } - return time.NewTimer(d) -} - // RoundTripOpt is like RoundTrip, but takes options. func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) { @@ -573,13 +626,27 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res backoff := float64(uint(1) << (uint(retry) - 1)) backoff += backoff * (0.1 * mathrand.Float64()) d := time.Second * time.Duration(backoff) - timer := backoffNewTimer(d) + var tm timer + if t.syncHooks != nil { + tm = t.syncHooks.newTimer(d) + t.syncHooks.blockUntil(func() bool { + select { + case <-tm.C(): + case <-req.Context().Done(): + default: + return false + } + return true + }) + } else { + tm = newTimeTimer(d) + } select { - case <-timer.C: + case <-tm.C(): t.vlogf("RoundTrip retrying after failure: %v", roundTripErr) continue case <-req.Context().Done(): - timer.Stop() + tm.Stop() err = req.Context().Err() } } @@ -658,6 +725,9 @@ func canRetryError(err error) bool { } func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) { + if t.syncHooks != nil { + return t.newClientConn(nil, singleUse, t.syncHooks) + } host, _, err := net.SplitHostPort(addr) if err != nil { return nil, err @@ -666,7 +736,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b if err != nil { return nil, err } - return t.newClientConn(tconn, singleUse) + return t.newClientConn(tconn, singleUse, nil) } func (t *Transport) newTLSConfig(host string) *tls.Config { @@ -732,10 +802,10 @@ func (t *Transport) maxEncoderHeaderTableSize() uint32 { } func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { - return t.newClientConn(c, t.disableKeepAlives()) + return t.newClientConn(c, t.disableKeepAlives(), nil) } -func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) { +func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHooks) (*ClientConn, error) { cc := &ClientConn{ t: t, tconn: c, @@ -750,10 +820,15 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro wantSettingsAck: true, pings: make(map[[8]byte]chan struct{}), reqHeaderMu: make(chan struct{}, 1), + syncHooks: hooks, + } + if hooks != nil { + hooks.newclientconn(cc) + c = cc.tconn } if d := t.idleConnTimeout(); d != 0 { cc.idleTimeout = d - cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout) + cc.idleTimer = cc.afterFunc(d, cc.onIdleTimeout) } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) @@ -818,7 +893,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro return nil, cc.werr } - go cc.readLoop() + cc.goRun(cc.readLoop) return cc, nil } @@ -826,7 +901,7 @@ func (cc *ClientConn) healthCheck() { pingTimeout := cc.t.pingTimeout() // We don't need to periodically ping in the health check, because the readLoop of ClientConn will // trigger the healthCheck again if there is no frame received. - ctx, cancel := context.WithTimeout(context.Background(), pingTimeout) + ctx, cancel := cc.contextWithTimeout(context.Background(), pingTimeout) defer cancel() cc.vlogf("http2: Transport sending health check") err := cc.Ping(ctx) @@ -1056,7 +1131,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { // Wait for all in-flight streams to complete or connection to close done := make(chan struct{}) cancelled := false // guarded by cc.mu - go func() { + cc.goRun(func() { cc.mu.Lock() defer cc.mu.Unlock() for { @@ -1068,9 +1143,9 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { if cancelled { break } - cc.cond.Wait() + cc.condWait() } - }() + }) shutdownEnterWaitStateHook() select { case <-done: @@ -1080,7 +1155,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { cc.mu.Lock() // Free the goroutine above cancelled = true - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() return ctx.Err() } @@ -1118,7 +1193,7 @@ func (cc *ClientConn) closeForError(err error) { for _, cs := range cc.streams { cs.abortStreamLocked(err) } - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() cc.closeConn() } @@ -1215,6 +1290,10 @@ func (cc *ClientConn) decrStreamReservationsLocked() { } func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { + return cc.roundTrip(req, nil) +} + +func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) (*http.Response, error) { ctx := req.Context() cs := &clientStream{ cc: cc, @@ -1229,9 +1308,23 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { respHeaderRecv: make(chan struct{}), donec: make(chan struct{}), } - go cs.doRequest(req) + cc.goRun(func() { + cs.doRequest(req) + }) waitDone := func() error { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.donec: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.donec: return nil @@ -1292,7 +1385,24 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { return err } + if streamf != nil { + streamf(cs) + } + for { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.respHeaderRecv: + case <-cs.abort: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.respHeaderRecv: return handleResponseHeaders() @@ -1348,6 +1458,21 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { if cc.reqHeaderMu == nil { panic("RoundTrip on uninitialized ClientConn") // for tests } + var newStreamHook func(*clientStream) + if cc.syncHooks != nil { + newStreamHook = cc.syncHooks.newstream + cc.syncHooks.blockUntil(func() bool { + select { + case cc.reqHeaderMu <- struct{}{}: + <-cc.reqHeaderMu + case <-cs.reqCancel: + case <-ctx.Done(): + default: + return false + } + return true + }) + } select { case cc.reqHeaderMu <- struct{}{}: case <-cs.reqCancel: @@ -1372,6 +1497,10 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { } cc.mu.Unlock() + if newStreamHook != nil { + newStreamHook(cs) + } + // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? if !cc.t.disableCompression() && req.Header.Get("Accept-Encoding") == "" && @@ -1452,15 +1581,30 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { var respHeaderTimer <-chan time.Time var respHeaderRecv chan struct{} if d := cc.responseHeaderTimeout(); d != 0 { - timer := time.NewTimer(d) + timer := cc.newTimer(d) defer timer.Stop() - respHeaderTimer = timer.C + respHeaderTimer = timer.C() respHeaderRecv = cs.respHeaderRecv } // Wait until the peer half-closes its end of the stream, // or until the request is aborted (via context, error, or otherwise), // whichever comes first. for { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.peerClosed: + case <-respHeaderTimer: + case <-respHeaderRecv: + case <-cs.abort: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.peerClosed: return nil @@ -1609,7 +1753,7 @@ func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { return nil } cc.pendingRequests++ - cc.cond.Wait() + cc.condWait() cc.pendingRequests-- select { case <-cs.abort: @@ -1871,10 +2015,26 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) cs.flow.take(take) return take, nil } - cc.cond.Wait() + cc.condWait() } } +func validateHeaders(hdrs http.Header) string { + for k, vv := range hdrs { + if !httpguts.ValidHeaderFieldName(k) { + return fmt.Sprintf("name %q", k) + } + for _, v := range vv { + if !httpguts.ValidHeaderFieldValue(v) { + // Don't include the value in the error, + // because it may be sensitive. + return fmt.Sprintf("value for header %q", k) + } + } + } + return "" +} + var errNilRequestURL = errors.New("http2: Request.URI is nil") // requires cc.wmu be held. @@ -1912,19 +2072,14 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail } } - // Check for any invalid headers and return an error before we + // Check for any invalid headers+trailers and return an error before we // potentially pollute our hpack state. (We want to be able to // continue to reuse the hpack encoder for future requests) - for k, vv := range req.Header { - if !httpguts.ValidHeaderFieldName(k) { - return nil, fmt.Errorf("invalid HTTP header name %q", k) - } - for _, v := range vv { - if !httpguts.ValidHeaderFieldValue(v) { - // Don't include the value in the error, because it may be sensitive. - return nil, fmt.Errorf("invalid HTTP header value for header %q", k) - } - } + if err := validateHeaders(req.Header); err != "" { + return nil, fmt.Errorf("invalid HTTP header %s", err) + } + if err := validateHeaders(req.Trailer); err != "" { + return nil, fmt.Errorf("invalid HTTP trailer %s", err) } enumerateHeaders := func(f func(name, value string)) { @@ -2143,7 +2298,7 @@ func (cc *ClientConn) forgetStreamID(id uint32) { } // Wake up writeRequestBody via clientStream.awaitFlowControl and // wake up RoundTrip if there is a pending request. - cc.cond.Broadcast() + cc.condBroadcast() closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 { @@ -2231,7 +2386,7 @@ func (rl *clientConnReadLoop) cleanup() { cs.abortStreamLocked(err) } } - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() } @@ -2266,10 +2421,9 @@ func (rl *clientConnReadLoop) run() error { cc := rl.cc gotSettings := false readIdleTimeout := cc.t.ReadIdleTimeout - var t *time.Timer + var t timer if readIdleTimeout != 0 { - t = time.AfterFunc(readIdleTimeout, cc.healthCheck) - defer t.Stop() + t = cc.afterFunc(readIdleTimeout, cc.healthCheck) } for { f, err := cc.fr.ReadFrame() @@ -2684,7 +2838,7 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { }) return nil } - if !cs.firstByte { + if !cs.pastHeaders { cc.logf("protocol error: received DATA before a HEADERS frame") rl.endStreamError(cs, StreamError{ StreamID: f.StreamID, @@ -2867,7 +3021,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { for _, cs := range cc.streams { cs.flow.add(delta) } - cc.cond.Broadcast() + cc.condBroadcast() cc.initialWindowSize = s.Val case SettingHeaderTableSize: @@ -2911,9 +3065,18 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { fl = &cs.flow } if !fl.add(int32(f.Increment)) { + // For stream, the sender sends RST_STREAM with an error code of FLOW_CONTROL_ERROR + if cs != nil { + rl.endStreamError(cs, StreamError{ + StreamID: f.StreamID, + Code: ErrCodeFlowControl, + }) + return nil + } + return ConnectionError(ErrCodeFlowControl) } - cc.cond.Broadcast() + cc.condBroadcast() return nil } @@ -2955,24 +3118,38 @@ func (cc *ClientConn) Ping(ctx context.Context) error { } cc.mu.Unlock() } - errc := make(chan error, 1) - go func() { + var pingError error + errc := make(chan struct{}) + cc.goRun(func() { cc.wmu.Lock() defer cc.wmu.Unlock() - if err := cc.fr.WritePing(false, p); err != nil { - errc <- err + if pingError = cc.fr.WritePing(false, p); pingError != nil { + close(errc) return } - if err := cc.bw.Flush(); err != nil { - errc <- err + if pingError = cc.bw.Flush(); pingError != nil { + close(errc) return } - }() + }) + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-c: + case <-errc: + case <-ctx.Done(): + case <-cc.readerDone: + default: + return false + } + return true + }) + } select { case <-c: return nil - case err := <-errc: - return err + case <-errc: + return pingError case <-ctx.Done(): return ctx.Err() case <-cc.readerDone: @@ -3141,9 +3318,17 @@ func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, err } func (t *Transport) idleConnTimeout() time.Duration { + // to keep things backwards compatible, we use non-zero values of + // IdleConnTimeout, followed by using the IdleConnTimeout on the underlying + // http1 transport, followed by 0 + if t.IdleConnTimeout != 0 { + return t.IdleConnTimeout + } + if t.t1 != nil { return t.t1.IdleConnTimeout } + return 0 } diff --git a/vendor/golang.org/x/sys/unix/aliases.go b/vendor/golang.org/x/sys/unix/aliases.go index e7d3df4bd3..b0e4198575 100644 --- a/vendor/golang.org/x/sys/unix/aliases.go +++ b/vendor/golang.org/x/sys/unix/aliases.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9 +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos package unix diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go index 16dc699379..2f0fa76e4f 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build darwin && go1.12 +//go:build darwin package unix diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go index 64d1bb4dba..2b57e0f73b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -13,6 +13,7 @@ package unix import ( + "errors" "sync" "unsafe" ) @@ -169,25 +170,26 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { func Uname(uname *Utsname) error { mib := []_C_int{CTL_KERN, KERN_OSTYPE} n := unsafe.Sizeof(uname.Sysname) - if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { + // Suppress ENOMEM errors to be compatible with the C library __xuname() implementation. + if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_HOSTNAME} n = unsafe.Sizeof(uname.Nodename) - if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_OSRELEASE} n = unsafe.Sizeof(uname.Release) - if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_VERSION} n = unsafe.Sizeof(uname.Version) - if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } @@ -205,7 +207,7 @@ func Uname(uname *Utsname) error { mib = []_C_int{CTL_HW, HW_MACHINE} n = unsafe.Sizeof(uname.Machine) - if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 0f85e29e62..5682e2628a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1849,6 +1849,105 @@ func Dup2(oldfd, newfd int) error { //sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error) //sys Fsopen(fsName string, flags int) (fd int, err error) //sys Fspick(dirfd int, pathName string, flags int) (fd int, err error) + +//sys fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) + +func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) { + var keyp *byte + if keyp, err = BytePtrFromString(key); err != nil { + return + } + return fsconfig(fd, cmd, keyp, value, aux) +} + +// FsconfigSetFlag is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_FLAG. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +func FsconfigSetFlag(fd int, key string) (err error) { + return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0) +} + +// FsconfigSetString is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_STRING. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is the parameter value to set. +func FsconfigSetString(fd int, key string, value string) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(value); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0) +} + +// FsconfigSetBinary is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_BINARY. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is the parameter value to set. +func FsconfigSetBinary(fd int, key string, value []byte) (err error) { + if len(value) == 0 { + return EINVAL + } + return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value)) +} + +// FsconfigSetPath is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_PATH. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// path is a non-empty path for specified key. +// atfd is a file descriptor at which to start lookup from or AT_FDCWD. +func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(path); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd) +} + +// FsconfigSetPathEmpty is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as +// FconfigSetPath but with AT_PATH_EMPTY implied. +func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(path); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd) +} + +// FsconfigSetFd is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_FD. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is a file descriptor to be assigned to specified key. +func FsconfigSetFd(fd int, key string, value int) (err error) { + return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value) +} + +// FsconfigCreate is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_CMD_CREATE. +// +// fd is the filesystem context to act upon. +func FsconfigCreate(fd int) (err error) { + return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0) +} + +// FsconfigReconfigure is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_CMD_RECONFIGURE. +// +// fd is the filesystem context to act upon. +func FsconfigReconfigure(fd int) (err error) { + return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0) +} + //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 //sysnb Getpgid(pid int) (pgid int, err error) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 1488d27128..87d8612a1d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -906,6 +906,16 @@ func Fspick(dirfd int, pathName string, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) { + _, _, e1 := Syscall6(SYS_FSCONFIG, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(value)), uintptr(aux), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdents(fd int, buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index dc0c955eec..eff6bcdef8 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -836,6 +836,15 @@ const ( FSPICK_EMPTY_PATH = 0x8 FSMOUNT_CLOEXEC = 0x1 + + FSCONFIG_SET_FLAG = 0x0 + FSCONFIG_SET_STRING = 0x1 + FSCONFIG_SET_BINARY = 0x2 + FSCONFIG_SET_PATH = 0x3 + FSCONFIG_SET_PATH_EMPTY = 0x4 + FSCONFIG_SET_FD = 0x5 + FSCONFIG_CMD_CREATE = 0x6 + FSCONFIG_CMD_RECONFIGURE = 0x7 ) type OpenHow struct { @@ -1550,6 +1559,7 @@ const ( IFLA_DEVLINK_PORT = 0x3e IFLA_GSO_IPV4_MAX_SIZE = 0x3f IFLA_GRO_IPV4_MAX_SIZE = 0x40 + IFLA_DPLL_PIN = 0x41 IFLA_PROTO_DOWN_REASON_UNSPEC = 0x0 IFLA_PROTO_DOWN_REASON_MASK = 0x1 IFLA_PROTO_DOWN_REASON_VALUE = 0x2 @@ -1565,6 +1575,7 @@ const ( IFLA_INET6_ICMP6STATS = 0x6 IFLA_INET6_TOKEN = 0x7 IFLA_INET6_ADDR_GEN_MODE = 0x8 + IFLA_INET6_RA_MTU = 0x9 IFLA_BR_UNSPEC = 0x0 IFLA_BR_FORWARD_DELAY = 0x1 IFLA_BR_HELLO_TIME = 0x2 @@ -1612,6 +1623,9 @@ const ( IFLA_BR_MCAST_MLD_VERSION = 0x2c IFLA_BR_VLAN_STATS_PER_PORT = 0x2d IFLA_BR_MULTI_BOOLOPT = 0x2e + IFLA_BR_MCAST_QUERIER_STATE = 0x2f + IFLA_BR_FDB_N_LEARNED = 0x30 + IFLA_BR_FDB_MAX_LEARNED = 0x31 IFLA_BRPORT_UNSPEC = 0x0 IFLA_BRPORT_STATE = 0x1 IFLA_BRPORT_PRIORITY = 0x2 @@ -1649,6 +1663,14 @@ const ( IFLA_BRPORT_BACKUP_PORT = 0x22 IFLA_BRPORT_MRP_RING_OPEN = 0x23 IFLA_BRPORT_MRP_IN_OPEN = 0x24 + IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT = 0x25 + IFLA_BRPORT_MCAST_EHT_HOSTS_CNT = 0x26 + IFLA_BRPORT_LOCKED = 0x27 + IFLA_BRPORT_MAB = 0x28 + IFLA_BRPORT_MCAST_N_GROUPS = 0x29 + IFLA_BRPORT_MCAST_MAX_GROUPS = 0x2a + IFLA_BRPORT_NEIGH_VLAN_SUPPRESS = 0x2b + IFLA_BRPORT_BACKUP_NHID = 0x2c IFLA_INFO_UNSPEC = 0x0 IFLA_INFO_KIND = 0x1 IFLA_INFO_DATA = 0x2 @@ -1670,6 +1692,9 @@ const ( IFLA_MACVLAN_MACADDR = 0x4 IFLA_MACVLAN_MACADDR_DATA = 0x5 IFLA_MACVLAN_MACADDR_COUNT = 0x6 + IFLA_MACVLAN_BC_QUEUE_LEN = 0x7 + IFLA_MACVLAN_BC_QUEUE_LEN_USED = 0x8 + IFLA_MACVLAN_BC_CUTOFF = 0x9 IFLA_VRF_UNSPEC = 0x0 IFLA_VRF_TABLE = 0x1 IFLA_VRF_PORT_UNSPEC = 0x0 @@ -1693,9 +1718,22 @@ const ( IFLA_XFRM_UNSPEC = 0x0 IFLA_XFRM_LINK = 0x1 IFLA_XFRM_IF_ID = 0x2 + IFLA_XFRM_COLLECT_METADATA = 0x3 IFLA_IPVLAN_UNSPEC = 0x0 IFLA_IPVLAN_MODE = 0x1 IFLA_IPVLAN_FLAGS = 0x2 + NETKIT_NEXT = -0x1 + NETKIT_PASS = 0x0 + NETKIT_DROP = 0x2 + NETKIT_REDIRECT = 0x7 + NETKIT_L2 = 0x0 + NETKIT_L3 = 0x1 + IFLA_NETKIT_UNSPEC = 0x0 + IFLA_NETKIT_PEER_INFO = 0x1 + IFLA_NETKIT_PRIMARY = 0x2 + IFLA_NETKIT_POLICY = 0x3 + IFLA_NETKIT_PEER_POLICY = 0x4 + IFLA_NETKIT_MODE = 0x5 IFLA_VXLAN_UNSPEC = 0x0 IFLA_VXLAN_ID = 0x1 IFLA_VXLAN_GROUP = 0x2 @@ -1726,6 +1764,8 @@ const ( IFLA_VXLAN_GPE = 0x1b IFLA_VXLAN_TTL_INHERIT = 0x1c IFLA_VXLAN_DF = 0x1d + IFLA_VXLAN_VNIFILTER = 0x1e + IFLA_VXLAN_LOCALBYPASS = 0x1f IFLA_GENEVE_UNSPEC = 0x0 IFLA_GENEVE_ID = 0x1 IFLA_GENEVE_REMOTE = 0x2 @@ -1740,6 +1780,7 @@ const ( IFLA_GENEVE_LABEL = 0xb IFLA_GENEVE_TTL_INHERIT = 0xc IFLA_GENEVE_DF = 0xd + IFLA_GENEVE_INNER_PROTO_INHERIT = 0xe IFLA_BAREUDP_UNSPEC = 0x0 IFLA_BAREUDP_PORT = 0x1 IFLA_BAREUDP_ETHERTYPE = 0x2 @@ -1752,6 +1793,8 @@ const ( IFLA_GTP_FD1 = 0x2 IFLA_GTP_PDP_HASHSIZE = 0x3 IFLA_GTP_ROLE = 0x4 + IFLA_GTP_CREATE_SOCKETS = 0x5 + IFLA_GTP_RESTART_COUNT = 0x6 IFLA_BOND_UNSPEC = 0x0 IFLA_BOND_MODE = 0x1 IFLA_BOND_ACTIVE_SLAVE = 0x2 @@ -1781,6 +1824,9 @@ const ( IFLA_BOND_AD_ACTOR_SYSTEM = 0x1a IFLA_BOND_TLB_DYNAMIC_LB = 0x1b IFLA_BOND_PEER_NOTIF_DELAY = 0x1c + IFLA_BOND_AD_LACP_ACTIVE = 0x1d + IFLA_BOND_MISSED_MAX = 0x1e + IFLA_BOND_NS_IP6_TARGET = 0x1f IFLA_BOND_AD_INFO_UNSPEC = 0x0 IFLA_BOND_AD_INFO_AGGREGATOR = 0x1 IFLA_BOND_AD_INFO_NUM_PORTS = 0x2 @@ -1796,6 +1842,7 @@ const ( IFLA_BOND_SLAVE_AD_AGGREGATOR_ID = 0x6 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE = 0x7 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE = 0x8 + IFLA_BOND_SLAVE_PRIO = 0x9 IFLA_VF_INFO_UNSPEC = 0x0 IFLA_VF_INFO = 0x1 IFLA_VF_UNSPEC = 0x0 @@ -1854,8 +1901,16 @@ const ( IFLA_STATS_LINK_XSTATS_SLAVE = 0x3 IFLA_STATS_LINK_OFFLOAD_XSTATS = 0x4 IFLA_STATS_AF_SPEC = 0x5 + IFLA_STATS_GETSET_UNSPEC = 0x0 + IFLA_STATS_GET_FILTERS = 0x1 + IFLA_STATS_SET_OFFLOAD_XSTATS_L3_STATS = 0x2 IFLA_OFFLOAD_XSTATS_UNSPEC = 0x0 IFLA_OFFLOAD_XSTATS_CPU_HIT = 0x1 + IFLA_OFFLOAD_XSTATS_HW_S_INFO = 0x2 + IFLA_OFFLOAD_XSTATS_L3_STATS = 0x3 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_UNSPEC = 0x0 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST = 0x1 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED = 0x2 IFLA_XDP_UNSPEC = 0x0 IFLA_XDP_FD = 0x1 IFLA_XDP_ATTACHED = 0x2 @@ -1885,6 +1940,11 @@ const ( IFLA_RMNET_UNSPEC = 0x0 IFLA_RMNET_MUX_ID = 0x1 IFLA_RMNET_FLAGS = 0x2 + IFLA_MCTP_UNSPEC = 0x0 + IFLA_MCTP_NET = 0x1 + IFLA_DSA_UNSPEC = 0x0 + IFLA_DSA_CONDUIT = 0x1 + IFLA_DSA_MASTER = 0x1 ) const ( diff --git a/vendor/modules.txt b/vendor/modules.txt index 887918f248..97339eafbe 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2012,7 +2012,7 @@ go.uber.org/zap/internal/color go.uber.org/zap/internal/exit go.uber.org/zap/zapcore go.uber.org/zap/zapgrpc -# golang.org/x/crypto v0.19.0 +# golang.org/x/crypto v0.21.0 ## explicit; go 1.18 golang.org/x/crypto/argon2 golang.org/x/crypto/bcrypt @@ -2062,7 +2062,7 @@ golang.org/x/image/vector golang.org/x/mod/internal/lazyregexp golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.21.0 +# golang.org/x/net v0.23.0 ## explicit; go 1.18 golang.org/x/net/bpf golang.org/x/net/context @@ -2094,7 +2094,7 @@ golang.org/x/oauth2/internal golang.org/x/sync/errgroup golang.org/x/sync/semaphore golang.org/x/sync/singleflight -# golang.org/x/sys v0.17.0 +# golang.org/x/sys v0.18.0 ## explicit; go 1.18 golang.org/x/sys/cpu golang.org/x/sys/execabs @@ -2105,7 +2105,7 @@ golang.org/x/sys/windows/registry golang.org/x/sys/windows/svc golang.org/x/sys/windows/svc/eventlog golang.org/x/sys/windows/svc/mgr -# golang.org/x/term v0.17.0 +# golang.org/x/term v0.18.0 ## explicit; go 1.18 golang.org/x/term # golang.org/x/text v0.14.0 From 9bcb949813b0b1aa5838e3c9f635702df1ded5ad Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Thu, 4 Apr 2024 16:23:30 +0200 Subject: [PATCH 02/26] Add API struct to ocs Signed-off-by: Christian Richter --- services/ocs/pkg/config/config.go | 3 ++- services/ocs/pkg/config/reva.go | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/services/ocs/pkg/config/config.go b/services/ocs/pkg/config/config.go index 4097ff4ef6..ed7a0ab96e 100644 --- a/services/ocs/pkg/config/config.go +++ b/services/ocs/pkg/config/config.go @@ -19,7 +19,8 @@ type Config struct { Debug Debug `yaml:"debug"` HTTP HTTP `yaml:"http"` - + API API `yaml:"api"` + GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"` GrpcClient client.Client `yaml:"-"` diff --git a/services/ocs/pkg/config/reva.go b/services/ocs/pkg/config/reva.go index 8413904dab..d321c16a49 100644 --- a/services/ocs/pkg/config/reva.go +++ b/services/ocs/pkg/config/reva.go @@ -4,3 +4,7 @@ package config type TokenManager struct { JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;OCS_JWT_SECRET" desc:"The secret to mint and validate jwt tokens." introductionVersion:"pre5.0"` } + +type API struct { + ShowUserEmailInResults bool `yaml:"show_email_in_results" env:"OCIS_SHOW_USER_EMAIL_IN_RESULTS" desc:"Mask user email addresses in responses." introductionVersion:"5.1"` +} From 0e680f31e4005fce48450e5fd6c3cd51ea8b3cc9 Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Thu, 4 Apr 2024 16:26:34 +0200 Subject: [PATCH 03/26] bump reva Signed-off-by: Christian Richter --- go.mod | 2 +- go.sum | 4 ++-- .../http/services/owncloud/ocs/config/config.go | 1 + .../handlers/apps/sharing/sharees/sharees.go | 17 +++++++++++++++++ vendor/modules.txt | 2 +- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 5e1ae10e6f..7f3a3b933d 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible github.com/coreos/go-oidc/v3 v3.9.0 github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 - github.com/cs3org/reva/v2 v2.19.2 + github.com/cs3org/reva/v2 v2.19.3 github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25 github.com/disintegration/imaging v1.6.2 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e diff --git a/go.sum b/go.sum index 885f9d7595..fc49275add 100644 --- a/go.sum +++ b/go.sum @@ -1019,8 +1019,8 @@ github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c= github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 h1:BUdwkIlf8IS2FasrrPg8gGPHQPOrQ18MS1Oew2tmGtY= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= -github.com/cs3org/reva/v2 v2.19.2 h1:p5b9ZLZlrRnUzpwgcAsqEse/YGFTde8InA43StTdyKM= -github.com/cs3org/reva/v2 v2.19.2/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E= +github.com/cs3org/reva/v2 v2.19.3 h1:MKzUAa0HYuZog14dEg7TSBjT/0MtcOd2HZ4js/m7Gfg= +github.com/cs3org/reva/v2 v2.19.3/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/config/config.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/config/config.go index 554a9eeb3c..031eecf0dc 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/config/config.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/config/config.go @@ -47,6 +47,7 @@ type Config struct { ListOCMShares bool `mapstructure:"list_ocm_shares"` Notifications map[string]interface{} `mapstructure:"notifications"` IncludeOCMSharees bool `mapstructure:"include_ocm_sharees"` + ShowEmailInResults bool `mapstructure:"show_email_in_results"` } // Init sets sane defaults diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/sharees.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/sharees.go index e3e3bbbeca..978f3d9666 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/sharees.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/sharees.go @@ -40,6 +40,7 @@ type Handler struct { gatewayAddr string additionalInfoAttribute string includeOCMSharees bool + showUserEmailInResults bool } // Init initializes this and any contained handlers @@ -47,6 +48,7 @@ func (h *Handler) Init(c *config.Config) { h.gatewayAddr = c.GatewaySvc h.additionalInfoAttribute = c.AdditionalInfoAttribute h.includeOCMSharees = c.IncludeOCMSharees + h.showUserEmailInResults = c.ShowEmailInResults } // FindSharees implements the /apps/files_sharing/api/v1/sharees endpoint @@ -123,6 +125,21 @@ func (h *Handler) FindSharees(w http.ResponseWriter, r *http.Request) { } } + if !h.showUserEmailInResults { + for _, m := range userMatches { + m.Value.ShareWithAdditionalInfo = m.Value.ShareWith + } + for _, m := range exactUserMatches { + m.Value.ShareWithAdditionalInfo = m.Value.ShareWith + } + for _, m := range groupMatches { + m.Value.ShareWithAdditionalInfo = m.Value.ShareWith + } + for _, m := range exactGroupMatches { + m.Value.ShareWithAdditionalInfo = m.Value.ShareWith + } + } + response.WriteOCSSuccess(w, r, &conversions.ShareeData{ Exact: &conversions.ExactMatchesData{ Users: exactUserMatches, diff --git a/vendor/modules.txt b/vendor/modules.txt index 97339eafbe..aec61e5e3f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -359,7 +359,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1 github.com/cs3org/go-cs3apis/cs3/types/v1beta1 -# github.com/cs3org/reva/v2 v2.19.2 +# github.com/cs3org/reva/v2 v2.19.3 ## explicit; go 1.21 github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/runtime From f4b673a4e0be63eaccde8a45dfb91612bcc96a61 Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Thu, 4 Apr 2024 16:34:15 +0200 Subject: [PATCH 04/26] change default behaviour to avoid a breaking change Signed-off-by: Christian Richter --- services/ocs/pkg/config/defaults/defaultconfig.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/ocs/pkg/config/defaults/defaultconfig.go b/services/ocs/pkg/config/defaults/defaultconfig.go index 6a9ebec588..a665c78b2a 100644 --- a/services/ocs/pkg/config/defaults/defaultconfig.go +++ b/services/ocs/pkg/config/defaults/defaultconfig.go @@ -44,6 +44,9 @@ func DefaultConfig() *config.Config { Nodes: []string{"127.0.0.1:9233"}, TTL: time.Hour * 12, }, + API: config.API{ + ShowUserEmailInResults: true, + }, } } From 51ef72532b45ba10bec2c46499647e4fb7bcb5be Mon Sep 17 00:00:00 2001 From: Christian Richter <1058116+dragonchaser@users.noreply.github.com> Date: Fri, 5 Apr 2024 10:24:20 +0200 Subject: [PATCH 05/26] Update services/ocs/pkg/config/reva.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jörn Friedrich Dreyer --- services/ocs/pkg/config/reva.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ocs/pkg/config/reva.go b/services/ocs/pkg/config/reva.go index d321c16a49..05e8d8c8d7 100644 --- a/services/ocs/pkg/config/reva.go +++ b/services/ocs/pkg/config/reva.go @@ -6,5 +6,5 @@ type TokenManager struct { } type API struct { - ShowUserEmailInResults bool `yaml:"show_email_in_results" env:"OCIS_SHOW_USER_EMAIL_IN_RESULTS" desc:"Mask user email addresses in responses." introductionVersion:"5.1"` + ShowUserEmailInResults bool `yaml:"show_email_in_results" env:"OCIS_SHOW_USER_EMAIL_IN_RESULTS" desc:"Mask user email addresses in responses. (EXPERIMENTAL)" introductionVersion:"5.1"` } From 355f486ca1678beb25341ef79d73cb296d3923dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 5 Apr 2024 11:26:48 +0200 Subject: [PATCH 06/26] bump reva to 2.19.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- go.mod | 2 +- go.sum | 4 +- ocis/pkg/command/migrate.go | 4 +- .../v2/pkg/share/manager/jsoncs3/jsoncs3.go | 116 ++++++++++++------ vendor/modules.txt | 2 +- 5 files changed, 84 insertions(+), 44 deletions(-) diff --git a/go.mod b/go.mod index 7f3a3b933d..413c4f5373 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible github.com/coreos/go-oidc/v3 v3.9.0 github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 - github.com/cs3org/reva/v2 v2.19.3 + github.com/cs3org/reva/v2 v2.19.4 github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25 github.com/disintegration/imaging v1.6.2 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e diff --git a/go.sum b/go.sum index fc49275add..0cfa3eb2d5 100644 --- a/go.sum +++ b/go.sum @@ -1019,8 +1019,8 @@ github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c= github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 h1:BUdwkIlf8IS2FasrrPg8gGPHQPOrQ18MS1Oew2tmGtY= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= -github.com/cs3org/reva/v2 v2.19.3 h1:MKzUAa0HYuZog14dEg7TSBjT/0MtcOd2HZ4js/m7Gfg= -github.com/cs3org/reva/v2 v2.19.3/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E= +github.com/cs3org/reva/v2 v2.19.4 h1:gOcV6cgV+es624ckLUkXWL9mbHZpPXEgsa83/YA6WYA= +github.com/cs3org/reva/v2 v2.19.4/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= diff --git a/ocis/pkg/command/migrate.go b/ocis/pkg/command/migrate.go index 319cc83500..3ec250a06b 100644 --- a/ocis/pkg/command/migrate.go +++ b/ocis/pkg/command/migrate.go @@ -106,11 +106,11 @@ func RebuildJSONCS3Indexes(cfg *config.Config) *cli.Command { if err != nil { return err } - gc, err := pool.GetGatewayServiceClient(conf.GatewayAddr) + gatewaySelector, err := pool.GatewaySelector(conf.GatewayAddr) if err != nil { return err } - mgr, err := jsoncs3.New(s, gc, 0, nil, 1) + mgr, err := jsoncs3.New(s, gatewaySelector, 0, nil, 1) if err != nil { return err } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go index be1629119b..edd5e00b2c 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go @@ -29,14 +29,6 @@ import ( rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - "github.com/google/uuid" - "github.com/mitchellh/mapstructure" - "github.com/pkg/errors" - "github.com/rs/zerolog/log" - "go.opentelemetry.io/otel/codes" - "golang.org/x/sync/errgroup" - "google.golang.org/genproto/protobuf/field_mask" - "github.com/cs3org/reva/v2/pkg/appctx" ctxpkg "github.com/cs3org/reva/v2/pkg/ctx" "github.com/cs3org/reva/v2/pkg/errtypes" @@ -52,6 +44,13 @@ import ( "github.com/cs3org/reva/v2/pkg/storage/utils/metadata" // nolint:staticcheck // we need the legacy package to convert V1 to V2 messages "github.com/cs3org/reva/v2/pkg/storagespace" "github.com/cs3org/reva/v2/pkg/utils" + "github.com/google/uuid" + "github.com/mitchellh/mapstructure" + "github.com/pkg/errors" + "go.opentelemetry.io/otel/codes" + "golang.org/x/sync/errgroup" + "google.golang.org/genproto/protobuf/field_mask" + "google.golang.org/protobuf/types/known/fieldmaskpb" ) /* @@ -153,8 +152,8 @@ type Manager struct { MaxConcurrency int - gateway gatewayv1beta1.GatewayAPIClient - eventStream events.Stream + gatewaySelector pool.Selectable[gatewayv1beta1.GatewayAPIClient] + eventStream events.Stream } // NewDefault returns a new manager instance with default dependencies @@ -170,7 +169,7 @@ func NewDefault(m map[string]interface{}) (share.Manager, error) { return nil, err } - gc, err := pool.GetGatewayServiceClient(c.GatewayAddr) + gatewaySelector, err := pool.GatewaySelector(c.GatewayAddr) if err != nil { return nil, err } @@ -183,11 +182,11 @@ func NewDefault(m map[string]interface{}) (share.Manager, error) { } } - return New(s, gc, c.CacheTTL, es, c.MaxConcurrency) + return New(s, gatewaySelector, c.CacheTTL, es, c.MaxConcurrency) } // New returns a new manager instance. -func New(s metadata.Storage, gc gatewayv1beta1.GatewayAPIClient, ttlSeconds int, es events.Stream, maxconcurrency int) (*Manager, error) { +func New(s metadata.Storage, gatewaySelector pool.Selectable[gatewayv1beta1.GatewayAPIClient], ttlSeconds int, es events.Stream, maxconcurrency int) (*Manager, error) { ttl := time.Duration(ttlSeconds) * time.Second return &Manager{ Cache: providercache.New(s, ttl), @@ -195,7 +194,7 @@ func New(s metadata.Storage, gc gatewayv1beta1.GatewayAPIClient, ttlSeconds int, UserReceivedStates: receivedsharecache.New(s, ttl), GroupReceivedCache: sharecache.New(s, "groups", "received.json", ttl), storage: s, - gateway: gc, + gatewaySelector: gatewaySelector, eventStream: es, MaxConcurrency: maxconcurrency, }, nil @@ -411,6 +410,7 @@ func (m *Manager) get(ctx context.Context, ref *collaboration.ShareReference) (s func (m *Manager) GetShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.Share, error) { ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "GetShare") defer span.End() + sublog := appctx.GetLogger(ctx).With().Str("id", ref.GetId().GetOpaqueId()).Str("key", ref.GetKey().String()).Str("driver", "jsoncs3").Str("handler", "GetShare").Logger() if err := m.initialize(ctx); err != nil { return nil, err } @@ -421,7 +421,7 @@ func (m *Manager) GetShare(ctx context.Context, ref *collaboration.ShareReferenc } if share.IsExpired(s) { if err := m.removeShare(ctx, s); err != nil { - log.Error().Err(err). + sublog.Error().Err(err). Msg("failed to unshare expired share") } if err := events.Publish(ctx, m.eventStream, events.ShareExpired{ @@ -432,7 +432,7 @@ func (m *Manager) GetShare(ctx context.Context, ref *collaboration.ShareReferenc GranteeUserID: s.GetGrantee().GetUserId(), GranteeGroupID: s.GetGrantee().GetGroupId(), }); err != nil { - log.Error().Err(err). + sublog.Error().Err(err). Msg("failed to publish share expired event") } } @@ -445,8 +445,15 @@ func (m *Manager) GetShare(ctx context.Context, ref *collaboration.ShareReferenc req := &provider.StatRequest{ Ref: &provider.Reference{ResourceId: s.ResourceId}, + FieldMask: &fieldmaskpb.FieldMask{ + Paths: []string{"permissions"}, + }, } - res, err := m.gateway.Stat(ctx, req) + client, err := m.gatewaySelector.Next() + if err != nil { + return nil, err + } + res, err := client.Stat(ctx, req) if err == nil && res.Status.Code == rpcv1beta1.Code_CODE_OK && res.Info.PermissionSet.ListGrants { @@ -523,8 +530,15 @@ func (m *Manager) UpdateShare(ctx context.Context, ref *collaboration.ShareRefer if !share.IsCreatedByUser(toUpdate, user) { req := &provider.StatRequest{ Ref: &provider.Reference{ResourceId: toUpdate.ResourceId}, + FieldMask: &fieldmaskpb.FieldMask{ + Paths: []string{"permissions"}, + }, } - res, err := m.gateway.Stat(ctx, req) + client, err := m.gatewaySelector.Next() + if err != nil { + return nil, err + } + res, err := client.Stat(ctx, req) if err != nil || res.Status.Code != rpcv1beta1.Code_CODE_OK || !res.Info.PermissionSet.UpdateGrant { @@ -583,6 +597,7 @@ func (m *Manager) ListShares(ctx context.Context, filters []*collaboration.Filte func (m *Manager) listSharesByIDs(ctx context.Context, user *userv1beta1.User, filters []*collaboration.Filter) ([]*collaboration.Share, error) { ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "listSharesByIDs") defer span.End() + sublog := appctx.GetLogger(ctx).With().Str("userid", user.GetId().GetOpaqueId()).Str("useridp", user.GetId().GetIdp()).Str("driver", "jsoncs3").Str("handler", "listSharesByIDs").Logger() providerSpaces := make(map[string]map[string]struct{}) for _, f := range share.FilterFiltersByType(filters, collaboration.Filter_TYPE_RESOURCE_ID) { @@ -604,19 +619,21 @@ func (m *Manager) listSharesByIDs(ctx context.Context, user *userv1beta1.User, f } for _, s := range shares.Shares { + resourceID := s.GetResourceId() + sublog = sublog.With().Str("storageid", resourceID.GetStorageId()).Str("spaceid", resourceID.GetSpaceId()).Str("opaqueid", resourceID.GetOpaqueId()).Logger() if share.IsExpired(s) { if err := m.removeShare(ctx, s); err != nil { - log.Error().Err(err). + sublog.Error().Err(err). Msg("failed to unshare expired share") } if err := events.Publish(ctx, m.eventStream, events.ShareExpired{ ShareOwner: s.GetOwner(), - ItemID: s.GetResourceId(), + ItemID: resourceID, ExpiredAt: time.Unix(int64(s.GetExpiration().GetSeconds()), int64(s.GetExpiration().GetNanos())), GranteeUserID: s.GetGrantee().GetUserId(), GranteeGroupID: s.GetGrantee().GetGroupId(), }); err != nil { - log.Error().Err(err). + sublog.Error().Err(err). Msg("failed to publish share expired event") } continue @@ -626,17 +643,33 @@ func (m *Manager) listSharesByIDs(ctx context.Context, user *userv1beta1.User, f } if !(share.IsCreatedByUser(s, user) || share.IsGrantedToUser(s, user)) { - key := storagespace.FormatResourceID(*s.ResourceId) + key := storagespace.FormatResourceID(*resourceID) if _, hit := statCache[key]; !hit { req := &provider.StatRequest{ - Ref: &provider.Reference{ResourceId: s.ResourceId}, + Ref: &provider.Reference{ResourceId: resourceID}, + FieldMask: &fieldmaskpb.FieldMask{ + Paths: []string{"permissions"}, + }, } - res, err := m.gateway.Stat(ctx, req) - if err != nil || - res.Status.Code != rpcv1beta1.Code_CODE_OK || - !res.Info.PermissionSet.ListGrants { + client, err := m.gatewaySelector.Next() + if err != nil { + sublog.Error().Err(err).Msg("failed to select next gateway client") continue } + res, err := client.Stat(ctx, req) + if err != nil { + sublog.Error().Err(err).Msg("failed to make stat call") + continue + } + if res.Status.Code != rpcv1beta1.Code_CODE_OK { + sublog.Debug().Str("code", res.GetStatus().GetCode().String()).Msg(res.GetStatus().GetMessage()) + continue + } + if !res.Info.PermissionSet.ListGrants { + sublog.Debug().Msg("user has no list grants permission") + continue + } + sublog.Debug().Msg("listing share for non participating user") statCache[key] = struct{}{} } } @@ -652,6 +685,7 @@ func (m *Manager) listSharesByIDs(ctx context.Context, user *userv1beta1.User, f func (m *Manager) listCreatedShares(ctx context.Context, user *userv1beta1.User, filters []*collaboration.Filter) ([]*collaboration.Share, error) { ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "listCreatedShares") defer span.End() + sublog := appctx.GetLogger(ctx).With().Str("userid", user.GetId().GetOpaqueId()).Str("useridp", user.GetId().GetIdp()).Str("driver", "jsoncs3").Str("handler", "listCreatedShares").Logger() list, err := m.CreatedCache.List(ctx, user.Id.OpaqueId) if err != nil { @@ -694,7 +728,7 @@ func (m *Manager) listCreatedShares(ctx context.Context, user *userv1beta1.User, // fetch all shares from space with one request _, err := m.Cache.ListSpace(ctx, storageID, spaceID) if err != nil { - log.Error().Err(err). + sublog.Error().Err(err). Str("storageid", storageID). Str("spaceid", spaceID). Msg("failed to list shares in space") @@ -707,7 +741,7 @@ func (m *Manager) listCreatedShares(ctx context.Context, user *userv1beta1.User, } if share.IsExpired(s) { if err := m.removeShare(ctx, s); err != nil { - log.Error().Err(err). + sublog.Error().Err(err). Msg("failed to unshare expired share") } if err := events.Publish(ctx, m.eventStream, events.ShareExpired{ @@ -717,7 +751,7 @@ func (m *Manager) listCreatedShares(ctx context.Context, user *userv1beta1.User, GranteeUserID: s.GetGrantee().GetUserId(), GranteeGroupID: s.GetGrantee().GetGroupId(), }); err != nil { - log.Error().Err(err). + sublog.Error().Err(err). Msg("failed to publish share expired event") } continue @@ -762,6 +796,7 @@ func (m *Manager) listCreatedShares(ctx context.Context, user *userv1beta1.User, func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter, forUser *userv1beta1.UserId) ([]*collaboration.ReceivedShare, error) { ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "ListReceivedShares") defer span.End() + sublog := appctx.GetLogger(ctx).With().Str("driver", "jsoncs3").Str("handler", "ListReceivedShares").Logger() if err := m.initialize(ctx); err != nil { return nil, err @@ -769,7 +804,11 @@ func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborati user := ctxpkg.ContextMustGetUser(ctx) if user.GetId().GetType() == userv1beta1.UserType_USER_TYPE_SERVICE { - u, err := utils.GetUser(forUser, m.gateway) + client, err := m.gatewaySelector.Next() + if err != nil { + return nil, err + } + u, err := utils.GetUser(forUser, client) if err != nil { return nil, errtypes.BadRequest("user not found") } @@ -852,12 +891,11 @@ func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborati g.Go(func() error { for w := range work { storageID, spaceID, _ := shareid.Decode(w.ssid) + sublogr := sublog.With().Str("storageid", storageID).Str("spaceid", spaceID).Logger() // fetch all shares from space with one request _, err := m.Cache.ListSpace(ctx, storageID, spaceID) if err != nil { - log.Error().Err(err). - Str("storageid", storageID). - Str("spaceid", spaceID). + sublogr.Error().Err(err). Msg("failed to list shares in space") continue } @@ -866,9 +904,10 @@ func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborati if err != nil || s == nil { continue } + sublogr = sublogr.With().Str("shareid", shareID).Logger() if share.IsExpired(s) { if err := m.removeShare(ctx, s); err != nil { - log.Error().Err(err). + sublogr.Error().Err(err). Msg("failed to unshare expired share") } if err := events.Publish(ctx, m.eventStream, events.ShareExpired{ @@ -878,7 +917,7 @@ func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborati GranteeUserID: s.GetGrantee().GetUserId(), GranteeGroupID: s.GetGrantee().GetGroupId(), }); err != nil { - log.Error().Err(err). + sublogr.Error().Err(err). Msg("failed to publish share expired event") } continue @@ -959,6 +998,7 @@ func (m *Manager) GetReceivedShare(ctx context.Context, ref *collaboration.Share func (m *Manager) getReceived(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.ReceivedShare, error) { ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "getReceived") defer span.End() + sublog := appctx.GetLogger(ctx).With().Str("id", ref.GetId().GetOpaqueId()).Str("key", ref.GetKey().String()).Str("driver", "jsoncs3").Str("handler", "getReceived").Logger() s, err := m.get(ctx, ref) if err != nil { @@ -970,7 +1010,7 @@ func (m *Manager) getReceived(ctx context.Context, ref *collaboration.ShareRefer } if share.IsExpired(s) { if err := m.removeShare(ctx, s); err != nil { - log.Error().Err(err). + sublog.Error().Err(err). Msg("failed to unshare expired share") } if err := events.Publish(ctx, m.eventStream, events.ShareExpired{ @@ -980,7 +1020,7 @@ func (m *Manager) getReceived(ctx context.Context, ref *collaboration.ShareRefer GranteeUserID: s.GetGrantee().GetUserId(), GranteeGroupID: s.GetGrantee().GetGroupId(), }); err != nil { - log.Error().Err(err). + sublog.Error().Err(err). Msg("failed to publish share expired event") } } diff --git a/vendor/modules.txt b/vendor/modules.txt index aec61e5e3f..710ff93548 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -359,7 +359,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1 github.com/cs3org/go-cs3apis/cs3/types/v1beta1 -# github.com/cs3org/reva/v2 v2.19.3 +# github.com/cs3org/reva/v2 v2.19.4 ## explicit; go 1.21 github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/runtime From 8a464c921ca9899552255233ce7a5a6135455f37 Mon Sep 17 00:00:00 2001 From: mmattel Date: Mon, 8 Apr 2024 09:12:07 +0200 Subject: [PATCH 07/26] [docs-only] [5.0] Fix envvar description (storage-users) --- services/storage-users/pkg/config/config.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/storage-users/pkg/config/config.go b/services/storage-users/pkg/config/config.go index b18cd09717..23af0b3e1b 100644 --- a/services/storage-users/pkg/config/config.go +++ b/services/storage-users/pkg/config/config.go @@ -130,9 +130,9 @@ type OCISDriver struct { GeneralSpaceAliasTemplate string `yaml:"generalspacealias_template" env:"STORAGE_USERS_OCIS_GENERAL_SPACE_ALIAS_TEMPLATE" desc:"Template string to construct general space aliases." introductionVersion:"pre5.0"` // ShareFolder defines the name of the folder jailing all shares ShareFolder string `yaml:"share_folder" env:"STORAGE_USERS_OCIS_SHARE_FOLDER" desc:"Name of the folder jailing all shares." introductionVersion:"pre5.0"` - MaxAcquireLockCycles int `yaml:"max_acquire_lock_cycles" env:"STORAGE_USERS_OCIS_MAX_ACQUIRE_LOCK_CYCLES" desc:"When trying to lock files, ocis will try this amount of times to acquire the lock before failing. After each try it will wait for an increasing amount of time. Values of 0 or below will be ignored and the default value of 20 will be used." introductionVersion:"pre5.0"` - LockCycleDurationFactor int `yaml:"lock_cycle_duration_factor" env:"STORAGE_USERS_OCIS_LOCK_CYCLE_DURATION_FACTOR" desc:"When trying to lock files, ocis will multiply the cycle with this factor and use it as a millisecond timeout. Values of 0 or below will be ignored and the default value of 30 will be used." introductionVersion:"pre5.0"` - MaxConcurrency int `yaml:"max_concurrency" env:"STORAGE_USERS_OCIS_MAX_CONCURRENCY" desc:"Maximum number of concurrent go-routines. Higher values can potentially get work done faster but will also cause more load on the system. Values of 0 or below will be ignored and the default value of 100 will be used." introductionVersion:"pre5.0"` + MaxAcquireLockCycles int `yaml:"max_acquire_lock_cycles" env:"STORAGE_USERS_OCIS_MAX_ACQUIRE_LOCK_CYCLES" desc:"When trying to lock files, ocis will try this amount of times to acquire the lock before failing. After each try it will wait for an increasing amount of time. Values of 0 or below will be ignored and the default value will be used." introductionVersion:"pre5.0"` + LockCycleDurationFactor int `yaml:"lock_cycle_duration_factor" env:"STORAGE_USERS_OCIS_LOCK_CYCLE_DURATION_FACTOR" desc:"When trying to lock files, ocis will multiply the cycle with this factor and use it as a millisecond timeout. Values of 0 or below will be ignored and the default value will be used." introductionVersion:"pre5.0"` + MaxConcurrency int `yaml:"max_concurrency" env:"STORAGE_USERS_OCIS_MAX_CONCURRENCY" desc:"Maximum number of concurrent go-routines. Higher values can potentially get work done faster but will also cause more load on the system. Values of 0 or below will be ignored and the default value will be used." introductionVersion:"pre5.0"` AsyncUploads bool `yaml:"async_uploads" env:"OCIS_ASYNC_UPLOADS" desc:"Enable asynchronous file uploads." introductionVersion:"pre5.0"` MaxQuota uint64 `yaml:"max_quota" env:"OCIS_SPACES_MAX_QUOTA;STORAGE_USERS_OCIS_MAX_QUOTA" desc:"Set a global max quota for spaces in bytes. A value of 0 equals unlimited. If not using the global OCIS_SPACES_MAX_QUOTA, you must define the FRONTEND_MAX_QUOTA in the frontend service." introductionVersion:"pre5.0"` } From 5eac54959d903c1d876a602cefd263cbab93d5f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Duffeck?= Date: Mon, 8 Apr 2024 12:12:42 +0200 Subject: [PATCH 08/26] Fix personal space cache config --- services/gateway/pkg/revaconfig/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/gateway/pkg/revaconfig/config.go b/services/gateway/pkg/revaconfig/config.go index c13688aee9..6c6e102275 100644 --- a/services/gateway/pkg/revaconfig/config.go +++ b/services/gateway/pkg/revaconfig/config.go @@ -72,11 +72,11 @@ func GatewayConfigFromStruct(cfg *config.Config, logger log.Logger) map[string]i "cache_auth_username": cfg.Cache.ProviderCacheAuthUsername, "cache_auth_password": cfg.Cache.ProviderCacheAuthPassword, }, - "create_home_cache_config": map[string]interface{}{ + "create_personal_space_cache_config": map[string]interface{}{ "cache_store": cfg.Cache.CreateHomeCacheStore, "cache_nodes": cfg.Cache.CreateHomeCacheNodes, "cache_database": cfg.Cache.CreateHomeCacheDatabase, - "cache_table": "create_home", + "cache_table": "create_personal_space", "cache_ttl": cfg.Cache.CreateHomeCacheTTL, "cache_size": cfg.Cache.CreateHomeCacheSize, "cache_disable_persistence": cfg.Cache.CreateHomeCacheDisablePersistence, From f5d9e1f8cf4b07559c08030e1086d2131154cbee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Duffeck?= Date: Mon, 8 Apr 2024 12:34:18 +0200 Subject: [PATCH 09/26] Add changelog --- changelog/unreleased/fix-create-personal-space-cache.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog/unreleased/fix-create-personal-space-cache.md diff --git a/changelog/unreleased/fix-create-personal-space-cache.md b/changelog/unreleased/fix-create-personal-space-cache.md new file mode 100644 index 0000000000..cd7831bce1 --- /dev/null +++ b/changelog/unreleased/fix-create-personal-space-cache.md @@ -0,0 +1,5 @@ +Bugfix: Fix the create personal space cache + +We fixed a problem with the config for the create personal space cache which resulted in the cache never being used. + +https://github.com/owncloud/ocis/pull/8799 From 9b795c085b33270d0bd738ed2caef25af62c8dc8 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Tue, 9 Apr 2024 07:47:25 +0000 Subject: [PATCH 10/26] Automated changelog update [skip ci] --- CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6feb9ea8c3..a7577ad8e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Table of Contents +* [Changelog for unreleased](#changelog-for-unreleased-unreleased) * [Changelog for 5.0.0](#changelog-for-500-2024-03-18) * [Changelog for 4.0.6](#changelog-for-406-2024-02-07) * [Changelog for 4.0.5](#changelog-for-405-2023-12-21) @@ -33,6 +34,25 @@ * [Changelog for 1.1.0](#changelog-for-110-2021-01-22) * [Changelog for 1.0.0](#changelog-for-100-2020-12-17) +# Changelog for [unreleased] (UNRELEASED) + +The following sections list the changes for unreleased. + +[unreleased]: https://github.com/owncloud/ocis/compare/v5.0.0...master + +## Summary + +* Bugfix - Fix the create personal space cache: [#8799](https://github.com/owncloud/ocis/pull/8799) + +## Details + +* Bugfix - Fix the create personal space cache: [#8799](https://github.com/owncloud/ocis/pull/8799) + + We fixed a problem with the config for the create personal space cache which + resulted in the cache never being used. + + https://github.com/owncloud/ocis/pull/8799 + # Changelog for [5.0.0] (2024-03-18) The following sections list the changes for 5.0.0. From 2ab941dea22bf5da8f553dd315bc01760e461074 Mon Sep 17 00:00:00 2001 From: jkoberg Date: Thu, 4 Apr 2024 17:02:28 +0200 Subject: [PATCH 11/26] fix(postprocessing): repair restart logic Signed-off-by: jkoberg --- .../unreleased/fix-postprocessing-restart.md | 5 +++ .../pkg/config/defaults/defaultconfig.go | 5 ++- .../pkg/postprocessing/postprocessing.go | 2 +- .../postprocessing/pkg/service/service.go | 37 ++++++++++++------- services/storage-users/pkg/command/uploads.go | 2 +- 5 files changed, 33 insertions(+), 18 deletions(-) create mode 100644 changelog/unreleased/fix-postprocessing-restart.md diff --git a/changelog/unreleased/fix-postprocessing-restart.md b/changelog/unreleased/fix-postprocessing-restart.md new file mode 100644 index 0000000000..66d810b306 --- /dev/null +++ b/changelog/unreleased/fix-postprocessing-restart.md @@ -0,0 +1,5 @@ +Bugfix: Fix restarting of postprocessing + +When an upload is not found, the logic to restart postprocessing was bunked + +https://github.com/owncloud/ocis/pull/8782 diff --git a/services/postprocessing/pkg/config/defaults/defaultconfig.go b/services/postprocessing/pkg/config/defaults/defaultconfig.go index 11cf3f02af..51a9bb6112 100644 --- a/services/postprocessing/pkg/config/defaults/defaultconfig.go +++ b/services/postprocessing/pkg/config/defaults/defaultconfig.go @@ -35,9 +35,10 @@ func DefaultConfig() *config.Config { MaxRetries: 14, }, Store: config.Store{ - Store: "memory", + Store: "nats-js-kv", + Nodes: []string{"127.0.0.1:9233"}, Database: "postprocessing", - Table: "postprocessing", + Table: "", }, } } diff --git a/services/postprocessing/pkg/postprocessing/postprocessing.go b/services/postprocessing/pkg/postprocessing/postprocessing.go index e3c9ca6bff..40b94d56f8 100644 --- a/services/postprocessing/pkg/postprocessing/postprocessing.go +++ b/services/postprocessing/pkg/postprocessing/postprocessing.go @@ -39,7 +39,7 @@ func New(config config.Postprocessing) *Postprocessing { } // Init is the first step of the postprocessing -func (pp *Postprocessing) Init(ev events.BytesReceived) interface{} { +func (pp *Postprocessing) Init(_ events.BytesReceived) interface{} { if len(pp.Steps) == 0 { return pp.finished(events.PPOutcomeContinue) } diff --git a/services/postprocessing/pkg/service/service.go b/services/postprocessing/pkg/service/service.go index f2a3c122e2..70e1221a57 100644 --- a/services/postprocessing/pkg/service/service.go +++ b/services/postprocessing/pkg/service/service.go @@ -29,10 +29,12 @@ type PostprocessingService struct { } var ( - // errFatal is returned when a fatal error occurs and we want to exit. - errFatal = errors.New("fatal error") + // ErrFatal is returned when a fatal error occurs and we want to exit. + ErrFatal = errors.New("fatal error") // ErrEvent is returned when something went wrong with a specific event. - errEvent = errors.New("event error") + ErrEvent = errors.New("event error") + // ErrNotFound is returned when a postprocessing is not found in the store. + ErrNotFound = errors.New("postprocessing not found") ) // NewPostprocessingService returns a new instance of a postprocessing service @@ -66,9 +68,9 @@ func (pps *PostprocessingService) Run() error { err := pps.processEvent(e) if err != nil { switch { - case errors.Is(err, errFatal): + case errors.Is(err, ErrFatal): return err - case errors.Is(err, errEvent): + case errors.Is(err, ErrEvent): continue default: pps.log.Fatal().Err(err).Msg("unknown error - exiting") @@ -109,7 +111,7 @@ func (pps *PostprocessingService) processEvent(e events.Event) error { pp, err = pps.getPP(pps.store, ev.UploadID) if err != nil { pps.log.Error().Str("uploadID", ev.UploadID).Err(err).Msg("cannot get upload") - return fmt.Errorf("%w: cannot get upload", errEvent) + return fmt.Errorf("%w: cannot get upload", ErrEvent) } next = pp.NextStep(ev) @@ -141,7 +143,7 @@ func (pps *PostprocessingService) processEvent(e events.Event) error { pp, err = pps.getPP(pps.store, ev.UploadID) if err != nil { pps.log.Error().Str("uploadID", ev.UploadID).Err(err).Msg("cannot get upload") - return fmt.Errorf("%w: cannot get upload", errEvent) + return fmt.Errorf("%w: cannot get upload", ErrEvent) } next = pp.Delay() case events.UploadReady: @@ -153,7 +155,7 @@ func (pps *PostprocessingService) processEvent(e events.Event) error { // the storage provider thinks the upload is done - so no need to keep it any more if err := pps.store.Delete(ev.UploadID); err != nil { pps.log.Error().Str("uploadID", ev.UploadID).Err(err).Msg("cannot delete upload") - return fmt.Errorf("%w: cannot delete upload", errEvent) + return fmt.Errorf("%w: cannot delete upload", ErrEvent) } case events.ResumePostprocessing: return pps.handleResumePPEvent(ctx, ev) @@ -162,13 +164,13 @@ func (pps *PostprocessingService) processEvent(e events.Event) error { if pp != nil { if err := storePP(pps.store, pp); err != nil { pps.log.Error().Str("uploadID", pp.ID).Err(err).Msg("cannot store upload") - return fmt.Errorf("%w: cannot store upload", errEvent) + return fmt.Errorf("%w: cannot store upload", ErrEvent) } } if next != nil { if err := events.Publish(ctx, pps.pub, next); err != nil { pps.log.Error().Err(err).Msg("unable to publish event") - return fmt.Errorf("%w: unable to publish event", errFatal) // we can't publish -> we are screwed + return fmt.Errorf("%w: unable to publish event", ErrFatal) // we can't publish -> we are screwed } } return nil @@ -177,10 +179,17 @@ func (pps *PostprocessingService) processEvent(e events.Event) error { func (pps *PostprocessingService) getPP(sto store.Store, uploadID string) (*postprocessing.Postprocessing, error) { recs, err := sto.Read(uploadID) if err != nil { + if err == store.ErrNotFound { + return nil, ErrNotFound + } return nil, err } - if len(recs) != 1 { + if len(recs) == 0 { + return nil, ErrNotFound + } + + if len(recs) > 1 { return nil, fmt.Errorf("expected only one result for '%s', got %d", uploadID, len(recs)) } @@ -226,7 +235,7 @@ func (pps *PostprocessingService) handleResumePPEvent(ctx context.Context, ev ev for _, id := range ids { if err := pps.resumePP(ctx, id); err != nil { pps.log.Error().Str("uploadID", id).Err(err).Msg("cannot resume upload") - return fmt.Errorf("%w: cannot resume upload", errEvent) + return fmt.Errorf("cannot resume upload: %w", err) } } return nil @@ -235,7 +244,7 @@ func (pps *PostprocessingService) handleResumePPEvent(ctx context.Context, ev ev func (pps *PostprocessingService) resumePP(ctx context.Context, uploadID string) error { pp, err := pps.getPP(pps.store, uploadID) if err != nil { - if err == store.ErrNotFound { + if err == ErrNotFound { if err := events.Publish(ctx, pps.pub, events.RestartPostprocessing{ UploadID: uploadID, Timestamp: utils.TSNow(), @@ -244,7 +253,7 @@ func (pps *PostprocessingService) resumePP(ctx context.Context, uploadID string) } return nil } - return fmt.Errorf("%w: cannot get upload", errEvent) + return fmt.Errorf("cannot get upload: %w", err) } return events.Publish(ctx, pps.pub, pp.CurrentStep()) diff --git a/services/storage-users/pkg/command/uploads.go b/services/storage-users/pkg/command/uploads.go index 1c651cc9f1..99d93e533b 100644 --- a/services/storage-users/pkg/command/uploads.go +++ b/services/storage-users/pkg/command/uploads.go @@ -69,7 +69,7 @@ func ListUploads(cfg *config.Config) *cli.Command { fmt.Println("Incomplete uploads:") for _, u := range uploads { ref := u.Reference() - fmt.Printf(" - %s (Space: %s, Name: %s, Size: %d/%d, Expires: %s, Processing: %t)\n", ref.GetResourceId().GetSpaceId(), u.ID(), u.Filename(), u.Offset(), u.Size(), u.Expires(), u.IsProcessing()) + fmt.Printf(" - %s (Space: %s, Name: %s, Size: %d/%d, Expires: %s, Processing: %t)\n", u.ID(), ref.GetResourceId().GetSpaceId(), u.Filename(), u.Offset(), u.Size(), u.Expires(), u.IsProcessing()) } return nil }, From 69a68ac515f872e3192bd4f9bc29244178b32724 Mon Sep 17 00:00:00 2001 From: jkoberg Date: Mon, 8 Apr 2024 08:49:49 +0200 Subject: [PATCH 12/26] feat(storage-users): allow restarting multiple uploads at once Signed-off-by: jkoberg --- .../unreleased/fix-postprocessing-restart.md | 5 ++- services/storage-users/pkg/command/uploads.go | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/changelog/unreleased/fix-postprocessing-restart.md b/changelog/unreleased/fix-postprocessing-restart.md index 66d810b306..6183701f16 100644 --- a/changelog/unreleased/fix-postprocessing-restart.md +++ b/changelog/unreleased/fix-postprocessing-restart.md @@ -1,5 +1,8 @@ Bugfix: Fix restarting of postprocessing -When an upload is not found, the logic to restart postprocessing was bunked +When an upload is not found, the logic to restart postprocessing was bunked. Additionally we extended the upload sessions +command to be able to restart the uploads without using a second command. + +NOTE: This also includes a breaking fix for the deprecated `ocis storage-users uploads list` command https://github.com/owncloud/ocis/pull/8782 diff --git a/services/storage-users/pkg/command/uploads.go b/services/storage-users/pkg/command/uploads.go index 99d93e533b..e5ae4f2561 100644 --- a/services/storage-users/pkg/command/uploads.go +++ b/services/storage-users/pkg/command/uploads.go @@ -1,6 +1,7 @@ package command import ( + "context" "encoding/json" "fmt" "os" @@ -13,11 +14,14 @@ import ( "github.com/urfave/cli/v2" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + "github.com/cs3org/reva/v2/pkg/events" "github.com/cs3org/reva/v2/pkg/storage" "github.com/cs3org/reva/v2/pkg/storage/fs/registry" + "github.com/cs3org/reva/v2/pkg/utils" "github.com/owncloud/ocis/v2/ocis-pkg/config/configlog" "github.com/owncloud/ocis/v2/services/storage-users/pkg/config" "github.com/owncloud/ocis/v2/services/storage-users/pkg/config/parser" + "github.com/owncloud/ocis/v2/services/storage-users/pkg/event" "github.com/owncloud/ocis/v2/services/storage-users/pkg/revaconfig" ) @@ -101,6 +105,10 @@ func ListUploadSessions(cfg *config.Config) *cli.Command { Name: "json", Usage: "output as json", }, + &cli.BoolFlag{ + Name: "restart", + Usage: "send restart event for all listed sessions", + }, }, Before: func(c *cli.Context) error { return configlog.ReturnFatal(parser.ParseConfig(cfg)) @@ -124,6 +132,15 @@ func ListUploadSessions(cfg *config.Config) *cli.Command { os.Exit(1) } + var stream events.Stream + if c.Bool("restart") { + stream, err = event.NewStream(cfg) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create event stream: %v\n", err) + os.Exit(1) + } + } + var b strings.Builder filter := storage.UploadSessionFilter{} if c.IsSet("processing") { @@ -200,6 +217,17 @@ func ListUploadSessions(cfg *config.Config) *cli.Command { fmt.Println(err) } fmt.Println(string(j)) + + if c.Bool("restart") { + if err := events.Publish(context.Background(), stream, events.ResumePostprocessing{ + UploadID: u.ID(), + Timestamp: utils.TSNow(), + }); err != nil { + fmt.Fprintf(os.Stderr, "Failed to send restart event for upload session '%s'\n", u.ID()) + // if publishing fails there is no need to try publishing other events - they will fail too. + os.Exit(1) + } + } } } else { @@ -223,6 +251,17 @@ func ListUploadSessions(cfg *config.Config) *cli.Command { u.Expires().Format(time.RFC3339), strconv.FormatBool(u.IsProcessing()), }) + + if c.Bool("restart") { + if err := events.Publish(context.Background(), stream, events.ResumePostprocessing{ + UploadID: u.ID(), + Timestamp: utils.TSNow(), + }); err != nil { + fmt.Fprintf(os.Stderr, "Failed to send restart event for upload session '%s'\n", u.ID()) + // if publishing fails there is no need to try publishing other events - they will fail too. + os.Exit(1) + } + } } table.Render() } From 470d3c5ae1d13fd3e57fb7561695c972b803e81d Mon Sep 17 00:00:00 2001 From: jkoberg Date: Mon, 8 Apr 2024 12:07:20 +0200 Subject: [PATCH 13/26] feat(postprocessing): improve docu Signed-off-by: jkoberg --- services/postprocessing/README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/services/postprocessing/README.md b/services/postprocessing/README.md index 9e08ba2180..5b58319318 100644 --- a/services/postprocessing/README.md +++ b/services/postprocessing/README.md @@ -81,12 +81,17 @@ See the [cs3 org](https://github.com/cs3org/reva/blob/edge/pkg/events/postproces If postprocessing fails in one step due to an unforseen error, current uploads will not be retried automatically. A system admin can instead run a CLI command to retry the failed upload which is a two step process: -- First find the upload ID of the failed upload. +- First list ongoing upload sessions ```bash -ocis storage-users uploads list +ocis storage-users uploads sessions ``` -- Then use the restart command to resume postprocessing of the ID selected. +- If you want to restart all uploads just rerun the command with the `--restart` flag +```bash +ocis storage-users uploads sessions --restart +``` + +- If you want to restart only one upload use the postprocessing restart command ```bash ocis postprocessing restart -u ``` From d5b08881b59d8e424aeefd50477c7476bb33948e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Tue, 9 Apr 2024 14:58:02 +0000 Subject: [PATCH 14/26] Automated changelog update [skip ci] --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7577ad8e7..3ecea83151 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,10 +42,22 @@ The following sections list the changes for unreleased. ## Summary +* Bugfix - Fix restarting of postprocessing: [#8782](https://github.com/owncloud/ocis/pull/8782) * Bugfix - Fix the create personal space cache: [#8799](https://github.com/owncloud/ocis/pull/8799) ## Details +* Bugfix - Fix restarting of postprocessing: [#8782](https://github.com/owncloud/ocis/pull/8782) + + When an upload is not found, the logic to restart postprocessing was bunked. + Additionally we extended the upload sessions command to be able to restart the + uploads without using a second command. + + NOTE: This also includes a breaking fix for the deprecated `ocis storage-users + uploads list` command + + https://github.com/owncloud/ocis/pull/8782 + * Bugfix - Fix the create personal space cache: [#8799](https://github.com/owncloud/ocis/pull/8799) We fixed a problem with the config for the create personal space cache which From 9a236b15f6d07924143b0bc2a1578d0705f8db51 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Tue, 9 Apr 2024 17:29:35 +0200 Subject: [PATCH 15/26] docs: add reva changelog --- changelog/unreleased/bump-reva.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 changelog/unreleased/bump-reva.md diff --git a/changelog/unreleased/bump-reva.md b/changelog/unreleased/bump-reva.md new file mode 100644 index 0000000000..e471886cee --- /dev/null +++ b/changelog/unreleased/bump-reva.md @@ -0,0 +1,7 @@ +Bugfix: Update reva to v2.19.4 + +We updated reva to v2.19.4 + +* Bugfix [cs3org/reva#4612](https://github.com/cs3org/reva/pull/4612): Use gateway selector in jsoncs3 to scale the service + +https://github.com/owncloud/ocis/pull/8787 From f43e15fb625cb7eb725574bcc1c44b28cccc4a7b Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Tue, 9 Apr 2024 15:30:44 +0000 Subject: [PATCH 16/26] Automated changelog update [skip ci] --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ecea83151..2e428bf554 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ The following sections list the changes for unreleased. ## Summary * Bugfix - Fix restarting of postprocessing: [#8782](https://github.com/owncloud/ocis/pull/8782) +* Bugfix - Update reva to v2.19.4: [#8787](https://github.com/owncloud/ocis/pull/8787) * Bugfix - Fix the create personal space cache: [#8799](https://github.com/owncloud/ocis/pull/8799) ## Details @@ -58,6 +59,14 @@ The following sections list the changes for unreleased. https://github.com/owncloud/ocis/pull/8782 +* Bugfix - Update reva to v2.19.4: [#8787](https://github.com/owncloud/ocis/pull/8787) + + We updated reva to v2.19.4 + + * Bugfix [cs3org/reva#4612](https://github.com/cs3org/reva/pull/4612): Use gateway selector in jsoncs3 to scale the service + + https://github.com/owncloud/ocis/pull/8787 + * Bugfix - Fix the create personal space cache: [#8799](https://github.com/owncloud/ocis/pull/8799) We fixed a problem with the config for the create personal space cache which From 109fc22c71e64ac0ef6ed65b765069cabfcabfd1 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Tue, 9 Apr 2024 17:35:24 +0200 Subject: [PATCH 17/26] docs: add reva changelog for 2.19.3 --- changelog/unreleased/bump-reva.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelog/unreleased/bump-reva.md b/changelog/unreleased/bump-reva.md index e471886cee..57c4a4c2eb 100644 --- a/changelog/unreleased/bump-reva.md +++ b/changelog/unreleased/bump-reva.md @@ -5,3 +5,9 @@ We updated reva to v2.19.4 * Bugfix [cs3org/reva#4612](https://github.com/cs3org/reva/pull/4612): Use gateway selector in jsoncs3 to scale the service https://github.com/owncloud/ocis/pull/8787 + +We updated reva to v2.19.3 + +* Bugfix[cs3org/reva#4607](https://github.com/cs3org/reva/pull/4607): Mask user email in output + +https://github.com/owncloud/ocis/pull/8781 From b65dbd28cd0639b9cf66de1e62378027746d9f12 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Tue, 9 Apr 2024 15:37:00 +0000 Subject: [PATCH 18/26] Automated changelog update [skip ci] --- CHANGELOG.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e428bf554..7661a4b656 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,12 +42,26 @@ The following sections list the changes for unreleased. ## Summary +* Bugfix - Update reva to v2.19.4: [#8781](https://github.com/owncloud/ocis/pull/8781) * Bugfix - Fix restarting of postprocessing: [#8782](https://github.com/owncloud/ocis/pull/8782) -* Bugfix - Update reva to v2.19.4: [#8787](https://github.com/owncloud/ocis/pull/8787) * Bugfix - Fix the create personal space cache: [#8799](https://github.com/owncloud/ocis/pull/8799) ## Details +* Bugfix - Update reva to v2.19.4: [#8781](https://github.com/owncloud/ocis/pull/8781) + + We updated reva to v2.19.4 + + * Bugfix [cs3org/reva#4612](https://github.com/cs3org/reva/pull/4612): Use gateway selector in jsoncs3 to scale the service + + Https://github.com/owncloud/ocis/pull/8787 + + We updated reva to v2.19.3 + + * Bugfix[cs3org/reva#4607](https://github.com/cs3org/reva/pull/4607): Mask user email in output + + https://github.com/owncloud/ocis/pull/8781 + * Bugfix - Fix restarting of postprocessing: [#8782](https://github.com/owncloud/ocis/pull/8782) When an upload is not found, the logic to restart postprocessing was bunked. @@ -59,14 +73,6 @@ The following sections list the changes for unreleased. https://github.com/owncloud/ocis/pull/8782 -* Bugfix - Update reva to v2.19.4: [#8787](https://github.com/owncloud/ocis/pull/8787) - - We updated reva to v2.19.4 - - * Bugfix [cs3org/reva#4612](https://github.com/cs3org/reva/pull/4612): Use gateway selector in jsoncs3 to scale the service - - https://github.com/owncloud/ocis/pull/8787 - * Bugfix - Fix the create personal space cache: [#8799](https://github.com/owncloud/ocis/pull/8799) We fixed a problem with the config for the create personal space cache which From f04be9f8707295ab65fe2e0eb3bdbe50965d5001 Mon Sep 17 00:00:00 2001 From: Florian Schade Date: Mon, 25 Mar 2024 10:16:10 +0100 Subject: [PATCH 19/26] enhancement: same site strict cookies (#8716) To enhance the security of our application and prevent Cross-Site Request Forgery (CSRF) attacks, we have updated the SameSite attribute of the build in Identity Provider (IDP) cookies to Strict. --- .../enhancement-strict-same-site-cookie.md | 12 ++++++++++ go.mod | 2 +- go.sum | 4 ++-- .../idp/pkg/backends/cs3/bootstrap/cs3.go | 19 ++++++++++----- services/idp/pkg/config/config.go | 2 ++ .../idp/pkg/config/defaults/defaultconfig.go | 2 ++ .../lico/bootstrap/backends/ldap/ldap.go | 18 ++++++++++----- .../backends/libregraph/libregraph.go | 18 ++++++++++----- .../libregraph/lico/bootstrap/bootstrap.go | 18 +++++++++++---- .../libregraph/lico/bootstrap/config.go | 3 +++ .../libregraph/lico/bootstrap/settings.go | 5 ++++ .../libregraph/lico/identifier/config.go | 13 ++++++++--- .../libregraph/lico/identifier/cookie.go | 12 +++++----- .../libregraph/lico/identifier/identifier.go | 23 +++++++++++++++---- .../libregraph/lico/oidc/provider/config.go | 11 +++++---- .../libregraph/lico/oidc/provider/cookie.go | 8 +++---- .../libregraph/lico/oidc/provider/provider.go | 20 +++++++++------- vendor/modules.txt | 2 +- 18 files changed, 136 insertions(+), 56 deletions(-) create mode 100644 changelog/unreleased/enhancement-strict-same-site-cookie.md diff --git a/changelog/unreleased/enhancement-strict-same-site-cookie.md b/changelog/unreleased/enhancement-strict-same-site-cookie.md new file mode 100644 index 0000000000..94b2916116 --- /dev/null +++ b/changelog/unreleased/enhancement-strict-same-site-cookie.md @@ -0,0 +1,12 @@ +Enhancement: Make IDP cookies same site strict + +To enhance the security of our application and prevent Cross-Site Request Forgery (CSRF) attacks, we have updated the +SameSite attribute of the build in Identity Provider (IDP) cookies to Strict. + +This change restricts the browser from sending these cookies with any cross-site requests, +thereby limiting the exposure of the user's session to potential threats. + +This update does not impact the existing functionality of the application but provides an additional layer of security +where needed. + +https://github.com/owncloud/ocis/pull/8716 diff --git a/go.mod b/go.mod index 413c4f5373..15ff4d4d2a 100644 --- a/go.mod +++ b/go.mod @@ -56,7 +56,7 @@ require ( github.com/justinas/alice v1.2.0 github.com/leonelquinteros/gotext v1.5.3-0.20230317130943-71a59c05b2c1 github.com/libregraph/idm v0.4.1-0.20231213140724-56a222fb4215 - github.com/libregraph/lico v0.61.2 + github.com/libregraph/lico v0.61.3-0.20240322112242-72cf9221d3a7 github.com/mitchellh/mapstructure v1.5.0 github.com/mna/pigeon v1.2.1 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 diff --git a/go.sum b/go.sum index 0cfa3eb2d5..2721eebd1b 100644 --- a/go.sum +++ b/go.sum @@ -1623,8 +1623,8 @@ github.com/leonelquinteros/gotext v1.5.3-0.20230317130943-71a59c05b2c1 h1:k56sFO github.com/leonelquinteros/gotext v1.5.3-0.20230317130943-71a59c05b2c1/go.mod h1:AT4NpQrOmyj1L/+hLja6aR0lk81yYYL4ePnj2kp7d6M= github.com/libregraph/idm v0.4.1-0.20231213140724-56a222fb4215 h1:Yw/I6l/0S/zDq2Hnibvwy8cVLpMaBwDe0aUSv/FNU6U= github.com/libregraph/idm v0.4.1-0.20231213140724-56a222fb4215/go.mod h1:h/B7mB5OqrsrobydErMGewHxonYDKjGOaJsFabXyRo8= -github.com/libregraph/lico v0.61.2 h1:sU8eQ2E9Uq5wnTkD33YX5+gRj59MkPLgDVoB72L1q8w= -github.com/libregraph/lico v0.61.2/go.mod h1:TgZGBAYzVRQSRdBC8PgGQKjYhtXuTr6UCM3ZZyGTleQ= +github.com/libregraph/lico v0.61.3-0.20240322112242-72cf9221d3a7 h1:fcPgiBu7DGyGeokE0Qk+S+GW/3n+QWu1dIjw0TqadhI= +github.com/libregraph/lico v0.61.3-0.20240322112242-72cf9221d3a7/go.mod h1:TgZGBAYzVRQSRdBC8PgGQKjYhtXuTr6UCM3ZZyGTleQ= github.com/libregraph/oidc-go v1.0.0 h1:l2tE/EwLyLXVy0B5BuVKgIFX9pNpz/5J3x5IBw0KEhc= github.com/libregraph/oidc-go v1.0.0/go.mod h1:7TRHrY/H1Vg6JqFjV0oAe1+kN+mGFBqXYvclSyvhRyc= github.com/linode/linodego v0.25.3/go.mod h1:GSBKPpjoQfxEfryoCRcgkuUOCuVtGHWhzI8OMdycNTE= diff --git a/services/idp/pkg/backends/cs3/bootstrap/cs3.go b/services/idp/pkg/backends/cs3/bootstrap/cs3.go index 24bc638d11..10c093a397 100644 --- a/services/idp/pkg/backends/cs3/bootstrap/cs3.go +++ b/services/idp/pkg/backends/cs3/bootstrap/cs3.go @@ -25,6 +25,7 @@ import ( "github.com/libregraph/lico/identifier" "github.com/libregraph/lico/identity" "github.com/libregraph/lico/identity/managers" + cs3 "github.com/owncloud/ocis/v2/services/idp/pkg/backends/cs3/identifier" ) @@ -88,12 +89,18 @@ func NewIdentityManager(bs bootstrap.Bootstrap) (identity.Manager, error) { activeIdentifier, err := identifier.NewIdentifier(&identifier.Config{ Config: config.Config, - BaseURI: config.IssuerIdentifierURI, - PathPrefix: bs.MakeURIPath(bootstrap.APITypeSignin, ""), - StaticFolder: config.IdentifierClientPath, - LogonCookieName: "__Secure-KKT", // Kopano-Konnect-Token - ScopesConf: config.IdentifierScopesConf, - WebAppDisabled: config.IdentifierClientDisabled, + BaseURI: config.IssuerIdentifierURI, + PathPrefix: bs.MakeURIPath(bootstrap.APITypeSignin, ""), + StaticFolder: config.IdentifierClientPath, + ScopesConf: config.IdentifierScopesConf, + WebAppDisabled: config.IdentifierClientDisabled, + + LogonCookieName: "__Secure-KKT", // Kopano-Konnect-Token + LogonCookieSameSite: config.CookieSameSite, + + ConsentCookieSameSite: config.CookieSameSite, + + StateCookieSameSite: config.CookieSameSite, AuthorizationEndpointURI: fullAuthorizationEndpointURL, SignedOutEndpointURI: fullSignedOutEndpointURL, diff --git a/services/idp/pkg/config/config.go b/services/idp/pkg/config/config.go index 2697197991..2c3fcf91ba 100644 --- a/services/idp/pkg/config/config.go +++ b/services/idp/pkg/config/config.go @@ -2,6 +2,7 @@ package config import ( "context" + "net/http" "github.com/owncloud/ocis/v2/ocis-pkg/shared" ) @@ -112,6 +113,7 @@ type Settings struct { CookieBackendURI string CookieNames []string + CookieSameSite http.SameSite AccessTokenDurationSeconds uint64 `yaml:"access_token_duration_seconds" env:"IDP_ACCESS_TOKEN_EXPIRATION" desc:"'Access token lifespan in seconds (time before an access token is expired).'" introductionVersion:"pre5.0"` IDTokenDurationSeconds uint64 `yaml:"id_token_duration_seconds" env:"IDP_ID_TOKEN_EXPIRATION" desc:"ID token lifespan in seconds (time before an ID token is expired)." introductionVersion:"pre5.0"` diff --git a/services/idp/pkg/config/defaults/defaultconfig.go b/services/idp/pkg/config/defaults/defaultconfig.go index ac0d15bf5d..aa908a8656 100644 --- a/services/idp/pkg/config/defaults/defaultconfig.go +++ b/services/idp/pkg/config/defaults/defaultconfig.go @@ -1,6 +1,7 @@ package defaults import ( + "net/http" "path/filepath" "strings" @@ -64,6 +65,7 @@ func DefaultConfig() *config.Config { ValidationKeysPath: "", CookieBackendURI: "", CookieNames: nil, + CookieSameSite: http.SameSiteStrictMode, AccessTokenDurationSeconds: 60 * 5, // 5 minutes IDTokenDurationSeconds: 60 * 5, // 5 minutes RefreshTokenDurationSeconds: 60 * 60 * 24 * 30, // 30 days diff --git a/vendor/github.com/libregraph/lico/bootstrap/backends/ldap/ldap.go b/vendor/github.com/libregraph/lico/bootstrap/backends/ldap/ldap.go index 4d3cd379fe..943a55e703 100644 --- a/vendor/github.com/libregraph/lico/bootstrap/backends/ldap/ldap.go +++ b/vendor/github.com/libregraph/lico/bootstrap/backends/ldap/ldap.go @@ -127,12 +127,18 @@ func NewIdentityManager(bs bootstrap.Bootstrap) (identity.Manager, error) { activeIdentifier, err := identifier.NewIdentifier(&identifier.Config{ Config: config.Config, - BaseURI: config.IssuerIdentifierURI, - PathPrefix: bs.MakeURIPath(bootstrap.APITypeSignin, ""), - StaticFolder: config.IdentifierClientPath, - LogonCookieName: "__Secure-KKT", // Kopano-Konnect-Token - ScopesConf: config.IdentifierScopesConf, - WebAppDisabled: config.IdentifierClientDisabled, + BaseURI: config.IssuerIdentifierURI, + PathPrefix: bs.MakeURIPath(bootstrap.APITypeSignin, ""), + StaticFolder: config.IdentifierClientPath, + ScopesConf: config.IdentifierScopesConf, + WebAppDisabled: config.IdentifierClientDisabled, + + LogonCookieName: "__Secure-KKT", // Kopano-Konnect-Token + LogonCookieSameSite: config.CookieSameSite, + + ConsentCookieSameSite: config.CookieSameSite, + + StateCookieSameSite: config.CookieSameSite, AuthorizationEndpointURI: fullAuthorizationEndpointURL, SignedOutEndpointURI: fullSignedOutEndpointURL, diff --git a/vendor/github.com/libregraph/lico/bootstrap/backends/libregraph/libregraph.go b/vendor/github.com/libregraph/lico/bootstrap/backends/libregraph/libregraph.go index 6ba682eee3..0fe760c041 100644 --- a/vendor/github.com/libregraph/lico/bootstrap/backends/libregraph/libregraph.go +++ b/vendor/github.com/libregraph/lico/bootstrap/backends/libregraph/libregraph.go @@ -110,12 +110,18 @@ func NewIdentityManager(bs bootstrap.Bootstrap) (identity.Manager, error) { activeIdentifier, err := identifier.NewIdentifier(&identifier.Config{ Config: config.Config, - BaseURI: config.IssuerIdentifierURI, - PathPrefix: bs.MakeURIPath(bootstrap.APITypeSignin, ""), - StaticFolder: config.IdentifierClientPath, - LogonCookieName: "__Secure-KKT", // Kopano-Konnect-Token - ScopesConf: config.IdentifierScopesConf, - WebAppDisabled: config.IdentifierClientDisabled, + BaseURI: config.IssuerIdentifierURI, + PathPrefix: bs.MakeURIPath(bootstrap.APITypeSignin, ""), + StaticFolder: config.IdentifierClientPath, + ScopesConf: config.IdentifierScopesConf, + WebAppDisabled: config.IdentifierClientDisabled, + + LogonCookieName: "__Secure-KKT", // Kopano-Konnect-Token + LogonCookieSameSite: config.CookieSameSite, + + ConsentCookieSameSite: config.CookieSameSite, + + StateCookieSameSite: config.CookieSameSite, AuthorizationEndpointURI: fullAuthorizationEndpointURL, SignedOutEndpointURI: fullSignedOutEndpointURL, diff --git a/vendor/github.com/libregraph/lico/bootstrap/bootstrap.go b/vendor/github.com/libregraph/lico/bootstrap/bootstrap.go index 29785a19cd..9002c16904 100644 --- a/vendor/github.com/libregraph/lico/bootstrap/bootstrap.go +++ b/vendor/github.com/libregraph/lico/bootstrap/bootstrap.go @@ -26,6 +26,7 @@ import ( "fmt" "io/ioutil" "net" + "net/http" "net/url" "os" "path/filepath" @@ -58,6 +59,7 @@ const ( DefaultSigningKeyBits = 2048 DefaultGuestIdentityManagerName = "guest" + DefaultCookieSameSite = http.SameSiteNoneMode ) // Bootstrap is a data structure to hold configuration required to start @@ -332,6 +334,12 @@ func (bs *bootstrap) initialize(settings *Settings) error { } bs.config.DyamicClientSecretDurationSeconds = settings.DyamicClientSecretDurationSeconds + // add setting to allow setting the same site attribute of the cookies + bs.config.CookieSameSite = settings.CookieSameSite + if bs.config.CookieSameSite == 0 { + bs.config.CookieSameSite = DefaultCookieSameSite + } + return nil } @@ -472,11 +480,13 @@ func (bs *bootstrap) setupOIDCProvider(ctx context.Context) (*oidcProvider.Provi CheckSessionIframePath: bs.MakeURIPath(APITypeKonnect, "/session/check-session.html"), RegistrationPath: registrationPath, - BrowserStateCookiePath: bs.MakeURIPath(APITypeKonnect, "/session/"), - BrowserStateCookieName: "__Secure-KKBS", // Kopano-Konnect-Browser-State + BrowserStateCookiePath: bs.MakeURIPath(APITypeKonnect, "/session/"), + BrowserStateCookieName: "__Secure-KKBS", // Kopano-Konnect-Browser-State + BrowserStateCookieSameSite: bs.config.CookieSameSite, - SessionCookiePath: sessionCookiePath, - SessionCookieName: "__Secure-KKCS", // Kopano-Konnect-Client-Session + SessionCookiePath: sessionCookiePath, + SessionCookieName: "__Secure-KKCS", // Kopano-Konnect-Client-Session + SessionCookieSameSite: bs.config.CookieSameSite, AccessTokenDuration: time.Duration(bs.config.AccessTokenDurationSeconds) * time.Second, IDTokenDuration: time.Duration(bs.config.IDTokenDurationSeconds) * time.Second, diff --git a/vendor/github.com/libregraph/lico/bootstrap/config.go b/vendor/github.com/libregraph/lico/bootstrap/config.go index 56e184c1bd..de42e711e0 100644 --- a/vendor/github.com/libregraph/lico/bootstrap/config.go +++ b/vendor/github.com/libregraph/lico/bootstrap/config.go @@ -21,6 +21,7 @@ import ( "crypto" "crypto/tls" "crypto/x509" + "net/http" "net/url" "github.com/golang-jwt/jwt/v4" @@ -64,4 +65,6 @@ type Config struct { IDTokenDurationSeconds uint64 RefreshTokenDurationSeconds uint64 DyamicClientSecretDurationSeconds uint64 + + CookieSameSite http.SameSite } diff --git a/vendor/github.com/libregraph/lico/bootstrap/settings.go b/vendor/github.com/libregraph/lico/bootstrap/settings.go index 1a87a35e1f..a5cdc434c4 100644 --- a/vendor/github.com/libregraph/lico/bootstrap/settings.go +++ b/vendor/github.com/libregraph/lico/bootstrap/settings.go @@ -17,6 +17,10 @@ package bootstrap +import ( + "net/http" +) + // Settings is a typed application config which represents the user accessible // boostrap settings params. type Settings struct { @@ -48,6 +52,7 @@ type Settings struct { ValidationKeysPath string CookieBackendURI string CookieNames []string + CookieSameSite http.SameSite AccessTokenDurationSeconds uint64 IDTokenDurationSeconds uint64 RefreshTokenDurationSeconds uint64 diff --git a/vendor/github.com/libregraph/lico/identifier/config.go b/vendor/github.com/libregraph/lico/identifier/config.go index f5741d9b43..715560f40e 100644 --- a/vendor/github.com/libregraph/lico/identifier/config.go +++ b/vendor/github.com/libregraph/lico/identifier/config.go @@ -18,6 +18,7 @@ package identifier import ( + "net/http" "net/url" "github.com/libregraph/lico/config" @@ -28,9 +29,15 @@ import ( type Config struct { Config *config.Config - BaseURI *url.URL - LogonCookieName string - ScopesConf string + BaseURI *url.URL + ScopesConf string + + LogonCookieName string + LogonCookieSameSite http.SameSite + + ConsentCookieSameSite http.SameSite + + StateCookieSameSite http.SameSite PathPrefix string StaticFolder string diff --git a/vendor/github.com/libregraph/lico/identifier/cookie.go b/vendor/github.com/libregraph/lico/identifier/cookie.go index 7ab74b432f..4c57cb1466 100644 --- a/vendor/github.com/libregraph/lico/identifier/cookie.go +++ b/vendor/github.com/libregraph/lico/identifier/cookie.go @@ -37,7 +37,7 @@ func (i *Identifier) setLogonCookie(rw http.ResponseWriter, value string) error Path: i.pathPrefix + "/identifier/_/", Secure: true, HttpOnly: true, - SameSite: http.SameSiteNoneMode, + SameSite: i.logonCookieSameSite, } http.SetCookie(rw, &cookie) @@ -55,7 +55,7 @@ func (i *Identifier) removeLogonCookie(rw http.ResponseWriter) error { Path: i.pathPrefix + "/identifier/_/", Secure: true, HttpOnly: true, - SameSite: http.SameSiteNoneMode, + SameSite: i.logonCookieSameSite, Expires: farPastExpiryTime, } @@ -78,7 +78,7 @@ func (i *Identifier) setConsentCookie(rw http.ResponseWriter, cr *ConsentRequest Path: i.pathPrefix + "/identifier/_/", Secure: true, HttpOnly: true, - SameSite: http.SameSiteNoneMode, + SameSite: i.consentCookieSameSite, } http.SetCookie(rw, &cookie) @@ -106,7 +106,7 @@ func (i *Identifier) removeConsentCookie(rw http.ResponseWriter, req *http.Reque Path: i.pathPrefix + "/identifier/_/", Secure: true, HttpOnly: true, - SameSite: http.SameSiteNoneMode, + SameSite: i.consentCookieSameSite, Expires: farPastExpiryTime, } @@ -150,7 +150,7 @@ func (i *Identifier) setStateCookie(rw http.ResponseWriter, scope string, state Path: i.pathPrefix + "/identifier/" + scope, Secure: true, HttpOnly: true, - SameSite: http.SameSiteNoneMode, + SameSite: i.stateCookieSameSite, } http.SetCookie(rw, &cookie) @@ -178,7 +178,7 @@ func (i *Identifier) removeStateCookie(rw http.ResponseWriter, req *http.Request Path: i.pathPrefix + "/identifier/" + scope, Secure: true, HttpOnly: true, - SameSite: http.SameSiteNoneMode, + SameSite: i.stateCookieSameSite, Expires: farPastExpiryTime, } diff --git a/vendor/github.com/libregraph/lico/identifier/identifier.go b/vendor/github.com/libregraph/lico/identifier/identifier.go index 60e4326b0a..d34bc998e1 100644 --- a/vendor/github.com/libregraph/lico/identifier/identifier.go +++ b/vendor/github.com/libregraph/lico/identifier/identifier.go @@ -32,8 +32,10 @@ import ( "github.com/gorilla/mux" "github.com/longsleep/rndm" "github.com/sirupsen/logrus" - jose "gopkg.in/square/go-jose.v2" - jwt "gopkg.in/square/go-jose.v2/jwt" + "gopkg.in/square/go-jose.v2" + "gopkg.in/square/go-jose.v2/jwt" + + "github.com/libregraph/oidc-go" konnect "github.com/libregraph/lico" "github.com/libregraph/lico/identifier/backends" @@ -44,7 +46,6 @@ import ( "github.com/libregraph/lico/identity/clients" "github.com/libregraph/lico/managers" "github.com/libregraph/lico/utils" - "github.com/libregraph/oidc-go" ) // audienceMarker defines the value which gets included in logon cookies. Valid @@ -62,10 +63,16 @@ type Identifier struct { baseURI *url.URL pathPrefix string staticFolder string - logonCookieName string scopesConf string webappIndexHTML []byte + logonCookieName string + logonCookieSameSite http.SameSite + + consentCookieSameSite http.SameSite + + stateCookieSameSite http.SameSite + authorizationEndpointURI *url.URL signedOutEndpointURI *url.URL oauth2CbEndpointURI *url.URL @@ -114,10 +121,16 @@ func NewIdentifier(c *Config) (*Identifier, error) { baseURI: c.BaseURI, pathPrefix: c.PathPrefix, staticFolder: staticFolder, - logonCookieName: c.LogonCookieName, scopesConf: c.ScopesConf, webappIndexHTML: webappIndexHTML, + logonCookieName: c.LogonCookieName, + logonCookieSameSite: c.LogonCookieSameSite, + + consentCookieSameSite: c.ConsentCookieSameSite, + + stateCookieSameSite: c.StateCookieSameSite, + authorizationEndpointURI: c.AuthorizationEndpointURI, signedOutEndpointURI: c.SignedOutEndpointURI, oauth2CbEndpointURI: oauth2CbEndpointURI, diff --git a/vendor/github.com/libregraph/lico/oidc/provider/config.go b/vendor/github.com/libregraph/lico/oidc/provider/config.go index 4a3e15404f..1f695ddc09 100644 --- a/vendor/github.com/libregraph/lico/oidc/provider/config.go +++ b/vendor/github.com/libregraph/lico/oidc/provider/config.go @@ -18,6 +18,7 @@ package provider import ( + "net/http" "time" "github.com/libregraph/lico/config" @@ -37,11 +38,13 @@ type Config struct { CheckSessionIframePath string RegistrationPath string - BrowserStateCookiePath string - BrowserStateCookieName string + BrowserStateCookiePath string + BrowserStateCookieName string + BrowserStateCookieSameSite http.SameSite - SessionCookiePath string - SessionCookieName string + SessionCookiePath string + SessionCookieName string + SessionCookieSameSite http.SameSite AccessTokenDuration time.Duration IDTokenDuration time.Duration diff --git a/vendor/github.com/libregraph/lico/oidc/provider/cookie.go b/vendor/github.com/libregraph/lico/oidc/provider/cookie.go index cb25a944f7..3279a57c0f 100644 --- a/vendor/github.com/libregraph/lico/oidc/provider/cookie.go +++ b/vendor/github.com/libregraph/lico/oidc/provider/cookie.go @@ -29,7 +29,7 @@ func (p *Provider) setBrowserStateCookie(rw http.ResponseWriter, value string) e Path: p.browserStateCookiePath, Secure: true, HttpOnly: false, // This Cookie is intended to be read by Javascript. - SameSite: http.SameSiteNoneMode, + SameSite: p.browserStateCookieSameSite, } http.SetCookie(rw, &cookie) @@ -43,7 +43,7 @@ func (p *Provider) removeBrowserStateCookie(rw http.ResponseWriter) error { Path: p.browserStateCookiePath, Secure: true, HttpOnly: false, // This Cookie is intended to be read by Javascript. - SameSite: http.SameSiteNoneMode, + SameSite: p.browserStateCookieSameSite, Expires: farPastExpiryTime, } @@ -60,7 +60,7 @@ func (p *Provider) setSessionCookie(rw http.ResponseWriter, value string) error Path: p.sessionCookiePath, Secure: true, HttpOnly: true, - SameSite: http.SameSiteNoneMode, + SameSite: p.sessionCookieSameSite, } http.SetCookie(rw, &cookie) @@ -83,7 +83,7 @@ func (p *Provider) removeSessionCookie(rw http.ResponseWriter) error { Path: p.sessionCookiePath, Secure: true, HttpOnly: true, - SameSite: http.SameSiteNoneMode, + SameSite: p.sessionCookieSameSite, Expires: farPastExpiryTime, } diff --git a/vendor/github.com/libregraph/lico/oidc/provider/provider.go b/vendor/github.com/libregraph/lico/oidc/provider/provider.go index 82fdf004a5..e0e0394853 100644 --- a/vendor/github.com/libregraph/lico/oidc/provider/provider.go +++ b/vendor/github.com/libregraph/lico/oidc/provider/provider.go @@ -73,11 +73,13 @@ type Provider struct { validationKeys map[string]crypto.PublicKey certificates map[string][]*x509.Certificate - browserStateCookiePath string - browserStateCookieName string + browserStateCookiePath string + browserStateCookieName string + browserStateCookieSameSite http.SameSite - sessionCookiePath string - sessionCookieName string + sessionCookiePath string + sessionCookieName string + sessionCookieSameSite http.SameSite accessTokenDuration time.Duration idTokenDuration time.Duration @@ -105,11 +107,13 @@ func NewProvider(c *Config) (*Provider, error) { validationKeys: make(map[string]crypto.PublicKey), certificates: make(map[string][]*x509.Certificate), - browserStateCookiePath: c.BrowserStateCookiePath, - browserStateCookieName: c.BrowserStateCookieName, + browserStateCookiePath: c.BrowserStateCookiePath, + browserStateCookieName: c.BrowserStateCookieName, + browserStateCookieSameSite: c.BrowserStateCookieSameSite, - sessionCookiePath: c.SessionCookiePath, - sessionCookieName: c.SessionCookieName, + sessionCookiePath: c.SessionCookiePath, + sessionCookieName: c.SessionCookieName, + sessionCookieSameSite: c.SessionCookieSameSite, accessTokenDuration: c.AccessTokenDuration, idTokenDuration: c.IDTokenDuration, diff --git a/vendor/modules.txt b/vendor/modules.txt index 710ff93548..5e24b61df5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1265,7 +1265,7 @@ github.com/libregraph/idm/server github.com/libregraph/idm/server/handler github.com/libregraph/idm/server/handler/boltdb github.com/libregraph/idm/server/handler/ldif -# github.com/libregraph/lico v0.61.2 +# github.com/libregraph/lico v0.61.3-0.20240322112242-72cf9221d3a7 ## explicit; go 1.18 github.com/libregraph/lico github.com/libregraph/lico/bootstrap From 436757fd8dd0d1ee67429cfa0cf957659e87af20 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Wed, 10 Apr 2024 10:24:35 +0000 Subject: [PATCH 20/26] Automated changelog update [skip ci] --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7661a4b656..facbd12b6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ The following sections list the changes for unreleased. * Bugfix - Update reva to v2.19.4: [#8781](https://github.com/owncloud/ocis/pull/8781) * Bugfix - Fix restarting of postprocessing: [#8782](https://github.com/owncloud/ocis/pull/8782) * Bugfix - Fix the create personal space cache: [#8799](https://github.com/owncloud/ocis/pull/8799) +* Enhancement - Make IDP cookies same site strict: [#8716](https://github.com/owncloud/ocis/pull/8716) ## Details @@ -80,6 +81,21 @@ The following sections list the changes for unreleased. https://github.com/owncloud/ocis/pull/8799 +* Enhancement - Make IDP cookies same site strict: [#8716](https://github.com/owncloud/ocis/pull/8716) + + To enhance the security of our application and prevent Cross-Site Request + Forgery (CSRF) attacks, we have updated the SameSite attribute of the build in + Identity Provider (IDP) cookies to Strict. + + This change restricts the browser from sending these cookies with any cross-site + requests, thereby limiting the exposure of the user's session to potential + threats. + + This update does not impact the existing functionality of the application but + provides an additional layer of security where needed. + + https://github.com/owncloud/ocis/pull/8716 + # Changelog for [5.0.0] (2024-03-18) The following sections list the changes for 5.0.0. From 47353cb198fba02d05d2d9eb94511f8337138060 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Wed, 10 Apr 2024 15:04:19 +0200 Subject: [PATCH 21/26] docs: prepare changelog --- changelog/{unreleased => 5.0.1_2024-04-10}/bump-reva.md | 0 .../enhancement-strict-same-site-cookie.md | 0 .../fix-create-personal-space-cache.md | 0 .../fix-postprocessing-restart.md | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename changelog/{unreleased => 5.0.1_2024-04-10}/bump-reva.md (100%) rename changelog/{unreleased => 5.0.1_2024-04-10}/enhancement-strict-same-site-cookie.md (100%) rename changelog/{unreleased => 5.0.1_2024-04-10}/fix-create-personal-space-cache.md (100%) rename changelog/{unreleased => 5.0.1_2024-04-10}/fix-postprocessing-restart.md (100%) diff --git a/changelog/unreleased/bump-reva.md b/changelog/5.0.1_2024-04-10/bump-reva.md similarity index 100% rename from changelog/unreleased/bump-reva.md rename to changelog/5.0.1_2024-04-10/bump-reva.md diff --git a/changelog/unreleased/enhancement-strict-same-site-cookie.md b/changelog/5.0.1_2024-04-10/enhancement-strict-same-site-cookie.md similarity index 100% rename from changelog/unreleased/enhancement-strict-same-site-cookie.md rename to changelog/5.0.1_2024-04-10/enhancement-strict-same-site-cookie.md diff --git a/changelog/unreleased/fix-create-personal-space-cache.md b/changelog/5.0.1_2024-04-10/fix-create-personal-space-cache.md similarity index 100% rename from changelog/unreleased/fix-create-personal-space-cache.md rename to changelog/5.0.1_2024-04-10/fix-create-personal-space-cache.md diff --git a/changelog/unreleased/fix-postprocessing-restart.md b/changelog/5.0.1_2024-04-10/fix-postprocessing-restart.md similarity index 100% rename from changelog/unreleased/fix-postprocessing-restart.md rename to changelog/5.0.1_2024-04-10/fix-postprocessing-restart.md From 28b95304dd93102065281d069630a718bb40fcdb Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Wed, 10 Apr 2024 15:05:41 +0200 Subject: [PATCH 22/26] chore: bump version --- .../continuous-deployment-config/ocis_keycloak/released.yml | 2 +- deployments/continuous-deployment-config/ocis_ldap/released.yml | 2 +- .../continuous-deployment-config/ocis_traefik/released.yml | 2 +- deployments/continuous-deployment-config/ocis_wopi/released.yml | 2 +- ocis-pkg/version/version.go | 2 +- sonar-project.properties | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/deployments/continuous-deployment-config/ocis_keycloak/released.yml b/deployments/continuous-deployment-config/ocis_keycloak/released.yml index cf91c92d60..6818781211 100644 --- a/deployments/continuous-deployment-config/ocis_keycloak/released.yml +++ b/deployments/continuous-deployment-config/ocis_keycloak/released.yml @@ -32,7 +32,7 @@ env: INSECURE: "false" TRAEFIK_ACME_MAIL: mbarz@owncloud.com - OCIS_DOCKER_TAG: 5.0.0 + OCIS_DOCKER_TAG: 5.0.1 OCIS_DOMAIN: ocis.ocis-keycloak.released.owncloud.works KEYCLOAK_DOMAIN: keycloak.ocis-keycloak.released.owncloud.works COMPOSE_FILE: docker-compose.yml:monitoring_tracing/docker-compose-additions.yml diff --git a/deployments/continuous-deployment-config/ocis_ldap/released.yml b/deployments/continuous-deployment-config/ocis_ldap/released.yml index 9beff9103b..1936bf7588 100644 --- a/deployments/continuous-deployment-config/ocis_ldap/released.yml +++ b/deployments/continuous-deployment-config/ocis_ldap/released.yml @@ -32,7 +32,7 @@ env: INSECURE: "false" TRAEFIK_ACME_MAIL: mbarz@owncloud.com - OCIS_DOCKER_TAG: 5.0.0 + OCIS_DOCKER_TAG: 5.0.1 OCIS_DOMAIN: ocis.ocis-ldap.released.owncloud.works LDAP_MANAGER_DOMAIN: ldap.ocis-ldap.released.owncloud.works COMPOSE_FILE: docker-compose.yml:monitoring_tracing/docker-compose-additions.yml diff --git a/deployments/continuous-deployment-config/ocis_traefik/released.yml b/deployments/continuous-deployment-config/ocis_traefik/released.yml index d0ff5fc789..1345b85f12 100644 --- a/deployments/continuous-deployment-config/ocis_traefik/released.yml +++ b/deployments/continuous-deployment-config/ocis_traefik/released.yml @@ -32,7 +32,7 @@ env: INSECURE: "false" TRAEFIK_ACME_MAIL: mbarz@owncloud.com - OCIS_DOCKER_TAG: 5.0.0 + OCIS_DOCKER_TAG: 5.0.1 OCIS_DOMAIN: ocis.ocis-traefik.released.owncloud.works DEMO_USERS: "true" INBUCKET_DOMAIN: mail.ocis-traefik.released.owncloud.works diff --git a/deployments/continuous-deployment-config/ocis_wopi/released.yml b/deployments/continuous-deployment-config/ocis_wopi/released.yml index f570f3a52d..4673fb4872 100644 --- a/deployments/continuous-deployment-config/ocis_wopi/released.yml +++ b/deployments/continuous-deployment-config/ocis_wopi/released.yml @@ -32,7 +32,7 @@ env: INSECURE: "false" TRAEFIK_ACME_MAIL: mbarz@owncloud.com - OCIS_DOCKER_TAG: 5.0.0 + OCIS_DOCKER_TAG: 5.0.1 OCIS_DOMAIN: ocis.ocis-wopi.released.owncloud.works COMPANION_DOMAIN: companion.ocis-wopi.released.owncloud.works COMPANION_IMAGE: owncloud/uppy-companion:3.12.13-owncloud diff --git a/ocis-pkg/version/version.go b/ocis-pkg/version/version.go index 2215caa54b..f2edadb80e 100644 --- a/ocis-pkg/version/version.go +++ b/ocis-pkg/version/version.go @@ -16,7 +16,7 @@ var ( // LatestTag is the latest released version plus the dev meta version. // Will be overwritten by the release pipeline // Needs a manual change for every tagged release - LatestTag = "5.0.0+dev" + LatestTag = "5.0.1+dev" // Date indicates the build date. // This has been removed, it looks like you can only replace static strings with recent go versions diff --git a/sonar-project.properties b/sonar-project.properties index ba4e4a42f7..84ce284c09 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -2,7 +2,7 @@ sonar.projectKey=owncloud_ocis sonar.organization=owncloud-1 sonar.projectName=ocis -sonar.projectVersion=5.0.0 +sonar.projectVersion=5.0.1 sonar.host.url=https://sonarcloud.io # ===================================================== From 8d1ba0244c3203c9bd2ac05b683d01afe885fc8d Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Wed, 10 Apr 2024 16:15:58 +0200 Subject: [PATCH 23/26] fix: ocs config was connected incorrectly --- services/frontend/pkg/config/config.go | 1 + services/frontend/pkg/config/defaults/defaultconfig.go | 1 + services/frontend/pkg/revaconfig/config.go | 3 ++- services/ocs/pkg/config/config.go | 3 +-- services/ocs/pkg/config/defaults/defaultconfig.go | 3 --- services/ocs/pkg/config/reva.go | 4 ---- 6 files changed, 5 insertions(+), 10 deletions(-) diff --git a/services/frontend/pkg/config/config.go b/services/frontend/pkg/config/config.go index 9cae9ab91a..bfb61f8990 100644 --- a/services/frontend/pkg/config/config.go +++ b/services/frontend/pkg/config/config.go @@ -145,6 +145,7 @@ type OCS struct { PublicShareMustHavePassword bool `yaml:"public_sharing_share_must_have_password" env:"OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD;FRONTEND_OCS_PUBLIC_SHARE_MUST_HAVE_PASSWORD" desc:"Set this to true if you want to enforce passwords on all public shares." introductionVersion:"5.0"` WriteablePublicShareMustHavePassword bool `yaml:"public_sharing_writeableshare_must_have_password" env:"OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD;FRONTEND_OCS_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD" desc:"Set this to true if you want to enforce passwords on Uploader, Editor or Contributor shares." introductionVersion:"5.0"` IncludeOCMSharees bool `yaml:"include_ocm_sharees" env:"FRONTEND_OCS_INCLUDE_OCM_SHAREES" desc:"Include OCM sharees when listing sharees." introductionVersion:"5.0"` + ShowUserEmailInResults bool `yaml:"show_email_in_results" env:"FRONTEND_SHOW_USER_EMAIL_IN_RESULTS;OCIS_SHOW_USER_EMAIL_IN_RESULTS" desc:"Mask user email addresses in responses. (EXPERIMENTAL)" introductionVersion:"5.1"` } type CacheWarmupDrivers struct { diff --git a/services/frontend/pkg/config/defaults/defaultconfig.go b/services/frontend/pkg/config/defaults/defaultconfig.go index 5a9b81c9ac..ae99b4aadd 100644 --- a/services/frontend/pkg/config/defaults/defaultconfig.go +++ b/services/frontend/pkg/config/defaults/defaultconfig.go @@ -116,6 +116,7 @@ func DefaultConfig() *config.Config { ListOCMShares: true, PublicShareMustHavePassword: true, IncludeOCMSharees: false, + ShowUserEmailInResults: true, }, Middleware: config.Middleware{ Auth: config.Auth{ diff --git a/services/frontend/pkg/revaconfig/config.go b/services/frontend/pkg/revaconfig/config.go index 0b38abaab5..9226737782 100644 --- a/services/frontend/pkg/revaconfig/config.go +++ b/services/frontend/pkg/revaconfig/config.go @@ -339,7 +339,8 @@ func FrontendConfigFromStruct(cfg *config.Config, logger log.Logger) (map[string "productversion": version.GetString(), }, }, - "include_ocm_sharees": cfg.OCS.IncludeOCMSharees, + "include_ocm_sharees": cfg.OCS.IncludeOCMSharees, + "show_email_in_results": cfg.OCS.ShowUserEmailInResults, }, }, }, diff --git a/services/ocs/pkg/config/config.go b/services/ocs/pkg/config/config.go index ed7a0ab96e..4097ff4ef6 100644 --- a/services/ocs/pkg/config/config.go +++ b/services/ocs/pkg/config/config.go @@ -19,8 +19,7 @@ type Config struct { Debug Debug `yaml:"debug"` HTTP HTTP `yaml:"http"` - API API `yaml:"api"` - + GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"` GrpcClient client.Client `yaml:"-"` diff --git a/services/ocs/pkg/config/defaults/defaultconfig.go b/services/ocs/pkg/config/defaults/defaultconfig.go index a665c78b2a..6a9ebec588 100644 --- a/services/ocs/pkg/config/defaults/defaultconfig.go +++ b/services/ocs/pkg/config/defaults/defaultconfig.go @@ -44,9 +44,6 @@ func DefaultConfig() *config.Config { Nodes: []string{"127.0.0.1:9233"}, TTL: time.Hour * 12, }, - API: config.API{ - ShowUserEmailInResults: true, - }, } } diff --git a/services/ocs/pkg/config/reva.go b/services/ocs/pkg/config/reva.go index 05e8d8c8d7..8413904dab 100644 --- a/services/ocs/pkg/config/reva.go +++ b/services/ocs/pkg/config/reva.go @@ -4,7 +4,3 @@ package config type TokenManager struct { JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;OCS_JWT_SECRET" desc:"The secret to mint and validate jwt tokens." introductionVersion:"pre5.0"` } - -type API struct { - ShowUserEmailInResults bool `yaml:"show_email_in_results" env:"OCIS_SHOW_USER_EMAIL_IN_RESULTS" desc:"Mask user email addresses in responses. (EXPERIMENTAL)" introductionVersion:"5.1"` -} From 2804a42274ab84868c498e8f01b8fb411c9ec5ef Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Thu, 11 Apr 2024 08:13:21 +0000 Subject: [PATCH 24/26] Automated changelog update [skip ci] --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index facbd12b6b..2e4becc886 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Table of Contents -* [Changelog for unreleased](#changelog-for-unreleased-unreleased) +* [Changelog for 5.0.1](#changelog-for-501-2024-04-10) * [Changelog for 5.0.0](#changelog-for-500-2024-03-18) * [Changelog for 4.0.6](#changelog-for-406-2024-02-07) * [Changelog for 4.0.5](#changelog-for-405-2023-12-21) @@ -34,11 +34,11 @@ * [Changelog for 1.1.0](#changelog-for-110-2021-01-22) * [Changelog for 1.0.0](#changelog-for-100-2020-12-17) -# Changelog for [unreleased] (UNRELEASED) +# Changelog for [5.0.1] (2024-04-10) -The following sections list the changes for unreleased. +The following sections list the changes for 5.0.1. -[unreleased]: https://github.com/owncloud/ocis/compare/v5.0.0...master +[5.0.1]: https://github.com/owncloud/ocis/compare/v5.0.0...v5.0.1 ## Summary From 711fe74a6c82cdd0c87ff1a68df82d6ddb403b79 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Thu, 11 Apr 2024 11:03:06 +0200 Subject: [PATCH 25/26] docs: clarify changelog --- .../5.0.1_2024-04-10/enhancement-strict-same-site-cookie.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/changelog/5.0.1_2024-04-10/enhancement-strict-same-site-cookie.md b/changelog/5.0.1_2024-04-10/enhancement-strict-same-site-cookie.md index 94b2916116..c3a4e1a1f3 100644 --- a/changelog/5.0.1_2024-04-10/enhancement-strict-same-site-cookie.md +++ b/changelog/5.0.1_2024-04-10/enhancement-strict-same-site-cookie.md @@ -1,4 +1,4 @@ -Enhancement: Make IDP cookies same site strict +Bugfix: Make IDP cookies same site strict To enhance the security of our application and prevent Cross-Site Request Forgery (CSRF) attacks, we have updated the SameSite attribute of the build in Identity Provider (IDP) cookies to Strict. @@ -9,4 +9,6 @@ thereby limiting the exposure of the user's session to potential threats. This update does not impact the existing functionality of the application but provides an additional layer of security where needed. +This only affects cookies set by the built-in IDP. Production systems should not be affected. + https://github.com/owncloud/ocis/pull/8716 From 3a2294f4faf3184057e2e74027e8b9a45fac12de Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Thu, 11 Apr 2024 09:04:54 +0000 Subject: [PATCH 26/26] Automated changelog update [skip ci] --- CHANGELOG.md | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e4becc886..1012543198 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,13 +42,31 @@ The following sections list the changes for 5.0.1. ## Summary +* Bugfix - Make IDP cookies same site strict: [#8716](https://github.com/owncloud/ocis/pull/8716) * Bugfix - Update reva to v2.19.4: [#8781](https://github.com/owncloud/ocis/pull/8781) * Bugfix - Fix restarting of postprocessing: [#8782](https://github.com/owncloud/ocis/pull/8782) * Bugfix - Fix the create personal space cache: [#8799](https://github.com/owncloud/ocis/pull/8799) -* Enhancement - Make IDP cookies same site strict: [#8716](https://github.com/owncloud/ocis/pull/8716) ## Details +* Bugfix - Make IDP cookies same site strict: [#8716](https://github.com/owncloud/ocis/pull/8716) + + To enhance the security of our application and prevent Cross-Site Request + Forgery (CSRF) attacks, we have updated the SameSite attribute of the build in + Identity Provider (IDP) cookies to Strict. + + This change restricts the browser from sending these cookies with any cross-site + requests, thereby limiting the exposure of the user's session to potential + threats. + + This update does not impact the existing functionality of the application but + provides an additional layer of security where needed. + + This only affects cookies set by the built-in IDP. Production systems should not + be affected. + + https://github.com/owncloud/ocis/pull/8716 + * Bugfix - Update reva to v2.19.4: [#8781](https://github.com/owncloud/ocis/pull/8781) We updated reva to v2.19.4 @@ -81,21 +99,6 @@ The following sections list the changes for 5.0.1. https://github.com/owncloud/ocis/pull/8799 -* Enhancement - Make IDP cookies same site strict: [#8716](https://github.com/owncloud/ocis/pull/8716) - - To enhance the security of our application and prevent Cross-Site Request - Forgery (CSRF) attacks, we have updated the SameSite attribute of the build in - Identity Provider (IDP) cookies to Strict. - - This change restricts the browser from sending these cookies with any cross-site - requests, thereby limiting the exposure of the user's session to potential - threats. - - This update does not impact the existing functionality of the application but - provides an additional layer of security where needed. - - https://github.com/owncloud/ocis/pull/8716 - # Changelog for [5.0.0] (2024-03-18) The following sections list the changes for 5.0.0.