mirror of
https://github.com/hoernschen/dendrite.git
synced 2024-12-27 07:28:27 +00:00
c7193e24d0
There are cases where a dendrite instance is unaware of a pseudo ID for a user, the user is not a member of that room. To represent this case, we currently use the 'zero' value, which is often not checked and so causes errors later down the line. To make this case more explict, and to be consistent with `QueryUserIDForSender`, this PR changes this to use a pointer (and `nil` to mean no sender ID). Signed-off-by: `Sam Wedgwood <sam@wedgwood.dev>`
311 lines
15 KiB
Go
311 lines
15 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"crypto/ed25519"
|
|
|
|
"github.com/matrix-org/gomatrixserverlib"
|
|
"github.com/matrix-org/gomatrixserverlib/fclient"
|
|
"github.com/matrix-org/gomatrixserverlib/spec"
|
|
"github.com/matrix-org/util"
|
|
|
|
asAPI "github.com/matrix-org/dendrite/appservice/api"
|
|
fsAPI "github.com/matrix-org/dendrite/federationapi/api"
|
|
"github.com/matrix-org/dendrite/roomserver/types"
|
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
|
)
|
|
|
|
// ErrInvalidID is an error returned if the userID is invalid
|
|
type ErrInvalidID struct {
|
|
Err error
|
|
}
|
|
|
|
func (e ErrInvalidID) Error() string {
|
|
return e.Err.Error()
|
|
}
|
|
|
|
// ErrNotAllowed is an error returned if the user is not allowed
|
|
// to execute some action (e.g. invite)
|
|
type ErrNotAllowed struct {
|
|
Err error
|
|
}
|
|
|
|
func (e ErrNotAllowed) Error() string {
|
|
return e.Err.Error()
|
|
}
|
|
|
|
// ErrRoomUnknownOrNotAllowed is an error return if either the provided
|
|
// room ID does not exist, or points to a room that the requester does
|
|
// not have access to.
|
|
type ErrRoomUnknownOrNotAllowed struct {
|
|
Err error
|
|
}
|
|
|
|
func (e ErrRoomUnknownOrNotAllowed) Error() string {
|
|
return e.Err.Error()
|
|
}
|
|
|
|
type RestrictedJoinAPI interface {
|
|
CurrentStateEvent(ctx context.Context, roomID spec.RoomID, eventType string, stateKey string) (gomatrixserverlib.PDU, error)
|
|
InvitePending(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (bool, error)
|
|
RestrictedRoomJoinInfo(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID, localServerName spec.ServerName) (*gomatrixserverlib.RestrictedRoomJoinInfo, error)
|
|
QueryRoomInfo(ctx context.Context, roomID spec.RoomID) (*types.RoomInfo, error)
|
|
QueryServerJoinedToRoom(ctx context.Context, req *QueryServerJoinedToRoomRequest, res *QueryServerJoinedToRoomResponse) error
|
|
UserJoinedToRoom(ctx context.Context, roomID types.RoomNID, senderID spec.SenderID) (bool, error)
|
|
LocallyJoinedUsers(ctx context.Context, roomVersion gomatrixserverlib.RoomVersion, roomNID types.RoomNID) ([]gomatrixserverlib.PDU, error)
|
|
}
|
|
|
|
// RoomserverInputAPI is used to write events to the room server.
|
|
type RoomserverInternalAPI interface {
|
|
SyncRoomserverAPI
|
|
AppserviceRoomserverAPI
|
|
ClientRoomserverAPI
|
|
UserRoomserverAPI
|
|
FederationRoomserverAPI
|
|
QuerySenderIDAPI
|
|
UserRoomPrivateKeyCreator
|
|
|
|
// needed to avoid chicken and egg scenario when setting up the
|
|
// interdependencies between the roomserver and other input APIs
|
|
SetFederationAPI(fsAPI fsAPI.RoomserverFederationAPI, keyRing *gomatrixserverlib.KeyRing)
|
|
SetAppserviceAPI(asAPI asAPI.AppServiceInternalAPI)
|
|
SetUserAPI(userAPI userapi.RoomserverUserAPI)
|
|
|
|
// QueryAuthChain returns the entire auth chain for the event IDs given.
|
|
// The response includes the events in the request.
|
|
// Omits without error for any missing auth events. There will be no duplicates.
|
|
// Used in MSC2836.
|
|
QueryAuthChain(
|
|
ctx context.Context,
|
|
req *QueryAuthChainRequest,
|
|
res *QueryAuthChainResponse,
|
|
) error
|
|
}
|
|
|
|
type UserRoomPrivateKeyCreator interface {
|
|
// GetOrCreateUserRoomPrivateKey gets the user room key for the specified user. If no key exists yet, a new one is created.
|
|
GetOrCreateUserRoomPrivateKey(ctx context.Context, userID spec.UserID, roomID spec.RoomID) (ed25519.PrivateKey, error)
|
|
StoreUserRoomPublicKey(ctx context.Context, senderID spec.SenderID, userID spec.UserID, roomID spec.RoomID) error
|
|
}
|
|
|
|
type InputRoomEventsAPI interface {
|
|
InputRoomEvents(
|
|
ctx context.Context,
|
|
req *InputRoomEventsRequest,
|
|
res *InputRoomEventsResponse,
|
|
)
|
|
}
|
|
|
|
type QuerySenderIDAPI interface {
|
|
QuerySenderIDForUser(ctx context.Context, roomID spec.RoomID, userID spec.UserID) (*spec.SenderID, error)
|
|
QueryUserIDForSender(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error)
|
|
}
|
|
|
|
// Query the latest events and state for a room from the room server.
|
|
type QueryLatestEventsAndStateAPI interface {
|
|
QueryLatestEventsAndState(ctx context.Context, req *QueryLatestEventsAndStateRequest, res *QueryLatestEventsAndStateResponse) error
|
|
}
|
|
|
|
// QueryBulkStateContent does a bulk query for state event content in the given rooms.
|
|
type QueryBulkStateContentAPI interface {
|
|
QueryBulkStateContent(ctx context.Context, req *QueryBulkStateContentRequest, res *QueryBulkStateContentResponse) error
|
|
}
|
|
|
|
type QueryEventsAPI interface {
|
|
// QueryEventsByID queries a list of events by event ID for one room. If no room is specified, it will try to determine
|
|
// which room to use by querying the first events roomID.
|
|
QueryEventsByID(
|
|
ctx context.Context,
|
|
req *QueryEventsByIDRequest,
|
|
res *QueryEventsByIDResponse,
|
|
) error
|
|
// QueryCurrentState retrieves the requested state events. If state events are not found, they will be missing from
|
|
// the response.
|
|
QueryCurrentState(ctx context.Context, req *QueryCurrentStateRequest, res *QueryCurrentStateResponse) error
|
|
}
|
|
|
|
type QueryRoomHierarchyAPI interface {
|
|
// Traverse the room hierarchy using the provided walker up to the provided limit,
|
|
// returning a new walker which can be used to fetch the next page.
|
|
//
|
|
// If limit is -1, this is treated as no limit, and the entire hierarchy will be traversed.
|
|
//
|
|
// If returned walker is nil, then there are no more rooms left to traverse. This method does not modify the provided walker, so it
|
|
// can be cached.
|
|
QueryNextRoomHierarchyPage(ctx context.Context, walker RoomHierarchyWalker, limit int) ([]fclient.RoomHierarchyRoom, *RoomHierarchyWalker, error)
|
|
}
|
|
|
|
// API functions required by the syncapi
|
|
type SyncRoomserverAPI interface {
|
|
QueryLatestEventsAndStateAPI
|
|
QueryBulkStateContentAPI
|
|
QuerySenderIDAPI
|
|
// QuerySharedUsers returns a list of users who share at least 1 room in common with the given user.
|
|
QuerySharedUsers(ctx context.Context, req *QuerySharedUsersRequest, res *QuerySharedUsersResponse) error
|
|
// QueryEventsByID queries a list of events by event ID for one room. If no room is specified, it will try to determine
|
|
// which room to use by querying the first events roomID.
|
|
QueryEventsByID(
|
|
ctx context.Context,
|
|
req *QueryEventsByIDRequest,
|
|
res *QueryEventsByIDResponse,
|
|
) error
|
|
// Query the membership event for an user for a room.
|
|
QueryMembershipForUser(
|
|
ctx context.Context,
|
|
req *QueryMembershipForUserRequest,
|
|
res *QueryMembershipForUserResponse,
|
|
) error
|
|
|
|
// Query the state after a list of events in a room from the room server.
|
|
QueryStateAfterEvents(
|
|
ctx context.Context,
|
|
req *QueryStateAfterEventsRequest,
|
|
res *QueryStateAfterEventsResponse,
|
|
) error
|
|
|
|
// Query a given amount (or less) of events prior to a given set of events.
|
|
PerformBackfill(
|
|
ctx context.Context,
|
|
req *PerformBackfillRequest,
|
|
res *PerformBackfillResponse,
|
|
) error
|
|
|
|
// QueryMembershipAtEvent queries the memberships at the given events.
|
|
// Returns a map from eventID to a slice of types.HeaderedEvent.
|
|
QueryMembershipAtEvent(
|
|
ctx context.Context,
|
|
request *QueryMembershipAtEventRequest,
|
|
response *QueryMembershipAtEventResponse,
|
|
) error
|
|
}
|
|
|
|
type AppserviceRoomserverAPI interface {
|
|
QuerySenderIDAPI
|
|
// QueryEventsByID queries a list of events by event ID for one room. If no room is specified, it will try to determine
|
|
// which room to use by querying the first events roomID.
|
|
QueryEventsByID(
|
|
ctx context.Context,
|
|
req *QueryEventsByIDRequest,
|
|
res *QueryEventsByIDResponse,
|
|
) error
|
|
// Query a list of membership events for a room
|
|
QueryMembershipsForRoom(
|
|
ctx context.Context,
|
|
req *QueryMembershipsForRoomRequest,
|
|
res *QueryMembershipsForRoomResponse,
|
|
) error
|
|
// Get all known aliases for a room ID
|
|
GetAliasesForRoomID(
|
|
ctx context.Context,
|
|
req *GetAliasesForRoomIDRequest,
|
|
res *GetAliasesForRoomIDResponse,
|
|
) error
|
|
}
|
|
|
|
type ClientRoomserverAPI interface {
|
|
InputRoomEventsAPI
|
|
QueryLatestEventsAndStateAPI
|
|
QueryBulkStateContentAPI
|
|
QueryEventsAPI
|
|
QuerySenderIDAPI
|
|
UserRoomPrivateKeyCreator
|
|
QueryRoomHierarchyAPI
|
|
QueryMembershipForUser(ctx context.Context, req *QueryMembershipForUserRequest, res *QueryMembershipForUserResponse) error
|
|
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
|
|
QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error
|
|
QueryStateAfterEvents(ctx context.Context, req *QueryStateAfterEventsRequest, res *QueryStateAfterEventsResponse) error
|
|
// QueryKnownUsers returns a list of users that we know about from our joined rooms.
|
|
QueryKnownUsers(ctx context.Context, req *QueryKnownUsersRequest, res *QueryKnownUsersResponse) error
|
|
QueryRoomVersionForRoom(ctx context.Context, roomID string) (gomatrixserverlib.RoomVersion, error)
|
|
QueryPublishedRooms(ctx context.Context, req *QueryPublishedRoomsRequest, res *QueryPublishedRoomsResponse) error
|
|
|
|
GetRoomIDForAlias(ctx context.Context, req *GetRoomIDForAliasRequest, res *GetRoomIDForAliasResponse) error
|
|
GetAliasesForRoomID(ctx context.Context, req *GetAliasesForRoomIDRequest, res *GetAliasesForRoomIDResponse) error
|
|
|
|
PerformCreateRoom(ctx context.Context, userID spec.UserID, roomID spec.RoomID, createRequest *PerformCreateRoomRequest) (string, *util.JSONResponse)
|
|
// PerformRoomUpgrade upgrades a room to a newer version
|
|
PerformRoomUpgrade(ctx context.Context, roomID string, userID spec.UserID, roomVersion gomatrixserverlib.RoomVersion) (newRoomID string, err error)
|
|
PerformAdminEvacuateRoom(ctx context.Context, roomID string) (affected []string, err error)
|
|
PerformAdminEvacuateUser(ctx context.Context, userID string) (affected []string, err error)
|
|
PerformAdminPurgeRoom(ctx context.Context, roomID string) error
|
|
PerformAdminDownloadState(ctx context.Context, roomID, userID string, serverName spec.ServerName) error
|
|
PerformPeek(ctx context.Context, req *PerformPeekRequest) (roomID string, err error)
|
|
PerformUnpeek(ctx context.Context, roomID, userID, deviceID string) error
|
|
PerformInvite(ctx context.Context, req *PerformInviteRequest) error
|
|
PerformJoin(ctx context.Context, req *PerformJoinRequest) (roomID string, joinedVia spec.ServerName, err error)
|
|
PerformLeave(ctx context.Context, req *PerformLeaveRequest, res *PerformLeaveResponse) error
|
|
PerformPublish(ctx context.Context, req *PerformPublishRequest) error
|
|
// PerformForget forgets a rooms history for a specific user
|
|
PerformForget(ctx context.Context, req *PerformForgetRequest, resp *PerformForgetResponse) error
|
|
|
|
// Sets a room alias, as provided sender, pointing to the provided room ID.
|
|
//
|
|
// If err is nil, then the returned boolean indicates if the alias is already in use.
|
|
// If true, then the alias has not been set to the provided room, as it already in use.
|
|
SetRoomAlias(ctx context.Context, senderID spec.SenderID, roomID spec.RoomID, alias string) (aliasAlreadyExists bool, err error)
|
|
|
|
//RemoveRoomAlias(ctx context.Context, req *RemoveRoomAliasRequest, res *RemoveRoomAliasResponse) error
|
|
// Removes a room alias, as provided sender.
|
|
//
|
|
// Returns whether the alias was found, whether it was removed, and an error (if any occurred)
|
|
RemoveRoomAlias(ctx context.Context, senderID spec.SenderID, alias string) (aliasFound bool, aliasRemoved bool, err error)
|
|
|
|
SigningIdentityFor(ctx context.Context, roomID spec.RoomID, senderID spec.UserID) (fclient.SigningIdentity, error)
|
|
}
|
|
|
|
type UserRoomserverAPI interface {
|
|
QuerySenderIDAPI
|
|
QueryLatestEventsAndStateAPI
|
|
KeyserverRoomserverAPI
|
|
QueryCurrentState(ctx context.Context, req *QueryCurrentStateRequest, res *QueryCurrentStateResponse) error
|
|
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
|
|
PerformAdminEvacuateUser(ctx context.Context, userID string) (affected []string, err error)
|
|
PerformJoin(ctx context.Context, req *PerformJoinRequest) (roomID string, joinedVia spec.ServerName, err error)
|
|
JoinedUserCount(ctx context.Context, roomID string) (int, error)
|
|
}
|
|
|
|
type FederationRoomserverAPI interface {
|
|
RestrictedJoinAPI
|
|
InputRoomEventsAPI
|
|
QueryLatestEventsAndStateAPI
|
|
QueryBulkStateContentAPI
|
|
QuerySenderIDAPI
|
|
QueryRoomHierarchyAPI
|
|
UserRoomPrivateKeyCreator
|
|
AssignRoomNID(ctx context.Context, roomID spec.RoomID, roomVersion gomatrixserverlib.RoomVersion) (roomNID types.RoomNID, err error)
|
|
SigningIdentityFor(ctx context.Context, roomID spec.RoomID, senderID spec.UserID) (fclient.SigningIdentity, error)
|
|
// QueryServerBannedFromRoom returns whether a server is banned from a room by server ACLs.
|
|
QueryServerBannedFromRoom(ctx context.Context, req *QueryServerBannedFromRoomRequest, res *QueryServerBannedFromRoomResponse) error
|
|
QueryMembershipForUser(ctx context.Context, req *QueryMembershipForUserRequest, res *QueryMembershipForUserResponse) error
|
|
QueryMembershipForSenderID(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID, res *QueryMembershipForUserResponse) error
|
|
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
|
|
QueryRoomVersionForRoom(ctx context.Context, roomID string) (gomatrixserverlib.RoomVersion, error)
|
|
GetRoomIDForAlias(ctx context.Context, req *GetRoomIDForAliasRequest, res *GetRoomIDForAliasResponse) error
|
|
// QueryEventsByID queries a list of events by event ID for one room. If no room is specified, it will try to determine
|
|
// which room to use by querying the first events roomID.
|
|
QueryEventsByID(ctx context.Context, req *QueryEventsByIDRequest, res *QueryEventsByIDResponse) error
|
|
// Query to get state and auth chain for a (potentially hypothetical) event.
|
|
// Takes lists of PrevEventIDs and AuthEventsIDs and uses them to calculate
|
|
// the state and auth chain to return.
|
|
QueryStateAndAuthChain(ctx context.Context, req *QueryStateAndAuthChainRequest, res *QueryStateAndAuthChainResponse) error
|
|
QueryPublishedRooms(ctx context.Context, req *QueryPublishedRoomsRequest, res *QueryPublishedRoomsResponse) error
|
|
// Query missing events for a room from roomserver
|
|
QueryMissingEvents(ctx context.Context, req *QueryMissingEventsRequest, res *QueryMissingEventsResponse) error
|
|
// Query whether a server is allowed to see an event
|
|
QueryServerAllowedToSeeEvent(ctx context.Context, serverName spec.ServerName, eventID string, roomID string) (allowed bool, err error)
|
|
QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error
|
|
QueryRestrictedJoinAllowed(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (string, error)
|
|
PerformInboundPeek(ctx context.Context, req *PerformInboundPeekRequest, res *PerformInboundPeekResponse) error
|
|
HandleInvite(ctx context.Context, event *types.HeaderedEvent) error
|
|
|
|
PerformInvite(ctx context.Context, req *PerformInviteRequest) error
|
|
// Query a given amount (or less) of events prior to a given set of events.
|
|
PerformBackfill(ctx context.Context, req *PerformBackfillRequest, res *PerformBackfillResponse) error
|
|
|
|
IsKnownRoom(ctx context.Context, roomID spec.RoomID) (bool, error)
|
|
StateQuerier() gomatrixserverlib.StateQuerier
|
|
}
|
|
|
|
type KeyserverRoomserverAPI interface {
|
|
QueryLeftUsers(ctx context.Context, req *QueryLeftUsersRequest, res *QueryLeftUsersResponse) error
|
|
}
|