Merge branch 'master' into matthew/peeking

This commit is contained in:
Neil Alexander 2020-09-04 14:15:51 +01:00
commit 2b8f0b8f59
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
29 changed files with 113 additions and 715 deletions

View file

@ -273,7 +273,7 @@ func SetVisibility(
req *http.Request, stateAPI currentstateAPI.CurrentStateInternalAPI, rsAPI roomserverAPI.RoomserverInternalAPI, dev *userapi.Device,
roomID string,
) util.JSONResponse {
resErr := checkMemberInRoom(req.Context(), stateAPI, dev.UserID, roomID)
resErr := checkMemberInRoom(req.Context(), rsAPI, dev.UserID, roomID)
if resErr != nil {
return *resErr
}

View file

@ -25,7 +25,6 @@ import (
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/threepid"
currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/roomserver/api"
@ -95,7 +94,6 @@ func SendKick(
req *http.Request, accountDB accounts.Database, device *userapi.Device,
roomID string, cfg *config.ClientAPI,
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI,
stateAPI currentstateAPI.CurrentStateInternalAPI,
) util.JSONResponse {
body, evTime, roomVer, reqErr := extractRequestData(req, roomID, rsAPI)
if reqErr != nil {
@ -108,7 +106,7 @@ func SendKick(
}
}
errRes := checkMemberInRoom(req.Context(), stateAPI, device.UserID, roomID)
errRes := checkMemberInRoom(req.Context(), rsAPI, device.UserID, roomID)
if errRes != nil {
return *errRes
}
@ -372,13 +370,13 @@ func checkAndProcessThreepid(
return
}
func checkMemberInRoom(ctx context.Context, stateAPI currentstateAPI.CurrentStateInternalAPI, userID, roomID string) *util.JSONResponse {
func checkMemberInRoom(ctx context.Context, rsAPI api.RoomserverInternalAPI, userID, roomID string) *util.JSONResponse {
tuple := gomatrixserverlib.StateKeyTuple{
EventType: gomatrixserverlib.MRoomMember,
StateKey: userID,
}
var membershipRes currentstateAPI.QueryCurrentStateResponse
err := stateAPI.QueryCurrentState(ctx, &currentstateAPI.QueryCurrentStateRequest{
var membershipRes api.QueryCurrentStateResponse
err := rsAPI.QueryCurrentState(ctx, &api.QueryCurrentStateRequest{
RoomID: roomID,
StateTuples: []gomatrixserverlib.StateKeyTuple{tuple},
}, &membershipRes)

View file

@ -21,7 +21,6 @@ import (
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/roomserver/api"
@ -41,9 +40,9 @@ type redactionResponse struct {
func SendRedaction(
req *http.Request, device *userapi.Device, roomID, eventID string, cfg *config.ClientAPI,
rsAPI roomserverAPI.RoomserverInternalAPI, stateAPI currentstateAPI.CurrentStateInternalAPI,
rsAPI roomserverAPI.RoomserverInternalAPI,
) util.JSONResponse {
resErr := checkMemberInRoom(req.Context(), stateAPI, device.UserID, roomID)
resErr := checkMemberInRoom(req.Context(), rsAPI, device.UserID, roomID)
if resErr != nil {
return *resErr
}
@ -67,7 +66,7 @@ func SendRedaction(
// https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
allowedToRedact := ev.Sender() == device.UserID
if !allowedToRedact {
plEvent := currentstateAPI.GetEvent(req.Context(), stateAPI, roomID, gomatrixserverlib.StateKeyTuple{
plEvent := roomserverAPI.GetStateEvent(req.Context(), rsAPI, roomID, gomatrixserverlib.StateKeyTuple{
EventType: gomatrixserverlib.MRoomPowerLevels,
StateKey: "",
})

View file

@ -176,7 +176,7 @@ func Setup(
if err != nil {
return util.ErrorResponse(err)
}
return SendKick(req, accountDB, device, vars["roomID"], cfg, rsAPI, asAPI, stateAPI)
return SendKick(req, accountDB, device, vars["roomID"], cfg, rsAPI, asAPI)
}),
).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/unban",
@ -372,7 +372,7 @@ func Setup(
if err != nil {
return util.ErrorResponse(err)
}
return SendTyping(req, device, vars["roomID"], vars["userID"], accountDB, eduAPI, stateAPI)
return SendTyping(req, device, vars["roomID"], vars["userID"], accountDB, eduAPI, rsAPI)
}),
).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/redact/{eventID}",
@ -381,7 +381,7 @@ func Setup(
if err != nil {
return util.ErrorResponse(err)
}
return SendRedaction(req, device, vars["roomID"], vars["eventID"], cfg, rsAPI, stateAPI)
return SendRedaction(req, device, vars["roomID"], vars["eventID"], cfg, rsAPI)
}),
).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/redact/{eventID}/{txnId}",
@ -390,7 +390,7 @@ func Setup(
if err != nil {
return util.ErrorResponse(err)
}
return SendRedaction(req, device, vars["roomID"], vars["eventID"], cfg, rsAPI, stateAPI)
return SendRedaction(req, device, vars["roomID"], vars["eventID"], cfg, rsAPI)
}),
).Methods(http.MethodPut, http.MethodOptions)
@ -650,7 +650,7 @@ func Setup(
req.Context(),
device,
userAPI,
stateAPI,
rsAPI,
cfg.Matrix.ServerName,
postContent.SearchString,
postContent.Limit,

View file

@ -17,8 +17,8 @@ import (
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api"
"github.com/matrix-org/dendrite/eduserver/api"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/util"
@ -35,7 +35,7 @@ func SendTyping(
req *http.Request, device *userapi.Device, roomID string,
userID string, accountDB accounts.Database,
eduAPI api.EDUServerInputAPI,
stateAPI currentstateAPI.CurrentStateInternalAPI,
rsAPI roomserverAPI.RoomserverInternalAPI,
) util.JSONResponse {
if device.UserID != userID {
return util.JSONResponse{
@ -45,7 +45,7 @@ func SendTyping(
}
// Verify that the user is a member of this room
resErr := checkMemberInRoom(req.Context(), stateAPI, userID, roomID)
resErr := checkMemberInRoom(req.Context(), rsAPI, userID, roomID)
if resErr != nil {
return *resErr
}

View file

@ -19,7 +19,7 @@ import (
"fmt"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api"
"github.com/matrix-org/dendrite/roomserver/api"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
@ -34,7 +34,7 @@ func SearchUserDirectory(
ctx context.Context,
device *userapi.Device,
userAPI userapi.UserInternalAPI,
stateAPI currentstateAPI.CurrentStateInternalAPI,
rsAPI api.RoomserverInternalAPI,
serverName gomatrixserverlib.ServerName,
searchString string,
limit int,
@ -81,14 +81,14 @@ func SearchUserDirectory(
// start searching for known users from joined rooms.
if len(results) <= limit {
stateReq := &currentstateAPI.QueryKnownUsersRequest{
stateReq := &api.QueryKnownUsersRequest{
UserID: device.UserID,
SearchString: searchString,
Limit: limit - len(results),
}
stateRes := &currentstateAPI.QueryKnownUsersResponse{}
if err := stateAPI.QueryKnownUsers(ctx, stateReq, stateRes); err != nil {
errRes := util.ErrorResponse(fmt.Errorf("stateAPI.QueryKnownUsers: %w", err))
stateRes := &api.QueryKnownUsersResponse{}
if err := rsAPI.QueryKnownUsers(ctx, stateReq, stateRes); err != nil {
errRes := util.ErrorResponse(fmt.Errorf("rsAPI.QueryKnownUsers: %w", err))
return &errRes
}

View file

@ -1,164 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package acls
import (
"context"
"encoding/json"
"fmt"
"net"
"regexp"
"strings"
"sync"
"github.com/matrix-org/gomatrixserverlib"
"github.com/sirupsen/logrus"
)
type ServerACLDatabase interface {
// GetKnownRooms returns a list of all rooms we know about.
GetKnownRooms(ctx context.Context) ([]string, error)
// GetStateEvent returns the state event of a given type for a given room with a given state key
// If no event could be found, returns nil
// If there was an issue during the retrieval, returns an error
GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*gomatrixserverlib.HeaderedEvent, error)
}
type ServerACLs struct {
acls map[string]*serverACL // room ID -> ACL
aclsMutex sync.RWMutex // protects the above
}
func NewServerACLs(db ServerACLDatabase) *ServerACLs {
ctx := context.TODO()
acls := &ServerACLs{
acls: make(map[string]*serverACL),
}
// Look up all of the rooms that the current state server knows about.
rooms, err := db.GetKnownRooms(ctx)
if err != nil {
logrus.WithError(err).Fatalf("Failed to get known rooms")
}
// For each room, let's see if we have a server ACL state event. If we
// do then we'll process it into memory so that we have the regexes to
// hand.
for _, room := range rooms {
state, err := db.GetStateEvent(ctx, room, "m.room.server_acl", "")
if err != nil {
logrus.WithError(err).Errorf("Failed to get server ACLs for room %q", room)
continue
}
if state != nil {
acls.OnServerACLUpdate(&state.Event)
}
}
return acls
}
type ServerACL struct {
Allowed []string `json:"allow"`
Denied []string `json:"deny"`
AllowIPLiterals bool `json:"allow_ip_literals"`
}
type serverACL struct {
ServerACL
allowedRegexes []*regexp.Regexp
deniedRegexes []*regexp.Regexp
}
func compileACLRegex(orig string) (*regexp.Regexp, error) {
escaped := regexp.QuoteMeta(orig)
escaped = strings.Replace(escaped, "\\?", ".", -1)
escaped = strings.Replace(escaped, "\\*", ".*", -1)
return regexp.Compile(escaped)
}
func (s *ServerACLs) OnServerACLUpdate(state *gomatrixserverlib.Event) {
acls := &serverACL{}
if err := json.Unmarshal(state.Content(), &acls.ServerACL); err != nil {
logrus.WithError(err).Errorf("Failed to unmarshal state content for server ACLs")
return
}
// The spec calls only for * (zero or more chars) and ? (exactly one char)
// to be supported as wildcard components, so we will escape all of the regex
// special characters and then replace * and ? with their regex counterparts.
// https://matrix.org/docs/spec/client_server/r0.6.1#m-room-server-acl
for _, orig := range acls.Allowed {
if expr, err := compileACLRegex(orig); err != nil {
logrus.WithError(err).Errorf("Failed to compile allowed regex")
} else {
acls.allowedRegexes = append(acls.allowedRegexes, expr)
}
}
for _, orig := range acls.Denied {
if expr, err := compileACLRegex(orig); err != nil {
logrus.WithError(err).Errorf("Failed to compile denied regex")
} else {
acls.deniedRegexes = append(acls.deniedRegexes, expr)
}
}
logrus.WithFields(logrus.Fields{
"allow_ip_literals": acls.AllowIPLiterals,
"num_allowed": len(acls.allowedRegexes),
"num_denied": len(acls.deniedRegexes),
}).Debugf("Updating server ACLs for %q", state.RoomID())
s.aclsMutex.Lock()
defer s.aclsMutex.Unlock()
s.acls[state.RoomID()] = acls
}
func (s *ServerACLs) IsServerBannedFromRoom(serverName gomatrixserverlib.ServerName, roomID string) bool {
s.aclsMutex.RLock()
// First of all check if we have an ACL for this room. If we don't then
// no servers are banned from the room.
acls, ok := s.acls[roomID]
if !ok {
s.aclsMutex.RUnlock()
return false
}
s.aclsMutex.RUnlock()
// Split the host and port apart. This is because the spec calls on us to
// validate the hostname only in cases where the port is also present.
if serverNameOnly, _, err := net.SplitHostPort(string(serverName)); err == nil {
serverName = gomatrixserverlib.ServerName(serverNameOnly)
}
// Check if the hostname is an IPv4 or IPv6 literal. We cheat here by adding
// a /0 prefix length just to trick ParseCIDR into working. If we find that
// the server is an IP literal and we don't allow those then stop straight
// away.
if _, _, err := net.ParseCIDR(fmt.Sprintf("%s/0", serverName)); err == nil {
if !acls.AllowIPLiterals {
return true
}
}
// Check if the hostname matches one of the denied regexes. If it does then
// the server is banned from the room.
for _, expr := range acls.deniedRegexes {
if expr.MatchString(string(serverName)) {
return true
}
}
// Check if the hostname matches one of the allowed regexes. If it does then
// the server is NOT banned from the room.
for _, expr := range acls.allowedRegexes {
if expr.MatchString(string(serverName)) {
return false
}
}
// If we've got to this point then we haven't matched any regexes or an IP
// hostname if disallowed. The spec calls for default-deny here.
return true
}

View file

@ -1,105 +0,0 @@
// Copyright 2020 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package acls
import (
"regexp"
"testing"
)
func TestOpenACLsWithBlacklist(t *testing.T) {
roomID := "!test:test.com"
allowRegex, err := compileACLRegex("*")
if err != nil {
t.Fatalf(err.Error())
}
denyRegex, err := compileACLRegex("foo.com")
if err != nil {
t.Fatalf(err.Error())
}
acls := ServerACLs{
acls: make(map[string]*serverACL),
}
acls.acls[roomID] = &serverACL{
ServerACL: ServerACL{
AllowIPLiterals: true,
},
allowedRegexes: []*regexp.Regexp{allowRegex},
deniedRegexes: []*regexp.Regexp{denyRegex},
}
if acls.IsServerBannedFromRoom("1.2.3.4", roomID) {
t.Fatal("Expected 1.2.3.4 to be allowed but wasn't")
}
if acls.IsServerBannedFromRoom("1.2.3.4:2345", roomID) {
t.Fatal("Expected 1.2.3.4:2345 to be allowed but wasn't")
}
if !acls.IsServerBannedFromRoom("foo.com", roomID) {
t.Fatal("Expected foo.com to be banned but wasn't")
}
if !acls.IsServerBannedFromRoom("foo.com:3456", roomID) {
t.Fatal("Expected foo.com:3456 to be banned but wasn't")
}
if acls.IsServerBannedFromRoom("bar.com", roomID) {
t.Fatal("Expected bar.com to be allowed but wasn't")
}
if acls.IsServerBannedFromRoom("bar.com:4567", roomID) {
t.Fatal("Expected bar.com:4567 to be allowed but wasn't")
}
}
func TestDefaultACLsWithWhitelist(t *testing.T) {
roomID := "!test:test.com"
allowRegex, err := compileACLRegex("foo.com")
if err != nil {
t.Fatalf(err.Error())
}
acls := ServerACLs{
acls: make(map[string]*serverACL),
}
acls.acls[roomID] = &serverACL{
ServerACL: ServerACL{
AllowIPLiterals: false,
},
allowedRegexes: []*regexp.Regexp{allowRegex},
deniedRegexes: []*regexp.Regexp{},
}
if !acls.IsServerBannedFromRoom("1.2.3.4", roomID) {
t.Fatal("Expected 1.2.3.4 to be banned but wasn't")
}
if !acls.IsServerBannedFromRoom("1.2.3.4:2345", roomID) {
t.Fatal("Expected 1.2.3.4:2345 to be banned but wasn't")
}
if acls.IsServerBannedFromRoom("foo.com", roomID) {
t.Fatal("Expected foo.com to be allowed but wasn't")
}
if acls.IsServerBannedFromRoom("foo.com:3456", roomID) {
t.Fatal("Expected foo.com:3456 to be allowed but wasn't")
}
if !acls.IsServerBannedFromRoom("bar.com", roomID) {
t.Fatal("Expected bar.com to be allowed but wasn't")
}
if !acls.IsServerBannedFromRoom("baz.com", roomID) {
t.Fatal("Expected baz.com to be allowed but wasn't")
}
if !acls.IsServerBannedFromRoom("qux.com:4567", roomID) {
t.Fatal("Expected qux.com:4567 to be allowed but wasn't")
}
}

View file

@ -16,28 +16,17 @@ package api
import (
"context"
"encoding/json"
"fmt"
"strings"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/gomatrixserverlib"
)
type CurrentStateInternalAPI interface {
// QueryCurrentState retrieves the requested state events. If state events are not found, they will be missing from
// the response.
QueryCurrentState(ctx context.Context, req *QueryCurrentStateRequest, res *QueryCurrentStateResponse) error
// QueryRoomsForUser retrieves a list of room IDs matching the given query.
QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error
// QueryBulkStateContent does a bulk query for state event content in the given rooms.
QueryBulkStateContent(ctx context.Context, req *QueryBulkStateContentRequest, res *QueryBulkStateContentResponse) error
// QuerySharedUsers returns a list of users who share at least 1 room in common with the given user.
QuerySharedUsers(ctx context.Context, req *QuerySharedUsersRequest, res *QuerySharedUsersResponse) error
// QueryKnownUsers returns a list of users that we know about from our joined rooms.
QueryKnownUsers(ctx context.Context, req *QueryKnownUsersRequest, res *QueryKnownUsersResponse) error
// QueryServerBannedFromRoom returns whether a server is banned from a room by server ACLs.
QueryServerBannedFromRoom(ctx context.Context, req *QueryServerBannedFromRoomRequest, res *QueryServerBannedFromRoomResponse) error
}
type QuerySharedUsersRequest struct {
@ -83,58 +72,3 @@ type QueryBulkStateContentResponse struct {
// map of room ID -> tuple -> content_value
Rooms map[string]map[gomatrixserverlib.StateKeyTuple]string
}
type QueryCurrentStateRequest struct {
RoomID string
StateTuples []gomatrixserverlib.StateKeyTuple
}
type QueryCurrentStateResponse struct {
StateEvents map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent
}
type QueryKnownUsersRequest struct {
UserID string `json:"user_id"`
SearchString string `json:"search_string"`
Limit int `json:"limit"`
}
type QueryKnownUsersResponse struct {
Users []authtypes.FullyQualifiedProfile `json:"profiles"`
}
type QueryServerBannedFromRoomRequest struct {
ServerName gomatrixserverlib.ServerName `json:"server_name"`
RoomID string `json:"room_id"`
}
type QueryServerBannedFromRoomResponse struct {
Banned bool `json:"banned"`
}
// MarshalJSON stringifies the StateKeyTuple keys so they can be sent over the wire in HTTP API mode.
func (r *QueryCurrentStateResponse) MarshalJSON() ([]byte, error) {
se := make(map[string]*gomatrixserverlib.HeaderedEvent, len(r.StateEvents))
for k, v := range r.StateEvents {
// use 0x1F (unit separator) as the delimiter between type/state key,
se[fmt.Sprintf("%s\x1F%s", k.EventType, k.StateKey)] = v
}
return json.Marshal(se)
}
func (r *QueryCurrentStateResponse) UnmarshalJSON(data []byte) error {
res := make(map[string]*gomatrixserverlib.HeaderedEvent)
err := json.Unmarshal(data, &res)
if err != nil {
return err
}
r.StateEvents = make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent, len(res))
for k, v := range res {
fields := strings.Split(k, "\x1F")
r.StateEvents[gomatrixserverlib.StateKeyTuple{
EventType: fields[0],
StateKey: fields[1],
}] = v
}
return nil
}

View file

@ -21,38 +21,6 @@ import (
"github.com/matrix-org/util"
)
// GetEvent returns the current state event in the room or nil.
func GetEvent(ctx context.Context, stateAPI CurrentStateInternalAPI, roomID string, tuple gomatrixserverlib.StateKeyTuple) *gomatrixserverlib.HeaderedEvent {
var res QueryCurrentStateResponse
err := stateAPI.QueryCurrentState(ctx, &QueryCurrentStateRequest{
RoomID: roomID,
StateTuples: []gomatrixserverlib.StateKeyTuple{tuple},
}, &res)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("Failed to QueryCurrentState")
return nil
}
ev, ok := res.StateEvents[tuple]
if ok {
return ev
}
return nil
}
// IsServerBannedFromRoom returns whether the server is banned from a room by server ACLs.
func IsServerBannedFromRoom(ctx context.Context, stateAPI CurrentStateInternalAPI, roomID string, serverName gomatrixserverlib.ServerName) bool {
req := &QueryServerBannedFromRoomRequest{
ServerName: serverName,
RoomID: roomID,
}
res := &QueryServerBannedFromRoomResponse{}
if err := stateAPI.QueryServerBannedFromRoom(ctx, req, res); err != nil {
util.GetLogger(ctx).WithError(err).Error("Failed to QueryServerBannedFromRoom")
return true
}
return res.Banned
}
// PopulatePublicRooms extracts PublicRoom information for all the provided room IDs. The IDs are not checked to see if they are visible in the
// published room directory.
// due to lots of switches

View file

@ -19,7 +19,6 @@ import (
"encoding/json"
"github.com/Shopify/sarama"
"github.com/matrix-org/dendrite/currentstateserver/acls"
"github.com/matrix-org/dendrite/currentstateserver/storage"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/roomserver/api"
@ -31,10 +30,9 @@ import (
type OutputRoomEventConsumer struct {
rsConsumer *internal.ContinualConsumer
db storage.Database
acls *acls.ServerACLs
}
func NewOutputRoomEventConsumer(topicName string, kafkaConsumer sarama.Consumer, store storage.Database, acls *acls.ServerACLs) *OutputRoomEventConsumer {
func NewOutputRoomEventConsumer(topicName string, kafkaConsumer sarama.Consumer, store storage.Database) *OutputRoomEventConsumer {
consumer := &internal.ContinualConsumer{
ComponentName: "currentstateserver/roomserver",
Topic: topicName,
@ -44,7 +42,6 @@ func NewOutputRoomEventConsumer(topicName string, kafkaConsumer sarama.Consumer,
s := &OutputRoomEventConsumer{
rsConsumer: consumer,
db: store,
acls: acls,
}
consumer.ProcessMessage = s.onMessage
@ -80,10 +77,6 @@ func (c *OutputRoomEventConsumer) onNewRoomEvent(
) error {
ev := msg.Event
if ev.Type() == "m.room.server_acl" && ev.StateKeyEquals("") {
defer c.acls.OnServerACLUpdate(&ev.Event)
}
addsStateEvents := msg.AddsState()
ev, err := c.updateStateEvent(ev)

View file

@ -17,7 +17,6 @@ package currentstateserver
import (
"github.com/Shopify/sarama"
"github.com/gorilla/mux"
"github.com/matrix-org/dendrite/currentstateserver/acls"
"github.com/matrix-org/dendrite/currentstateserver/api"
"github.com/matrix-org/dendrite/currentstateserver/consumers"
"github.com/matrix-org/dendrite/currentstateserver/internal"
@ -40,15 +39,13 @@ func NewInternalAPI(cfg *config.CurrentStateServer, consumer sarama.Consumer) ap
if err != nil {
logrus.WithError(err).Panicf("failed to open database")
}
serverACLs := acls.NewServerACLs(csDB)
roomConsumer := consumers.NewOutputRoomEventConsumer(
cfg.Matrix.Kafka.TopicFor(config.TopicOutputRoomEvent), consumer, csDB, serverACLs,
cfg.Matrix.Kafka.TopicFor(config.TopicOutputRoomEvent), consumer, csDB,
)
if err = roomConsumer.Start(); err != nil {
logrus.WithError(err).Panicf("failed to start room server consumer")
}
return &internal.CurrentStateInternalAPI{
DB: csDB,
ServerACLs: serverACLs,
DB: csDB,
}
}

View file

@ -15,7 +15,6 @@
package currentstateserver
import (
"bytes"
"context"
"crypto/ed25519"
"encoding/json"
@ -139,81 +138,6 @@ func MustMakeInternalAPI(t *testing.T) (api.CurrentStateInternalAPI, storage.Dat
}
}
func TestQueryCurrentState(t *testing.T) {
currStateAPI, db, producer, cancel := MustMakeInternalAPI(t)
defer cancel()
plTuple := gomatrixserverlib.StateKeyTuple{
EventType: "m.room.power_levels",
StateKey: "",
}
plEvent := testEvents[4]
offset := MustWriteOutputEvent(t, producer, &roomserverAPI.OutputNewRoomEvent{
Event: plEvent,
AddsStateEventIDs: []string{plEvent.EventID()},
})
waitForOffsetProcessed(t, db, offset)
testCases := []struct {
req api.QueryCurrentStateRequest
wantRes api.QueryCurrentStateResponse
wantErr error
}{
{
req: api.QueryCurrentStateRequest{
RoomID: plEvent.RoomID(),
StateTuples: []gomatrixserverlib.StateKeyTuple{
plTuple,
},
},
wantRes: api.QueryCurrentStateResponse{
StateEvents: map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent{
plTuple: &plEvent,
},
},
},
}
runCases := func(testAPI api.CurrentStateInternalAPI) {
for _, tc := range testCases {
var gotRes api.QueryCurrentStateResponse
gotErr := testAPI.QueryCurrentState(context.TODO(), &tc.req, &gotRes)
if tc.wantErr == nil && gotErr != nil || tc.wantErr != nil && gotErr == nil {
t.Errorf("QueryCurrentState error, got %s want %s", gotErr, tc.wantErr)
continue
}
for tuple, wantEvent := range tc.wantRes.StateEvents {
gotEvent, ok := gotRes.StateEvents[tuple]
if !ok {
t.Errorf("QueryCurrentState want tuple %+v but it is missing from the response", tuple)
continue
}
gotCanon, err := gomatrixserverlib.CanonicalJSON(gotEvent.JSON())
if err != nil {
t.Errorf("CanonicalJSON failed: %w", err)
continue
}
if !bytes.Equal(gotCanon, wantEvent.JSON()) {
t.Errorf("QueryCurrentState tuple %+v got event JSON %s want %s", tuple, string(gotCanon), string(wantEvent.JSON()))
}
}
}
}
t.Run("HTTP API", func(t *testing.T) {
router := mux.NewRouter().PathPrefix(httputil.InternalPathPrefix).Subrouter()
AddInternalRoutes(router, currStateAPI)
apiURL, cancel := test.ListenAndServe(t, router, false)
defer cancel()
httpAPI, err := inthttp.NewCurrentStateAPIClient(apiURL, &http.Client{})
if err != nil {
t.Fatalf("failed to create HTTP client")
}
runCases(httpAPI)
})
t.Run("Monolith", func(t *testing.T) {
runCases(currStateAPI)
})
}
func mustMakeMembershipEvent(t *testing.T, roomID, userID, membership string) *roomserverAPI.OutputNewRoomEvent {
eb := gomatrixserverlib.EventBuilder{
RoomID: roomID,

View file

@ -16,32 +16,14 @@ package internal
import (
"context"
"errors"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/currentstateserver/acls"
"github.com/matrix-org/dendrite/currentstateserver/api"
"github.com/matrix-org/dendrite/currentstateserver/storage"
"github.com/matrix-org/gomatrixserverlib"
)
type CurrentStateInternalAPI struct {
DB storage.Database
ServerACLs *acls.ServerACLs
}
func (a *CurrentStateInternalAPI) QueryCurrentState(ctx context.Context, req *api.QueryCurrentStateRequest, res *api.QueryCurrentStateResponse) error {
res.StateEvents = make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent)
for _, tuple := range req.StateTuples {
ev, err := a.DB.GetStateEvent(ctx, req.RoomID, tuple.EventType, tuple.StateKey)
if err != nil {
return err
}
if ev != nil {
res.StateEvents[tuple] = ev
}
}
return nil
DB storage.Database
}
func (a *CurrentStateInternalAPI) QueryRoomsForUser(ctx context.Context, req *api.QueryRoomsForUserRequest, res *api.QueryRoomsForUserResponse) error {
@ -53,19 +35,6 @@ func (a *CurrentStateInternalAPI) QueryRoomsForUser(ctx context.Context, req *ap
return nil
}
func (a *CurrentStateInternalAPI) QueryKnownUsers(ctx context.Context, req *api.QueryKnownUsersRequest, res *api.QueryKnownUsersResponse) error {
users, err := a.DB.GetKnownUsers(ctx, req.UserID, req.SearchString, req.Limit)
if err != nil {
return err
}
for _, user := range users {
res.Users = append(res.Users, authtypes.FullyQualifiedProfile{
UserID: user,
})
}
return nil
}
func (a *CurrentStateInternalAPI) QueryBulkStateContent(ctx context.Context, req *api.QueryBulkStateContentRequest, res *api.QueryBulkStateContentResponse) error {
events, err := a.DB.GetBulkStateContent(ctx, req.RoomIDs, req.StateTuples, req.AllowWildcards)
if err != nil {
@ -115,11 +84,3 @@ func (a *CurrentStateInternalAPI) QuerySharedUsers(ctx context.Context, req *api
res.UserIDsToCount = users
return nil
}
func (a *CurrentStateInternalAPI) QueryServerBannedFromRoom(ctx context.Context, req *api.QueryServerBannedFromRoomRequest, res *api.QueryServerBannedFromRoomResponse) error {
if a.ServerACLs == nil {
return errors.New("no server ACL tracking")
}
res.Banned = a.ServerACLs.IsServerBannedFromRoom(req.ServerName, req.RoomID)
return nil
}

View file

@ -26,12 +26,9 @@ import (
// HTTP paths for the internal HTTP APIs
const (
QueryCurrentStatePath = "/currentstateserver/queryCurrentState"
QueryRoomsForUserPath = "/currentstateserver/queryRoomsForUser"
QueryBulkStateContentPath = "/currentstateserver/queryBulkStateContent"
QuerySharedUsersPath = "/currentstateserver/querySharedUsers"
QueryKnownUsersPath = "/currentstateserver/queryKnownUsers"
QueryServerBannedFromRoomPath = "/currentstateserver/queryServerBannedFromRoom"
QueryRoomsForUserPath = "/currentstateserver/queryRoomsForUser"
QueryBulkStateContentPath = "/currentstateserver/queryBulkStateContent"
QuerySharedUsersPath = "/currentstateserver/querySharedUsers"
)
// NewCurrentStateAPIClient creates a CurrentStateInternalAPI implemented by talking to a HTTP POST API.
@ -54,18 +51,6 @@ type httpCurrentStateInternalAPI struct {
httpClient *http.Client
}
func (h *httpCurrentStateInternalAPI) QueryCurrentState(
ctx context.Context,
request *api.QueryCurrentStateRequest,
response *api.QueryCurrentStateResponse,
) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryCurrentState")
defer span.Finish()
apiURL := h.apiURL + QueryCurrentStatePath
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
}
func (h *httpCurrentStateInternalAPI) QueryRoomsForUser(
ctx context.Context,
request *api.QueryRoomsForUserRequest,
@ -99,23 +84,3 @@ func (h *httpCurrentStateInternalAPI) QuerySharedUsers(
apiURL := h.apiURL + QuerySharedUsersPath
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
}
func (h *httpCurrentStateInternalAPI) QueryKnownUsers(
ctx context.Context, req *api.QueryKnownUsersRequest, res *api.QueryKnownUsersResponse,
) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryKnownUsers")
defer span.Finish()
apiURL := h.apiURL + QueryKnownUsersPath
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
}
func (h *httpCurrentStateInternalAPI) QueryServerBannedFromRoom(
ctx context.Context, req *api.QueryServerBannedFromRoomRequest, res *api.QueryServerBannedFromRoomResponse,
) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryServerBannedFromRoom")
defer span.Finish()
apiURL := h.apiURL + QueryServerBannedFromRoomPath
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
}

View file

@ -25,19 +25,6 @@ import (
)
func AddRoutes(internalAPIMux *mux.Router, intAPI api.CurrentStateInternalAPI) {
internalAPIMux.Handle(QueryCurrentStatePath,
httputil.MakeInternalAPI("queryCurrentState", func(req *http.Request) util.JSONResponse {
request := api.QueryCurrentStateRequest{}
response := api.QueryCurrentStateResponse{}
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.MessageResponse(http.StatusBadRequest, err.Error())
}
if err := intAPI.QueryCurrentState(req.Context(), &request, &response); err != nil {
return util.ErrorResponse(err)
}
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
internalAPIMux.Handle(QueryRoomsForUserPath,
httputil.MakeInternalAPI("queryRoomsForUser", func(req *http.Request) util.JSONResponse {
request := api.QueryRoomsForUserRequest{}
@ -77,30 +64,4 @@ func AddRoutes(internalAPIMux *mux.Router, intAPI api.CurrentStateInternalAPI) {
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
internalAPIMux.Handle(QuerySharedUsersPath,
httputil.MakeInternalAPI("queryKnownUsers", func(req *http.Request) util.JSONResponse {
request := api.QueryKnownUsersRequest{}
response := api.QueryKnownUsersResponse{}
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.MessageResponse(http.StatusBadRequest, err.Error())
}
if err := intAPI.QueryKnownUsers(req.Context(), &request, &response); err != nil {
return util.ErrorResponse(err)
}
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
internalAPIMux.Handle(QueryServerBannedFromRoomPath,
httputil.MakeInternalAPI("queryServerBannedFromRoom", func(req *http.Request) util.JSONResponse {
request := api.QueryServerBannedFromRoomRequest{}
response := api.QueryServerBannedFromRoomResponse{}
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.MessageResponse(http.StatusBadRequest, err.Error())
}
if err := intAPI.QueryServerBannedFromRoom(req.Context(), &request, &response); err != nil {
return util.ErrorResponse(err)
}
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
}

View file

@ -76,7 +76,7 @@ func Setup(
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return Send(
httpReq, request, gomatrixserverlib.TransactionID(vars["txnID"]),
cfg, rsAPI, eduAPI, keyAPI, stateAPI, keys, federation,
cfg, rsAPI, eduAPI, keyAPI, keys, federation,
)
},
)).Methods(http.MethodPut, http.MethodOptions)
@ -84,7 +84,7 @@ func Setup(
v1fedmux.Handle("/invite/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_invite", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -100,7 +100,7 @@ func Setup(
v2fedmux.Handle("/invite/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_invite", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -140,7 +140,7 @@ func Setup(
v1fedmux.Handle("/state/{roomID}", httputil.MakeFedAPI(
"federation_get_state", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -155,7 +155,7 @@ func Setup(
v1fedmux.Handle("/state_ids/{roomID}", httputil.MakeFedAPI(
"federation_get_state_ids", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -170,7 +170,7 @@ func Setup(
v1fedmux.Handle("/event_auth/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_get_event_auth", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -212,7 +212,7 @@ func Setup(
v1fedmux.Handle("/make_join/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_make_join", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -243,7 +243,7 @@ func Setup(
v1fedmux.Handle("/send_join/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_send_join", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -275,7 +275,7 @@ func Setup(
v2fedmux.Handle("/send_join/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_send_join", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -292,7 +292,7 @@ func Setup(
v1fedmux.Handle("/make_leave/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_make_leave", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -309,7 +309,7 @@ func Setup(
v1fedmux.Handle("/send_leave/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_send_leave", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -341,7 +341,7 @@ func Setup(
v2fedmux.Handle("/send_leave/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_send_leave", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -365,7 +365,7 @@ func Setup(
v1fedmux.Handle("/get_missing_events/{roomID}", httputil.MakeFedAPI(
"federation_get_missing_events", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),
@ -378,7 +378,7 @@ func Setup(
v1fedmux.Handle("/backfill/{roomID}", httputil.MakeFedAPI(
"federation_backfill", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
if currentstateAPI.IsServerBannedFromRoom(httpReq.Context(), stateAPI, vars["roomID"], request.Origin()) {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Forbidden by server ACLs"),

View file

@ -21,7 +21,6 @@ import (
"net/http"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api"
eduserverAPI "github.com/matrix-org/dendrite/eduserver/api"
"github.com/matrix-org/dendrite/internal/config"
keyapi "github.com/matrix-org/dendrite/keyserver/api"
@ -40,7 +39,6 @@ func Send(
rsAPI api.RoomserverInternalAPI,
eduAPI eduserverAPI.EDUServerInputAPI,
keyAPI keyapi.KeyInternalAPI,
stateAPI currentstateAPI.CurrentStateInternalAPI,
keys gomatrixserverlib.JSONVerifier,
federation *gomatrixserverlib.FederationClient,
) util.JSONResponse {
@ -48,7 +46,6 @@ func Send(
context: httpReq.Context(),
rsAPI: rsAPI,
eduAPI: eduAPI,
stateAPI: stateAPI,
keys: keys,
federation: federation,
haveEvents: make(map[string]*gomatrixserverlib.HeaderedEvent),
@ -107,7 +104,6 @@ type txnReq struct {
rsAPI api.RoomserverInternalAPI
eduAPI eduserverAPI.EDUServerInputAPI
keyAPI keyapi.KeyInternalAPI
stateAPI currentstateAPI.CurrentStateInternalAPI
keys gomatrixserverlib.JSONVerifier
federation txnFederationClient
// local cache of events for auth checks, etc - this may include events
@ -168,7 +164,7 @@ func (t *txnReq) processTransaction() (*gomatrixserverlib.RespSend, *util.JSONRe
util.GetLogger(t.context).WithError(err).Warnf("Transaction: Failed to parse event JSON of event %s", string(pdu))
continue
}
if currentstateAPI.IsServerBannedFromRoom(t.context, t.stateAPI, event.RoomID(), t.Origin) {
if api.IsServerBannedFromRoom(t.context, t.rsAPI, event.RoomID(), t.Origin) {
results[event.EventID()] = gomatrixserverlib.PDUResult{
Error: "Forbidden by server ACLs",
}

View file

@ -8,7 +8,6 @@ import (
"testing"
"time"
currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api"
eduAPI "github.com/matrix-org/dendrite/eduserver/api"
fsAPI "github.com/matrix-org/dendrite/federationsender/api"
"github.com/matrix-org/dendrite/internal/test"
@ -320,33 +319,6 @@ func (t *testRoomserverAPI) QueryServerBannedFromRoom(ctx context.Context, req *
return nil
}
type testStateAPI struct {
}
func (t *testStateAPI) QueryCurrentState(ctx context.Context, req *currentstateAPI.QueryCurrentStateRequest, res *currentstateAPI.QueryCurrentStateResponse) error {
return nil
}
func (t *testStateAPI) QueryRoomsForUser(ctx context.Context, req *currentstateAPI.QueryRoomsForUserRequest, res *currentstateAPI.QueryRoomsForUserResponse) error {
return fmt.Errorf("not implemented")
}
func (t *testStateAPI) QueryBulkStateContent(ctx context.Context, req *currentstateAPI.QueryBulkStateContentRequest, res *currentstateAPI.QueryBulkStateContentResponse) error {
return fmt.Errorf("not implemented")
}
func (t *testStateAPI) QuerySharedUsers(ctx context.Context, req *currentstateAPI.QuerySharedUsersRequest, res *currentstateAPI.QuerySharedUsersResponse) error {
return fmt.Errorf("not implemented")
}
func (t *testStateAPI) QueryKnownUsers(ctx context.Context, req *currentstateAPI.QueryKnownUsersRequest, res *currentstateAPI.QueryKnownUsersResponse) error {
return fmt.Errorf("not implemented")
}
func (t *testStateAPI) QueryServerBannedFromRoom(ctx context.Context, req *currentstateAPI.QueryServerBannedFromRoomRequest, res *currentstateAPI.QueryServerBannedFromRoomResponse) error {
return nil
}
type txnFedClient struct {
state map[string]gomatrixserverlib.RespState // event_id to response
stateIDs map[string]gomatrixserverlib.RespStateIDs // event_id to response
@ -391,12 +363,11 @@ func (c *txnFedClient) LookupMissingEvents(ctx context.Context, s gomatrixserver
return c.getMissingEvents(missing)
}
func mustCreateTransaction(rsAPI api.RoomserverInternalAPI, stateAPI currentstateAPI.CurrentStateInternalAPI, fedClient txnFederationClient, pdus []json.RawMessage) *txnReq {
func mustCreateTransaction(rsAPI api.RoomserverInternalAPI, fedClient txnFederationClient, pdus []json.RawMessage) *txnReq {
t := &txnReq{
context: context.Background(),
rsAPI: rsAPI,
eduAPI: &testEDUProducer{},
stateAPI: stateAPI,
keys: &test.NopJSONVerifier{},
federation: fedClient,
haveEvents: make(map[string]*gomatrixserverlib.HeaderedEvent),
@ -476,11 +447,10 @@ func TestBasicTransaction(t *testing.T) {
}
},
}
stateAPI := &testStateAPI{}
pdus := []json.RawMessage{
testData[len(testData)-1], // a message event
}
txn := mustCreateTransaction(rsAPI, stateAPI, &txnFedClient{}, pdus)
txn := mustCreateTransaction(rsAPI, &txnFedClient{}, pdus)
mustProcessTransaction(t, txn, nil)
assertInputRoomEvents(t, rsAPI.inputRoomEvents, []gomatrixserverlib.HeaderedEvent{testEvents[len(testEvents)-1]})
}
@ -499,11 +469,10 @@ func TestTransactionFailAuthChecks(t *testing.T) {
}
},
}
stateAPI := &testStateAPI{}
pdus := []json.RawMessage{
testData[len(testData)-1], // a message event
}
txn := mustCreateTransaction(rsAPI, stateAPI, &txnFedClient{}, pdus)
txn := mustCreateTransaction(rsAPI, &txnFedClient{}, pdus)
mustProcessTransaction(t, txn, []string{
// expect the event to have an error
testEvents[len(testEvents)-1].EventID(),
@ -558,8 +527,6 @@ func TestTransactionFetchMissingPrevEvents(t *testing.T) {
},
}
stateAPI := &testStateAPI{}
cli := &txnFedClient{
getMissingEvents: func(missing gomatrixserverlib.MissingEvents) (res gomatrixserverlib.RespMissingEvents, err error) {
if !reflect.DeepEqual(missing.EarliestEvents, []string{haveEvent.EventID()}) {
@ -579,7 +546,7 @@ func TestTransactionFetchMissingPrevEvents(t *testing.T) {
pdus := []json.RawMessage{
inputEvent.JSON(),
}
txn := mustCreateTransaction(rsAPI, stateAPI, cli, pdus)
txn := mustCreateTransaction(rsAPI, cli, pdus)
mustProcessTransaction(t, txn, nil)
assertInputRoomEvents(t, rsAPI.inputRoomEvents, []gomatrixserverlib.HeaderedEvent{prevEvent, inputEvent})
}
@ -729,12 +696,10 @@ func TestTransactionFetchMissingStateByStateIDs(t *testing.T) {
},
}
stateAPI := &testStateAPI{}
pdus := []json.RawMessage{
eventD.JSON(),
}
txn := mustCreateTransaction(rsAPI, stateAPI, cli, pdus)
txn := mustCreateTransaction(rsAPI, cli, pdus)
mustProcessTransaction(t, txn, nil)
assertInputRoomEvents(t, rsAPI.inputRoomEvents, []gomatrixserverlib.HeaderedEvent{eventB, eventC, eventD})
}

View file

@ -59,7 +59,7 @@ func NewInternalAPI(
queues := queue.NewOutgoingQueues(
federationSenderDB, cfg.Matrix.ServerName, federation,
rsAPI, stateAPI, stats,
rsAPI, stats,
&queue.SigningInfo{
KeyID: cfg.Matrix.KeyID,
PrivateKey: cfg.Matrix.PrivateKey,

View file

@ -22,7 +22,6 @@ import (
"sync"
"time"
stateapi "github.com/matrix-org/dendrite/currentstateserver/api"
"github.com/matrix-org/dendrite/federationsender/statistics"
"github.com/matrix-org/dendrite/federationsender/storage"
"github.com/matrix-org/dendrite/roomserver/api"
@ -36,7 +35,6 @@ import (
type OutgoingQueues struct {
db storage.Database
rsAPI api.RoomserverInternalAPI
stateAPI stateapi.CurrentStateInternalAPI
origin gomatrixserverlib.ServerName
client *gomatrixserverlib.FederationClient
statistics *statistics.Statistics
@ -51,14 +49,12 @@ func NewOutgoingQueues(
origin gomatrixserverlib.ServerName,
client *gomatrixserverlib.FederationClient,
rsAPI api.RoomserverInternalAPI,
stateAPI stateapi.CurrentStateInternalAPI,
statistics *statistics.Statistics,
signing *SigningInfo,
) *OutgoingQueues {
queues := &OutgoingQueues{
db: db,
rsAPI: rsAPI,
stateAPI: stateAPI,
origin: origin,
client: client,
statistics: statistics,
@ -144,9 +140,9 @@ func (oqs *OutgoingQueues) SendEvent(
// Check if any of the destinations are prohibited by server ACLs.
for destination := range destmap {
if stateapi.IsServerBannedFromRoom(
if api.IsServerBannedFromRoom(
context.TODO(),
oqs.stateAPI,
oqs.rsAPI,
ev.RoomID(),
destination,
) {
@ -208,9 +204,9 @@ func (oqs *OutgoingQueues) SendEDU(
// ACLs.
if result := gjson.GetBytes(e.Content, "room_id"); result.Exists() {
for destination := range destmap {
if stateapi.IsServerBannedFromRoom(
if api.IsServerBannedFromRoom(
context.TODO(),
oqs.stateAPI,
oqs.rsAPI,
result.Str,
destination,
) {

2
go.mod
View file

@ -21,7 +21,7 @@ require (
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd
github.com/matrix-org/gomatrixserverlib v0.0.0-20200902135805-f7a5b5e89750
github.com/matrix-org/gomatrixserverlib v0.0.0-20200903230638-083d02f49d4d
github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
github.com/mattn/go-sqlite3 v1.14.2

4
go.sum
View file

@ -567,8 +567,8 @@ github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bh
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd h1:xVrqJK3xHREMNjwjljkAUaadalWc0rRbmVuQatzmgwg=
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200902135805-f7a5b5e89750 h1:k5vsLfpylXHOXgN51N0QNbak9i+4bT33Puk/ZJgcdDw=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200902135805-f7a5b5e89750/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200903230638-083d02f49d4d h1:nA6S6qtLsUgwfJusQJLeNjvTLjZ7F9w+eWV9RzRZrzk=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200903230638-083d02f49d4d/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91 h1:HJ6U3S3ljJqNffYMcIeAncp5qT/i+ZMiJ2JC2F0aXP4=
github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91/go.mod h1:sjyPyRxKM5uw1nD2cJ6O2OxI6GOqyVBfNXqKjBZTBZE=
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo=

View file

@ -41,6 +41,7 @@ func NewRoomserverAPI(
outputRoomEventTopic string, caches caching.RoomServerCaches,
keyRing gomatrixserverlib.JSONVerifier,
) *RoomserverInternalAPI {
serverACLs := acls.NewServerACLs(roomserverDB)
a := &RoomserverInternalAPI{
DB: roomserverDB,
Cfg: cfg,
@ -50,13 +51,14 @@ func NewRoomserverAPI(
Queryer: &query.Queryer{
DB: roomserverDB,
Cache: caches,
ServerACLs: acls.NewServerACLs(roomserverDB),
ServerACLs: serverACLs,
},
Inputer: &input.Inputer{
DB: roomserverDB,
OutputRoomEventTopic: outputRoomEventTopic,
Producer: producer,
ServerName: cfg.Matrix.ServerName,
ACLs: serverACLs,
},
// perform-er structs get initialised when we have a federation sender to use
}

View file

@ -22,6 +22,7 @@ import (
"time"
"github.com/Shopify/sarama"
"github.com/matrix-org/dendrite/roomserver/acls"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/roomserver/storage"
"github.com/matrix-org/gomatrixserverlib"
@ -33,6 +34,7 @@ type Inputer struct {
DB storage.Database
Producer sarama.SyncProducer
ServerName gomatrixserverlib.ServerName
ACLs *acls.ServerACLs
OutputRoomEventTopic string
workers sync.Map // room ID -> *inputWorker
@ -88,6 +90,10 @@ func (r *Inputer) WriteOutputEvents(roomID string, updates []api.OutputEvent) er
"send_as_server": updates[i].NewRoomEvent.SendAsServer,
"sender": updates[i].NewRoomEvent.Event.Sender(),
})
if updates[i].NewRoomEvent.Event.Type() == "m.room.server_acl" && updates[i].NewRoomEvent.Event.StateKeyEquals("") {
ev := updates[i].NewRoomEvent.Event.Unwrap()
defer r.ACLs.OnServerACLUpdate(&ev)
}
}
logger.Infof("Producing to topic '%s'", r.OutputRoomEventTopic)
messages[i] = &sarama.ProducerMessage{

View file

@ -364,7 +364,7 @@ func AddRoutes(r api.RoomserverInternalAPI, internalAPIMux *mux.Router) {
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
internalAPIMux.Handle(RoomserverQuerySharedUsersPath,
internalAPIMux.Handle(RoomserverQueryKnownUsersPath,
httputil.MakeInternalAPI("queryKnownUsers", func(req *http.Request) util.JSONResponse {
request := api.QueryKnownUsersRequest{}
response := api.QueryKnownUsersResponse{}

View file

@ -21,6 +21,7 @@ import (
"github.com/lib/pq"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/roomserver/storage/shared"
"github.com/matrix-org/dendrite/roomserver/storage/tables"
"github.com/matrix-org/dendrite/roomserver/types"
@ -117,7 +118,8 @@ func (s *eventTypeStatements) InsertEventTypeNID(
ctx context.Context, txn *sql.Tx, eventType string,
) (types.EventTypeNID, error) {
var eventTypeNID int64
err := txn.Stmt(s.insertEventTypeNIDStmt).QueryRowContext(ctx, eventType).Scan(&eventTypeNID)
stmt := sqlutil.TxStmt(txn, s.insertEventTypeNIDStmt)
err := stmt.QueryRowContext(ctx, eventType).Scan(&eventTypeNID)
return types.EventTypeNID(eventTypeNID), err
}
@ -125,7 +127,8 @@ func (s *eventTypeStatements) SelectEventTypeNID(
ctx context.Context, txn *sql.Tx, eventType string,
) (types.EventTypeNID, error) {
var eventTypeNID int64
err := txn.Stmt(s.selectEventTypeNIDStmt).QueryRowContext(ctx, eventType).Scan(&eventTypeNID)
stmt := sqlutil.TxStmt(txn, s.selectEventTypeNIDStmt)
err := stmt.QueryRowContext(ctx, eventType).Scan(&eventTypeNID)
return types.EventTypeNID(eventTypeNID), err
}

View file

@ -53,14 +53,6 @@ type mockCurrentStateAPI struct {
roomIDToJoinedMembers map[string][]string
}
func (s *mockCurrentStateAPI) QueryCurrentState(ctx context.Context, req *api.QueryCurrentStateRequest, res *api.QueryCurrentStateResponse) error {
return nil
}
func (s *mockCurrentStateAPI) QueryKnownUsers(ctx context.Context, req *api.QueryKnownUsersRequest, res *api.QueryKnownUsersResponse) error {
return nil
}
// QueryRoomsForUser retrieves a list of room IDs matching the given query.
func (s *mockCurrentStateAPI) QueryRoomsForUser(ctx context.Context, req *api.QueryRoomsForUserRequest, res *api.QueryRoomsForUserResponse) error {
return nil
@ -114,10 +106,6 @@ func (s *mockCurrentStateAPI) QuerySharedUsers(ctx context.Context, req *api.Que
return nil
}
func (t *mockCurrentStateAPI) QueryServerBannedFromRoom(ctx context.Context, req *api.QueryServerBannedFromRoomRequest, res *api.QueryServerBannedFromRoomResponse) error {
return nil
}
type wantCatchup struct {
hasNew bool
changed []string

View file

@ -698,9 +698,9 @@ func (d *Database) getResponseWithPDUsForCompleteSync(
return //res, toPos, joinedRoomIDs, err
}
func (d* Database) getJoinResponseForCompleteSync(
func (d *Database) getJoinResponseForCompleteSync(
ctx context.Context, txn *sql.Tx,
roomID string,
roomID string,
r types.Range,
stateFilter *gomatrixserverlib.StateFilter,
numRecentEventsPerRoom int,
@ -798,8 +798,10 @@ func (d *Database) addInvitesToResponse(
res.Rooms.Invite[roomID] = *ir
}
for roomID := range retiredInvites {
lr := types.NewLeaveResponse()
res.Rooms.Leave[roomID] = *lr
if _, ok := res.Rooms.Join[roomID]; !ok {
lr := types.NewLeaveResponse()
res.Rooms.Leave[roomID] = *lr
}
}
return nil
}
@ -1112,37 +1114,20 @@ func (d *Database) getStateDeltas(
// requests with full_state=true.
// Fetches full state for all joined rooms and uses selectStateInRange to get
// updates for other rooms.
// nolint:gocyclo
func (d *Database) getStateDeltasForFullStateSync(
ctx context.Context, device *userapi.Device, txn *sql.Tx,
r types.Range, userID string,
stateFilter *gomatrixserverlib.StateFilter,
) ([]stateDelta, []string, error) {
joinedRoomIDs, err := d.CurrentRoomState.SelectRoomIDsWithMembership(ctx, txn, userID, gomatrixserverlib.Join)
if err != nil {
return nil, nil, err
}
// Use a reasonable initial capacity
deltas := make(map[string]stateDelta)
peeks, err := d.Peeks.SelectPeeks(ctx, txn, userID, device.ID)
if err != nil {
return nil, nil, err
}
// Use a reasonable initial capacity
deltas := make([]stateDelta, 0, len(joinedRoomIDs) + len(peeks))
// Add full states for all joined rooms
for _, joinedRoomID := range joinedRoomIDs {
s, stateErr := d.currentStateStreamEventsForRoom(ctx, txn, joinedRoomID, stateFilter)
if stateErr != nil {
return nil, nil, stateErr
}
deltas = append(deltas, stateDelta{
membership: gomatrixserverlib.Join,
stateEvents: d.StreamEventsToEvents(device, s),
roomID: joinedRoomID,
})
}
// Add full states for all peeking rooms
newPeeks := false
for _, peek := range peeks {
@ -1153,16 +1138,16 @@ func (d *Database) getStateDeltasForFullStateSync(
if stateErr != nil {
return nil, nil, stateErr
}
deltas = append(deltas, stateDelta{
deltas[peek.RoomID] = stateDelta{
membership: gomatrixserverlib.Peek,
stateEvents: d.StreamEventsToEvents(device, s),
roomID: peek.RoomID,
})
}
}
if newPeeks {
err = d.Writer.Do(d.DB, txn, func(txn *sql.Tx) error {
return d.Peeks.MarkPeeksAsOld(ctx, txn, userID, device.ID)
return d.Peeks.MarkPeeksAsOld(ctx, txn, userID, device.ID)
})
if err != nil {
return nil, nil, err
@ -1183,12 +1168,12 @@ func (d *Database) getStateDeltasForFullStateSync(
for _, ev := range stateStreamEvents {
if membership := getMembershipFromEvent(&ev.Event, userID); membership != "" {
if membership != gomatrixserverlib.Join { // We've already added full state for all joined rooms above.
deltas = append(deltas, stateDelta{
deltas[roomID] = stateDelta{
membership: membership,
membershipPos: ev.StreamPosition,
stateEvents: d.StreamEventsToEvents(device, stateStreamEvents),
roomID: roomID,
})
}
}
break
@ -1196,7 +1181,33 @@ func (d *Database) getStateDeltasForFullStateSync(
}
}
return deltas, joinedRoomIDs, nil
joinedRoomIDs, err := d.CurrentRoomState.SelectRoomIDsWithMembership(ctx, txn, userID, gomatrixserverlib.Join)
if err != nil {
return nil, nil, err
}
// Add full states for all joined rooms
for _, joinedRoomID := range joinedRoomIDs {
s, stateErr := d.currentStateStreamEventsForRoom(ctx, txn, joinedRoomID, stateFilter)
if stateErr != nil {
return nil, nil, stateErr
}
deltas[joinedRoomID] = stateDelta{
membership: gomatrixserverlib.Join,
stateEvents: d.StreamEventsToEvents(device, s),
roomID: joinedRoomID,
}
}
// Create a response array.
result := make([]stateDelta, len(deltas))
i := 0
for _, delta := range deltas {
result[i] = delta
i++
}
return result, joinedRoomIDs, nil
}
func (d *Database) currentStateStreamEventsForRoom(