mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-07 06:53:09 -06:00
Upstream release v0.9.5
This commit is contained in:
commit
387868e65d
2
.github/workflows/dendrite.yml
vendored
2
.github/workflows/dendrite.yml
vendored
|
|
@ -297,6 +297,8 @@ jobs:
|
||||||
# Build initial Dendrite image
|
# Build initial Dendrite image
|
||||||
- run: docker build -t complement-dendrite -f build/scripts/Complement${{ matrix.postgres }}.Dockerfile .
|
- run: docker build -t complement-dendrite -f build/scripts/Complement${{ matrix.postgres }}.Dockerfile .
|
||||||
working-directory: dendrite
|
working-directory: dendrite
|
||||||
|
env:
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
|
|
||||||
# Run Complement
|
# Run Complement
|
||||||
- run: |
|
- run: |
|
||||||
|
|
|
||||||
12
CHANGES.md
12
CHANGES.md
|
|
@ -1,5 +1,17 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Dendrite 0.9.5 (2022-08-25)
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* The roomserver will now correctly unreject previously rejected events if necessary when reprocessing
|
||||||
|
* The handling of event soft-failure has been improved on the roomserver input by no longer applying rejection rules and still calculating state before the event if possible
|
||||||
|
* The federation `/state` and `/state_ids` endpoints should now return the correct error code when the state isn't known instead of returning a HTTP 500
|
||||||
|
* The federation `/event` should now return outlier events correctly instead of returning a HTTP 500
|
||||||
|
* A bug in the federation backoff allowing zero intervals has been corrected
|
||||||
|
* The `create-account` utility will no longer error if the homeserver URL ends in a trailing slash
|
||||||
|
* A regression in `/sync` introduced in 0.9.4 should be fixed
|
||||||
|
|
||||||
## Dendrite 0.9.4 (2022-08-19)
|
## Dendrite 0.9.4 (2022-08-19)
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
#syntax=docker/dockerfile:1.2
|
||||||
|
|
||||||
FROM golang:1.18-stretch as build
|
FROM golang:1.18-stretch as build
|
||||||
RUN apt-get update && apt-get install -y sqlite3
|
RUN apt-get update && apt-get install -y sqlite3
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
|
@ -8,14 +10,12 @@ RUN mkdir /dendrite
|
||||||
|
|
||||||
# Utilise Docker caching when downloading dependencies, this stops us needlessly
|
# Utilise Docker caching when downloading dependencies, this stops us needlessly
|
||||||
# downloading dependencies every time.
|
# downloading dependencies every time.
|
||||||
COPY go.mod .
|
RUN --mount=target=. \
|
||||||
COPY go.sum .
|
--mount=type=cache,target=/go/pkg/mod \
|
||||||
RUN go mod download
|
--mount=type=cache,target=/root/.cache/go-build \
|
||||||
|
go build -o /dendrite ./cmd/generate-config && \
|
||||||
COPY . .
|
go build -o /dendrite ./cmd/generate-keys && \
|
||||||
RUN go build -o /dendrite ./cmd/dendrite-monolith-server
|
go build -o /dendrite ./cmd/dendrite-monolith-server
|
||||||
RUN go build -o /dendrite ./cmd/generate-keys
|
|
||||||
RUN go build -o /dendrite ./cmd/generate-config
|
|
||||||
|
|
||||||
WORKDIR /dendrite
|
WORKDIR /dendrite
|
||||||
RUN ./generate-keys --private-key matrix_key.pem
|
RUN ./generate-keys --private-key matrix_key.pem
|
||||||
|
|
@ -26,7 +26,7 @@ EXPOSE 8008 8448
|
||||||
|
|
||||||
# At runtime, generate TLS cert based on the CA now mounted at /ca
|
# At runtime, generate TLS cert based on the CA now mounted at /ca
|
||||||
# At runtime, replace the SERVER_NAME with what we are told
|
# At runtime, replace the SERVER_NAME with what we are told
|
||||||
CMD ./generate-keys --server $SERVER_NAME --tls-cert server.crt --tls-key server.key --tls-authority-cert /complement/ca/ca.crt --tls-authority-key /complement/ca/ca.key && \
|
CMD ./generate-keys -keysize 1024 --server $SERVER_NAME --tls-cert server.crt --tls-key server.key --tls-authority-cert /complement/ca/ca.crt --tls-authority-key /complement/ca/ca.key && \
|
||||||
./generate-config -server $SERVER_NAME --ci > dendrite.yaml && \
|
./generate-config -server $SERVER_NAME --ci > dendrite.yaml && \
|
||||||
cp /complement/ca/ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates && \
|
cp /complement/ca/ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates && \
|
||||||
./dendrite-monolith-server --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml -api=${API:-0}
|
exec ./dendrite-monolith-server --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml -api=${API:-0}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
#syntax=docker/dockerfile:1.2
|
||||||
|
|
||||||
# A local development Complement dockerfile, to be used with host mounts
|
# A local development Complement dockerfile, to be used with host mounts
|
||||||
# /cache -> Contains the entire dendrite code at Dockerfile build time. Builds binaries but only keeps the generate-* ones. Pre-compilation saves time.
|
# /cache -> Contains the entire dendrite code at Dockerfile build time. Builds binaries but only keeps the generate-* ones. Pre-compilation saves time.
|
||||||
# /dendrite -> Host-mounted sources
|
# /dendrite -> Host-mounted sources
|
||||||
|
|
@ -9,11 +11,10 @@
|
||||||
FROM golang:1.18-stretch
|
FROM golang:1.18-stretch
|
||||||
RUN apt-get update && apt-get install -y sqlite3
|
RUN apt-get update && apt-get install -y sqlite3
|
||||||
|
|
||||||
WORKDIR /runtime
|
|
||||||
|
|
||||||
ENV SERVER_NAME=localhost
|
ENV SERVER_NAME=localhost
|
||||||
EXPOSE 8008 8448
|
EXPOSE 8008 8448
|
||||||
|
|
||||||
|
WORKDIR /runtime
|
||||||
# This script compiles Dendrite for us.
|
# This script compiles Dendrite for us.
|
||||||
RUN echo '\
|
RUN echo '\
|
||||||
#!/bin/bash -eux \n\
|
#!/bin/bash -eux \n\
|
||||||
|
|
@ -29,25 +30,23 @@ RUN echo '\
|
||||||
RUN echo '\
|
RUN echo '\
|
||||||
#!/bin/bash -eu \n\
|
#!/bin/bash -eu \n\
|
||||||
./generate-keys --private-key matrix_key.pem \n\
|
./generate-keys --private-key matrix_key.pem \n\
|
||||||
./generate-keys --server $SERVER_NAME --tls-cert server.crt --tls-key server.key --tls-authority-cert /complement/ca/ca.crt --tls-authority-key /complement/ca/ca.key \n\
|
./generate-keys -keysize 1024 --server $SERVER_NAME --tls-cert server.crt --tls-key server.key --tls-authority-cert /complement/ca/ca.crt --tls-authority-key /complement/ca/ca.key \n\
|
||||||
./generate-config -server $SERVER_NAME --ci > dendrite.yaml \n\
|
./generate-config -server $SERVER_NAME --ci > dendrite.yaml \n\
|
||||||
cp /complement/ca/ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates \n\
|
cp /complement/ca/ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates \n\
|
||||||
./dendrite-monolith-server --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml \n\
|
exec ./dendrite-monolith-server --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml \n\
|
||||||
' > run.sh && chmod +x run.sh
|
' > run.sh && chmod +x run.sh
|
||||||
|
|
||||||
|
|
||||||
WORKDIR /cache
|
WORKDIR /cache
|
||||||
# Pre-download deps; we don't need to do this if the GOPATH is mounted.
|
|
||||||
COPY go.mod .
|
|
||||||
COPY go.sum .
|
|
||||||
RUN go mod download
|
|
||||||
|
|
||||||
# Build the monolith in /cache - we won't actually use this but will rely on build artifacts to speed
|
# Build the monolith in /cache - we won't actually use this but will rely on build artifacts to speed
|
||||||
# up the real compilation. Build the generate-* binaries in the true /runtime locations.
|
# up the real compilation. Build the generate-* binaries in the true /runtime locations.
|
||||||
# If the generate-* source is changed, this dockerfile needs re-running.
|
# If the generate-* source is changed, this dockerfile needs re-running.
|
||||||
COPY . .
|
RUN --mount=target=. \
|
||||||
RUN go build ./cmd/dendrite-monolith-server && go build -o /runtime ./cmd/generate-keys && go build -o /runtime ./cmd/generate-config
|
--mount=type=cache,target=/go/pkg/mod \
|
||||||
|
--mount=type=cache,target=/root/.cache/go-build \
|
||||||
|
go build -o /runtime ./cmd/generate-config && \
|
||||||
|
go build -o /runtime ./cmd/generate-keys
|
||||||
|
|
||||||
|
|
||||||
WORKDIR /runtime
|
WORKDIR /runtime
|
||||||
CMD /runtime/compile.sh && /runtime/run.sh
|
CMD /runtime/compile.sh && exec /runtime/run.sh
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
#syntax=docker/dockerfile:1.2
|
||||||
|
|
||||||
FROM golang:1.18-stretch as build
|
FROM golang:1.18-stretch as build
|
||||||
RUN apt-get update && apt-get install -y postgresql
|
RUN apt-get update && apt-get install -y postgresql
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
|
@ -26,14 +28,12 @@ RUN mkdir /dendrite
|
||||||
|
|
||||||
# Utilise Docker caching when downloading dependencies, this stops us needlessly
|
# Utilise Docker caching when downloading dependencies, this stops us needlessly
|
||||||
# downloading dependencies every time.
|
# downloading dependencies every time.
|
||||||
COPY go.mod .
|
RUN --mount=target=. \
|
||||||
COPY go.sum .
|
--mount=type=cache,target=/go/pkg/mod \
|
||||||
RUN go mod download
|
--mount=type=cache,target=/root/.cache/go-build \
|
||||||
|
go build -o /dendrite ./cmd/generate-config && \
|
||||||
COPY . .
|
go build -o /dendrite ./cmd/generate-keys && \
|
||||||
RUN go build -o /dendrite ./cmd/dendrite-monolith-server
|
go build -o /dendrite ./cmd/dendrite-monolith-server
|
||||||
RUN go build -o /dendrite ./cmd/generate-keys
|
|
||||||
RUN go build -o /dendrite ./cmd/generate-config
|
|
||||||
|
|
||||||
WORKDIR /dendrite
|
WORKDIR /dendrite
|
||||||
RUN ./generate-keys --private-key matrix_key.pem
|
RUN ./generate-keys --private-key matrix_key.pem
|
||||||
|
|
@ -45,10 +45,10 @@ EXPOSE 8008 8448
|
||||||
|
|
||||||
# At runtime, generate TLS cert based on the CA now mounted at /ca
|
# At runtime, generate TLS cert based on the CA now mounted at /ca
|
||||||
# At runtime, replace the SERVER_NAME with what we are told
|
# At runtime, replace the SERVER_NAME with what we are told
|
||||||
CMD /build/run_postgres.sh && ./generate-keys --server $SERVER_NAME --tls-cert server.crt --tls-key server.key --tls-authority-cert /complement/ca/ca.crt --tls-authority-key /complement/ca/ca.key && \
|
CMD /build/run_postgres.sh && ./generate-keys --keysize 1024 --server $SERVER_NAME --tls-cert server.crt --tls-key server.key --tls-authority-cert /complement/ca/ca.crt --tls-authority-key /complement/ca/ca.key && \
|
||||||
./generate-config -server $SERVER_NAME --ci > dendrite.yaml && \
|
./generate-config -server $SERVER_NAME --ci > dendrite.yaml && \
|
||||||
# Replace the connection string with a single postgres DB, using user/db = 'postgres' and no password, bump max_conns
|
# Replace the connection string with a single postgres DB, using user/db = 'postgres' and no password, bump max_conns
|
||||||
sed -i "s%connection_string:.*$%connection_string: postgresql://postgres@localhost/postgres?sslmode=disable%g" dendrite.yaml && \
|
sed -i "s%connection_string:.*$%connection_string: postgresql://postgres@localhost/postgres?sslmode=disable%g" dendrite.yaml && \
|
||||||
sed -i 's/max_open_conns:.*$/max_open_conns: 100/g' dendrite.yaml && \
|
sed -i 's/max_open_conns:.*$/max_open_conns: 100/g' dendrite.yaml && \
|
||||||
cp /complement/ca/ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates && \
|
cp /complement/ca/ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates && \
|
||||||
./dendrite-monolith-server --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml -api=${API:-0}
|
exec ./dendrite-monolith-server --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml -api=${API:-0}
|
||||||
|
|
@ -66,10 +66,11 @@ var (
|
||||||
resetPassword = flag.Bool("reset-password", false, "Deprecated")
|
resetPassword = flag.Bool("reset-password", false, "Deprecated")
|
||||||
serverURL = flag.String("url", "https://localhost:8448", "The URL to connect to.")
|
serverURL = flag.String("url", "https://localhost:8448", "The URL to connect to.")
|
||||||
validUsernameRegex = regexp.MustCompile(`^[0-9a-z_\-=./]+$`)
|
validUsernameRegex = regexp.MustCompile(`^[0-9a-z_\-=./]+$`)
|
||||||
|
timeout = flag.Duration("timeout", time.Second*30, "Timeout for the http client when connecting to the server")
|
||||||
)
|
)
|
||||||
|
|
||||||
var cl = http.Client{
|
var cl = http.Client{
|
||||||
Timeout: time.Second * 10,
|
Timeout: time.Second * 30,
|
||||||
Transport: http.DefaultTransport,
|
Transport: http.DefaultTransport,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,6 +109,8 @@ func main() {
|
||||||
logrus.Fatalln(err)
|
logrus.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cl.Timeout = *timeout
|
||||||
|
|
||||||
accessToken, err := sharedSecretRegister(cfg.ClientAPI.RegistrationSharedSecret, *serverURL, *username, pass, *isAdmin)
|
accessToken, err := sharedSecretRegister(cfg.ClientAPI.RegistrationSharedSecret, *serverURL, *username, pass, *isAdmin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatalln("Failed to create the account:", err.Error())
|
logrus.Fatalln("Failed to create the account:", err.Error())
|
||||||
|
|
@ -124,8 +127,8 @@ type sharedSecretRegistrationRequest struct {
|
||||||
Admin bool `json:"admin"`
|
Admin bool `json:"admin"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func sharedSecretRegister(sharedSecret, serverURL, localpart, password string, admin bool) (accesToken string, err error) {
|
func sharedSecretRegister(sharedSecret, serverURL, localpart, password string, admin bool) (accessToken string, err error) {
|
||||||
registerURL := fmt.Sprintf("%s/_synapse/admin/v1/register", serverURL)
|
registerURL := fmt.Sprintf("%s/_synapse/admin/v1/register", strings.Trim(serverURL, "/"))
|
||||||
nonceReq, err := http.NewRequest(http.MethodGet, registerURL, nil)
|
nonceReq, err := http.NewRequest(http.MethodGet, registerURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("unable to create http request: %w", err)
|
return "", fmt.Errorf("unable to create http request: %w", err)
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ var (
|
||||||
authorityCertFile = flag.String("tls-authority-cert", "", "Optional: Create TLS certificate/keys based on this CA authority. Useful for integration testing.")
|
authorityCertFile = flag.String("tls-authority-cert", "", "Optional: Create TLS certificate/keys based on this CA authority. Useful for integration testing.")
|
||||||
authorityKeyFile = flag.String("tls-authority-key", "", "Optional: Create TLS certificate/keys based on this CA authority. Useful for integration testing.")
|
authorityKeyFile = flag.String("tls-authority-key", "", "Optional: Create TLS certificate/keys based on this CA authority. Useful for integration testing.")
|
||||||
serverName = flag.String("server", "", "Optional: Create TLS certificate/keys with this domain name set. Useful for integration testing.")
|
serverName = flag.String("server", "", "Optional: Create TLS certificate/keys with this domain name set. Useful for integration testing.")
|
||||||
|
keySize = flag.Int("keysize", 4096, "Optional: Create TLS RSA private key with the given key size")
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
@ -58,12 +59,12 @@ func main() {
|
||||||
log.Fatal("Zero or both of --tls-key and --tls-cert must be supplied")
|
log.Fatal("Zero or both of --tls-key and --tls-cert must be supplied")
|
||||||
}
|
}
|
||||||
if *authorityCertFile == "" && *authorityKeyFile == "" {
|
if *authorityCertFile == "" && *authorityKeyFile == "" {
|
||||||
if err := test.NewTLSKey(*tlsKeyFile, *tlsCertFile); err != nil {
|
if err := test.NewTLSKey(*tlsKeyFile, *tlsCertFile, *keySize); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// generate the TLS cert/key based on the authority given.
|
// generate the TLS cert/key based on the authority given.
|
||||||
if err := test.NewTLSKeyWithAuthority(*serverName, *tlsKeyFile, *tlsCertFile, *authorityKeyFile, *authorityCertFile); err != nil {
|
if err := test.NewTLSKeyWithAuthority(*serverName, *tlsKeyFile, *tlsCertFile, *authorityKeyFile, *authorityCertFile, *keySize); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,12 @@ func SendJoin(
|
||||||
JSON: jsonerror.NotFound("Room does not exist"),
|
JSON: jsonerror.NotFound("Room does not exist"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !stateAndAuthChainResponse.StateKnown {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusForbidden,
|
||||||
|
JSON: jsonerror.Forbidden("State not known"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the user is already in the room. If they're already in then
|
// Check if the user is already in the room. If they're already in then
|
||||||
// there isn't much point in sending another join event into the room.
|
// there isn't much point in sending another join event into the room.
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,12 @@ func getState(
|
||||||
return nil, nil, &resErr
|
return nil, nil, &resErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !response.StateKnown {
|
||||||
|
return nil, nil, &util.JSONResponse{
|
||||||
|
Code: http.StatusNotFound,
|
||||||
|
JSON: jsonerror.NotFound("State not known"),
|
||||||
|
}
|
||||||
|
}
|
||||||
if response.IsRejected {
|
if response.IsRejected {
|
||||||
return nil, nil, &util.JSONResponse{
|
return nil, nil, &util.JSONResponse{
|
||||||
Code: http.StatusNotFound,
|
Code: http.StatusNotFound,
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,11 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/federationapi/storage"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"go.uber.org/atomic"
|
"go.uber.org/atomic"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/federationapi/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Statistics contains information about all of the remote federated
|
// Statistics contains information about all of the remote federated
|
||||||
|
|
@ -126,13 +127,13 @@ func (s *ServerStatistics) Failure() (time.Time, bool) {
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
until, ok := s.backoffUntil.Load().(time.Time)
|
until, ok := s.backoffUntil.Load().(time.Time)
|
||||||
if ok {
|
if ok && !until.IsZero() {
|
||||||
select {
|
select {
|
||||||
case <-time.After(time.Until(until)):
|
case <-time.After(time.Until(until)):
|
||||||
case <-s.interrupt:
|
case <-s.interrupt:
|
||||||
}
|
}
|
||||||
|
s.backoffStarted.Store(false)
|
||||||
}
|
}
|
||||||
s.backoffStarted.Store(false)
|
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -22,7 +22,7 @@ require (
|
||||||
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e
|
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e
|
||||||
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91
|
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16
|
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20220815094957-74b7ff4ae09c
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20220824082345-662dca17bf94
|
||||||
github.com/matrix-org/pinecone v0.0.0-20220803093810-b7a830c08fb9
|
github.com/matrix-org/pinecone v0.0.0-20220803093810-b7a830c08fb9
|
||||||
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
|
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
|
||||||
github.com/matryer/is v1.4.0
|
github.com/matryer/is v1.4.0
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -343,8 +343,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91/go.mod h1
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
|
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 h1:ZtO5uywdd5dLDCud4r0r55eP4j9FuUNpl60Gmntcop4=
|
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 h1:ZtO5uywdd5dLDCud4r0r55eP4j9FuUNpl60Gmntcop4=
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20220815094957-74b7ff4ae09c h1:GhKmb8s9iXA9qsFD1SbiRo6Ee7cnbfcgJQ/iy43wczM=
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20220824082345-662dca17bf94 h1:zoTv/qxg7C/O995JBPvp+Z8KMR69HhB+M+P22A8Hmm0=
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20220815094957-74b7ff4ae09c/go.mod h1:jX38yp3SSLJNftBg3PXU1ayd0PCLIiDHQ4xAc9DIixk=
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20220824082345-662dca17bf94/go.mod h1:jX38yp3SSLJNftBg3PXU1ayd0PCLIiDHQ4xAc9DIixk=
|
||||||
github.com/matrix-org/pinecone v0.0.0-20220803093810-b7a830c08fb9 h1:ed8yvWhTLk7+sNeK/eOZRTvESFTOHDRevoRoyeqPtvY=
|
github.com/matrix-org/pinecone v0.0.0-20220803093810-b7a830c08fb9 h1:ed8yvWhTLk7+sNeK/eOZRTvESFTOHDRevoRoyeqPtvY=
|
||||||
github.com/matrix-org/pinecone v0.0.0-20220803093810-b7a830c08fb9/go.mod h1:P4MqPf+u83OPulPJ+XTbSDbbWrdFYNY4LZ/B1PIduFE=
|
github.com/matrix-org/pinecone v0.0.0-20220803093810-b7a830c08fb9/go.mod h1:P4MqPf+u83OPulPJ+XTbSDbbWrdFYNY4LZ/B1PIduFE=
|
||||||
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
|
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ var build string
|
||||||
const (
|
const (
|
||||||
VersionMajor = 0
|
VersionMajor = 0
|
||||||
VersionMinor = 9
|
VersionMinor = 9
|
||||||
VersionPatch = 4
|
VersionPatch = 5
|
||||||
VersionTag = "" // example: "rc1"
|
VersionTag = "" // example: "rc1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,7 @@ type QueryStateAndAuthChainResponse struct {
|
||||||
// Do all the previous events exist on this roomserver?
|
// Do all the previous events exist on this roomserver?
|
||||||
// If some of previous events do not exist this will be false and StateEvents will be empty.
|
// If some of previous events do not exist this will be false and StateEvents will be empty.
|
||||||
PrevEventsExist bool `json:"prev_events_exist"`
|
PrevEventsExist bool `json:"prev_events_exist"`
|
||||||
|
StateKnown bool `json:"state_known"`
|
||||||
// The state and auth chain events that were requested.
|
// The state and auth chain events that were requested.
|
||||||
// The lists will be in an arbitrary order.
|
// The lists will be in an arbitrary order.
|
||||||
StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"`
|
StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"`
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import (
|
||||||
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SendEvents to the roomserver The events are written with KindNew.
|
// SendEvents to the roomserver The events are written with KindNew.
|
||||||
|
|
@ -69,6 +70,13 @@ func SendEventWithState(
|
||||||
stateEventIDs[i] = stateEvents[i].EventID()
|
stateEventIDs[i] = stateEvents[i].EventID()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logrus.WithContext(ctx).WithFields(logrus.Fields{
|
||||||
|
"room_id": event.RoomID(),
|
||||||
|
"event_id": event.EventID(),
|
||||||
|
"outliers": len(ires),
|
||||||
|
"state_ids": len(stateEventIDs),
|
||||||
|
}).Infof("Submitting %q event to roomserver with state snapshot", event.Type())
|
||||||
|
|
||||||
ires = append(ires, InputRoomEvent{
|
ires = append(ires, InputRoomEvent{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Event: event,
|
Event: event,
|
||||||
|
|
|
||||||
|
|
@ -254,8 +254,15 @@ func CheckServerAllowedToSeeEvent(
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// Something else went wrong
|
switch err.(type) {
|
||||||
return false, err
|
case types.MissingStateError:
|
||||||
|
// If there's no state then we assume it's open visibility, as Synapse does:
|
||||||
|
// https://github.com/matrix-org/synapse/blob/aec87a0f9369a3015b2a53469f88d1de274e8b71/synapse/visibility.py#L654-L655
|
||||||
|
return true, nil
|
||||||
|
default:
|
||||||
|
// Something else went wrong
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return auth.IsServerAllowed(serverName, isServerInRoom, stateAtEvent), nil
|
return auth.IsServerAllowed(serverName, isServerInRoom, stateAtEvent), nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/roomserver/internal/query"
|
"github.com/matrix-org/dendrite/roomserver/internal/query"
|
||||||
"github.com/matrix-org/dendrite/roomserver/producers"
|
"github.com/matrix-org/dendrite/roomserver/producers"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage"
|
"github.com/matrix-org/dendrite/roomserver/storage"
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/types"
|
||||||
"github.com/matrix-org/dendrite/setup/base"
|
"github.com/matrix-org/dendrite/setup/base"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/setup/jetstream"
|
"github.com/matrix-org/dendrite/setup/jetstream"
|
||||||
|
|
@ -247,14 +248,24 @@ func (w *worker) _next() {
|
||||||
// it was a synchronous request.
|
// it was a synchronous request.
|
||||||
var errString string
|
var errString string
|
||||||
if err = w.r.processRoomEvent(w.r.ProcessContext.Context(), &inputRoomEvent); err != nil {
|
if err = w.r.processRoomEvent(w.r.ProcessContext.Context(), &inputRoomEvent); err != nil {
|
||||||
if !errors.Is(err, context.DeadlineExceeded) && !errors.Is(err, context.Canceled) {
|
switch err.(type) {
|
||||||
sentry.CaptureException(err)
|
case types.RejectedError:
|
||||||
|
// Don't send events that were rejected to Sentry
|
||||||
|
logrus.WithError(err).WithFields(logrus.Fields{
|
||||||
|
"room_id": w.roomID,
|
||||||
|
"event_id": inputRoomEvent.Event.EventID(),
|
||||||
|
"type": inputRoomEvent.Event.Type(),
|
||||||
|
}).Warn("Roomserver rejected event")
|
||||||
|
default:
|
||||||
|
if !errors.Is(err, context.DeadlineExceeded) && !errors.Is(err, context.Canceled) {
|
||||||
|
sentry.CaptureException(err)
|
||||||
|
}
|
||||||
|
logrus.WithError(err).WithFields(logrus.Fields{
|
||||||
|
"room_id": w.roomID,
|
||||||
|
"event_id": inputRoomEvent.Event.EventID(),
|
||||||
|
"type": inputRoomEvent.Event.Type(),
|
||||||
|
}).Warn("Roomserver failed to process event")
|
||||||
}
|
}
|
||||||
logrus.WithError(err).WithFields(logrus.Fields{
|
|
||||||
"room_id": w.roomID,
|
|
||||||
"event_id": inputRoomEvent.Event.EventID(),
|
|
||||||
"type": inputRoomEvent.Event.Type(),
|
|
||||||
}).Warn("Roomserver failed to process async event")
|
|
||||||
_ = msg.Term()
|
_ = msg.Term()
|
||||||
errString = err.Error()
|
errString = err.Error()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,7 @@ func (r *Inputer) processRoomEvent(
|
||||||
// bother doing this if the event was already rejected as it just ends up
|
// bother doing this if the event was already rejected as it just ends up
|
||||||
// burning CPU time.
|
// burning CPU time.
|
||||||
historyVisibility := gomatrixserverlib.HistoryVisibilityShared // Default to shared.
|
historyVisibility := gomatrixserverlib.HistoryVisibilityShared // Default to shared.
|
||||||
if input.Kind != api.KindOutlier && rejectionErr == nil && !isRejected && !softfail {
|
if input.Kind != api.KindOutlier && rejectionErr == nil && !isRejected {
|
||||||
var err error
|
var err error
|
||||||
historyVisibility, rejectionErr, err = r.processStateBefore(ctx, input, missingPrev)
|
historyVisibility, rejectionErr, err = r.processStateBefore(ctx, input, missingPrev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -313,7 +313,7 @@ func (r *Inputer) processRoomEvent(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the event.
|
// Store the event.
|
||||||
_, _, stateAtEvent, redactionEvent, redactedEventID, err := r.DB.StoreEvent(ctx, event, authEventNIDs, isRejected || softfail)
|
_, _, stateAtEvent, redactionEvent, redactedEventID, err := r.DB.StoreEvent(ctx, event, authEventNIDs, isRejected)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("updater.StoreEvent: %w", err)
|
return fmt.Errorf("updater.StoreEvent: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -353,14 +353,18 @@ func (r *Inputer) processRoomEvent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We stop here if the event is rejected: We've stored it but won't update forward extremities or notify anyone about it.
|
// We stop here if the event is rejected: We've stored it but won't update
|
||||||
if isRejected || softfail {
|
// forward extremities or notify downstream components about it.
|
||||||
logger.WithError(rejectionErr).WithFields(logrus.Fields{
|
switch {
|
||||||
"room_id": event.RoomID(),
|
case isRejected:
|
||||||
"event_id": event.EventID(),
|
logger.WithError(rejectionErr).Warn("Stored rejected event")
|
||||||
"soft_fail": softfail,
|
if rejectionErr != nil {
|
||||||
"missing_prev": missingPrev,
|
return types.RejectedError(rejectionErr.Error())
|
||||||
}).Warn("Stored rejected event")
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case softfail:
|
||||||
|
logger.WithError(rejectionErr).Warn("Stored soft-failed event")
|
||||||
if rejectionErr != nil {
|
if rejectionErr != nil {
|
||||||
return types.RejectedError(rejectionErr.Error())
|
return types.RejectedError(rejectionErr.Error())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/getsentry/sentry-go"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
@ -320,7 +319,6 @@ FederationHit:
|
||||||
b.eventIDToBeforeStateIDs[targetEvent.EventID()] = res
|
b.eventIDToBeforeStateIDs[targetEvent.EventID()] = res
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
sentry.CaptureException(lastErr) // temporary to see if we might need to raise the server limit
|
|
||||||
return nil, lastErr
|
return nil, lastErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -398,7 +396,6 @@ func (b *backfillRequester) StateBeforeEvent(ctx context.Context, roomVer gomatr
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
sentry.CaptureException(lastErr) // temporary to see if we might need to raise the server limit
|
|
||||||
return nil, lastErr
|
return nil, lastErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -509,10 +509,11 @@ func (r *Queryer) QueryStateAndAuthChain(
|
||||||
}
|
}
|
||||||
|
|
||||||
var stateEvents []*gomatrixserverlib.Event
|
var stateEvents []*gomatrixserverlib.Event
|
||||||
stateEvents, rejected, err := r.loadStateAtEventIDs(ctx, info, request.PrevEventIDs)
|
stateEvents, rejected, stateMissing, err := r.loadStateAtEventIDs(ctx, info, request.PrevEventIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
response.StateKnown = !stateMissing
|
||||||
response.IsRejected = rejected
|
response.IsRejected = rejected
|
||||||
response.PrevEventsExist = true
|
response.PrevEventsExist = true
|
||||||
|
|
||||||
|
|
@ -548,15 +549,18 @@ func (r *Queryer) QueryStateAndAuthChain(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Queryer) loadStateAtEventIDs(ctx context.Context, roomInfo *types.RoomInfo, eventIDs []string) ([]*gomatrixserverlib.Event, bool, error) {
|
// first bool: is rejected, second bool: state missing
|
||||||
|
func (r *Queryer) loadStateAtEventIDs(ctx context.Context, roomInfo *types.RoomInfo, eventIDs []string) ([]*gomatrixserverlib.Event, bool, bool, error) {
|
||||||
roomState := state.NewStateResolution(r.DB, roomInfo)
|
roomState := state.NewStateResolution(r.DB, roomInfo)
|
||||||
prevStates, err := r.DB.StateAtEventIDs(ctx, eventIDs)
|
prevStates, err := r.DB.StateAtEventIDs(ctx, eventIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case types.MissingEventError:
|
case types.MissingEventError:
|
||||||
return nil, false, nil
|
return nil, false, true, nil
|
||||||
|
case types.MissingStateError:
|
||||||
|
return nil, false, true, nil
|
||||||
default:
|
default:
|
||||||
return nil, false, err
|
return nil, false, false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Currently only used on /state and /state_ids
|
// Currently only used on /state and /state_ids
|
||||||
|
|
@ -573,12 +577,11 @@ func (r *Queryer) loadStateAtEventIDs(ctx context.Context, roomInfo *types.RoomI
|
||||||
ctx, prevStates,
|
ctx, prevStates,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rejected, err
|
return nil, rejected, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
events, err := helpers.LoadStateEvents(ctx, r.DB, stateEntries)
|
events, err := helpers.LoadStateEvents(ctx, r.DB, stateEntries)
|
||||||
|
return events, rejected, false, err
|
||||||
return events, rejected, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type eventsFromIDs func(context.Context, []string) ([]types.Event, error)
|
type eventsFromIDs func(context.Context, []string) ([]types.Event, error)
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ const insertEventSQL = "" +
|
||||||
"INSERT INTO roomserver_events AS e (room_nid, event_type_nid, event_state_key_nid, event_id, reference_sha256, auth_event_nids, depth, is_rejected)" +
|
"INSERT INTO roomserver_events AS e (room_nid, event_type_nid, event_state_key_nid, event_id, reference_sha256, auth_event_nids, depth, is_rejected)" +
|
||||||
" VALUES ($1, $2, $3, $4, $5, $6, $7, $8)" +
|
" VALUES ($1, $2, $3, $4, $5, $6, $7, $8)" +
|
||||||
" ON CONFLICT ON CONSTRAINT roomserver_event_id_unique DO UPDATE" +
|
" ON CONFLICT ON CONSTRAINT roomserver_event_id_unique DO UPDATE" +
|
||||||
" SET is_rejected = $8 WHERE e.event_id = $4 AND e.is_rejected = FALSE" +
|
" SET is_rejected = $8 WHERE e.event_id = $4 AND e.is_rejected = TRUE" +
|
||||||
" RETURNING event_nid, state_snapshot_nid"
|
" RETURNING event_nid, state_snapshot_nid"
|
||||||
|
|
||||||
const selectEventSQL = "" +
|
const selectEventSQL = "" +
|
||||||
|
|
@ -346,7 +346,7 @@ func (s *eventStatements) BulkSelectStateAtEventByID(
|
||||||
// Genuine create events are the only case where it's OK to have no previous state.
|
// Genuine create events are the only case where it's OK to have no previous state.
|
||||||
isCreate := result.EventTypeNID == types.MRoomCreateNID && result.EventStateKeyNID == 1
|
isCreate := result.EventTypeNID == types.MRoomCreateNID && result.EventStateKeyNID == 1
|
||||||
if result.BeforeStateSnapshotNID == 0 && !isCreate {
|
if result.BeforeStateSnapshotNID == 0 && !isCreate {
|
||||||
return nil, types.MissingEventError(
|
return nil, types.MissingStateError(
|
||||||
fmt.Sprintf("storage: missing state for event NID %d", result.EventNID),
|
fmt.Sprintf("storage: missing state for event NID %d", result.EventNID),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ const insertEventSQL = `
|
||||||
INSERT INTO roomserver_events (room_nid, event_type_nid, event_state_key_nid, event_id, reference_sha256, auth_event_nids, depth, is_rejected)
|
INSERT INTO roomserver_events (room_nid, event_type_nid, event_state_key_nid, event_id, reference_sha256, auth_event_nids, depth, is_rejected)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||||
ON CONFLICT DO UPDATE
|
ON CONFLICT DO UPDATE
|
||||||
SET is_rejected = $8 WHERE is_rejected = 0
|
SET is_rejected = $8 WHERE is_rejected = 1
|
||||||
RETURNING event_nid, state_snapshot_nid;
|
RETURNING event_nid, state_snapshot_nid;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -362,7 +362,7 @@ func (s *eventStatements) BulkSelectStateAtEventByID(
|
||||||
// Genuine create events are the only case where it's OK to have no previous state.
|
// Genuine create events are the only case where it's OK to have no previous state.
|
||||||
isCreate := result.EventTypeNID == types.MRoomCreateNID && result.EventStateKeyNID == 1
|
isCreate := result.EventTypeNID == types.MRoomCreateNID && result.EventStateKeyNID == 1
|
||||||
if result.BeforeStateSnapshotNID == 0 && !isCreate {
|
if result.BeforeStateSnapshotNID == 0 && !isCreate {
|
||||||
return nil, types.MissingEventError(
|
return nil, types.MissingStateError(
|
||||||
fmt.Sprintf("storage: missing state for event NID %d", result.EventNID),
|
fmt.Sprintf("storage: missing state for event NID %d", result.EventNID),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,16 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/matrix-org/util"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
|
||||||
keyapi "github.com/matrix-org/dendrite/keyserver/api"
|
keyapi "github.com/matrix-org/dendrite/keyserver/api"
|
||||||
keytypes "github.com/matrix-org/dendrite/keyserver/types"
|
keytypes "github.com/matrix-org/dendrite/keyserver/types"
|
||||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/syncapi/storage"
|
"github.com/matrix-org/dendrite/syncapi/storage"
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
"github.com/matrix-org/util"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeviceOTKCounts adds one-time key counts to the /sync response
|
// DeviceOTKCounts adds one-time key counts to the /sync response
|
||||||
|
|
@ -125,7 +127,7 @@ func DeviceListCatchup(
|
||||||
"from": offset,
|
"from": offset,
|
||||||
"to": toOffset,
|
"to": toOffset,
|
||||||
"response_offset": queryRes.Offset,
|
"response_offset": queryRes.Offset,
|
||||||
}).Debugf("QueryKeyChanges request result: %+v", res.DeviceLists)
|
}).Tracef("QueryKeyChanges request result: %+v", res.DeviceLists)
|
||||||
|
|
||||||
return types.StreamPosition(queryRes.Offset), hasNew, nil
|
return types.StreamPosition(queryRes.Offset), hasNew, nil
|
||||||
}
|
}
|
||||||
|
|
@ -277,6 +279,10 @@ func membershipEventPresent(events []gomatrixserverlib.ClientEvent, userID strin
|
||||||
// it's enough to know that we have our member event here, don't need to check membership content
|
// it's enough to know that we have our member event here, don't need to check membership content
|
||||||
// as it's implied by being in the respective section of the sync response.
|
// as it's implied by being in the respective section of the sync response.
|
||||||
if ev.Type == gomatrixserverlib.MRoomMember && ev.StateKey != nil && *ev.StateKey == userID {
|
if ev.Type == gomatrixserverlib.MRoomMember && ev.StateKey != nil && *ev.StateKey == userID {
|
||||||
|
// ignore e.g. join -> join changes
|
||||||
|
if gjson.GetBytes(ev.Unsigned, "prev_content.membership").Str == gjson.GetBytes(ev.Content, "membership").Str {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,11 @@ import (
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||||
|
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Database interface {
|
type Database interface {
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,18 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
|
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/syncapi/storage/tables"
|
"github.com/matrix-org/dendrite/syncapi/storage/tables"
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Database is a temporary struct until we have made syncserver.go the same for both pq/sqlite
|
// Database is a temporary struct until we have made syncserver.go the same for both pq/sqlite
|
||||||
|
|
@ -683,7 +686,7 @@ func (d *Database) GetStateDeltas(
|
||||||
ctx context.Context, device *userapi.Device,
|
ctx context.Context, device *userapi.Device,
|
||||||
r types.Range, userID string,
|
r types.Range, userID string,
|
||||||
stateFilter *gomatrixserverlib.StateFilter,
|
stateFilter *gomatrixserverlib.StateFilter,
|
||||||
) ([]types.StateDelta, []string, error) {
|
) (deltas []types.StateDelta, joinedRoomsIDs []string, err error) {
|
||||||
// Implement membership change algorithm: https://github.com/matrix-org/synapse/blob/v0.19.3/synapse/handlers/sync.py#L821
|
// Implement membership change algorithm: https://github.com/matrix-org/synapse/blob/v0.19.3/synapse/handlers/sync.py#L821
|
||||||
// - Get membership list changes for this user in this sync response
|
// - Get membership list changes for this user in this sync response
|
||||||
// - For each room which has membership list changes:
|
// - For each room which has membership list changes:
|
||||||
|
|
@ -718,8 +721,6 @@ func (d *Database) GetStateDeltas(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var deltas []types.StateDelta
|
|
||||||
|
|
||||||
// get all the state events ever (i.e. for all available rooms) between these two positions
|
// get all the state events ever (i.e. for all available rooms) between these two positions
|
||||||
stateNeeded, eventMap, err := d.OutputEvents.SelectStateInRange(ctx, txn, r, stateFilter, allRoomIDs)
|
stateNeeded, eventMap, err := d.OutputEvents.SelectStateInRange(ctx, txn, r, stateFilter, allRoomIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -767,15 +768,11 @@ func (d *Database) GetStateDeltas(
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle newly joined rooms and non-joined rooms
|
// handle newly joined rooms and non-joined rooms
|
||||||
|
newlyJoinedRooms := make(map[string]bool, len(state))
|
||||||
for roomID, stateStreamEvents := range state {
|
for roomID, stateStreamEvents := range state {
|
||||||
for _, ev := range stateStreamEvents {
|
for _, ev := range stateStreamEvents {
|
||||||
// TODO: Currently this will incorrectly add rooms which were ALREADY joined but they sent another no-op join event.
|
if membership, prevMembership := getMembershipFromEvent(ev.Event, userID); membership != "" {
|
||||||
// We should be checking if the user was already joined at fromPos and not proceed if so. As a result of this,
|
if membership == gomatrixserverlib.Join && prevMembership != membership {
|
||||||
// dupe join events will result in the entire room state coming down to the client again. This is added in
|
|
||||||
// the 'state' part of the response though, so is transparent modulo bandwidth concerns as it is not added to
|
|
||||||
// the timeline.
|
|
||||||
if membership := getMembershipFromEvent(ev.Event, userID); membership != "" {
|
|
||||||
if membership == gomatrixserverlib.Join {
|
|
||||||
// send full room state down instead of a delta
|
// send full room state down instead of a delta
|
||||||
var s []types.StreamEvent
|
var s []types.StreamEvent
|
||||||
s, err = d.currentStateStreamEventsForRoom(ctx, txn, roomID, stateFilter)
|
s, err = d.currentStateStreamEventsForRoom(ctx, txn, roomID, stateFilter)
|
||||||
|
|
@ -786,6 +783,7 @@ func (d *Database) GetStateDeltas(
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
state[roomID] = s
|
state[roomID] = s
|
||||||
|
newlyJoinedRooms[roomID] = true
|
||||||
continue // we'll add this room in when we do joined rooms
|
continue // we'll add this room in when we do joined rooms
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -806,6 +804,7 @@ func (d *Database) GetStateDeltas(
|
||||||
Membership: gomatrixserverlib.Join,
|
Membership: gomatrixserverlib.Join,
|
||||||
StateEvents: d.StreamEventsToEvents(device, state[joinedRoomID]),
|
StateEvents: d.StreamEventsToEvents(device, state[joinedRoomID]),
|
||||||
RoomID: joinedRoomID,
|
RoomID: joinedRoomID,
|
||||||
|
NewlyJoined: newlyJoinedRooms[joinedRoomID],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -892,7 +891,7 @@ func (d *Database) GetStateDeltasForFullStateSync(
|
||||||
|
|
||||||
for roomID, stateStreamEvents := range state {
|
for roomID, stateStreamEvents := range state {
|
||||||
for _, ev := range stateStreamEvents {
|
for _, ev := range stateStreamEvents {
|
||||||
if membership := getMembershipFromEvent(ev.Event, userID); membership != "" {
|
if membership, _ := getMembershipFromEvent(ev.Event, userID); membership != "" {
|
||||||
if membership != gomatrixserverlib.Join { // We've already added full state for all joined rooms above.
|
if membership != gomatrixserverlib.Join { // We've already added full state for all joined rooms above.
|
||||||
deltas[roomID] = types.StateDelta{
|
deltas[roomID] = types.StateDelta{
|
||||||
Membership: membership,
|
Membership: membership,
|
||||||
|
|
@ -1003,15 +1002,16 @@ func (d *Database) CleanSendToDeviceUpdates(
|
||||||
|
|
||||||
// getMembershipFromEvent returns the value of content.membership iff the event is a state event
|
// getMembershipFromEvent returns the value of content.membership iff the event is a state event
|
||||||
// with type 'm.room.member' and state_key of userID. Otherwise, an empty string is returned.
|
// with type 'm.room.member' and state_key of userID. Otherwise, an empty string is returned.
|
||||||
func getMembershipFromEvent(ev *gomatrixserverlib.Event, userID string) string {
|
func getMembershipFromEvent(ev *gomatrixserverlib.Event, userID string) (string, string) {
|
||||||
if ev.Type() != "m.room.member" || !ev.StateKeyEquals(userID) {
|
if ev.Type() != "m.room.member" || !ev.StateKeyEquals(userID) {
|
||||||
return ""
|
return "", ""
|
||||||
}
|
}
|
||||||
membership, err := ev.Membership()
|
membership, err := ev.Membership()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return "", ""
|
||||||
}
|
}
|
||||||
return membership
|
prevMembership := gjson.GetBytes(ev.Unsigned(), "prev_content.membership").Str
|
||||||
|
return membership, prevMembership
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreReceipt stores user receipts
|
// StoreReceipt stores user receipts
|
||||||
|
|
|
||||||
|
|
@ -178,24 +178,24 @@ func (p *PDUStreamProvider) IncrementalSync(
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var stateDeltas []types.StateDelta
|
var stateDeltas []types.StateDelta
|
||||||
var joinedRooms []string
|
var syncJoinedRooms []string
|
||||||
|
|
||||||
stateFilter := req.Filter.Room.State
|
stateFilter := req.Filter.Room.State
|
||||||
eventFilter := req.Filter.Room.Timeline
|
eventFilter := req.Filter.Room.Timeline
|
||||||
|
|
||||||
if req.WantFullState {
|
if req.WantFullState {
|
||||||
if stateDeltas, joinedRooms, err = p.DB.GetStateDeltasForFullStateSync(ctx, req.Device, r, req.Device.UserID, &stateFilter); err != nil {
|
if stateDeltas, syncJoinedRooms, err = p.DB.GetStateDeltasForFullStateSync(ctx, req.Device, r, req.Device.UserID, &stateFilter); err != nil {
|
||||||
req.Log.WithError(err).Error("p.DB.GetStateDeltasForFullStateSync failed")
|
req.Log.WithError(err).Error("p.DB.GetStateDeltasForFullStateSync failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if stateDeltas, joinedRooms, err = p.DB.GetStateDeltas(ctx, req.Device, r, req.Device.UserID, &stateFilter); err != nil {
|
if stateDeltas, syncJoinedRooms, err = p.DB.GetStateDeltas(ctx, req.Device, r, req.Device.UserID, &stateFilter); err != nil {
|
||||||
req.Log.WithError(err).Error("p.DB.GetStateDeltas failed")
|
req.Log.WithError(err).Error("p.DB.GetStateDeltas failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, roomID := range joinedRooms {
|
for _, roomID := range syncJoinedRooms {
|
||||||
req.Rooms[roomID] = gomatrixserverlib.Join
|
req.Rooms[roomID] = gomatrixserverlib.Join
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -209,11 +209,27 @@ func (p *PDUStreamProvider) IncrementalSync(
|
||||||
|
|
||||||
newPos = from
|
newPos = from
|
||||||
for _, delta := range stateDeltas {
|
for _, delta := range stateDeltas {
|
||||||
|
newRange := r
|
||||||
|
// If this room was joined in this sync, try to fetch
|
||||||
|
// as much timeline events as allowed by the filter.
|
||||||
|
if delta.NewlyJoined {
|
||||||
|
// Reverse the range, so we get the most recent first.
|
||||||
|
// This will be limited by the eventFilter.
|
||||||
|
newRange = types.Range{
|
||||||
|
From: r.To,
|
||||||
|
To: 0,
|
||||||
|
Backwards: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
var pos types.StreamPosition
|
var pos types.StreamPosition
|
||||||
if pos, err = p.addRoomDeltaToResponse(ctx, req.Device, r, delta, &eventFilter, &stateFilter, req.Response); err != nil {
|
if pos, err = p.addRoomDeltaToResponse(ctx, req.Device, newRange, delta, &eventFilter, &stateFilter, req.Response); err != nil {
|
||||||
req.Log.WithError(err).Error("d.addRoomDeltaToResponse failed")
|
req.Log.WithError(err).Error("d.addRoomDeltaToResponse failed")
|
||||||
return to
|
return to
|
||||||
}
|
}
|
||||||
|
// Reset the position, as it is only for the special case of newly joined rooms
|
||||||
|
if delta.NewlyJoined {
|
||||||
|
pos = newRange.From
|
||||||
|
}
|
||||||
switch {
|
switch {
|
||||||
case r.Backwards && pos < newPos:
|
case r.Backwards && pos < newPos:
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
@ -309,12 +325,12 @@ func (p *PDUStreamProvider) addRoomDeltaToResponse(
|
||||||
logrus.WithError(err).Error("unable to apply history visibility filter")
|
logrus.WithError(err).Error("unable to apply history visibility filter")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(events) > 0 {
|
|
||||||
updateLatestPosition(events[len(events)-1].EventID())
|
|
||||||
}
|
|
||||||
if len(delta.StateEvents) > 0 {
|
if len(delta.StateEvents) > 0 {
|
||||||
updateLatestPosition(delta.StateEvents[len(delta.StateEvents)-1].EventID())
|
updateLatestPosition(delta.StateEvents[len(delta.StateEvents)-1].EventID())
|
||||||
}
|
}
|
||||||
|
if len(events) > 0 {
|
||||||
|
updateLatestPosition(events[len(events)-1].EventID())
|
||||||
|
}
|
||||||
|
|
||||||
switch delta.Membership {
|
switch delta.Membership {
|
||||||
case gomatrixserverlib.Join:
|
case gomatrixserverlib.Join:
|
||||||
|
|
@ -387,6 +403,8 @@ func applyHistoryVisibilityFilter(
|
||||||
logrus.WithFields(logrus.Fields{
|
logrus.WithFields(logrus.Fields{
|
||||||
"duration": time.Since(startTime),
|
"duration": time.Since(startTime),
|
||||||
"room_id": roomID,
|
"room_id": roomID,
|
||||||
|
"before": len(recentEvents),
|
||||||
|
"after": len(events),
|
||||||
}).Debug("applied history visibility (sync)")
|
}).Debug("applied history visibility (sync)")
|
||||||
return events, nil
|
return events, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,11 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/syncapi/notifier"
|
"github.com/matrix-org/dendrite/syncapi/notifier"
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type PresenceStreamProvider struct {
|
type PresenceStreamProvider struct {
|
||||||
|
|
@ -159,6 +161,10 @@ func membershipEventPresent(events []gomatrixserverlib.ClientEvent, userID strin
|
||||||
// it's enough to know that we have our member event here, don't need to check membership content
|
// it's enough to know that we have our member event here, don't need to check membership content
|
||||||
// as it's implied by being in the respective section of the sync response.
|
// as it's implied by being in the respective section of the sync response.
|
||||||
if ev.Type == gomatrixserverlib.MRoomMember && ev.StateKey != nil && *ev.StateKey == userID {
|
if ev.Type == gomatrixserverlib.MRoomMember && ev.StateKey != nil && *ev.StateKey == userID {
|
||||||
|
// ignore e.g. join -> join changes
|
||||||
|
if gjson.GetBytes(ev.Unsigned, "prev_content.membership").Str == gjson.GetBytes(ev.Content, "membership").Str {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,13 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/syncapi/storage"
|
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/syncapi/storage"
|
||||||
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultSyncTimeout = time.Duration(0)
|
const defaultSyncTimeout = time.Duration(0)
|
||||||
|
|
@ -46,15 +47,9 @@ func newSyncRequest(req *http.Request, device userapi.Device, syncDB storage.Dat
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: read from stored filters too
|
|
||||||
|
// Create a default filter and apply a stored filter on top of it (if specified)
|
||||||
filter := gomatrixserverlib.DefaultFilter()
|
filter := gomatrixserverlib.DefaultFilter()
|
||||||
if since.IsEmpty() {
|
|
||||||
// Send as much account data down for complete syncs as possible
|
|
||||||
// by default, otherwise clients do weird things while waiting
|
|
||||||
// for the rest of the data to trickle down.
|
|
||||||
filter.AccountData.Limit = math.MaxInt32
|
|
||||||
filter.Room.AccountData.Limit = math.MaxInt32
|
|
||||||
}
|
|
||||||
filterQuery := req.URL.Query().Get("filter")
|
filterQuery := req.URL.Query().Get("filter")
|
||||||
if filterQuery != "" {
|
if filterQuery != "" {
|
||||||
if filterQuery[0] == '{' {
|
if filterQuery[0] == '{' {
|
||||||
|
|
@ -76,6 +71,17 @@ func newSyncRequest(req *http.Request, device userapi.Device, syncDB storage.Dat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A loaded filter might have overwritten these values,
|
||||||
|
// so set them after loading the filter.
|
||||||
|
if since.IsEmpty() {
|
||||||
|
// Send as much account data down for complete syncs as possible
|
||||||
|
// by default, otherwise clients do weird things while waiting
|
||||||
|
// for the rest of the data to trickle down.
|
||||||
|
filter.AccountData.Limit = math.MaxInt32
|
||||||
|
filter.Room.AccountData.Limit = math.MaxInt32
|
||||||
|
filter.Room.State.Limit = math.MaxInt32
|
||||||
|
}
|
||||||
|
|
||||||
logger := util.GetLogger(req.Context()).WithFields(logrus.Fields{
|
logger := util.GetLogger(req.Context()).WithFields(logrus.Fields{
|
||||||
"user_id": device.UserID,
|
"user_id": device.UserID,
|
||||||
"device_id": device.ID,
|
"device_id": device.ID,
|
||||||
|
|
|
||||||
|
|
@ -307,8 +307,8 @@ func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *userapi.
|
||||||
return giveup()
|
return giveup()
|
||||||
|
|
||||||
case <-userStreamListener.GetNotifyChannel(syncReq.Since):
|
case <-userStreamListener.GetNotifyChannel(syncReq.Since):
|
||||||
syncReq.Log.Debugln("Responding to sync after wake-up")
|
|
||||||
currentPos.ApplyUpdates(userStreamListener.GetSyncPosition())
|
currentPos.ApplyUpdates(userStreamListener.GetSyncPosition())
|
||||||
|
syncReq.Log.WithField("currentPos", currentPos).Debugln("Responding to sync after wake-up")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
syncReq.Log.WithField("currentPos", currentPos).Debugln("Responding to sync immediately")
|
syncReq.Log.WithField("currentPos", currentPos).Debugln("Responding to sync immediately")
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,7 @@ func TestSyncAPICreateRoomSyncEarly(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSyncAPICreateRoomSyncEarly(t *testing.T, dbType test.DBType) {
|
func testSyncAPICreateRoomSyncEarly(t *testing.T, dbType test.DBType) {
|
||||||
|
t.Skip("Skipped, possibly fixed")
|
||||||
user := test.NewUser(t)
|
user := test.NewUser(t)
|
||||||
room := test.NewRoom(t, user)
|
room := test.NewRoom(t, user)
|
||||||
alice := userapi.Device{
|
alice := userapi.Device{
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ var (
|
||||||
type StateDelta struct {
|
type StateDelta struct {
|
||||||
RoomID string
|
RoomID string
|
||||||
StateEvents []*gomatrixserverlib.HeaderedEvent
|
StateEvents []*gomatrixserverlib.HeaderedEvent
|
||||||
|
NewlyJoined bool
|
||||||
Membership string
|
Membership string
|
||||||
// The PDU stream position of the latest membership event for this user, if applicable.
|
// The PDU stream position of the latest membership event for this user, if applicable.
|
||||||
// Can be 0 if there is no membership event in this delta.
|
// Can be 0 if there is no membership event in this delta.
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ func ListenAndServe(t *testing.T, router http.Handler, withTLS bool) (apiURL str
|
||||||
if withTLS {
|
if withTLS {
|
||||||
certFile := filepath.Join(t.TempDir(), "dendrite.cert")
|
certFile := filepath.Join(t.TempDir(), "dendrite.cert")
|
||||||
keyFile := filepath.Join(t.TempDir(), "dendrite.key")
|
keyFile := filepath.Join(t.TempDir(), "dendrite.key")
|
||||||
err = NewTLSKey(keyFile, certFile)
|
err = NewTLSKey(keyFile, certFile, 1024)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to make TLS key: %s", err)
|
t.Errorf("failed to make TLS key: %s", err)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
12
test/keys.go
12
test/keys.go
|
|
@ -69,8 +69,8 @@ func NewMatrixKey(matrixKeyPath string) (err error) {
|
||||||
|
|
||||||
const certificateDuration = time.Hour * 24 * 365 * 10
|
const certificateDuration = time.Hour * 24 * 365 * 10
|
||||||
|
|
||||||
func generateTLSTemplate(dnsNames []string) (*rsa.PrivateKey, *x509.Certificate, error) {
|
func generateTLSTemplate(dnsNames []string, bitSize int) (*rsa.PrivateKey, *x509.Certificate, error) {
|
||||||
priv, err := rsa.GenerateKey(rand.Reader, 4096)
|
priv, err := rsa.GenerateKey(rand.Reader, bitSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -118,8 +118,8 @@ func writePrivateKey(tlsKeyPath string, priv *rsa.PrivateKey) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTLSKey generates a new RSA TLS key and certificate and writes it to a file.
|
// NewTLSKey generates a new RSA TLS key and certificate and writes it to a file.
|
||||||
func NewTLSKey(tlsKeyPath, tlsCertPath string) error {
|
func NewTLSKey(tlsKeyPath, tlsCertPath string, keySize int) error {
|
||||||
priv, template, err := generateTLSTemplate(nil)
|
priv, template, err := generateTLSTemplate(nil, keySize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -136,8 +136,8 @@ func NewTLSKey(tlsKeyPath, tlsCertPath string) error {
|
||||||
return writePrivateKey(tlsKeyPath, priv)
|
return writePrivateKey(tlsKeyPath, priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTLSKeyWithAuthority(serverName, tlsKeyPath, tlsCertPath, authorityKeyPath, authorityCertPath string) error {
|
func NewTLSKeyWithAuthority(serverName, tlsKeyPath, tlsCertPath, authorityKeyPath, authorityCertPath string, keySize int) error {
|
||||||
priv, template, err := generateTLSTemplate([]string{serverName})
|
priv, template, err := generateTLSTemplate([]string{serverName}, keySize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue