mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-17 03:43:11 -06:00
Add directory lookups of aliases
This commit is contained in:
parent
1d3ddaeb5f
commit
eda4efcf13
|
|
@ -8,6 +8,12 @@ import (
|
||||||
|
|
||||||
// FederationSenderInternalAPI is used to query information from the federation sender.
|
// FederationSenderInternalAPI is used to query information from the federation sender.
|
||||||
type FederationSenderInternalAPI interface {
|
type FederationSenderInternalAPI interface {
|
||||||
|
// PerformDirectoryLookup looks up a remote room ID from a room alias.
|
||||||
|
PerformDirectoryLookup(
|
||||||
|
ctx context.Context,
|
||||||
|
request *PerformDirectoryLookupRequest,
|
||||||
|
response *PerformDirectoryLookupResponse,
|
||||||
|
) error
|
||||||
// Query the joined hosts and the membership events accounting for their participation in a room.
|
// Query the joined hosts and the membership events accounting for their participation in a room.
|
||||||
// Note that if a server has multiple users in the room, it will have multiple entries in the returned slice.
|
// Note that if a server has multiple users in the room, it will have multiple entries in the returned slice.
|
||||||
// See `QueryJoinedHostServerNamesInRoom` for a de-duplicated version.
|
// See `QueryJoinedHostServerNamesInRoom` for a de-duplicated version.
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// FederationSenderPerformJoinRequestPath is the HTTP path for the PerformJoinRequest API.
|
||||||
|
FederationSenderPerformDirectoryLookupRequestPath = "/api/federationsender/performDirectoryLookup"
|
||||||
|
|
||||||
// FederationSenderPerformJoinRequestPath is the HTTP path for the PerformJoinRequest API.
|
// FederationSenderPerformJoinRequestPath is the HTTP path for the PerformJoinRequest API.
|
||||||
FederationSenderPerformJoinRequestPath = "/api/federationsender/performJoinRequest"
|
FederationSenderPerformJoinRequestPath = "/api/federationsender/performJoinRequest"
|
||||||
|
|
||||||
|
|
@ -16,6 +19,29 @@ const (
|
||||||
FederationSenderPerformLeaveRequestPath = "/api/federationsender/performLeaveRequest"
|
FederationSenderPerformLeaveRequestPath = "/api/federationsender/performLeaveRequest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PerformDirectoryLookupRequest struct {
|
||||||
|
RoomAlias string `json:"room_alias"`
|
||||||
|
ServerName gomatrixserverlib.ServerName `json:"server_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PerformDirectoryLookupResponse struct {
|
||||||
|
RoomID string `json:"room_id"`
|
||||||
|
ServerNames []gomatrixserverlib.ServerName `json:"server_names"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle an instruction to make_join & send_join with a remote server.
|
||||||
|
func (h *httpFederationSenderInternalAPI) PerformDirectoryLookup(
|
||||||
|
ctx context.Context,
|
||||||
|
request *PerformDirectoryLookupRequest,
|
||||||
|
response *PerformDirectoryLookupResponse,
|
||||||
|
) error {
|
||||||
|
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformDirectoryLookup")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
apiURL := h.federationSenderURL + FederationSenderPerformDirectoryLookupRequestPath
|
||||||
|
return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
|
}
|
||||||
|
|
||||||
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"`
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,25 @@ import (
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PerformLeaveRequest implements api.FederationSenderInternalAPI
|
||||||
|
func (r *FederationSenderInternalAPI) PerformDirectoryLookup(
|
||||||
|
ctx context.Context,
|
||||||
|
request *api.PerformDirectoryLookupRequest,
|
||||||
|
response *api.PerformDirectoryLookupResponse,
|
||||||
|
) (err error) {
|
||||||
|
dir, err := r.federation.LookupRoomAlias(
|
||||||
|
ctx,
|
||||||
|
request.ServerName,
|
||||||
|
request.RoomAlias,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
response.RoomID = dir.RoomID
|
||||||
|
response.ServerNames = dir.Servers
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// PerformJoinRequest implements api.FederationSenderInternalAPI
|
// PerformJoinRequest implements api.FederationSenderInternalAPI
|
||||||
func (r *FederationSenderInternalAPI) PerformJoin(
|
func (r *FederationSenderInternalAPI) PerformJoin(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,10 @@ func (r *RoomserverInternalAPI) PerformJoin(
|
||||||
) error {
|
) error {
|
||||||
_, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
_, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("supplied user ID %q in incorrect format", req.UserID)
|
return fmt.Errorf("Supplied user ID %q in incorrect format", req.UserID)
|
||||||
}
|
}
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if domain != r.Cfg.Matrix.ServerName {
|
||||||
return fmt.Errorf("user ID %q does not belong to this homeserver", req.UserID)
|
return fmt.Errorf("User %q does not belong to this homeserver", req.UserID)
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(req.RoomIDOrAlias, "!") {
|
if strings.HasPrefix(req.RoomIDOrAlias, "!") {
|
||||||
return r.performJoinRoomByID(ctx, req, res)
|
return r.performJoinRoomByID(ctx, req, res)
|
||||||
|
|
@ -32,7 +32,7 @@ func (r *RoomserverInternalAPI) PerformJoin(
|
||||||
if strings.HasPrefix(req.RoomIDOrAlias, "#") {
|
if strings.HasPrefix(req.RoomIDOrAlias, "#") {
|
||||||
return r.performJoinRoomByAlias(ctx, req, res)
|
return r.performJoinRoomByAlias(ctx, req, res)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unexpected sigil on room %q", req.RoomIDOrAlias)
|
return fmt.Errorf("Room ID or alias %q is invalid", req.RoomIDOrAlias)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoomserverInternalAPI) performJoinRoomByAlias(
|
func (r *RoomserverInternalAPI) performJoinRoomByAlias(
|
||||||
|
|
@ -43,14 +43,39 @@ func (r *RoomserverInternalAPI) performJoinRoomByAlias(
|
||||||
// Get the domain part of the room alias.
|
// Get the domain part of the room alias.
|
||||||
_, domain, err := gomatrixserverlib.SplitID('#', req.RoomIDOrAlias)
|
_, domain, err := gomatrixserverlib.SplitID('#', req.RoomIDOrAlias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("supplied room alias %q in incorrect format", req.RoomIDOrAlias)
|
return fmt.Errorf("Alias %q is not in the correct format", req.RoomIDOrAlias)
|
||||||
}
|
}
|
||||||
req.ServerNames = append(req.ServerNames, domain)
|
req.ServerNames = append(req.ServerNames, domain)
|
||||||
|
|
||||||
// Look up if we know this room alias.
|
// Check if this alias matches our own server configuration. If it
|
||||||
roomID, err := r.DB.GetRoomIDForAlias(ctx, req.RoomIDOrAlias)
|
// doesn't then we'll need to try a federated join.
|
||||||
|
var roomID string
|
||||||
|
if domain != r.Cfg.Matrix.ServerName {
|
||||||
|
// The alias isn't owned by us, so we will eed to try joining using
|
||||||
|
// a remote server.
|
||||||
|
dirReq := fsAPI.PerformDirectoryLookupRequest{
|
||||||
|
RoomAlias: req.RoomIDOrAlias, // the room alias to lookup
|
||||||
|
ServerName: domain, // the server to ask
|
||||||
|
}
|
||||||
|
dirRes := fsAPI.PerformDirectoryLookupResponse{}
|
||||||
|
err = r.fsAPI.PerformDirectoryLookup(ctx, &dirReq, &dirRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
logrus.WithError(err).Errorf("error looking up alias %q", req.RoomIDOrAlias)
|
||||||
|
return fmt.Errorf("Looking up alias %q over federation failed: %w", req.RoomIDOrAlias, err)
|
||||||
|
}
|
||||||
|
roomID = dirRes.RoomID
|
||||||
|
req.ServerNames = append(req.ServerNames, dirRes.ServerNames...)
|
||||||
|
} else {
|
||||||
|
// Otherwise, look up if we know this room alias locally.
|
||||||
|
roomID, err = r.DB.GetRoomIDForAlias(ctx, req.RoomIDOrAlias)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Lookup room alias %q failed: %w", req.RoomIDOrAlias, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the room ID is empty then we failed to look up the alias.
|
||||||
|
if roomID == "" {
|
||||||
|
return fmt.Errorf("Alias %q not found", req.RoomIDOrAlias)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we do, then pluck out the room ID and continue the join.
|
// If we do, then pluck out the room ID and continue the join.
|
||||||
|
|
@ -68,7 +93,7 @@ func (r *RoomserverInternalAPI) performJoinRoomByID(
|
||||||
// Get the domain part of the room ID.
|
// Get the domain part of the room ID.
|
||||||
_, domain, err := gomatrixserverlib.SplitID('!', req.RoomIDOrAlias)
|
_, domain, err := gomatrixserverlib.SplitID('!', req.RoomIDOrAlias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("supplied room ID %q in incorrect format", req.RoomIDOrAlias)
|
return fmt.Errorf("Room ID %q is invalid", req.RoomIDOrAlias)
|
||||||
}
|
}
|
||||||
req.ServerNames = append(req.ServerNames, domain)
|
req.ServerNames = append(req.ServerNames, domain)
|
||||||
|
|
||||||
|
|
@ -135,7 +160,7 @@ func (r *RoomserverInternalAPI) performJoinRoomByID(
|
||||||
// room. If it is then there's nothing more to do - the room just
|
// room. If it is then there's nothing more to do - the room just
|
||||||
// hasn't been created yet.
|
// hasn't been created yet.
|
||||||
if domain == r.Cfg.Matrix.ServerName {
|
if domain == r.Cfg.Matrix.ServerName {
|
||||||
return fmt.Errorf("room ID %q does not exist", req.RoomIDOrAlias)
|
return fmt.Errorf("Room ID %q does not exist", req.RoomIDOrAlias)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try joining by all of the supplied server names.
|
// Try joining by all of the supplied server names.
|
||||||
|
|
@ -164,13 +189,13 @@ func (r *RoomserverInternalAPI) performJoinRoomByID(
|
||||||
// servers then return an error saying such.
|
// servers then return an error saying such.
|
||||||
if !joined {
|
if !joined {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"failed to join %q using %d server(s)",
|
"Failed to join %q using %d server(s)",
|
||||||
req.RoomIDOrAlias, len(req.ServerNames),
|
req.RoomIDOrAlias, len(req.ServerNames),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("error joining room %q: %w", req.RoomIDOrAlias, err)
|
return fmt.Errorf("Error joining room %q: %w", req.RoomIDOrAlias, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue