aboutsummaryrefslogtreecommitdiff
path: root/roomserver
diff options
context:
space:
mode:
authorKegsay <kegan@matrix.org>2020-06-26 11:07:52 +0100
committerGitHub <noreply@github.com>2020-06-26 11:07:52 +0100
commit4897beabeed3281f3e45a1426e6f1c9359e3152b (patch)
tree4746aecb87086d81de065ec30283c8ec48ff9f36 /roomserver
parentc1d2382e6d7f459ddf911a16aac7d4e63d50838b (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.go2
-rw-r--r--roomserver/internal/perform_leave.go47
-rw-r--r--roomserver/storage/interface.go4
-rw-r--r--roomserver/storage/postgres/invite_table.go15
-rw-r--r--roomserver/storage/shared/storage.go2
-rw-r--r--roomserver/storage/sqlite3/invite_table.go15
-rw-r--r--roomserver/storage/tables/interface.go4
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