Merge branch 'master' into txn-cache-scope

This commit is contained in:
Andrew Morgan 2019-08-06 15:10:57 +01:00
commit 3a8ccb3d82
23 changed files with 321 additions and 65 deletions

View file

@ -230,7 +230,7 @@ func (d *Database) newMembership(
}
// Only "join" membership events can be considered as new memberships
if membership == "join" {
if membership == gomatrixserverlib.Join {
if err := d.saveMembership(ctx, txn, localpart, roomID, eventID); err != nil {
return err
}

View file

@ -55,10 +55,6 @@ const (
presetPublicChat = "public_chat"
)
const (
joinRulePublic = "public"
joinRuleInvite = "invite"
)
const (
historyVisibilityShared = "shared"
// TODO: These should be implemented once history visibility is implemented
@ -201,7 +197,7 @@ func createRoom(
}
membershipContent := common.MemberContent{
Membership: "join",
Membership: gomatrixserverlib.Join,
DisplayName: profile.DisplayName,
AvatarURL: profile.AvatarURL,
}
@ -209,19 +205,19 @@ func createRoom(
var joinRules, historyVisibility string
switch r.Preset {
case presetPrivateChat:
joinRules = joinRuleInvite
joinRules = gomatrixserverlib.Invite
historyVisibility = historyVisibilityShared
case presetTrustedPrivateChat:
joinRules = joinRuleInvite
joinRules = gomatrixserverlib.Invite
historyVisibility = historyVisibilityShared
// TODO If trusted_private_chat, all invitees are given the same power level as the room creator.
case presetPublicChat:
joinRules = joinRulePublic
joinRules = gomatrixserverlib.Public
historyVisibility = historyVisibilityShared
default:
// Default room rules, r.Preset was previously checked for valid values so
// only a request with no preset should end up here.
joinRules = joinRuleInvite
joinRules = gomatrixserverlib.Invite
historyVisibility = historyVisibilityShared
}

View file

@ -70,7 +70,7 @@ func JoinRoomByIDOrAlias(
return httputil.LogThenError(req, err)
}
content["membership"] = "join"
content["membership"] = gomatrixserverlib.Join
content["displayname"] = profile.DisplayName
content["avatar_url"] = profile.AvatarURL

View file

@ -102,7 +102,7 @@ func SendMembership(
var returnData interface{} = struct{}{}
// The join membership requires the room id to be sent in the response
if membership == "join" {
if membership == gomatrixserverlib.Join {
returnData = struct {
RoomID string `json:"room_id"`
}{roomID}
@ -141,7 +141,7 @@ func buildMembershipEvent(
// "unban" or "kick" isn't a valid membership value, change it to "leave"
if membership == "unban" || membership == "kick" {
membership = "leave"
membership = gomatrixserverlib.Leave
}
content := common.MemberContent{
@ -192,7 +192,7 @@ func loadProfile(
func getMembershipStateKey(
body threepid.MembershipRequest, device *authtypes.Device, membership string,
) (stateKey string, reason string, err error) {
if membership == "ban" || membership == "unban" || membership == "kick" || membership == "invite" {
if membership == gomatrixserverlib.Ban || membership == "unban" || membership == "kick" || membership == gomatrixserverlib.Invite {
// If we're in this case, the state key is contained in the request body,
// possibly along with a reason (for "kick" and "ban") so we need to parse
// it

View file

@ -264,7 +264,7 @@ func buildMembershipEvents(
}
content := common.MemberContent{
Membership: "join",
Membership: gomatrixserverlib.Join,
}
content.DisplayName = newProfile.DisplayName

View file

@ -0,0 +1,234 @@
// Copyright 2019 Sumukha PK
//
// 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 routing
import (
"encoding/json"
"net/http"
"github.com/sirupsen/logrus"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/producers"
"github.com/matrix-org/gomatrix"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
)
// newTag creates and returns a new gomatrix.TagContent
func newTag() gomatrix.TagContent {
return gomatrix.TagContent{
Tags: make(map[string]gomatrix.TagProperties),
}
}
// GetTags implements GET /_matrix/client/r0/user/{userID}/rooms/{roomID}/tags
func GetTags(
req *http.Request,
accountDB *accounts.Database,
device *authtypes.Device,
userID string,
roomID string,
syncProducer *producers.SyncAPIProducer,
) util.JSONResponse {
if device.UserID != userID {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Cannot retrieve another user's tags"),
}
}
_, data, err := obtainSavedTags(req, userID, roomID, accountDB)
if err != nil {
return httputil.LogThenError(req, err)
}
if len(data) == 0 {
return util.JSONResponse{
Code: http.StatusOK,
JSON: struct{}{},
}
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: data[0].Content,
}
}
// PutTag implements PUT /_matrix/client/r0/user/{userID}/rooms/{roomID}/tags/{tag}
// Put functionality works by getting existing data from the DB (if any), adding
// the tag to the "map" and saving the new "map" to the DB
func PutTag(
req *http.Request,
accountDB *accounts.Database,
device *authtypes.Device,
userID string,
roomID string,
tag string,
syncProducer *producers.SyncAPIProducer,
) util.JSONResponse {
if device.UserID != userID {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Cannot modify another user's tags"),
}
}
var properties gomatrix.TagProperties
if reqErr := httputil.UnmarshalJSONRequest(req, &properties); reqErr != nil {
return *reqErr
}
localpart, data, err := obtainSavedTags(req, userID, roomID, accountDB)
if err != nil {
return httputil.LogThenError(req, err)
}
var tagContent gomatrix.TagContent
if len(data) > 0 {
if err = json.Unmarshal(data[0].Content, &tagContent); err != nil {
return httputil.LogThenError(req, err)
}
} else {
tagContent = newTag()
}
tagContent.Tags[tag] = properties
if err = saveTagData(req, localpart, roomID, accountDB, tagContent); err != nil {
return httputil.LogThenError(req, err)
}
// Send data to syncProducer in order to inform clients of changes
// Run in a goroutine in order to prevent blocking the tag request response
go func() {
if err := syncProducer.SendData(userID, roomID, "m.tag"); err != nil {
logrus.WithError(err).Error("Failed to send m.tag account data update to syncapi")
}
}()
return util.JSONResponse{
Code: http.StatusOK,
JSON: struct{}{},
}
}
// DeleteTag implements DELETE /_matrix/client/r0/user/{userID}/rooms/{roomID}/tags/{tag}
// Delete functionality works by obtaining the saved tags, removing the intended tag from
// the "map" and then saving the new "map" in the DB
func DeleteTag(
req *http.Request,
accountDB *accounts.Database,
device *authtypes.Device,
userID string,
roomID string,
tag string,
syncProducer *producers.SyncAPIProducer,
) util.JSONResponse {
if device.UserID != userID {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("Cannot modify another user's tags"),
}
}
localpart, data, err := obtainSavedTags(req, userID, roomID, accountDB)
if err != nil {
return httputil.LogThenError(req, err)
}
// If there are no tags in the database, exit
if len(data) == 0 {
// Spec only defines 200 responses for this endpoint so we don't return anything else.
return util.JSONResponse{
Code: http.StatusOK,
JSON: struct{}{},
}
}
var tagContent gomatrix.TagContent
err = json.Unmarshal(data[0].Content, &tagContent)
if err != nil {
return httputil.LogThenError(req, err)
}
// Check whether the tag to be deleted exists
if _, ok := tagContent.Tags[tag]; ok {
delete(tagContent.Tags, tag)
} else {
// Spec only defines 200 responses for this endpoint so we don't return anything else.
return util.JSONResponse{
Code: http.StatusOK,
JSON: struct{}{},
}
}
if err = saveTagData(req, localpart, roomID, accountDB, tagContent); err != nil {
return httputil.LogThenError(req, err)
}
// Send data to syncProducer in order to inform clients of changes
// Run in a goroutine in order to prevent blocking the tag request response
go func() {
if err := syncProducer.SendData(userID, roomID, "m.tag"); err != nil {
logrus.WithError(err).Error("Failed to send m.tag account data update to syncapi")
}
}()
return util.JSONResponse{
Code: http.StatusOK,
JSON: struct{}{},
}
}
// obtainSavedTags gets all tags scoped to a userID and roomID
// from the database
func obtainSavedTags(
req *http.Request,
userID string,
roomID string,
accountDB *accounts.Database,
) (string, []gomatrixserverlib.ClientEvent, error) {
localpart, _, err := gomatrixserverlib.SplitID('@', userID)
if err != nil {
return "", nil, err
}
data, err := accountDB.GetAccountDataByType(
req.Context(), localpart, roomID, "m.tag",
)
return localpart, data, err
}
// saveTagData saves the provided tag data into the database
func saveTagData(
req *http.Request,
localpart string,
roomID string,
accountDB *accounts.Database,
Tag gomatrix.TagContent,
) error {
newTagData, err := json.Marshal(Tag)
if err != nil {
return err
}
return accountDB.SaveAccountData(req.Context(), localpart, roomID, "m.tag", string(newTagData))
}

View file

@ -93,7 +93,7 @@ func Setup(
}),
).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/join/{roomIDOrAlias}",
common.MakeAuthAPI("join", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
common.MakeAuthAPI(gomatrixserverlib.Join, authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
vars, err := common.URLDecodeMapValues(mux.Vars(req))
if err != nil {
return util.ErrorResponse(err)
@ -483,4 +483,34 @@ func Setup(
}}
}),
).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/user/{userId}/rooms/{roomId}/tags",
common.MakeAuthAPI("get_tags", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
vars, err := common.URLDecodeMapValues(mux.Vars(req))
if err != nil {
return util.ErrorResponse(err)
}
return GetTags(req, accountDB, device, vars["userId"], vars["roomId"], syncProducer)
}),
).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/user/{userId}/rooms/{roomId}/tags/{tag}",
common.MakeAuthAPI("put_tag", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
vars, err := common.URLDecodeMapValues(mux.Vars(req))
if err != nil {
return util.ErrorResponse(err)
}
return PutTag(req, accountDB, device, vars["userId"], vars["roomId"], vars["tag"], syncProducer)
}),
).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/user/{userId}/rooms/{roomId}/tags/{tag}",
common.MakeAuthAPI("delete_tag", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
vars, err := common.URLDecodeMapValues(mux.Vars(req))
if err != nil {
return util.ErrorResponse(err)
}
return DeleteTag(req, accountDB, device, vars["userId"], vars["roomId"], vars["tag"], syncProducer)
}),
).Methods(http.MethodDelete, http.MethodOptions)
}

View file

@ -91,7 +91,7 @@ func CheckAndProcessInvite(
producer *producers.RoomserverProducer, membership string, roomID string,
evTime time.Time,
) (inviteStoredOnIDServer bool, err error) {
if membership != "invite" || (body.Address == "" && body.IDServer == "" && body.Medium == "") {
if membership != gomatrixserverlib.Invite || (body.Address == "" && body.IDServer == "" && body.Medium == "") {
// If none of the 3PID-specific fields are supplied, it's a standard invite
// so return nil for it to be processed as such
return

View file

@ -86,7 +86,7 @@ func main() {
// Build a m.room.member event.
b.Type = "m.room.member"
b.StateKey = userID
b.SetContent(map[string]string{"membership": "join"}) // nolint: errcheck
b.SetContent(map[string]string{"membership": gomatrixserverlib.Join}) // nolint: errcheck
b.AuthEvents = []gomatrixserverlib.EventReference{create}
member := buildAndOutput()

View file

@ -58,7 +58,7 @@ func MakeJoin(
Type: "m.room.member",
StateKey: &userID,
}
err = builder.SetContent(map[string]interface{}{"membership": "join"})
err = builder.SetContent(map[string]interface{}{"membership": gomatrixserverlib.Join})
if err != nil {
return httputil.LogThenError(httpReq, err)
}

View file

@ -56,7 +56,7 @@ func MakeLeave(
Type: "m.room.member",
StateKey: &userID,
}
err = builder.SetContent(map[string]interface{}{"membership": "leave"})
err = builder.SetContent(map[string]interface{}{"membership": gomatrixserverlib.Leave})
if err != nil {
return httputil.LogThenError(httpReq, err)
}
@ -153,7 +153,7 @@ func SendLeave(
mem, err := event.Membership()
if err != nil {
return httputil.LogThenError(httpReq, err)
} else if mem != "leave" {
} else if mem != gomatrixserverlib.Leave {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.BadJSON("The membership in the event content must be set to leave"),

View file

@ -202,7 +202,7 @@ func createInviteFrom3PIDInvite(
content := common.MemberContent{
AvatarURL: profile.AvatarURL,
DisplayName: profile.DisplayName,
Membership: "invite",
Membership: gomatrixserverlib.Invite,
ThirdPartyInvite: &common.TPInvite{
Signed: inv.Signed,
},

View file

@ -233,7 +233,7 @@ func joinedHostsFromEvents(evs []gomatrixserverlib.Event) ([]types.JoinedHost, e
if err != nil {
return nil, err
}
if membership != "join" {
if membership != gomatrixserverlib.Join {
continue
}
_, serverName, err := gomatrixserverlib.SplitID('@', *ev.StateKey())

2
go.mod
View file

@ -24,7 +24,7 @@ require (
github.com/lib/pq v0.0.0-20170918175043-23da1db4f16d
github.com/matrix-org/dugong v0.0.0-20171220115018-ea0a4690a0d5
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26
github.com/matrix-org/gomatrixserverlib v0.0.0-20190724145009-a6df10ef35d6
github.com/matrix-org/gomatrixserverlib v0.0.0-20190805173246-3a2199d5ecd6
github.com/matrix-org/naffka v0.0.0-20171115094957-662bfd0841d0
github.com/matrix-org/util v0.0.0-20171127121716-2e2df66af2f5
github.com/matttproud/golang_protobuf_extensions v1.0.1

2
go.sum
View file

@ -56,6 +56,8 @@ github.com/matrix-org/gomatrixserverlib v0.0.0-20190619132215-178ed5e3b8e2 h1:pY
github.com/matrix-org/gomatrixserverlib v0.0.0-20190619132215-178ed5e3b8e2/go.mod h1:sf0RcKOdiwJeTti7A313xsaejNUGYDq02MQZ4JD4w/E=
github.com/matrix-org/gomatrixserverlib v0.0.0-20190724145009-a6df10ef35d6 h1:B8n1H5Wb1B5jwLzTylBpY0kJCMRqrofT7PmOw4aJFJA=
github.com/matrix-org/gomatrixserverlib v0.0.0-20190724145009-a6df10ef35d6/go.mod h1:sf0RcKOdiwJeTti7A313xsaejNUGYDq02MQZ4JD4w/E=
github.com/matrix-org/gomatrixserverlib v0.0.0-20190805173246-3a2199d5ecd6 h1:xr69Hk6QM3RIN6JSvx3RpDowBGpHpDDqhqXCeySwYow=
github.com/matrix-org/gomatrixserverlib v0.0.0-20190805173246-3a2199d5ecd6/go.mod h1:sf0RcKOdiwJeTti7A313xsaejNUGYDq02MQZ4JD4w/E=
github.com/matrix-org/naffka v0.0.0-20171115094957-662bfd0841d0 h1:p7WTwG+aXM86+yVrYAiCMW3ZHSmotVvuRbjtt3jC+4A=
github.com/matrix-org/naffka v0.0.0-20171115094957-662bfd0841d0/go.mod h1:cXoYQIENbdWIQHt1SyCo6Bl3C3raHwJ0wgVrXHSqf+A=
github.com/matrix-org/util v0.0.0-20171013132526-8b1c8ab81986 h1:TiWl4hLvezAhRPM8tPcPDFTysZ7k4T/1J4GPp/iqlZo=

View file

@ -19,6 +19,7 @@ import (
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/publicroomsapi/storage"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
)
@ -39,7 +40,7 @@ func GetVisibility(
var v roomVisibility
if isPublic {
v.Visibility = "public"
v.Visibility = gomatrixserverlib.Public
} else {
v.Visibility = "private"
}
@ -61,7 +62,7 @@ func SetVisibility(
return *reqErr
}
isPublic := v.Visibility == "public"
isPublic := v.Visibility == gomatrixserverlib.Public
if err := publicRoomsDatabase.SetRoomVisibility(req.Context(), isPublic, roomID); err != nil {
return httputil.LogThenError(req, err)
}

View file

@ -185,7 +185,7 @@ func (d *PublicRoomsServerDatabase) updateNumJoinedUsers(
return err
}
if membership != "join" {
if membership != gomatrixserverlib.Join {
return nil
}

View file

@ -23,7 +23,7 @@ func IsServerAllowed(
) bool {
for _, ev := range authEvents {
membership, err := ev.Membership()
if err != nil || membership != "join" {
if err != nil || membership != gomatrixserverlib.Join {
continue
}

View file

@ -23,13 +23,6 @@ import (
"github.com/matrix-org/gomatrixserverlib"
)
// Membership values
// TODO: Factor these out somewhere sensible?
const join = "join"
const leave = "leave"
const invite = "invite"
const ban = "ban"
// updateMembership updates the current membership and the invites for each
// user affected by a change in the current state of the room.
// Returns a list of output events to write to the kafka log to inform the
@ -91,8 +84,8 @@ func updateMembership(
) ([]api.OutputEvent, error) {
var err error
// Default the membership to Leave if no event was added or removed.
oldMembership := leave
newMembership := leave
oldMembership := gomatrixserverlib.Leave
newMembership := gomatrixserverlib.Leave
if remove != nil {
oldMembership, err = remove.Membership()
@ -106,7 +99,7 @@ func updateMembership(
return nil, err
}
}
if oldMembership == newMembership && newMembership != join {
if oldMembership == newMembership && newMembership != gomatrixserverlib.Join {
// If the membership is the same then nothing changed and we can return
// immediately, unless it's a Join update (e.g. profile update).
return updates, nil
@ -118,11 +111,11 @@ func updateMembership(
}
switch newMembership {
case invite:
case gomatrixserverlib.Invite:
return updateToInviteMembership(mu, add, updates)
case join:
case gomatrixserverlib.Join:
return updateToJoinMembership(mu, add, updates)
case leave, ban:
case gomatrixserverlib.Leave, gomatrixserverlib.Ban:
return updateToLeaveMembership(mu, add, newMembership, updates)
default:
panic(fmt.Errorf(
@ -183,7 +176,7 @@ func updateToJoinMembership(
for _, eventID := range retired {
orie := api.OutputRetireInviteEvent{
EventID: eventID,
Membership: join,
Membership: gomatrixserverlib.Join,
RetiredByEventID: add.EventID(),
TargetUserID: *add.StateKey(),
}

View file

@ -359,7 +359,7 @@ func (r *RoomserverQueryAPI) getMembershipsBeforeEventNID(
return nil, err
}
if membership == "join" {
if membership == gomatrixserverlib.Join {
events = append(events, event)
}
}

View file

@ -35,12 +35,6 @@ import (
"github.com/matrix-org/gomatrixserverlib"
)
const (
membershipJoin = "join"
membershipLeave = "leave"
membershipBan = "ban"
)
type stateDelta struct {
roomID string
stateEvents []gomatrixserverlib.Event
@ -356,7 +350,7 @@ func (d *SyncServerDatasource) IncrementalSync(
)
} else {
joinedRoomIDs, err = d.roomstate.selectRoomIDsWithMembership(
ctx, nil, device.UserID, membershipJoin,
ctx, nil, device.UserID, gomatrixserverlib.Join,
)
}
if err != nil {
@ -405,7 +399,7 @@ func (d *SyncServerDatasource) getResponseWithPDUsForCompleteSync(
res = types.NewResponse(toPos)
// Extract room state and recent events for all rooms the user is joined to.
joinedRoomIDs, err = d.roomstate.selectRoomIDsWithMembership(ctx, txn, userID, membershipJoin)
joinedRoomIDs, err = d.roomstate.selectRoomIDsWithMembership(ctx, txn, userID, gomatrixserverlib.Join)
if err != nil {
return
}
@ -583,7 +577,7 @@ func (d *SyncServerDatasource) addRoomDeltaToResponse(
res *types.Response,
) error {
endPos := toPos
if delta.membershipPos > 0 && delta.membership == membershipLeave {
if delta.membershipPos > 0 && delta.membership == gomatrixserverlib.Leave {
// make sure we don't leak recent events after the leave event.
// TODO: History visibility makes this somewhat complex to handle correctly. For example:
// TODO: This doesn't work for join -> leave in a single /sync request (see events prior to join).
@ -621,7 +615,7 @@ func (d *SyncServerDatasource) addRoomDeltaToResponse(
}
switch delta.membership {
case membershipJoin:
case gomatrixserverlib.Join:
jr := types.NewJoinResponse()
// Use the short form of batch token for prev_batch
jr.Timeline.PrevBatch = strconv.FormatInt(prevPDUPos, 10)
@ -629,9 +623,9 @@ func (d *SyncServerDatasource) addRoomDeltaToResponse(
jr.Timeline.Limited = false // TODO: if len(events) >= numRecents + 1 and then set limited:true
jr.State.Events = gomatrixserverlib.ToClientEvents(delta.stateEvents, gomatrixserverlib.FormatSync)
res.Rooms.Join[delta.roomID] = *jr
case membershipLeave:
case gomatrixserverlib.Leave:
fallthrough // transitions to leave are the same as ban
case membershipBan:
case gomatrixserverlib.Ban:
// TODO: recentEvents may contain events that this user is not allowed to see because they are
// no longer in the room.
lr := types.NewLeaveResponse()
@ -768,7 +762,7 @@ func (d *SyncServerDatasource) getStateDeltas(
// 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 == membershipJoin {
if membership == gomatrixserverlib.Join {
// send full room state down instead of a delta
var s []streamEvent
s, err = d.currentStateStreamEventsForRoom(ctx, txn, roomID)
@ -791,13 +785,13 @@ func (d *SyncServerDatasource) getStateDeltas(
}
// Add in currently joined rooms
joinedRoomIDs, err := d.roomstate.selectRoomIDsWithMembership(ctx, txn, userID, membershipJoin)
joinedRoomIDs, err := d.roomstate.selectRoomIDsWithMembership(ctx, txn, userID, gomatrixserverlib.Join)
if err != nil {
return nil, nil, err
}
for _, joinedRoomID := range joinedRoomIDs {
deltas = append(deltas, stateDelta{
membership: membershipJoin,
membership: gomatrixserverlib.Join,
stateEvents: streamEventsToEvents(device, state[joinedRoomID]),
roomID: joinedRoomID,
})
@ -814,7 +808,7 @@ func (d *SyncServerDatasource) getStateDeltasForFullStateSync(
ctx context.Context, device *authtypes.Device, txn *sql.Tx,
fromPos, toPos int64, userID string,
) ([]stateDelta, []string, error) {
joinedRoomIDs, err := d.roomstate.selectRoomIDsWithMembership(ctx, txn, userID, "join")
joinedRoomIDs, err := d.roomstate.selectRoomIDsWithMembership(ctx, txn, userID, gomatrixserverlib.Join)
if err != nil {
return nil, nil, err
}
@ -829,7 +823,7 @@ func (d *SyncServerDatasource) getStateDeltasForFullStateSync(
return nil, nil, stateErr
}
deltas = append(deltas, stateDelta{
membership: "join",
membership: gomatrixserverlib.Join,
stateEvents: streamEventsToEvents(device, s),
roomID: joinedRoomID,
})
@ -848,7 +842,7 @@ func (d *SyncServerDatasource) getStateDeltasForFullStateSync(
for roomID, stateStreamEvents := range state {
for _, ev := range stateStreamEvents {
if membership := getMembershipFromEvent(&ev.Event, userID); membership != "" {
if membership != "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 = append(deltas, stateDelta{
membership: membership,
membershipPos: ev.streamPosition,

View file

@ -93,16 +93,16 @@ func (n *Notifier) OnNewEvent(
} else {
// Keep the joined user map up-to-date
switch membership {
case "invite":
case gomatrixserverlib.Invite:
usersToNotify = append(usersToNotify, targetUserID)
case "join":
case gomatrixserverlib.Join:
// Manually append the new user's ID so they get notified
// along all members in the room
usersToNotify = append(usersToNotify, targetUserID)
n.addJoinedUser(ev.RoomID(), targetUserID)
case "leave":
case gomatrixserverlib.Leave:
fallthrough
case "ban":
case gomatrixserverlib.Ban:
n.removeJoinedUser(ev.RoomID(), targetUserID)
}
}

View file

@ -160,3 +160,9 @@ An event which redacts itself should be ignored
A pair of events which redact each other should be ignored
Full state sync includes joined rooms
A message sent after an initial sync appears in the timeline of an incremental sync.
Can add tag
Can remove tag
Can list tags for a room
Tags appear in an initial v2 /sync
Newly updated tags appear in an incremental v2 /sync
Deleted tags appear in an incremental v2 /sync