Fix local joins & make /rooms/roomid/join endpoint work

This commit is contained in:
Devon Hudson 2023-10-13 10:12:28 -06:00
parent f17de49c6b
commit 4bfcf27106
No known key found for this signature in database
GPG key ID: CD06B18E77F6A628
2 changed files with 48 additions and 25 deletions

View file

@ -397,7 +397,6 @@ func Setup(
return GetJoinedRooms(req, device, rsAPI) return GetJoinedRooms(req, device, rsAPI)
}, httputil.WithAllowGuests()), }, httputil.WithAllowGuests()),
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
// TODO: update for cryptoIDs
v3mux.Handle("/rooms/{roomID}/join", v3mux.Handle("/rooms/{roomID}/join",
httputil.MakeAuthAPI(spec.Join, userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { httputil.MakeAuthAPI(spec.Join, userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
if r := rateLimits.Limit(req, device); r != nil { if r := rateLimits.Limit(req, device); r != nil {
@ -420,6 +419,28 @@ func Setup(
return resp.(util.JSONResponse) return resp.(util.JSONResponse)
}, httputil.WithAllowGuests()), }, httputil.WithAllowGuests()),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
unstableMux.Handle("/org.matrix.msc_cryptoids/rooms/{roomID}/join",
httputil.MakeAuthAPI(spec.Join, userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
if r := rateLimits.Limit(req, device); r != nil {
return *r
}
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil {
return util.ErrorResponse(err)
}
// Only execute a join for roomID and UserID once. If there is a join in progress
// it waits for it to complete and returns that result for subsequent requests.
resp, _, _ := sf.Do(vars["roomID"]+device.UserID, func() (any, error) {
return JoinRoomByIDOrAliasCryptoIDs(
req, device, rsAPI, userAPI, vars["roomID"],
), nil
})
// once all joins are processed, drop them from the cache. Further requests
// will be processed as usual.
sf.Forget(vars["roomID"] + device.UserID)
return resp.(util.JSONResponse)
}, httputil.WithAllowGuests()),
).Methods(http.MethodPost, http.MethodOptions)
// TODO: update for cryptoIDs // TODO: update for cryptoIDs
v3mux.Handle("/rooms/{roomID}/leave", v3mux.Handle("/rooms/{roomID}/leave",
httputil.MakeAuthAPI("membership", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { httputil.MakeAuthAPI("membership", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {

View file

@ -125,33 +125,35 @@ func SendPDUs(
JSON: spec.Forbidden("userID doesn't have power level to change visibility"), JSON: spec.Forbidden("userID doesn't have power level to change visibility"),
} }
} }
queryReq := roomserverAPI.QueryMembershipForUserRequest{ if !cfg.Matrix.IsLocalServerName(pdu.RoomID().Domain()) {
RoomID: pdu.RoomID().String(), queryReq := roomserverAPI.QueryMembershipForUserRequest{
UserID: *deviceUserID, RoomID: pdu.RoomID().String(),
} UserID: *deviceUserID,
var queryRes roomserverAPI.QueryMembershipForUserResponse
if err := rsAPI.QueryMembershipForUser(req.Context(), &queryReq, &queryRes); err != nil {
util.GetLogger(req.Context()).WithError(err).Error("rsAPI.QueryMembershipsForRoom failed")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
} }
} var queryRes roomserverAPI.QueryMembershipForUserResponse
if !queryRes.IsInRoom { if err := rsAPI.QueryMembershipForUser(req.Context(), &queryReq, &queryRes); err != nil {
// This is a join event to a remote room util.GetLogger(req.Context()).WithError(err).Error("rsAPI.QueryMembershipsForRoom failed")
// TODO: cryptoIDs - figure out how to obtain unsigned contents for outstanding federated invites return util.JSONResponse{
joinReq := roomserverAPI.PerformJoinRequestCryptoIDs{ Code: http.StatusInternalServerError,
RoomID: pdu.RoomID().String(), JSON: spec.InternalServerError{},
UserID: device.UserID, }
IsGuest: device.AccountType == api.AccountTypeGuest,
ServerNames: []spec.ServerName{spec.ServerName(pdus.ViaServer)},
JoinEvent: pdu,
} }
err := rsAPI.PerformSendJoinCryptoIDs(req.Context(), &joinReq) if !queryRes.IsInRoom {
if err != nil { // This is a join event to a remote room
util.GetLogger(req.Context()).Errorf("Failed processing %s event (%s): %v", pdu.Type(), pdu.EventID(), err) // TODO: cryptoIDs - figure out how to obtain unsigned contents for outstanding federated invites
joinReq := roomserverAPI.PerformJoinRequestCryptoIDs{
RoomID: pdu.RoomID().String(),
UserID: device.UserID,
IsGuest: device.AccountType == api.AccountTypeGuest,
ServerNames: []spec.ServerName{spec.ServerName(pdus.ViaServer)},
JoinEvent: pdu,
}
err := rsAPI.PerformSendJoinCryptoIDs(req.Context(), &joinReq)
if err != nil {
util.GetLogger(req.Context()).Errorf("Failed processing %s event (%s): %v", pdu.Type(), pdu.EventID(), err)
}
continue // NOTE: don't send this event on to the roomserver
} }
continue // NOTE: don't send this event on to the roomserver
} }
} }
} }