Initial room creation refactor

This commit is contained in:
Devon Hudson 2023-05-25 18:06:40 -06:00
parent 11b557097c
commit 1c36c6a8d4
No known key found for this signature in database
GPG key ID: CD06B18E77F6A628
15 changed files with 75 additions and 51 deletions

View file

@ -165,6 +165,7 @@ func CreateRoom(
// nolint: gocyclo
func createRoom(
ctx context.Context,
// TODO: remove dependency on createRoomRequest
r createRoomRequest, device *api.Device,
cfg *config.ClientAPI,
profileAPI api.ClientUserAPI, rsAPI roomserverAPI.ClientRoomserverAPI,
@ -186,13 +187,13 @@ func createRoom(
}
}
logger := util.GetLogger(ctx)
userID := device.UserID
// TODO (#267): Check room ID doesn't clash with an existing one, and we
// probably shouldn't be using pseudo-random strings, maybe GUIDs?
roomID := fmt.Sprintf("!%s:%s", util.RandomString(16), userDomain)
logger := util.GetLogger(ctx)
userID := device.UserID
// Clobber keys: creator, room_version
roomVersion := roomserverVersion.DefaultRoomVersion()
@ -208,10 +209,6 @@ func createRoom(
roomVersion = candidateVersion
}
// TODO: visibility/presets/raw initial state
// TODO: Create room alias association
// Make sure this doesn't fall into an application service's namespace though!
logger.WithFields(log.Fields{
"userID": userID,
"roomID": roomID,
@ -227,6 +224,19 @@ func createRoom(
}
}
userDisplayName := profile.DisplayName
userAvatarURL := profile.AvatarURL
keyID := cfg.Matrix.KeyID
privateKey := cfg.Matrix.PrivateKey
// TODO: Move this whole function to roomserver to start
// HACK: asdklfjsdklfj
// TODO: visibility/presets/raw initial state
// TODO: Create room alias association
// Make sure this doesn't fall into an application service's namespace though!
createContent := map[string]interface{}{}
if len(r.CreationContent) > 0 {
if err = json.Unmarshal(r.CreationContent, &createContent); err != nil {
@ -298,8 +308,8 @@ func createRoom(
StateKey: userID,
Content: gomatrixserverlib.MemberContent{
Membership: spec.Join,
DisplayName: profile.DisplayName,
AvatarURL: profile.AvatarURL,
DisplayName: userDisplayName,
AvatarURL: userAvatarURL,
},
}
@ -480,7 +490,7 @@ func createRoom(
JSON: spec.InternalServerError{},
}
}
ev, err = builder.Build(evTime, userDomain, cfg.Matrix.KeyID, cfg.Matrix.PrivateKey)
ev, err = builder.Build(evTime, userDomain, keyID, privateKey)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("buildEvent failed")
return util.JSONResponse{
@ -518,7 +528,7 @@ func createRoom(
SendAsServer: roomserverAPI.DoNotSendToOtherServers,
})
}
if err = roomserverAPI.SendInputRoomEvents(ctx, rsAPI, device.UserDomain(), inputs, false); err != nil {
if err = roomserverAPI.SendInputRoomEvents(ctx, rsAPI, userDomain, inputs, false); err != nil {
util.GetLogger(ctx).WithError(err).Error("roomserverAPI.SendInputRoomEvents failed")
return util.JSONResponse{
Code: http.StatusInternalServerError,
@ -589,9 +599,9 @@ func createRoom(
var inviteEvent *types.HeaderedEvent
for _, invitee := range r.Invite {
// Build the invite event.
inviteEvent, err = buildMembershipEvent(
ctx, invitee, "", profileAPI, device, spec.Invite,
roomID, r.IsDirect, cfg, evTime, rsAPI, asAPI,
inviteEvent, err = buildMembershipEventDirect(
ctx, invitee, "", userDisplayName, userAvatarURL, userID, userDomain, spec.Invite,
roomID, r.IsDirect, keyID, privateKey, evTime, rsAPI,
)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("buildMembershipEvent failed")

View file

@ -16,12 +16,14 @@ package routing
import (
"context"
"crypto/ed25519"
"fmt"
"net/http"
"time"
"github.com/getsentry/sentry-go"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/fclient"
"github.com/matrix-org/gomatrixserverlib/spec"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
@ -308,6 +310,37 @@ func sendInvite(
}, nil
}
func buildMembershipEventDirect(
ctx context.Context,
targetUserID, reason string, userDisplayName, userAvatarURL string,
sender string, senderDomain spec.ServerName,
membership, roomID string, isDirect bool,
keyID gomatrixserverlib.KeyID, privateKey ed25519.PrivateKey, evTime time.Time,
rsAPI roomserverAPI.ClientRoomserverAPI,
) (*types.HeaderedEvent, error) {
proto := gomatrixserverlib.ProtoEvent{
Sender: sender,
RoomID: roomID,
Type: "m.room.member",
StateKey: &targetUserID,
}
content := gomatrixserverlib.MemberContent{
Membership: membership,
DisplayName: userDisplayName,
AvatarURL: userAvatarURL,
Reason: reason,
IsDirect: isDirect,
}
if err := proto.SetContent(content); err != nil {
return nil, err
}
identity := &fclient.SigningIdentity{senderDomain, keyID, privateKey}
return eventutil.QueryAndBuildEvent(ctx, &proto, identity, evTime, rsAPI, nil)
}
func buildMembershipEvent(
ctx context.Context,
targetUserID, reason string, profileAPI userapi.ClientUserAPI,
@ -321,31 +354,13 @@ func buildMembershipEvent(
return nil, err
}
proto := gomatrixserverlib.ProtoEvent{
Sender: device.UserID,
RoomID: roomID,
Type: "m.room.member",
StateKey: &targetUserID,
}
content := gomatrixserverlib.MemberContent{
Membership: membership,
DisplayName: profile.DisplayName,
AvatarURL: profile.AvatarURL,
Reason: reason,
IsDirect: isDirect,
}
if err = proto.SetContent(content); err != nil {
return nil, err
}
identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain())
if err != nil {
return nil, err
}
return eventutil.QueryAndBuildEvent(ctx, &proto, cfg.Matrix, identity, evTime, rsAPI, nil)
return buildMembershipEventDirect(ctx, targetUserID, reason, profile.DisplayName, profile.AvatarURL,
device.UserID, device.UserDomain(), membership, roomID, isDirect, identity.KeyID, identity.PrivateKey, evTime, rsAPI)
}
// loadProfile lookups the profile of a given user from the database and returns

View file

@ -387,7 +387,7 @@ func buildMembershipEvents(
return nil, err
}
event, err := eventutil.QueryAndBuildEvent(ctx, &proto, cfg.Matrix, identity, evTime, rsAPI, nil)
event, err := eventutil.QueryAndBuildEvent(ctx, &proto, identity, evTime, rsAPI, nil)
if err != nil {
return nil, err
}

View file

@ -137,7 +137,7 @@ func SendRedaction(
}
var queryRes roomserverAPI.QueryLatestEventsAndStateResponse
e, err := eventutil.QueryAndBuildEvent(req.Context(), &proto, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
e, err := eventutil.QueryAndBuildEvent(req.Context(), &proto, identity, time.Now(), rsAPI, &queryRes)
if errors.Is(err, eventutil.ErrRoomNoExists{}) {
return util.JSONResponse{
Code: http.StatusNotFound,

View file

@ -293,7 +293,7 @@ func generateSendEvent(
}
var queryRes api.QueryLatestEventsAndStateResponse
e, err := eventutil.QueryAndBuildEvent(ctx, &proto, cfg.Matrix, identity, evTime, rsAPI, &queryRes)
e, err := eventutil.QueryAndBuildEvent(ctx, &proto, identity, evTime, rsAPI, &queryRes)
switch specificErr := err.(type) {
case nil:
case eventutil.ErrRoomNoExists:

View file

@ -380,7 +380,7 @@ func emit3PIDInviteEvent(
}
queryRes := api.QueryLatestEventsAndStateResponse{}
event, err := eventutil.QueryAndBuildEvent(ctx, proto, cfg.Matrix, identity, evTime, rsAPI, &queryRes)
event, err := eventutil.QueryAndBuildEvent(ctx, proto, identity, evTime, rsAPI, &queryRes)
if err != nil {
return err
}

View file

@ -121,7 +121,7 @@ func MakeJoin(
queryRes := api.QueryLatestEventsAndStateResponse{
RoomVersion: roomVersion,
}
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), proto, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), proto, identity, time.Now(), rsAPI, &queryRes)
switch e := err.(type) {
case nil:
case eventutil.ErrRoomNoExists:

View file

@ -66,7 +66,7 @@ func MakeLeave(
}
queryRes := api.QueryLatestEventsAndStateResponse{}
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), proto, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), proto, identity, time.Now(), rsAPI, &queryRes)
switch e := err.(type) {
case nil:
case eventutil.ErrRoomNoExists:

View file

@ -22,7 +22,6 @@ import (
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/gomatrixserverlib/fclient"
"github.com/matrix-org/gomatrixserverlib/spec"
@ -51,7 +50,7 @@ func (e ErrRoomNoExists) Unwrap() error {
// Returns an error if something else went wrong
func QueryAndBuildEvent(
ctx context.Context,
proto *gomatrixserverlib.ProtoEvent, cfg *config.Global,
proto *gomatrixserverlib.ProtoEvent,
identity *fclient.SigningIdentity, evTime time.Time,
rsAPI api.QueryLatestEventsAndStateAPI, queryRes *api.QueryLatestEventsAndStateResponse,
) (*types.HeaderedEvent, error) {
@ -64,14 +63,14 @@ func QueryAndBuildEvent(
// This can pass through a ErrRoomNoExists to the caller
return nil, err
}
return BuildEvent(ctx, proto, cfg, identity, evTime, eventsNeeded, queryRes)
return BuildEvent(ctx, proto, identity, evTime, eventsNeeded, queryRes)
}
// BuildEvent builds a Matrix event from the builder and QueryLatestEventsAndStateResponse
// provided.
func BuildEvent(
ctx context.Context,
proto *gomatrixserverlib.ProtoEvent, cfg *config.Global,
proto *gomatrixserverlib.ProtoEvent,
identity *fclient.SigningIdentity, evTime time.Time,
eventsNeeded *gomatrixserverlib.StateNeeded, queryRes *api.QueryLatestEventsAndStateResponse,
) (*types.HeaderedEvent, error) {

View file

@ -208,7 +208,7 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias(
return err
}
newEvent, err := eventutil.BuildEvent(ctx, proto, &r.Cfg.Global, identity, time.Now(), &eventsNeeded, stateRes)
newEvent, err := eventutil.BuildEvent(ctx, proto, identity, time.Now(), &eventsNeeded, stateRes)
if err != nil {
return err
}

View file

@ -872,7 +872,7 @@ func (r *Inputer) kickGuests(ctx context.Context, event gomatrixserverlib.PDU, r
return err
}
event, err := eventutil.BuildEvent(ctx, fledglingEvent, r.Cfg.Matrix, r.SigningIdentity, time.Now(), &eventsNeeded, latestRes)
event, err := eventutil.BuildEvent(ctx, fledglingEvent, r.SigningIdentity, time.Now(), &eventsNeeded, latestRes)
if err != nil {
return err
}

View file

@ -119,7 +119,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
continue
}
event, err = eventutil.BuildEvent(ctx, fledglingEvent, r.Cfg.Matrix, identity, time.Now(), &eventsNeeded, latestRes)
event, err = eventutil.BuildEvent(ctx, fledglingEvent, identity, time.Now(), &eventsNeeded, latestRes)
if err != nil {
return nil, err
}
@ -306,7 +306,7 @@ func (r *Admin) PerformAdminDownloadState(
return err
}
ev, err := eventutil.BuildEvent(ctx, proto, r.Cfg.Matrix, identity, time.Now(), &eventsNeeded, queryRes)
ev, err := eventutil.BuildEvent(ctx, proto, identity, time.Now(), &eventsNeeded, queryRes)
if err != nil {
return fmt.Errorf("eventutil.BuildEvent: %w", err)
}

View file

@ -284,7 +284,7 @@ func (r *Joiner) performJoinRoomByID(
if err != nil {
return "", "", fmt.Errorf("error joining local room: %q", err)
}
event, err := eventutil.QueryAndBuildEvent(ctx, &proto, r.Cfg.Matrix, identity, time.Now(), r.RSAPI, &buildRes)
event, err := eventutil.QueryAndBuildEvent(ctx, &proto, identity, time.Now(), r.RSAPI, &buildRes)
switch err.(type) {
case nil:

View file

@ -183,7 +183,7 @@ func (r *Leaver) performLeaveRoomByID(
if err != nil {
return nil, fmt.Errorf("SigningIdentityFor: %w", err)
}
event, err := eventutil.QueryAndBuildEvent(ctx, &proto, r.Cfg.Matrix, identity, time.Now(), r.RSAPI, &buildRes)
event, err := eventutil.QueryAndBuildEvent(ctx, &proto, identity, time.Now(), r.RSAPI, &buildRes)
if err != nil {
return nil, fmt.Errorf("eventutil.QueryAndBuildEvent: %w", err)
}

View file

@ -555,7 +555,7 @@ func (r *Upgrader) makeHeaderedEvent(ctx context.Context, evTime time.Time, user
return nil, fmt.Errorf("failed to get signing identity for %q: %w", senderDomain, err)
}
var queryRes api.QueryLatestEventsAndStateResponse
headeredEvent, err := eventutil.QueryAndBuildEvent(ctx, &proto, r.Cfg.Matrix, identity, evTime, r.URSAPI, &queryRes)
headeredEvent, err := eventutil.QueryAndBuildEvent(ctx, &proto, identity, evTime, r.URSAPI, &queryRes)
switch e := err.(type) {
case nil:
case eventutil.ErrRoomNoExists: