Write the join event along with current state to the room server

This commit is contained in:
Mark Haines 2017-05-25 12:04:33 +01:00
parent f4d8dde480
commit 9cd7be1aa3
12 changed files with 230 additions and 72 deletions

View file

@ -45,22 +45,60 @@ func NewRoomserverProducer(kafkaURIs []string, topic string) (*RoomserverProduce
func (c *RoomserverProducer) SendEvents(events []gomatrixserverlib.Event) error { func (c *RoomserverProducer) SendEvents(events []gomatrixserverlib.Event) error {
eventIDs := make([]string, len(events)) eventIDs := make([]string, len(events))
ires := make([]api.InputRoomEvent, len(events)) ires := make([]api.InputRoomEvent, len(events))
for i := range events { for i, event := range events {
var authEventIDs []string ires[i] = api.InputRoomEvent{
for _, ref := range events[i].AuthEvents() {
authEventIDs = append(authEventIDs, ref.EventID)
}
ire := api.InputRoomEvent{
Kind: api.KindNew, Kind: api.KindNew,
Event: events[i].JSON(), Event: event.JSON(),
AuthEventIDs: authEventIDs, AuthEventIDs: authEventIDs(event),
} }
ires[i] = ire eventIDs[i] = event.EventID()
eventIDs[i] = events[i].EventID()
} }
return c.SendInputRoomEvents(ires, eventIDs) return c.SendInputRoomEvents(ires, eventIDs)
} }
// SendEventWithState writes an event with KindNew to the roomserver input log
// preceeded by the state at the event as KindOutlier.
func (c *RoomserverProducer) SendEventWithState(state gomatrixserverlib.RespState, event gomatrixserverlib.Event) error {
outliers, err := state.Events()
if err != nil {
return err
}
eventIDs := make([]string, len(outliers)+1)
ires := make([]api.InputRoomEvent, len(outliers)+1)
for i, outlier := range outliers {
ires[i] = api.InputRoomEvent{
Kind: api.KindOutlier,
Event: outlier.JSON(),
AuthEventIDs: authEventIDs(outlier),
}
eventIDs[i] = outlier.EventID()
}
stateEventIDs := make([]string, len(state.StateEvents))
for i := range state.StateEvents {
stateEventIDs[i] = state.StateEvents[i].EventID()
}
ires[len(outliers)] = api.InputRoomEvent{
Kind: api.KindNew,
Event: event.JSON(),
AuthEventIDs: authEventIDs(event),
HasState: true,
StateEventIDs: stateEventIDs,
}
eventIDs[len(outliers)] = event.EventID()
return c.SendInputRoomEvents(ires, eventIDs)
}
func authEventIDs(event gomatrixserverlib.Event) (ids []string) {
for _, ref := range event.AuthEvents() {
ids = append(ids, ref.EventID)
}
return
}
// SendInputRoomEvents writes the given input room events to the roomserver input log. The length of both // SendInputRoomEvents writes the given input room events to the roomserver input log. The length of both
// arrays must match, and each element must correspond to the same event. // arrays must match, and each element must correspond to the same event.
func (c *RoomserverProducer) SendInputRoomEvents(ires []api.InputRoomEvent, eventIDs []string) error { func (c *RoomserverProducer) SendInputRoomEvents(ires []api.InputRoomEvent, eventIDs []string) error {

View file

@ -40,9 +40,10 @@ const pathPrefixR0 = "/_matrix/client/r0"
func Setup( func Setup(
servMux *http.ServeMux, httpClient *http.Client, cfg config.ClientAPI, servMux *http.ServeMux, httpClient *http.Client, cfg config.ClientAPI,
producer *producers.RoomserverProducer, queryAPI api.RoomserverQueryAPI, producer *producers.RoomserverProducer, queryAPI api.RoomserverQueryAPI,
accountDB *storage.AccountDatabase, accountDB *accounts.Database,
deviceDB *devices.Database, deviceDB *devices.Database,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
keyRing gomatrixserverlib.KeyRing,
) { ) {
apiMux := mux.NewRouter() apiMux := mux.NewRouter()
r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter() r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter()
@ -52,10 +53,10 @@ func Setup(
}), }),
) )
r0mux.Handle("/join/{roomIDOrAlias}", r0mux.Handle("/join/{roomIDOrAlias}",
makeAPI("join", func(req *http.Request) util.JSONResponse { common.MakeAuthAPI("join", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
vars := mux.Vars(req) vars := mux.Vars(req)
return writers.JoinRoomByIDOrAlias( return writers.JoinRoomByIDOrAlias(
req, vars["roomIDOrAlias"], cfg, federation, producer, queryAPI, req, device, vars["roomIDOrAlias"], cfg, federation, producer, queryAPI, keyRing,
) )
}), }),
) )

View file

@ -16,7 +16,7 @@ package writers
import ( import (
"fmt" "fmt"
"github.com/matrix-org/dendrite/clientapi/auth" "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/config" "github.com/matrix-org/dendrite/clientapi/config"
"github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
@ -34,16 +34,14 @@ import (
// https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-join-roomidoralias // https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-join-roomidoralias
func JoinRoomByIDOrAlias( func JoinRoomByIDOrAlias(
req *http.Request, req *http.Request,
device *authtypes.Device,
roomIDOrAlias string, roomIDOrAlias string,
cfg config.ClientAPI, cfg config.ClientAPI,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
producer *producers.RoomserverProducer, producer *producers.RoomserverProducer,
queryAPI api.RoomserverQueryAPI, queryAPI api.RoomserverQueryAPI,
keyRing gomatrixserverlib.KeyRing,
) util.JSONResponse { ) util.JSONResponse {
userID, resErr := auth.VerifyAccessToken(req)
if resErr != nil {
return *resErr
}
var content map[string]interface{} // must be a JSON object var content map[string]interface{} // must be a JSON object
if resErr := httputil.UnmarshalJSONRequest(req, &content); resErr != nil { if resErr := httputil.UnmarshalJSONRequest(req, &content); resErr != nil {
return *resErr return *resErr
@ -51,7 +49,7 @@ func JoinRoomByIDOrAlias(
content["membership"] = "join" content["membership"] = "join"
r := joinRoomReq{req, content, userID, cfg, federation, producer, queryAPI} r := joinRoomReq{req, content, device.UserID, cfg, federation, producer, queryAPI, keyRing}
if strings.HasPrefix(roomIDOrAlias, "!") { if strings.HasPrefix(roomIDOrAlias, "!") {
return r.joinRoomByID() return r.joinRoomByID()
@ -73,6 +71,7 @@ type joinRoomReq struct {
federation *gomatrixserverlib.FederationClient federation *gomatrixserverlib.FederationClient
producer *producers.RoomserverProducer producer *producers.RoomserverProducer
queryAPI api.RoomserverQueryAPI queryAPI api.RoomserverQueryAPI
keyRing gomatrixserverlib.KeyRing
} }
// joinRoomByID joins a room by roomID // joinRoomByID joins a room by roomID
@ -163,7 +162,7 @@ func (r joinRoomReq) joinRoomUsingServers(
var event gomatrixserverlib.Event var event gomatrixserverlib.Event
var respMakeJoin gomatrixserverlib.RespMakeJoin var respMakeJoin gomatrixserverlib.RespMakeJoin
//var respSendJoin gomatrixserverlib.RespSendJoin var respSendJoin gomatrixserverlib.RespSendJoin
for _, server := range servers { for _, server := range servers {
respMakeJoin, err = r.federation.MakeJoin(server, roomID, r.userID) respMakeJoin, err = r.federation.MakeJoin(server, roomID, r.userID)
if err != nil { if err != nil {
@ -184,16 +183,22 @@ func (r joinRoomReq) joinRoomUsingServers(
); err != nil { ); err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
respSendJoin, err = r.federation.SendJoin(server, event)
_, err = r.federation.SendJoin(server, event)
if err != nil { if err != nil {
// Try the next server in the list. // Try the next server in the list.
continue continue
} }
// TODO: validate the state response. if err = respSendJoin.Check(r.keyRing, event); err != nil {
// TODO: check that the join event passes auth against the state response. // Try the next server in the list.
// TODO: send the state and the join event to the room server. continue
}
if err = r.producer.SendEventWithState(
gomatrixserverlib.RespState(respSendJoin), event,
); err != nil {
return util.ErrorResponse(err)
}
return util.JSONResponse{ return util.JSONResponse{
Code: 200, Code: 200,

View file

@ -94,6 +94,32 @@ func main() {
log.Panicf("Failed to setup device database(%s): %s", accountDataSource, err.Error()) log.Panicf("Failed to setup device database(%s): %s", accountDataSource, err.Error())
} }
routing.Setup(http.DefaultServeMux, http.DefaultClient, cfg, roomserverProducer, queryAPI, accountDB, deviceDB, federation) keyRing := gomatrixserverlib.KeyRing{
KeyFetchers: []gomatrixserverlib.KeyFetcher{
// TODO: Use perspective key fetchers for production.
&gomatrixserverlib.DirectKeyFetcher{federation.Client},
},
KeyDatabase: &dummyKeyDatabase{},
}
routing.Setup(
http.DefaultServeMux, http.DefaultClient, cfg, roomserverProducer,
queryAPI, accountDB, deviceDB, federation, keyRing,
)
log.Fatal(http.ListenAndServe(bindAddr, nil)) log.Fatal(http.ListenAndServe(bindAddr, nil))
} }
// TODO: Implement a proper key database.
type dummyKeyDatabase struct{}
func (d *dummyKeyDatabase) FetchKeys(
requests map[gomatrixserverlib.PublicKeyRequest]gomatrixserverlib.Timestamp,
) (map[gomatrixserverlib.PublicKeyRequest]gomatrixserverlib.ServerKeys, error) {
return nil, nil
}
func (d *dummyKeyDatabase) StoreKeys(
map[gomatrixserverlib.PublicKeyRequest]gomatrixserverlib.ServerKeys,
) error {
return nil
}

2
vendor/manifest vendored
View file

@ -98,7 +98,7 @@
{ {
"importpath": "github.com/matrix-org/gomatrixserverlib", "importpath": "github.com/matrix-org/gomatrixserverlib",
"repository": "https://github.com/matrix-org/gomatrixserverlib", "repository": "https://github.com/matrix-org/gomatrixserverlib",
"revision": "9cefcd6c3a00bff51e719a33e19a16edf52cdd6f", "revision": "c396ef3cc1e546729f7052f1f48e345cc59269f4",
"branch": "master" "branch": "master"
}, },
{ {

View file

@ -386,7 +386,7 @@ func (e Event) CheckFields() error {
// are allowed to have a different sender because they have the same // are allowed to have a different sender because they have the same
// sender as the "m.room.third_party_invite" event they derived from. // sender as the "m.room.third_party_invite" event they derived from.
// https://github.com/matrix-org/synapse/blob/v0.21.0/synapse/event_auth.py#L58-L64 // https://github.com/matrix-org/synapse/blob/v0.21.0/synapse/event_auth.py#L58-L64
if e.fields.Type != "m.room.member" { if e.fields.Type != MRoomMember {
return fmt.Errorf( return fmt.Errorf(
"gomatrixserverlib: sender domain doesn't match origin: %q != %q", "gomatrixserverlib: sender domain doesn't match origin: %q != %q",
eventDomain, e.fields.Origin, eventDomain, e.fields.Origin,

View file

@ -28,6 +28,22 @@ const (
leave = "leave" leave = "leave"
invite = "invite" invite = "invite"
public = "public" public = "public"
// MRoomCreate https://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-create
MRoomCreate = "m.room.create"
// MRoomJoinRules https://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-join-rules
MRoomJoinRules = "m.room.join_rules"
// MRoomPowerLevels https://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-power-levels
MRoomPowerLevels = "m.room.power_levels"
// MRoomMember https://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-member
MRoomMember = "m.room.member"
// MRoomThirdPartyInvite https://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-third-party-invite
MRoomThirdPartyInvite = "m.room.third_party_invite"
// MRoomAliases https://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-aliases
MRoomAliases = "m.room.aliases"
// MRoomHistoryVisibility https://matrix.org/docs/spec/client_server/r0.2.0.html#m-room-history-visibility
MRoomHistoryVisibility = "m.room.history_visibility"
// MRoomRedaction https://matrix.org/docs/spec/client_server/r0.2.0.html#id21
MRoomRedaction = "m.room.redaction"
) )
// StateNeeded lists the event types and state_keys needed to authenticate an event. // StateNeeded lists the event types and state_keys needed to authenticate an event.
@ -47,19 +63,19 @@ type StateNeeded struct {
// Tuples returns the needed state key tuples for performing auth on an event. // Tuples returns the needed state key tuples for performing auth on an event.
func (s StateNeeded) Tuples() (res []StateKeyTuple) { func (s StateNeeded) Tuples() (res []StateKeyTuple) {
if s.Create { if s.Create {
res = append(res, StateKeyTuple{"m.room.create", ""}) res = append(res, StateKeyTuple{MRoomCreate, ""})
} }
if s.JoinRules { if s.JoinRules {
res = append(res, StateKeyTuple{"m.room.join_rules", ""}) res = append(res, StateKeyTuple{MRoomJoinRules, ""})
} }
if s.PowerLevels { if s.PowerLevels {
res = append(res, StateKeyTuple{"m.room.power_levels", ""}) res = append(res, StateKeyTuple{MRoomPowerLevels, ""})
} }
for _, userID := range s.Member { for _, userID := range s.Member {
res = append(res, StateKeyTuple{"m.room.member", userID}) res = append(res, StateKeyTuple{MRoomMember, userID})
} }
for _, token := range s.ThirdPartyInvite { for _, token := range s.ThirdPartyInvite {
res = append(res, StateKeyTuple{"m.room.third_party_invite", token}) res = append(res, StateKeyTuple{MRoomThirdPartyInvite, token})
} }
return return
} }
@ -114,7 +130,7 @@ func (s StateNeeded) AuthEventReferences(provider AuthEventProvider) (refs []Eve
func StateNeededForEventBuilder(builder *EventBuilder) (result StateNeeded, err error) { func StateNeededForEventBuilder(builder *EventBuilder) (result StateNeeded, err error) {
// Extract the 'content' object from the event if it is m.room.member as we need to know 'membership' // Extract the 'content' object from the event if it is m.room.member as we need to know 'membership'
var content *memberContent var content *memberContent
if builder.Type == "m.room.member" { if builder.Type == MRoomMember {
if err = json.Unmarshal(builder.Content, &content); err != nil { if err = json.Unmarshal(builder.Content, &content); err != nil {
err = errorf("unparsable member event content: %s", err.Error()) err = errorf("unparsable member event content: %s", err.Error())
return return
@ -132,7 +148,7 @@ func StateNeededForAuth(events []Event) (result StateNeeded) {
for _, event := range events { for _, event := range events {
// Extract the 'content' object from the event if it is m.room.member as we need to know 'membership' // Extract the 'content' object from the event if it is m.room.member as we need to know 'membership'
var content *memberContent var content *memberContent
if event.Type() == "m.room.member" { if event.Type() == MRoomMember {
c, err := newMemberContentFromEvent(event) c, err := newMemberContentFromEvent(event)
if err == nil { if err == nil {
content = &c content = &c
@ -151,17 +167,17 @@ func StateNeededForAuth(events []Event) (result StateNeeded) {
func accumulateStateNeeded(result *StateNeeded, eventType, sender string, stateKey *string, content *memberContent) (err error) { func accumulateStateNeeded(result *StateNeeded, eventType, sender string, stateKey *string, content *memberContent) (err error) {
switch eventType { switch eventType {
case "m.room.create": case MRoomCreate:
// The create event doesn't require any state to authenticate. // The create event doesn't require any state to authenticate.
// https://github.com/matrix-org/synapse/blob/v0.18.5/synapse/api/auth.py#L123 // https://github.com/matrix-org/synapse/blob/v0.18.5/synapse/api/auth.py#L123
case "m.room.aliases": case MRoomAliases:
// Alias events need: // Alias events need:
// * The create event. // * The create event.
// https://github.com/matrix-org/synapse/blob/v0.18.5/synapse/api/auth.py#L128 // https://github.com/matrix-org/synapse/blob/v0.18.5/synapse/api/auth.py#L128
// Alias events need no further authentication. // Alias events need no further authentication.
// https://github.com/matrix-org/synapse/blob/v0.18.5/synapse/api/auth.py#L160 // https://github.com/matrix-org/synapse/blob/v0.18.5/synapse/api/auth.py#L160
result.Create = true result.Create = true
case "m.room.member": case MRoomMember:
// Member events need: // Member events need:
// * The previous membership of the target. // * The previous membership of the target.
// https://github.com/matrix-org/synapse/blob/v0.18.5/synapse/api/auth.py#L355 // https://github.com/matrix-org/synapse/blob/v0.18.5/synapse/api/auth.py#L355
@ -255,27 +271,27 @@ func (a *AuthEvents) AddEvent(event *Event) error {
// Create implements AuthEventProvider // Create implements AuthEventProvider
func (a *AuthEvents) Create() (*Event, error) { func (a *AuthEvents) Create() (*Event, error) {
return a.events[StateKeyTuple{"m.room.create", ""}], nil return a.events[StateKeyTuple{MRoomCreate, ""}], nil
} }
// JoinRules implements AuthEventProvider // JoinRules implements AuthEventProvider
func (a *AuthEvents) JoinRules() (*Event, error) { func (a *AuthEvents) JoinRules() (*Event, error) {
return a.events[StateKeyTuple{"m.room.join_rules", ""}], nil return a.events[StateKeyTuple{MRoomJoinRules, ""}], nil
} }
// PowerLevels implements AuthEventProvider // PowerLevels implements AuthEventProvider
func (a *AuthEvents) PowerLevels() (*Event, error) { func (a *AuthEvents) PowerLevels() (*Event, error) {
return a.events[StateKeyTuple{"m.room.power_levels", ""}], nil return a.events[StateKeyTuple{MRoomPowerLevels, ""}], nil
} }
// Member implements AuthEventProvider // Member implements AuthEventProvider
func (a *AuthEvents) Member(stateKey string) (*Event, error) { func (a *AuthEvents) Member(stateKey string) (*Event, error) {
return a.events[StateKeyTuple{"m.room.member", stateKey}], nil return a.events[StateKeyTuple{MRoomMember, stateKey}], nil
} }
// ThirdPartyInvite implements AuthEventProvider // ThirdPartyInvite implements AuthEventProvider
func (a *AuthEvents) ThirdPartyInvite(stateKey string) (*Event, error) { func (a *AuthEvents) ThirdPartyInvite(stateKey string) (*Event, error) {
return a.events[StateKeyTuple{"m.room.third_party_invite", stateKey}], nil return a.events[StateKeyTuple{MRoomThirdPartyInvite, stateKey}], nil
} }
// NewAuthEvents returns an AuthEventProvider backed by the given events. New events can be added by // NewAuthEvents returns an AuthEventProvider backed by the given events. New events can be added by
@ -306,15 +322,15 @@ func errorf(message string, args ...interface{}) error {
// If there was an error loading the auth events then it returns that error. // If there was an error loading the auth events then it returns that error.
func Allowed(event Event, authEvents AuthEventProvider) error { func Allowed(event Event, authEvents AuthEventProvider) error {
switch event.Type() { switch event.Type() {
case "m.room.create": case MRoomCreate:
return createEventAllowed(event) return createEventAllowed(event)
case "m.room.aliases": case MRoomAliases:
return aliasEventAllowed(event, authEvents) return aliasEventAllowed(event, authEvents)
case "m.room.member": case MRoomMember:
return memberEventAllowed(event, authEvents) return memberEventAllowed(event, authEvents)
case "m.room.power_levels": case MRoomPowerLevels:
return powerLevelsEventAllowed(event, authEvents) return powerLevelsEventAllowed(event, authEvents)
case "m.room.redaction": case MRoomRedaction:
return redactEventAllowed(event, authEvents) return redactEventAllowed(event, authEvents)
default: default:
return defaultEventAllowed(event, authEvents) return defaultEventAllowed(event, authEvents)

View file

@ -191,7 +191,7 @@ func (c *powerLevelContent) userLevel(userID string) int64 {
// eventLevel returns the power level needed to send an event in the room. // eventLevel returns the power level needed to send an event in the room.
func (c *powerLevelContent) eventLevel(eventType string, isState bool) int64 { func (c *powerLevelContent) eventLevel(eventType string, isState bool) int64 {
if eventType == "m.room.third_party_invite" { if eventType == MRoomThirdPartyInvite {
// Special case third_party_invite events to have the same level as // Special case third_party_invite events to have the same level as
// m.room.member invite events. // m.room.member invite events.
// https://github.com/matrix-org/synapse/blob/v0.18.5/synapse/api/auth.py#L182 // https://github.com/matrix-org/synapse/blob/v0.18.5/synapse/api/auth.py#L182

View file

@ -201,9 +201,9 @@ func VerifyEventSignatures(events []Event, keyRing KeyRing) error {
} }
toVerify = append(toVerify, v) toVerify = append(toVerify, v)
// "m.room.member" invite events are signed by both the server sending // MRoomMember invite events are signed by both the server sending
// the invite and the server the invite is for. // the invite and the server the invite is for.
if event.Type() == "m.room.member" && event.StateKey() != nil { if event.Type() == MRoomMember && event.StateKey() != nil {
targetDomain, err := domainFromID(*event.StateKey()) targetDomain, err := domainFromID(*event.StateKey())
if err != nil { if err != nil {
return err return err

View file

@ -34,6 +34,78 @@ type RespState struct {
AuthEvents []Event `json:"auth_chain"` AuthEvents []Event `json:"auth_chain"`
} }
// Events combines the auth events and the state events and returns
// them in an order where every event comes after its auth events.
// Each event will only appear once in the output list.
// Returns an error if there are missing auth events or if there is
// a cycle in the auth events.
func (r RespState) Events() ([]Event, error) {
eventsByID := map[string]*Event{}
// Collect a map of event reference to event
for i := range r.StateEvents {
eventsByID[r.StateEvents[i].EventID()] = &r.StateEvents[i]
}
for i := range r.AuthEvents {
eventsByID[r.AuthEvents[i].EventID()] = &r.AuthEvents[i]
}
queued := map[*Event]bool{}
outputted := map[*Event]bool{}
var result []Event
for _, event := range eventsByID {
if outputted[event] {
// If we've already written the event then we can skip it.
continue
}
// The code below does a depth first scan through the auth events
// looking for events that can be appended to the output.
// We use an explicit stack rather than using recursion so
// that we can check we aren't creating cycles.
stack := []*Event{event}
LoopProcessTopOfStack:
for len(stack) > 0 {
top := stack[len(stack)-1]
// Check if we can output the top of the stack.
// We can output it if we have outputted all of its auth_events.
for _, ref := range top.AuthEvents() {
authEvent := eventsByID[ref.EventID]
if authEvent == nil {
return nil, fmt.Errorf(
"gomatrixserverlib: missing auth event with ID %q for event %q",
ref.EventID, top.EventID(),
)
}
if outputted[authEvent] {
continue
}
if queued[authEvent] {
return nil, fmt.Errorf(
"gomatrixserverlib: auth event cycle for ID %q",
ref.EventID,
)
}
// If we haven't visited the auth event yet then we need to
// process it before processing the event currently on top of
// the stack.
stack = append(stack, authEvent)
queued[authEvent] = true
continue LoopProcessTopOfStack
}
// If we've processed all the auth events for the event on top of
// the stack then we can append it to the result and try processing
// the item below it in the stack.
result = append(result, *top)
outputted[top] = true
stack = stack[:len(stack)-1]
}
}
return result, nil
}
// Check that a response to /state is valid. // Check that a response to /state is valid.
func (r RespState) Check(keyRing KeyRing) error { func (r RespState) Check(keyRing KeyRing) error {
var allEvents []Event var allEvents []Event

View file

@ -140,17 +140,17 @@ func redactEvent(eventJSON []byte) ([]byte, error) {
// Copy the content fields that we should keep for the event type. // Copy the content fields that we should keep for the event type.
// By default we copy nothing leaving the content object empty. // By default we copy nothing leaving the content object empty.
switch event.Type { switch event.Type {
case "m.room.create": case MRoomCreate:
newContent.createContent = event.Content.createContent newContent.createContent = event.Content.createContent
case "m.room.member": case MRoomMember:
newContent.memberContent = event.Content.memberContent newContent.memberContent = event.Content.memberContent
case "m.room.join_rules": case MRoomJoinRules:
newContent.joinRulesContent = event.Content.joinRulesContent newContent.joinRulesContent = event.Content.joinRulesContent
case "m.room.power_levels": case MRoomPowerLevels:
newContent.powerLevelContent = event.Content.powerLevelContent newContent.powerLevelContent = event.Content.powerLevelContent
case "m.room.history_visibility": case MRoomHistoryVisibility:
newContent.historyVisibilityContent = event.Content.historyVisibilityContent newContent.historyVisibilityContent = event.Content.historyVisibilityContent
case "m.room.aliases": case MRoomAliases:
newContent.aliasesContent = event.Content.aliasesContent newContent.aliasesContent = event.Content.aliasesContent
} }
// Replace the content with our new filtered content. // Replace the content with our new filtered content.

View file

@ -114,24 +114,24 @@ func (r *stateResolver) addConflicted(events []Event) {
// By default we add the event to a block in the others list. // By default we add the event to a block in the others list.
blockList := &r.others blockList := &r.others
switch key.eventType { switch key.eventType {
case "m.room.create": case MRoomCreate:
if key.stateKey == "" { if key.stateKey == "" {
r.creates = append(r.creates, event) r.creates = append(r.creates, event)
continue continue
} }
case "m.room.power_levels": case MRoomPowerLevels:
if key.stateKey == "" { if key.stateKey == "" {
r.powerLevels = append(r.powerLevels, event) r.powerLevels = append(r.powerLevels, event)
continue continue
} }
case "m.room.join_rules": case MRoomJoinRules:
if key.stateKey == "" { if key.stateKey == "" {
r.joinRules = append(r.joinRules, event) r.joinRules = append(r.joinRules, event)
continue continue
} }
case "m.room.member": case MRoomMember:
blockList = &r.members blockList = &r.members
case "m.room.third_party_invite": case MRoomThirdPartyInvite:
blockList = &r.thirdPartyInvites blockList = &r.thirdPartyInvites
} }
// We need to find an entry for the state key in a block list. // We need to find an entry for the state key in a block list.
@ -153,21 +153,21 @@ func (r *stateResolver) addConflicted(events []Event) {
// Add an event to the resolved auth events. // Add an event to the resolved auth events.
func (r *stateResolver) addAuthEvent(event *Event) { func (r *stateResolver) addAuthEvent(event *Event) {
switch event.Type() { switch event.Type() {
case "m.room.create": case MRoomCreate:
if event.StateKeyEquals("") { if event.StateKeyEquals("") {
r.resolvedCreate = event r.resolvedCreate = event
} }
case "m.room.power_levels": case MRoomPowerLevels:
if event.StateKeyEquals("") { if event.StateKeyEquals("") {
r.resolvedPowerLevels = event r.resolvedPowerLevels = event
} }
case "m.room.join_rules": case MRoomJoinRules:
if event.StateKeyEquals("") { if event.StateKeyEquals("") {
r.resolvedJoinRules = event r.resolvedJoinRules = event
} }
case "m.room.member": case MRoomMember:
r.resolvedMembers[*event.StateKey()] = event r.resolvedMembers[*event.StateKey()] = event
case "m.room.third_party_invite": case MRoomThirdPartyInvite:
r.resolvedThirdPartyInvites[*event.StateKey()] = event r.resolvedThirdPartyInvites[*event.StateKey()] = event
default: default:
panic(fmt.Errorf("Unexpected auth event with type %q", event.Type())) panic(fmt.Errorf("Unexpected auth event with type %q", event.Type()))
@ -177,21 +177,21 @@ func (r *stateResolver) addAuthEvent(event *Event) {
// Remove the auth event with the given type and state key. // Remove the auth event with the given type and state key.
func (r *stateResolver) removeAuthEvent(eventType, stateKey string) { func (r *stateResolver) removeAuthEvent(eventType, stateKey string) {
switch eventType { switch eventType {
case "m.room.create": case MRoomCreate:
if stateKey == "" { if stateKey == "" {
r.resolvedCreate = nil r.resolvedCreate = nil
} }
case "m.room.power_levels": case MRoomPowerLevels:
if stateKey == "" { if stateKey == "" {
r.resolvedPowerLevels = nil r.resolvedPowerLevels = nil
} }
case "m.room.join_rules": case MRoomJoinRules:
if stateKey == "" { if stateKey == "" {
r.resolvedJoinRules = nil r.resolvedJoinRules = nil
} }
case "m.room.member": case MRoomMember:
r.resolvedMembers[stateKey] = nil r.resolvedMembers[stateKey] = nil
case "m.room.third_party_invite": case MRoomThirdPartyInvite:
r.resolvedThirdPartyInvites[stateKey] = nil r.resolvedThirdPartyInvites[stateKey] = nil
default: default:
panic(fmt.Errorf("Unexpected auth event with type %q", eventType)) panic(fmt.Errorf("Unexpected auth event with type %q", eventType))