mirror of
https://github.com/matrix-org/dendrite.git
synced 2026-01-11 08:03:09 -06:00
Temporary fix for remote room joins
This commit is contained in:
parent
c11e7061f3
commit
b647f1f3a1
|
|
@ -157,8 +157,9 @@ type PerformDirectoryLookupResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PerformJoinRequest struct {
|
type PerformJoinRequest struct {
|
||||||
RoomID string `json:"room_id"`
|
RoomID string `json:"room_id"`
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
|
SenderID spec.SenderID
|
||||||
// The sorted list of servers to try. Servers will be tried sequentially, after de-duplication.
|
// The sorted list of servers to try. Servers will be tried sequentially, after de-duplication.
|
||||||
ServerNames types.ServerNames `json:"server_names"`
|
ServerNames types.ServerNames `json:"server_names"`
|
||||||
Content map[string]interface{} `json:"content"`
|
Content map[string]interface{} `json:"content"`
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,7 @@ func testFederationAPIJoinThenKeyUpdate(t *testing.T, dbType test.DBType) {
|
||||||
fsapi.PerformJoin(context.Background(), &api.PerformJoinRequest{
|
fsapi.PerformJoin(context.Background(), &api.PerformJoinRequest{
|
||||||
RoomID: room.ID,
|
RoomID: room.ID,
|
||||||
UserID: joiningUser.ID,
|
UserID: joiningUser.ID,
|
||||||
|
SenderID: spec.SenderID(joiningUser.ID),
|
||||||
ServerNames: []spec.ServerName{serverA},
|
ServerNames: []spec.ServerName{serverA},
|
||||||
}, &resp)
|
}, &resp)
|
||||||
if resp.JoinedVia != serverA {
|
if resp.JoinedVia != serverA {
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,7 @@ func (r *FederationInternalAPI) PerformJoin(
|
||||||
ctx,
|
ctx,
|
||||||
request.RoomID,
|
request.RoomID,
|
||||||
request.UserID,
|
request.UserID,
|
||||||
|
request.SenderID,
|
||||||
request.Content,
|
request.Content,
|
||||||
serverName,
|
serverName,
|
||||||
request.Unsigned,
|
request.Unsigned,
|
||||||
|
|
@ -137,7 +138,7 @@ func (r *FederationInternalAPI) PerformJoin(
|
||||||
|
|
||||||
func (r *FederationInternalAPI) performJoinUsingServer(
|
func (r *FederationInternalAPI) performJoinUsingServer(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
roomID, userID string,
|
roomID, userID string, senderID spec.SenderID,
|
||||||
content map[string]interface{},
|
content map[string]interface{},
|
||||||
serverName spec.ServerName,
|
serverName spec.ServerName,
|
||||||
unsigned map[string]interface{},
|
unsigned map[string]interface{},
|
||||||
|
|
@ -154,10 +155,6 @@ func (r *FederationInternalAPI) performJoinUsingServer(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
senderID, err := r.rsAPI.QuerySenderIDForUser(ctx, roomID, *user)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
joinInput := gomatrixserverlib.PerformJoinInput{
|
joinInput := gomatrixserverlib.PerformJoinInput{
|
||||||
UserID: user,
|
UserID: user,
|
||||||
|
|
|
||||||
|
|
@ -174,44 +174,6 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
req.ServerNames = append(req.ServerNames, roomID.Domain())
|
req.ServerNames = append(req.ServerNames, roomID.Domain())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the template for the join event.
|
|
||||||
userID, err := spec.NewUserID(req.UserID, true)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", rsAPI.ErrInvalidID{Err: fmt.Errorf("user ID %q is invalid: %w", req.UserID, err)}
|
|
||||||
}
|
|
||||||
senderID, err := r.RSAPI.QuerySenderIDForUser(ctx, req.RoomIDOrAlias, *userID)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", rsAPI.ErrInvalidID{Err: fmt.Errorf("user ID %q is invalid: %w", req.UserID, err)}
|
|
||||||
}
|
|
||||||
senderIDString := string(senderID)
|
|
||||||
userDomain := userID.Domain()
|
|
||||||
proto := gomatrixserverlib.ProtoEvent{
|
|
||||||
Type: spec.MRoomMember,
|
|
||||||
SenderID: senderIDString,
|
|
||||||
StateKey: &senderIDString,
|
|
||||||
RoomID: req.RoomIDOrAlias,
|
|
||||||
Redacts: "",
|
|
||||||
}
|
|
||||||
if err = proto.SetUnsigned(struct{}{}); err != nil {
|
|
||||||
return "", "", fmt.Errorf("eb.SetUnsigned: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// It is possible for the request to include some "content" for the
|
|
||||||
// event. We'll always overwrite the "membership" key, but the rest,
|
|
||||||
// like "display_name" or "avatar_url", will be kept if supplied.
|
|
||||||
if req.Content == nil {
|
|
||||||
req.Content = map[string]interface{}{}
|
|
||||||
}
|
|
||||||
req.Content["membership"] = spec.Join
|
|
||||||
if authorisedVia, aerr := r.populateAuthorisedViaUserForRestrictedJoin(ctx, req, senderID); aerr != nil {
|
|
||||||
return "", "", aerr
|
|
||||||
} else if authorisedVia != "" {
|
|
||||||
req.Content["join_authorised_via_users_server"] = authorisedVia
|
|
||||||
}
|
|
||||||
if err = proto.SetContent(req.Content); err != nil {
|
|
||||||
return "", "", fmt.Errorf("eb.SetContent: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force a federated join if we aren't in the room and we've been
|
// Force a federated join if we aren't in the room and we've been
|
||||||
// given some server names to try joining by.
|
// given some server names to try joining by.
|
||||||
inRoomReq := &rsAPI.QueryServerJoinedToRoomRequest{
|
inRoomReq := &rsAPI.QueryServerJoinedToRoomRequest{
|
||||||
|
|
@ -224,6 +186,31 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
serverInRoom := inRoomRes.IsInRoom
|
serverInRoom := inRoomRes.IsInRoom
|
||||||
forceFederatedJoin := len(req.ServerNames) > 0 && !serverInRoom
|
forceFederatedJoin := len(req.ServerNames) > 0 && !serverInRoom
|
||||||
|
|
||||||
|
userID, err := spec.NewUserID(req.UserID, true)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", rsAPI.ErrInvalidID{Err: fmt.Errorf("user ID %q is invalid: %w", req.UserID, err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
var senderID spec.SenderID
|
||||||
|
var roomVersion gomatrixserverlib.RoomVersion
|
||||||
|
if forceFederatedJoin {
|
||||||
|
// TODO: pseudoIDs - lookup room version kere!
|
||||||
|
} else {
|
||||||
|
roomVersion, err = r.RSAPI.QueryRoomVersionForRoom(ctx, roomID.String())
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if roomVersion == gomatrixserverlib.RoomVersionPseudoIDs {
|
||||||
|
// TODO: pseudoIDs - generate senderID kere!
|
||||||
|
senderID = "pseudo_id.sender.key"
|
||||||
|
} else {
|
||||||
|
senderID = spec.SenderID(userID.String())
|
||||||
|
}
|
||||||
|
senderIDString := string(senderID)
|
||||||
|
userDomain := userID.Domain()
|
||||||
|
|
||||||
// Force a federated join if we're dealing with a pending invite
|
// Force a federated join if we're dealing with a pending invite
|
||||||
// and we aren't in the room.
|
// and we aren't in the room.
|
||||||
isInvitePending, inviteSender, _, inviteEvent, err := helpers.IsInvitePending(ctx, r.DB, req.RoomIDOrAlias, senderID)
|
isInvitePending, inviteSender, _, inviteEvent, err := helpers.IsInvitePending(ctx, r.DB, req.RoomIDOrAlias, senderID)
|
||||||
|
|
@ -274,7 +261,7 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
// If we should do a forced federated join then do that.
|
// If we should do a forced federated join then do that.
|
||||||
var joinedVia spec.ServerName
|
var joinedVia spec.ServerName
|
||||||
if forceFederatedJoin {
|
if forceFederatedJoin {
|
||||||
joinedVia, err = r.performFederatedJoinRoomByID(ctx, req)
|
joinedVia, err = r.performFederatedJoinRoomByID(ctx, req, senderID)
|
||||||
return req.RoomIDOrAlias, joinedVia, err
|
return req.RoomIDOrAlias, joinedVia, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,6 +276,34 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("error joining local room: %q", err)
|
return "", "", fmt.Errorf("error joining local room: %q", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare the template for the join event.
|
||||||
|
proto := gomatrixserverlib.ProtoEvent{
|
||||||
|
Type: spec.MRoomMember,
|
||||||
|
SenderID: senderIDString,
|
||||||
|
StateKey: &senderIDString,
|
||||||
|
RoomID: req.RoomIDOrAlias,
|
||||||
|
Redacts: "",
|
||||||
|
}
|
||||||
|
if err = proto.SetUnsigned(struct{}{}); err != nil {
|
||||||
|
return "", "", fmt.Errorf("eb.SetUnsigned: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is possible for the request to include some "content" for the
|
||||||
|
// event. We'll always overwrite the "membership" key, but the rest,
|
||||||
|
// like "display_name" or "avatar_url", will be kept if supplied.
|
||||||
|
if req.Content == nil {
|
||||||
|
req.Content = map[string]interface{}{}
|
||||||
|
}
|
||||||
|
req.Content["membership"] = spec.Join
|
||||||
|
if authorisedVia, aerr := r.populateAuthorisedViaUserForRestrictedJoin(ctx, req, senderID); aerr != nil {
|
||||||
|
return "", "", aerr
|
||||||
|
} else if authorisedVia != "" {
|
||||||
|
req.Content["join_authorised_via_users_server"] = authorisedVia
|
||||||
|
}
|
||||||
|
if err = proto.SetContent(req.Content); err != nil {
|
||||||
|
return "", "", fmt.Errorf("eb.SetContent: %w", err)
|
||||||
|
}
|
||||||
event, err := eventutil.QueryAndBuildEvent(ctx, &proto, identity, time.Now(), r.RSAPI, &buildRes)
|
event, err := eventutil.QueryAndBuildEvent(ctx, &proto, identity, time.Now(), r.RSAPI, &buildRes)
|
||||||
|
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
|
|
@ -334,7 +349,7 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform a federated room join.
|
// Perform a federated room join.
|
||||||
joinedVia, err = r.performFederatedJoinRoomByID(ctx, req)
|
joinedVia, err = r.performFederatedJoinRoomByID(ctx, req, senderID)
|
||||||
return req.RoomIDOrAlias, joinedVia, err
|
return req.RoomIDOrAlias, joinedVia, err
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -352,14 +367,16 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
func (r *Joiner) performFederatedJoinRoomByID(
|
func (r *Joiner) performFederatedJoinRoomByID(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *rsAPI.PerformJoinRequest,
|
req *rsAPI.PerformJoinRequest,
|
||||||
|
senderID spec.SenderID,
|
||||||
) (spec.ServerName, error) {
|
) (spec.ServerName, error) {
|
||||||
// Try joining by all of the supplied server names.
|
// Try joining by all of the supplied server names.
|
||||||
fedReq := fsAPI.PerformJoinRequest{
|
fedReq := fsAPI.PerformJoinRequest{
|
||||||
RoomID: req.RoomIDOrAlias, // the room ID to try and join
|
RoomID: req.RoomIDOrAlias, // the room ID to try and join
|
||||||
UserID: req.UserID, // the user ID joining the room
|
UserID: req.UserID, // the user ID joining the room
|
||||||
ServerNames: req.ServerNames, // the server to try joining with
|
SenderID: spec.SenderID(senderID),
|
||||||
Content: req.Content, // the membership event content
|
ServerNames: req.ServerNames, // the server to try joining with
|
||||||
Unsigned: req.Unsigned, // the unsigned event content, if any
|
Content: req.Content, // the membership event content
|
||||||
|
Unsigned: req.Unsigned, // the unsigned event content, if any
|
||||||
}
|
}
|
||||||
fedRes := fsAPI.PerformJoinResponse{}
|
fedRes := fsAPI.PerformJoinResponse{}
|
||||||
r.FSAPI.PerformJoin(ctx, &fedReq, &fedRes)
|
r.FSAPI.PerformJoin(ctx, &fedReq, &fedRes)
|
||||||
|
|
|
||||||
|
|
@ -717,12 +717,6 @@ func (d *Database) GetOrCreateRoomInfoFromID(ctx context.Context, roomID string)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if roomInfo == nil {
|
|
||||||
return nil, fmt.Errorf("Failed to find room info for %s", roomID)
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Cache.StoreRoomServerRoomID(roomInfo.RoomNID, roomID)
|
|
||||||
d.Cache.StoreRoomVersion(roomID, roomInfo.RoomVersion)
|
|
||||||
return roomInfo, nil
|
return roomInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue