mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-07 06:53:09 -06:00
proxy state requests to user IDs to sender IDs
- so state events that use user IDs translate to pseudo IDs in pseudo ID rooms - e.g. allowing to query m.room.member by user ID in a pseudo ID room
This commit is contained in:
parent
9a12420428
commit
efa50d9a0a
|
|
@ -217,6 +217,21 @@ func OnIncomingStateTypeRequest(
|
||||||
var worldReadable bool
|
var worldReadable bool
|
||||||
var wantLatestState bool
|
var wantLatestState bool
|
||||||
|
|
||||||
|
parsedRoomID, err := spec.NewRoomID(roomID)
|
||||||
|
if err != nil {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusNotFound,
|
||||||
|
JSON: spec.InvalidParam("invalid room ID"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle user ID state keys appropriately
|
||||||
|
newStateKey, errorResp := translateUserStateKey(ctx, rsAPI, stateKey, evType, *parsedRoomID)
|
||||||
|
if errorResp != nil {
|
||||||
|
return *errorResp
|
||||||
|
}
|
||||||
|
stateKey = *newStateKey
|
||||||
|
|
||||||
// Always fetch visibility so that we can work out whether to show
|
// Always fetch visibility so that we can work out whether to show
|
||||||
// the latest events or the last event from when the user was joined.
|
// the latest events or the last event from when the user was joined.
|
||||||
// Then include the requested event type and state key, assuming it
|
// Then include the requested event type and state key, assuming it
|
||||||
|
|
@ -389,3 +404,41 @@ func OnIncomingStateTypeRequest(
|
||||||
JSON: res,
|
JSON: res,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If provided state key is a user ID (state keys beginning with @ are reserved for this purpose)
|
||||||
|
// fetch it's associated sender ID and use that instead. Otherwise returns the same state key back.
|
||||||
|
//
|
||||||
|
// This function either returns the state key that should be used, or a JSON error response that should be returned to the user.
|
||||||
|
//
|
||||||
|
// TODO: if any step of this process fails, should we fail with 404, or silently continue without using sender ID?
|
||||||
|
func translateUserStateKey(ctx context.Context, rsAPI api.ClientRoomserverAPI, stateKey string, evType string, roomID spec.RoomID) (*string, *util.JSONResponse) {
|
||||||
|
if len(stateKey) >= 1 && stateKey[0] == '@' {
|
||||||
|
parsedStateKey, err := spec.NewUserID(stateKey, true)
|
||||||
|
if err != nil {
|
||||||
|
// If invalid user ID, then there is no associated state event.
|
||||||
|
return nil, &util.JSONResponse{
|
||||||
|
Code: http.StatusNotFound,
|
||||||
|
JSON: spec.NotFound(fmt.Sprintf("Cannot find state event for %q", evType)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
senderID, err := rsAPI.QuerySenderIDForUser(ctx, roomID, *parsedStateKey)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(ctx).WithError(err).Error("QuerySenderIDForUser failed")
|
||||||
|
return nil, &util.JSONResponse{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
JSON: spec.Unknown("internal server error"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if senderID == nil {
|
||||||
|
// If no sender ID, then there is no associated state event.
|
||||||
|
return nil, &util.JSONResponse{
|
||||||
|
Code: http.StatusNotFound,
|
||||||
|
JSON: spec.NotFound(fmt.Sprintf("Cannot find state event for %q", evType)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newStateKey := string(*senderID)
|
||||||
|
return &newStateKey, nil
|
||||||
|
} else {
|
||||||
|
return &stateKey, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue