mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-07-29 04:32:47 +00:00
More invite support (#979)
* Update gomatixserverlib * Try to build invite stripped state if not given to us * SendInvite improvements * Transpose invite_room_state into invite_state.events for sync API * Remove syncapi debugging output * Use RespInviteV2 * Update gomatrixserverlib * Send the invite event as a normal roomserver event too, for incorporating into room (should this be done by the roomserver automatically for invite inputs?) * Federation sender use invite_room_state, room server try to insert membership state * Check supported room versions on the invite endpoint * Prevent roomserver query API from trying to handle requests for stub rooms * Adding a nolint * Replace IsRoomStub with RoomNIDExcludingStubs, fix query API to use that instead * Review comments
This commit is contained in:
parent
be558f02aa
commit
3ab8ebf6b8
16 changed files with 175 additions and 77 deletions
|
@ -89,6 +89,8 @@ type InputInviteEvent struct {
|
|||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
Event gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
InviteRoomState []gomatrixserverlib.InviteV2StrippedState `json:"invite_room_state"`
|
||||
SendAsServer string `json:"send_as_server"`
|
||||
TransactionID *TransactionID `json:"transaction_id"`
|
||||
}
|
||||
|
||||
// InputRoomEventsRequest is a request to InputRoomEvents
|
||||
|
|
|
@ -196,8 +196,23 @@ func processInviteEvent(
|
|||
|
||||
event := input.Event.Unwrap()
|
||||
|
||||
if err = event.SetUnsignedField("invite_room_state", input.InviteRoomState); err != nil {
|
||||
return err
|
||||
if len(input.InviteRoomState) > 0 {
|
||||
// If we were supplied with some invite room state already (which is
|
||||
// most likely to be if the event came in over federation) then use
|
||||
// that.
|
||||
if err = event.SetUnsignedField("invite_room_state", input.InviteRoomState); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// There's no invite room state, so let's have a go at building it
|
||||
// up from local data (which is most likely to be if the event came
|
||||
// from the CS API). If we know about the room then we can insert
|
||||
// the invite room state, if we don't then we just fail quietly.
|
||||
if irs, ierr := buildInviteStrippedState(ctx, db, input); ierr == nil {
|
||||
if err = event.SetUnsignedField("invite_room_state", irs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outputUpdates, err := updateToInviteMembership(updater, &event, nil, input.Event.RoomVersion)
|
||||
|
@ -212,3 +227,50 @@ func processInviteEvent(
|
|||
succeeded = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildInviteStrippedState(
|
||||
ctx context.Context,
|
||||
db storage.Database,
|
||||
input api.InputInviteEvent,
|
||||
) ([]gomatrixserverlib.InviteV2StrippedState, error) {
|
||||
roomNID, err := db.RoomNID(ctx, input.Event.RoomID())
|
||||
if err != nil || roomNID == 0 {
|
||||
return nil, fmt.Errorf("room %q unknown", input.Event.RoomID())
|
||||
}
|
||||
stateWanted := []gomatrixserverlib.StateKeyTuple{}
|
||||
for _, t := range []string{
|
||||
gomatrixserverlib.MRoomName, gomatrixserverlib.MRoomCanonicalAlias,
|
||||
gomatrixserverlib.MRoomAliases, gomatrixserverlib.MRoomJoinRules,
|
||||
} {
|
||||
stateWanted = append(stateWanted, gomatrixserverlib.StateKeyTuple{
|
||||
EventType: t,
|
||||
StateKey: "",
|
||||
})
|
||||
}
|
||||
_, currentStateSnapshotNID, _, err := db.LatestEventIDs(ctx, roomNID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
roomState := state.NewStateResolution(db)
|
||||
stateEntries, err := roomState.LoadStateAtSnapshotForStringTuples(
|
||||
ctx, currentStateSnapshotNID, stateWanted,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stateNIDs := []types.EventNID{}
|
||||
for _, stateNID := range stateEntries {
|
||||
stateNIDs = append(stateNIDs, stateNID.EventNID)
|
||||
}
|
||||
stateEvents, err := db.Events(ctx, stateNIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inviteState := []gomatrixserverlib.InviteV2StrippedState{
|
||||
gomatrixserverlib.NewInviteV2StrippedState(&input.Event.Event),
|
||||
}
|
||||
for _, event := range stateEvents {
|
||||
inviteState = append(inviteState, gomatrixserverlib.NewInviteV2StrippedState(&event.Event))
|
||||
}
|
||||
return inviteState, nil
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ func updateToInviteMembership(
|
|||
// consider a single stream of events when determining whether a user
|
||||
// is invited, rather than having to combine multiple streams themselves.
|
||||
onie := api.OutputNewInviteEvent{
|
||||
Event: (*add).Headered(roomVersion),
|
||||
Event: add.Headered(roomVersion),
|
||||
RoomVersion: roomVersion,
|
||||
}
|
||||
updates = append(updates, api.OutputEvent{
|
||||
|
|
|
@ -54,7 +54,7 @@ func (r *RoomserverQueryAPI) QueryLatestEventsAndState(
|
|||
roomState := state.NewStateResolution(r.DB)
|
||||
|
||||
response.QueryLatestEventsAndStateRequest = *request
|
||||
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
||||
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ func (r *RoomserverQueryAPI) QueryStateAfterEvents(
|
|||
roomState := state.NewStateResolution(r.DB)
|
||||
|
||||
response.QueryStateAfterEventsRequest = *request
|
||||
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
||||
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -649,7 +649,7 @@ func (r *RoomserverQueryAPI) QueryStateAndAuthChain(
|
|||
response *api.QueryStateAndAuthChainResponse,
|
||||
) error {
|
||||
response.QueryStateAndAuthChainRequest = *request
|
||||
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
||||
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -71,6 +71,10 @@ type Database interface {
|
|||
GetLatestEventsForUpdate(ctx context.Context, roomNID types.RoomNID) (types.RoomRecentEventsUpdater, error)
|
||||
GetTransactionEventID(ctx context.Context, transactionID string, sessionID int64, userID string) (string, error)
|
||||
RoomNID(ctx context.Context, roomID string) (types.RoomNID, error)
|
||||
// RoomNIDExcludingStubs is a special variation of RoomNID that will return 0 as if the room
|
||||
// does not exist if the room has no latest events. This can happen when we've received an
|
||||
// invite over federation for a room that we don't know anything else about yet.
|
||||
RoomNIDExcludingStubs(ctx context.Context, roomID string) (types.RoomNID, error)
|
||||
LatestEventIDs(ctx context.Context, roomNID types.RoomNID) ([]gomatrixserverlib.EventReference, types.StateSnapshotNID, int64, error)
|
||||
GetInvitesForUser(ctx context.Context, roomNID types.RoomNID, targetUserNID types.EventStateKeyNID) (senderUserIDs []types.EventStateKeyNID, err error)
|
||||
SetRoomAlias(ctx context.Context, alias string, roomID string, creatorUserID string) error
|
||||
|
|
|
@ -471,6 +471,23 @@ func (d *Database) RoomNID(ctx context.Context, roomID string) (types.RoomNID, e
|
|||
return roomNID, err
|
||||
}
|
||||
|
||||
// RoomNIDExcludingStubs implements query.RoomserverQueryAPIDB
|
||||
func (d *Database) RoomNIDExcludingStubs(ctx context.Context, roomID string) (roomNID types.RoomNID, err error) {
|
||||
roomNID, err = d.RoomNID(ctx, roomID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
latestEvents, _, err := d.statements.selectLatestEventNIDs(ctx, roomNID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(latestEvents) == 0 {
|
||||
roomNID = 0
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// LatestEventIDs implements query.RoomserverQueryAPIDatabase
|
||||
func (d *Database) LatestEventIDs(
|
||||
ctx context.Context, roomNID types.RoomNID,
|
||||
|
|
|
@ -590,6 +590,23 @@ func (d *Database) RoomNID(ctx context.Context, roomID string) (roomNID types.Ro
|
|||
return
|
||||
}
|
||||
|
||||
// RoomNIDExcludingStubs implements query.RoomserverQueryAPIDB
|
||||
func (d *Database) RoomNIDExcludingStubs(ctx context.Context, roomID string) (roomNID types.RoomNID, err error) {
|
||||
roomNID, err = d.RoomNID(ctx, roomID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
latestEvents, _, err := d.statements.selectLatestEventNIDs(ctx, nil, roomNID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(latestEvents) == 0 {
|
||||
roomNID = 0
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// LatestEventIDs implements query.RoomserverQueryAPIDatabase
|
||||
func (d *Database) LatestEventIDs(
|
||||
ctx context.Context, roomNID types.RoomNID,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue