diff options
author | Kegsay <kegan@matrix.org> | 2020-06-26 11:07:52 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-26 11:07:52 +0100 |
commit | 4897beabeed3281f3e45a1426e6f1c9359e3152b (patch) | |
tree | 4746aecb87086d81de065ec30283c8ec48ff9f36 /roomserver | |
parent | c1d2382e6d7f459ddf911a16aac7d4e63d50838b (diff) |
Finish implementing retiring invites (#1166)
* Pass retired invites to the syncapi with the event ID of the invite
* Implement retire invite streaming
* Update whitelist
Diffstat (limited to 'roomserver')
-rw-r--r-- | roomserver/internal/perform_join.go | 2 | ||||
-rw-r--r-- | roomserver/internal/perform_leave.go | 47 | ||||
-rw-r--r-- | roomserver/storage/interface.go | 4 | ||||
-rw-r--r-- | roomserver/storage/postgres/invite_table.go | 15 | ||||
-rw-r--r-- | roomserver/storage/shared/storage.go | 2 | ||||
-rw-r--r-- | roomserver/storage/sqlite3/invite_table.go | 15 | ||||
-rw-r--r-- | roomserver/storage/tables/interface.go | 4 |
7 files changed, 54 insertions, 35 deletions
diff --git a/roomserver/internal/perform_join.go b/roomserver/internal/perform_join.go index b594c2d8..1a450889 100644 --- a/roomserver/internal/perform_join.go +++ b/roomserver/internal/perform_join.go @@ -155,7 +155,7 @@ func (r *RoomserverInternalAPI) performJoinRoomByID( // where we might think we know about a room in the following // section but don't know the latest state as all of our users // have left. - isInvitePending, inviteSender, err := r.isInvitePending(ctx, req.RoomIDOrAlias, req.UserID) + isInvitePending, inviteSender, _, err := r.isInvitePending(ctx, req.RoomIDOrAlias, req.UserID) if err == nil && isInvitePending { // Check if there's an invite pending. _, inviterDomain, ierr := gomatrixserverlib.SplitID('@', inviteSender) diff --git a/roomserver/internal/perform_leave.go b/roomserver/internal/perform_leave.go index 880c8b20..a19d0da9 100644 --- a/roomserver/internal/perform_leave.go +++ b/roomserver/internal/perform_leave.go @@ -9,6 +9,7 @@ import ( fsAPI "github.com/matrix-org/dendrite/federationsender/api" "github.com/matrix-org/dendrite/internal/eventutil" "github.com/matrix-org/dendrite/roomserver/api" + "github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/gomatrixserverlib" ) @@ -38,9 +39,9 @@ func (r *RoomserverInternalAPI) performLeaveRoomByID( ) error { // If there's an invite outstanding for the room then respond to // that. - isInvitePending, senderUser, err := r.isInvitePending(ctx, req.RoomID, req.UserID) + isInvitePending, senderUser, eventID, err := r.isInvitePending(ctx, req.RoomID, req.UserID) if err == nil && isInvitePending { - return r.performRejectInvite(ctx, req, res, senderUser) + return r.performRejectInvite(ctx, req, res, senderUser, eventID) } // There's no invite pending, so first of all we want to find out @@ -134,7 +135,7 @@ func (r *RoomserverInternalAPI) performRejectInvite( ctx context.Context, req *api.PerformLeaveRequest, res *api.PerformLeaveResponse, // nolint:unparam - senderUser string, + senderUser, eventID string, ) error { _, domain, err := gomatrixserverlib.SplitID('@', senderUser) if err != nil { @@ -152,56 +153,68 @@ func (r *RoomserverInternalAPI) performRejectInvite( return err } - // TODO: Withdraw the invite, so that the sync API etc are + // Withdraw the invite, so that the sync API etc are // notified that we rejected it. - - return nil + return r.WriteOutputEvents(req.RoomID, []api.OutputEvent{ + { + Type: api.OutputTypeRetireInviteEvent, + RetireInviteEvent: &api.OutputRetireInviteEvent{ + EventID: eventID, + Membership: "leave", + TargetUserID: req.UserID, + }, + }, + }) } func (r *RoomserverInternalAPI) isInvitePending( ctx context.Context, roomID, userID string, -) (bool, string, error) { +) (bool, string, string, error) { // Look up the room NID for the supplied room ID. roomNID, err := r.DB.RoomNID(ctx, roomID) if err != nil { - return false, "", fmt.Errorf("r.DB.RoomNID: %w", err) + return false, "", "", fmt.Errorf("r.DB.RoomNID: %w", err) } // Look up the state key NID for the supplied user ID. targetUserNIDs, err := r.DB.EventStateKeyNIDs(ctx, []string{userID}) if err != nil { - return false, "", fmt.Errorf("r.DB.EventStateKeyNIDs: %w", err) + return false, "", "", fmt.Errorf("r.DB.EventStateKeyNIDs: %w", err) } targetUserNID, targetUserFound := targetUserNIDs[userID] if !targetUserFound { - return false, "", fmt.Errorf("missing NID for user %q (%+v)", userID, targetUserNIDs) + return false, "", "", fmt.Errorf("missing NID for user %q (%+v)", userID, targetUserNIDs) } // Let's see if we have an event active for the user in the room. If // we do then it will contain a server name that we can direct the // send_leave to. - senderUserNIDs, err := r.DB.GetInvitesForUser(ctx, roomNID, targetUserNID) + senderUserNIDs, eventIDs, err := r.DB.GetInvitesForUser(ctx, roomNID, targetUserNID) if err != nil { - return false, "", fmt.Errorf("r.DB.GetInvitesForUser: %w", err) + return false, "", "", fmt.Errorf("r.DB.GetInvitesForUser: %w", err) } if len(senderUserNIDs) == 0 { - return false, "", nil + return false, "", "", nil + } + userNIDToEventID := make(map[types.EventStateKeyNID]string) + for i, nid := range senderUserNIDs { + userNIDToEventID[nid] = eventIDs[i] } // Look up the user ID from the NID. senderUsers, err := r.DB.EventStateKeys(ctx, senderUserNIDs) if err != nil { - return false, "", fmt.Errorf("r.DB.EventStateKeys: %w", err) + return false, "", "", fmt.Errorf("r.DB.EventStateKeys: %w", err) } if len(senderUsers) == 0 { - return false, "", fmt.Errorf("no senderUsers") + return false, "", "", fmt.Errorf("no senderUsers") } senderUser, senderUserFound := senderUsers[senderUserNIDs[0]] if !senderUserFound { - return false, "", fmt.Errorf("missing user for NID %d (%+v)", senderUserNIDs[0], senderUsers) + return false, "", "", fmt.Errorf("missing user for NID %d (%+v)", senderUserNIDs[0], senderUsers) } - return true, senderUser, nil + return true, senderUser, userNIDToEventID[senderUserNIDs[0]], nil } diff --git a/roomserver/storage/interface.go b/roomserver/storage/interface.go index 52e6a96b..0c4e2e0b 100644 --- a/roomserver/storage/interface.go +++ b/roomserver/storage/interface.go @@ -102,9 +102,9 @@ type Database interface { // Returns an error if there was a problem talking to the database. LatestEventIDs(ctx context.Context, roomNID types.RoomNID) ([]gomatrixserverlib.EventReference, types.StateSnapshotNID, int64, error) // Look up the active invites targeting a user in a room and return the - // numeric state key IDs for the user IDs who sent them. + // numeric state key IDs for the user IDs who sent them along with the event IDs for the invites. // Returns an error if there was a problem talking to the database. - GetInvitesForUser(ctx context.Context, roomNID types.RoomNID, targetUserNID types.EventStateKeyNID) (senderUserIDs []types.EventStateKeyNID, err error) + GetInvitesForUser(ctx context.Context, roomNID types.RoomNID, targetUserNID types.EventStateKeyNID) (senderUserIDs []types.EventStateKeyNID, eventIDs []string, err error) // Save a given room alias with the room ID it refers to. // Returns an error if there was a problem talking to the database. SetRoomAlias(ctx context.Context, alias string, roomID string, creatorUserID string) error diff --git a/roomserver/storage/postgres/invite_table.go b/roomserver/storage/postgres/invite_table.go index 048a094d..bb719516 100644 --- a/roomserver/storage/postgres/invite_table.go +++ b/roomserver/storage/postgres/invite_table.go @@ -62,7 +62,7 @@ const insertInviteEventSQL = "" + " ON CONFLICT DO NOTHING" const selectInviteActiveForUserInRoomSQL = "" + - "SELECT sender_nid FROM roomserver_invites" + + "SELECT invite_event_id, sender_nid FROM roomserver_invites" + " WHERE target_nid = $1 AND room_nid = $2" + " AND NOT retired" @@ -141,21 +141,24 @@ func (s *inviteStatements) UpdateInviteRetired( func (s *inviteStatements) SelectInviteActiveForUserInRoom( ctx context.Context, targetUserNID types.EventStateKeyNID, roomNID types.RoomNID, -) ([]types.EventStateKeyNID, error) { +) ([]types.EventStateKeyNID, []string, error) { rows, err := s.selectInviteActiveForUserInRoomStmt.QueryContext( ctx, targetUserNID, roomNID, ) if err != nil { - return nil, err + return nil, nil, err } defer internal.CloseAndLogIfError(ctx, rows, "selectInviteActiveForUserInRoom: rows.close() failed") var result []types.EventStateKeyNID + var eventIDs []string for rows.Next() { + var inviteEventID string var senderUserNID int64 - if err := rows.Scan(&senderUserNID); err != nil { - return nil, err + if err := rows.Scan(&inviteEventID, &senderUserNID); err != nil { + return nil, nil, err } result = append(result, types.EventStateKeyNID(senderUserNID)) + eventIDs = append(eventIDs, inviteEventID) } - return result, rows.Err() + return result, eventIDs, rows.Err() } diff --git a/roomserver/storage/shared/storage.go b/roomserver/storage/shared/storage.go index 2751cc55..e6d0e34e 100644 --- a/roomserver/storage/shared/storage.go +++ b/roomserver/storage/shared/storage.go @@ -265,7 +265,7 @@ func (d *Database) GetInvitesForUser( ctx context.Context, roomNID types.RoomNID, targetUserNID types.EventStateKeyNID, -) (senderUserIDs []types.EventStateKeyNID, err error) { +) (senderUserIDs []types.EventStateKeyNID, eventIDs []string, err error) { return d.InvitesTable.SelectInviteActiveForUserInRoom(ctx, targetUserNID, roomNID) } diff --git a/roomserver/storage/sqlite3/invite_table.go b/roomserver/storage/sqlite3/invite_table.go index 21745d1b..8b6cbe3f 100644 --- a/roomserver/storage/sqlite3/invite_table.go +++ b/roomserver/storage/sqlite3/invite_table.go @@ -45,7 +45,7 @@ const insertInviteEventSQL = "" + " ON CONFLICT DO NOTHING" const selectInviteActiveForUserInRoomSQL = "" + - "SELECT sender_nid FROM roomserver_invites" + + "SELECT invite_event_id, sender_nid FROM roomserver_invites" + " WHERE target_nid = $1 AND room_nid = $2" + " AND NOT retired" @@ -133,21 +133,24 @@ func (s *inviteStatements) UpdateInviteRetired( func (s *inviteStatements) SelectInviteActiveForUserInRoom( ctx context.Context, targetUserNID types.EventStateKeyNID, roomNID types.RoomNID, -) ([]types.EventStateKeyNID, error) { +) ([]types.EventStateKeyNID, []string, error) { rows, err := s.selectInviteActiveForUserInRoomStmt.QueryContext( ctx, targetUserNID, roomNID, ) if err != nil { - return nil, err + return nil, nil, err } defer internal.CloseAndLogIfError(ctx, rows, "selectInviteActiveForUserInRoom: rows.close() failed") var result []types.EventStateKeyNID + var eventIDs []string for rows.Next() { + var eventID string var senderUserNID int64 - if err := rows.Scan(&senderUserNID); err != nil { - return nil, err + if err := rows.Scan(&eventID, &senderUserNID); err != nil { + return nil, nil, err } result = append(result, types.EventStateKeyNID(senderUserNID)) + eventIDs = append(eventIDs, eventID) } - return result, nil + return result, eventIDs, nil } diff --git a/roomserver/storage/tables/interface.go b/roomserver/storage/tables/interface.go index 11cff8a8..3aa8c538 100644 --- a/roomserver/storage/tables/interface.go +++ b/roomserver/storage/tables/interface.go @@ -100,8 +100,8 @@ type PreviousEvents interface { type Invites interface { InsertInviteEvent(ctx context.Context, txn *sql.Tx, inviteEventID string, roomNID types.RoomNID, targetUserNID, senderUserNID types.EventStateKeyNID, inviteEventJSON []byte) (bool, error) UpdateInviteRetired(ctx context.Context, txn *sql.Tx, roomNID types.RoomNID, targetUserNID types.EventStateKeyNID) ([]string, error) - // SelectInviteActiveForUserInRoom returns a list of sender state key NIDs - SelectInviteActiveForUserInRoom(ctx context.Context, targetUserNID types.EventStateKeyNID, roomNID types.RoomNID) ([]types.EventStateKeyNID, error) + // SelectInviteActiveForUserInRoom returns a list of sender state key NIDs and invite event IDs matching those nids. + SelectInviteActiveForUserInRoom(ctx context.Context, targetUserNID types.EventStateKeyNID, roomNID types.RoomNID) ([]types.EventStateKeyNID, []string, error) } type MembershipState int64 |