Try to reconstuct membership events if it's an invite

This commit is contained in:
Till Faelligen 2022-08-17 07:41:36 +02:00
parent ad4ac2c016
commit d03a64873b
No known key found for this signature in database
GPG key ID: 3DF82D8AB9211D4E
8 changed files with 95 additions and 8 deletions

View file

@ -18,6 +18,10 @@ import (
"context"
"fmt"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
log "github.com/sirupsen/logrus"
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
@ -27,9 +31,6 @@ import (
"github.com/matrix-org/dendrite/roomserver/storage/shared"
"github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
log "github.com/sirupsen/logrus"
)
type Inviter struct {

View file

@ -24,6 +24,7 @@ import (
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
"github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/internal/caching"
@ -301,6 +302,41 @@ func (r *Queryer) QueryMembershipsForRoom(
if membershipEventNID == 0 {
response.HasBeenInRoom = false
response.JoinEvents = nil
// The sender didn't join this room, maybe a pending invite?
var data []byte
data, err = r.DB.GetInvitesJSON(ctx, request.Sender, info.RoomNID)
if err != nil {
logrus.WithError(err).Error("Failed to get invites JSON")
return nil
}
// For now, we only care about 1:1 rooms
if !gjson.GetBytes(data, "content.is_direct").Bool() {
return nil
}
// reconstruct membership events
for _, res := range gjson.GetBytes(data, "unsigned.invite_room_state").Array() {
sKey := res.Get("state_key").Str
if res.Get("type").Str == gomatrixserverlib.MRoomMember && sKey != "" {
ev := gomatrixserverlib.ClientEvent{
Content: gomatrixserverlib.RawJSON(res.Get("content").Raw),
RoomID: request.RoomID,
StateKey: &sKey,
Type: gomatrixserverlib.MRoomMember,
Sender: res.Get("sender").Str,
}
// Add the unsigned data, as this seems to make Element Web happy and put the
// room under "People"
if sKey == request.Sender {
ev.Unsigned = gomatrixserverlib.RawJSON(gjson.GetBytes(data, "unsigned").Raw)
}
response.JoinEvents = append(response.JoinEvents, ev)
}
}
response.HasBeenInRoom = response.JoinEvents != nil && len(response.JoinEvents) > 0
return nil
}

View file

@ -17,10 +17,11 @@ package storage
import (
"context"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/dendrite/roomserver/storage/shared"
"github.com/matrix-org/dendrite/roomserver/storage/tables"
"github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/gomatrixserverlib"
)
type Database interface {
@ -168,4 +169,6 @@ type Database interface {
ForgetRoom(ctx context.Context, userID, roomID string, forget bool) error
GetHistoryVisibilityState(ctx context.Context, roomInfo *types.RoomInfo, eventID string, domain string) ([]*gomatrixserverlib.Event, error)
GetInvitesJSON(ctx context.Context, userID string, nid types.RoomNID) ([]byte, error)
}

View file

@ -75,10 +75,16 @@ const updateInviteRetiredSQL = "" +
" WHERE room_nid = $1 AND target_nid = $2 AND NOT retired" +
" RETURNING invite_event_id"
const selectInviteJSONSQL = "" +
"SELECT invite_event_json FROM roomserver_invites" +
" WHERE target_nid = $1 and room_nid = $2" +
" AND NOT retired"
type inviteStatements struct {
insertInviteEventStmt *sql.Stmt
selectInviteActiveForUserInRoomStmt *sql.Stmt
updateInviteRetiredStmt *sql.Stmt
selectInviteJSONStmt *sql.Stmt
}
func CreateInvitesTable(db *sql.DB) error {
@ -93,6 +99,7 @@ func PrepareInvitesTable(db *sql.DB) (tables.Invites, error) {
{&s.insertInviteEventStmt, insertInviteEventSQL},
{&s.selectInviteActiveForUserInRoomStmt, selectInviteActiveForUserInRoomSQL},
{&s.updateInviteRetiredStmt, updateInviteRetiredSQL},
{&s.selectInviteJSONStmt, selectInviteJSONSQL},
}.Prepare(db)
}
@ -163,3 +170,13 @@ func (s *inviteStatements) SelectInviteActiveForUserInRoom(
}
return result, eventIDs, rows.Err()
}
func (s *inviteStatements) SelectInviteJSON(
ctx context.Context, txn *sql.Tx,
targetUserNID types.EventStateKeyNID, roomNID types.RoomNID,
) ([]byte, error) {
stmt := sqlutil.TxStmt(txn, s.selectInviteJSONStmt)
var resBytes []byte
err := stmt.QueryRowContext(ctx, targetUserNID, roomNID).Scan(&resBytes)
return resBytes, err
}

View file

@ -5,9 +5,10 @@ import (
"database/sql"
"fmt"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/dendrite/roomserver/storage/tables"
"github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/gomatrixserverlib"
)
type MembershipUpdater struct {

View file

@ -7,13 +7,14 @@ import (
"fmt"
"sort"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
"github.com/tidwall/gjson"
"github.com/matrix-org/dendrite/internal/caching"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/roomserver/storage/tables"
"github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
"github.com/tidwall/gjson"
)
// Ideally, when we have both events we should redact the event JSON and forget about the redaction, but we currently
@ -1388,6 +1389,14 @@ func (d *Database) loadStateAtSnapshot(
return fullState, nil
}
func (d *Database) GetInvitesJSON(ctx context.Context, userID string, roomNID types.RoomNID) ([]byte, error) {
userNID, err := d.EventStateKeysTable.SelectEventStateKeyNID(ctx, nil, userID)
if err != nil {
return nil, err
}
return d.InvitesTable.SelectInviteJSON(ctx, nil, userNID, roomNID)
}
type stateEntryListMap []types.StateEntryList
func (m stateEntryListMap) lookup(stateBlockNID types.StateBlockNID) (stateEntries []types.StateEntry, ok bool) {

View file

@ -60,6 +60,10 @@ const updateInviteRetiredSQL = `
const selectInvitesAboutToRetireSQL = `
SELECT invite_event_id FROM roomserver_invites WHERE room_nid = $1 AND target_nid = $2 AND NOT retired
`
const selectInviteJSONSQL = "" +
"SELECT invite_event_json FROM roomserver_invites" +
" WHERE target_nid = $1 and room_nid = $2" +
" AND NOT retired"
type inviteStatements struct {
db *sql.DB
@ -67,6 +71,7 @@ type inviteStatements struct {
selectInviteActiveForUserInRoomStmt *sql.Stmt
updateInviteRetiredStmt *sql.Stmt
selectInvitesAboutToRetireStmt *sql.Stmt
selectInviteJSONStmt *sql.Stmt
}
func CreateInvitesTable(db *sql.DB) error {
@ -84,6 +89,7 @@ func PrepareInvitesTable(db *sql.DB) (tables.Invites, error) {
{&s.selectInviteActiveForUserInRoomStmt, selectInviteActiveForUserInRoomSQL},
{&s.updateInviteRetiredStmt, updateInviteRetiredSQL},
{&s.selectInvitesAboutToRetireStmt, selectInvitesAboutToRetireSQL},
{&s.selectInviteJSONStmt, selectInviteJSONSQL},
}.Prepare(db)
}
@ -158,3 +164,13 @@ func (s *inviteStatements) SelectInviteActiveForUserInRoom(
}
return result, eventIDs, nil
}
func (s *inviteStatements) SelectInviteJSON(
ctx context.Context, txn *sql.Tx,
targetUserNID types.EventStateKeyNID, roomNID types.RoomNID,
) ([]byte, error) {
stmt := sqlutil.TxStmt(txn, s.selectInviteJSONStmt)
var resBytes []byte
err := stmt.QueryRowContext(ctx, targetUserNID, roomNID).Scan(&resBytes)
return resBytes, err
}

View file

@ -116,6 +116,10 @@ type Invites interface {
UpdateInviteRetired(ctx context.Context, txn *sql.Tx, roomNID types.RoomNID, targetUserNID types.EventStateKeyNID) ([]string, error)
// SelectInviteActiveForUserInRoom returns a list of sender state key NIDs and invite event IDs matching those nids.
SelectInviteActiveForUserInRoom(ctx context.Context, txn *sql.Tx, targetUserNID types.EventStateKeyNID, roomNID types.RoomNID) ([]types.EventStateKeyNID, []string, error)
SelectInviteJSON(
ctx context.Context, txn *sql.Tx,
targetUserNID types.EventStateKeyNID, roomNID types.RoomNID,
) ([]byte, error)
}
type MembershipState int64