diff --git a/src/github.com/matrix-org/dendrite/clientapi/auth/auth.go b/src/github.com/matrix-org/dendrite/clientapi/auth/auth.go index a661c1f8..24df9019 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/auth/auth.go +++ b/src/github.com/matrix-org/dendrite/clientapi/auth/auth.go @@ -41,7 +41,7 @@ var tokenByteLength = 32 // DeviceDatabase represents a device database. type DeviceDatabase interface { - // Lookup the device matching the given access token. + // Look up the device matching the given access token. GetDeviceByAccessToken(token string) (*authtypes.Device, error) } diff --git a/src/github.com/matrix-org/dendrite/roomserver/alias/alias.go b/src/github.com/matrix-org/dendrite/roomserver/alias/alias.go index faf91bc4..51ac0b42 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/alias/alias.go +++ b/src/github.com/matrix-org/dendrite/roomserver/alias/alias.go @@ -32,10 +32,10 @@ type RoomserverAliasAPIDatabase interface { // Save a given room alias with the room ID it refers to. // Returns an error if there was a problem talking to the database. SetRoomAlias(alias string, roomID string) error - // Lookup the room ID a given alias refers to. + // Look up the room ID a given alias refers to. // Returns an error if there was a problem talking to the database. GetRoomIDFromAlias(alias string) (string, error) - // Lookup all aliases referring to a given room ID. + // Look up all aliases referring to a given room ID. // Returns an error if there was a problem talking to the database. GetAliasesFromRoomID(roomID string) ([]string, error) // Remove a given room alias. @@ -86,7 +86,7 @@ func (r *RoomserverAliasAPI) GetAliasRoomID( request *api.GetAliasRoomIDRequest, response *api.GetAliasRoomIDResponse, ) error { - // Lookup the room ID in the database + // Look up the room ID in the database roomID, err := r.DB.GetRoomIDFromAlias(request.Alias) if err != nil { return err @@ -101,7 +101,7 @@ func (r *RoomserverAliasAPI) RemoveRoomAlias( request *api.RemoveRoomAliasRequest, response *api.RemoveRoomAliasResponse, ) error { - // Lookup the room ID in the database + // Look up the room ID in the database roomID, err := r.DB.GetRoomIDFromAlias(request.Alias) if err != nil { return err diff --git a/src/github.com/matrix-org/dendrite/roomserver/api/query.go b/src/github.com/matrix-org/dendrite/roomserver/api/query.go index f07da59e..e9573d1b 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/api/query.go +++ b/src/github.com/matrix-org/dendrite/roomserver/api/query.go @@ -117,6 +117,23 @@ type QueryMembershipsForRoomResponse struct { HasBeenInRoom bool `json:"has_been_in_room"` } +// QueryInvitesForUserRequest is a request to QueryInvitesForUser +type QueryInvitesForUserRequest struct { + // The room ID to look up invites in. + RoomID string `json:"room_id"` + // The User ID to look up invites for. + TargetUserID string `json:"target_user_id"` +} + +// QueryInvitesForUserResponse is a response to QueryInvitesForUser +// This is used when accepting an invite or rejecting a invite to tell which +// remote matrix servers to contact. +type QueryInvitesForUserResponse struct { + // A list of matrix user IDs for each sender of an active invite targeting + // the requested user ID. + InviteSenderUserIDs []string `json:"invite_sender_user_ids"` +} + // RoomserverQueryAPI is used to query information from the room server. type RoomserverQueryAPI interface { // Query the latest events and state for a room from the room server. @@ -142,6 +159,12 @@ type RoomserverQueryAPI interface { request *QueryMembershipsForRoomRequest, response *QueryMembershipsForRoomResponse, ) error + + // Query a list of invite event senders for a user in a room. + QueryInvitesForUser( + request *QueryInvitesForUserRequest, + response *QueryInvitesForUserResponse, + ) error } // RoomserverQueryLatestEventsAndStatePath is the HTTP path for the QueryLatestEventsAndState API. @@ -156,6 +179,9 @@ const RoomserverQueryEventsByIDPath = "/api/roomserver/queryEventsByID" // RoomserverQueryMembershipsForRoomPath is the HTTP path for the QueryMembershipsForRoom API const RoomserverQueryMembershipsForRoomPath = "/api/roomserver/queryMembershipsForRoom" +// RoomserverQueryInvitesForUserPath is the HTTP path for the QueryInvitesForUser API +const RoomserverQueryInvitesForUserPath = "/api/roomserver/queryInvitesForUser" + // NewRoomserverQueryAPIHTTP creates a RoomserverQueryAPI implemented by talking to a HTTP POST API. // If httpClient is nil then it uses the http.DefaultClient func NewRoomserverQueryAPIHTTP(roomserverURL string, httpClient *http.Client) RoomserverQueryAPI { @@ -206,6 +232,15 @@ func (h *httpRoomserverQueryAPI) QueryMembershipsForRoom( return postJSON(h.httpClient, apiURL, request, response) } +// QueryInvitesForUser implements RoomserverQueryAPI +func (h *httpRoomserverQueryAPI) QueryInvitesForUser( + request *QueryInvitesForUserRequest, + response *QueryInvitesForUserResponse, +) error { + apiURL := h.roomserverURL + RoomserverQueryInvitesForUserPath + return postJSON(h.httpClient, apiURL, request, response) +} + func postJSON(httpClient *http.Client, apiURL string, request, response interface{}) error { jsonBytes, err := json.Marshal(request) if err != nil { diff --git a/src/github.com/matrix-org/dendrite/roomserver/input/authevents.go b/src/github.com/matrix-org/dendrite/roomserver/input/authevents.go index ef70a61e..fbb7d7c0 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/input/authevents.go +++ b/src/github.com/matrix-org/dendrite/roomserver/input/authevents.go @@ -117,7 +117,7 @@ func loadAuthEvents( needed gomatrixserverlib.StateNeeded, state []types.StateEntry, ) (result authEvents, err error) { - // Lookup the numeric IDs for the state keys needed for auth. + // Look up the numeric IDs for the state keys needed for auth. var neededStateKeys []string neededStateKeys = append(neededStateKeys, needed.Member...) neededStateKeys = append(neededStateKeys, needed.ThirdPartyInvite...) diff --git a/src/github.com/matrix-org/dendrite/roomserver/input/events.go b/src/github.com/matrix-org/dendrite/roomserver/input/events.go index 82b4652e..88c60447 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/input/events.go +++ b/src/github.com/matrix-org/dendrite/roomserver/input/events.go @@ -29,18 +29,18 @@ type RoomEventDatabase interface { state.RoomStateDatabase // Stores a matrix room event in the database StoreEvent(event gomatrixserverlib.Event, authEventNIDs []types.EventNID) (types.RoomNID, types.StateAtEvent, error) - // Lookup the state entries for a list of string event IDs + // Look up the state entries for a list of string event IDs // Returns an error if the there is an error talking to the database // Returns a types.MissingEventError if the event IDs aren't in the database. StateEntriesForEventIDs(eventIDs []string) ([]types.StateEntry, error) // Set the state at an event. SetState(eventNID types.EventNID, stateNID types.StateSnapshotNID) error - // Lookup the latest events in a room in preparation for an update. + // Look up the latest events in a room in preparation for an update. // The RoomRecentEventsUpdater must have Commit or Rollback called on it if this doesn't return an error. // Returns the latest events in the room and the last eventID sent to the log along with an updater. // If this returns an error then no further action is required. GetLatestEventsForUpdate(roomNID types.RoomNID) (updater types.RoomRecentEventsUpdater, err error) - // Lookup the string event IDs for a list of numeric event IDs + // Look up the string event IDs for a list of numeric event IDs EventIDs(eventNIDs []types.EventNID) (map[types.EventNID]string, error) // Build a membership updater for the target user in a room. MembershipUpdater(roomID, targerUserID string) (types.MembershipUpdater, error) diff --git a/src/github.com/matrix-org/dendrite/roomserver/query/query.go b/src/github.com/matrix-org/dendrite/roomserver/query/query.go index 84f5d44c..a4eccb59 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/query/query.go +++ b/src/github.com/matrix-org/dendrite/roomserver/query/query.go @@ -29,36 +29,31 @@ import ( // RoomserverQueryAPIDatabase has the storage APIs needed to implement the query API. type RoomserverQueryAPIDatabase interface { state.RoomStateDatabase - // Lookup the numeric ID for the room. + // Look up the numeric ID for the room. // Returns 0 if the room doesn't exists. // Returns an error if there was a problem talking to the database. RoomNID(roomID string) (types.RoomNID, error) - // Lookup event references for the latest events in the room and the current state snapshot. + // Look up event references for the latest events in the room and the current state snapshot. // Returns the latest events, the current state and the maximum depth of the latest events plus 1. // Returns an error if there was a problem talking to the database. LatestEventIDs(roomNID types.RoomNID) ([]gomatrixserverlib.EventReference, types.StateSnapshotNID, int64, error) - // Lookup the numeric IDs for a list of events. + // Look up the numeric IDs for a list of events. // Returns an error if there was a problem talking to the database. EventNIDs(eventIDs []string) (map[string]types.EventNID, error) - // Save a given room alias with the room ID it refers to. - // Returns an error if there was a problem talking to the database. - SetRoomAlias(alias string, roomID string) error - // Lookup the room ID a given alias refers to. - // Returns an error if there was a problem talking to the database. - GetRoomIDFromAlias(alias string) (string, error) - // Lookup all aliases referring to a given room ID. - // Returns an error if there was a problem talking to the database. - GetAliasesFromRoomID(roomID string) ([]string, error) - // Remove a given room alias. - // Returns an error if there was a problem talking to the database. - RemoveRoomAlias(alias string) error - // Lookup the join events for all members in a room as requested by a given + // Look up the join events for all members in a room as requested by a given // user. If the user is currently in the room, returns the room's current // members, if not returns an empty array (TODO: Fix it) // If the user requesting the list of members has never been in the room, // returns nil. // If there was an issue retrieving the events, returns an error. GetMembershipEvents(roomNID types.RoomNID, requestSenderUserID string) (events []types.Event, err error) + // Look up the active invites targeting a user in a room and return the + // numeric state key IDs for the user IDs who sent them. + // Returns an error if there was a problem talking to the database. + GetInvitesForUser(roomNID types.RoomNID, targetUserNID types.EventStateKeyNID) (senderUserNIDs []types.EventStateKeyNID, err error) + // Look up the string event state keys for a list of numeric event state keys + // Returns an error if there was a problem talking to the database. + EventStateKeys([]types.EventStateKeyNID) (map[types.EventStateKeyNID]string, error) } // RoomserverQueryAPI is an implementation of api.RoomserverQueryAPI @@ -86,7 +81,7 @@ func (r *RoomserverQueryAPI) QueryLatestEventsAndState( return err } - // Lookup the currrent state for the requested tuples. + // Look up the currrent state for the requested tuples. stateEntries, err := state.LoadStateAtSnapshotForStringTuples(r.DB, currentStateSnapshotNID, request.StateToFetch) if err != nil { return err @@ -127,7 +122,7 @@ func (r *RoomserverQueryAPI) QueryStateAfterEvents( } response.PrevEventsExist = true - // Lookup the currrent state for the requested tuples. + // Look up the currrent state for the requested tuples. stateEntries, err := state.LoadStateAfterEventsForStringTuples(r.DB, prevStates, request.StateToFetch) if err != nil { return err @@ -220,6 +215,39 @@ func (r *RoomserverQueryAPI) QueryMembershipsForRoom( return nil } +// QueryInvitesForUser implements api.RoomserverQueryAPI +func (r *RoomserverQueryAPI) QueryInvitesForUser( + request *api.QueryInvitesForUserRequest, + response *api.QueryInvitesForUserResponse, +) error { + roomNID, err := r.DB.RoomNID(request.RoomID) + if err != nil { + return err + } + + targetUserNIDs, err := r.DB.EventStateKeyNIDs([]string{request.TargetUserID}) + if err != nil { + return err + } + targetUserNID := targetUserNIDs[request.TargetUserID] + + senderUserNIDs, err := r.DB.GetInvitesForUser(roomNID, targetUserNID) + if err != nil { + return err + } + + senderUserIDs, err := r.DB.EventStateKeys(senderUserNIDs) + if err != nil { + return err + } + + for _, senderUserID := range senderUserIDs { + response.InviteSenderUserIDs = append(response.InviteSenderUserIDs, senderUserID) + } + + return nil +} + // SetupHTTP adds the RoomserverQueryAPI handlers to the http.ServeMux. func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) { servMux.Handle( @@ -278,4 +306,18 @@ func (r *RoomserverQueryAPI) SetupHTTP(servMux *http.ServeMux) { return util.JSONResponse{Code: 200, JSON: &response} }), ) + servMux.Handle( + api.RoomserverQueryInvitesForUserPath, + common.MakeAPI("queryInvitesForUser", func(req *http.Request) util.JSONResponse { + var request api.QueryInvitesForUserRequest + var response api.QueryInvitesForUserResponse + if err := json.NewDecoder(req.Body).Decode(&request); err != nil { + return util.ErrorResponse(err) + } + if err := r.QueryInvitesForUser(&request, &response); err != nil { + return util.ErrorResponse(err) + } + return util.JSONResponse{Code: 200, JSON: &response} + }), + ) } diff --git a/src/github.com/matrix-org/dendrite/roomserver/state/state.go b/src/github.com/matrix-org/dendrite/roomserver/state/state.go index b5454c0c..3c2780ae 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/state/state.go +++ b/src/github.com/matrix-org/dendrite/roomserver/state/state.go @@ -30,30 +30,30 @@ import ( type RoomStateDatabase interface { // Store the room state at an event in the database AddState(roomNID types.RoomNID, stateBlockNIDs []types.StateBlockNID, state []types.StateEntry) (types.StateSnapshotNID, error) - // Lookup the state of a room at each event for a list of string event IDs. + // Look up the state of a room at each event for a list of string event IDs. // Returns an error if there is an error talking to the database // Returns a types.MissingEventError if the room state for the event IDs aren't in the database StateAtEventIDs(eventIDs []string) ([]types.StateAtEvent, error) - // Lookup the numeric IDs for a list of string event types. + // Look up the numeric IDs for a list of string event types. // Returns a map from string event type to numeric ID for the event type. EventTypeNIDs(eventTypes []string) (map[string]types.EventTypeNID, error) - // Lookup the numeric IDs for a list of string event state keys. + // Look up the numeric IDs for a list of string event state keys. // Returns a map from string state key to numeric ID for the state key. EventStateKeyNIDs(eventStateKeys []string) (map[string]types.EventStateKeyNID, error) - // Lookup the numeric state data IDs for each numeric state snapshot ID + // Look up the numeric state data IDs for each numeric state snapshot ID // The returned slice is sorted by numeric state snapshot ID. StateBlockNIDs(stateNIDs []types.StateSnapshotNID) ([]types.StateBlockNIDList, error) - // Lookup the state data for each numeric state data ID + // Look up the state data for each numeric state data ID // The returned slice is sorted by numeric state data ID. StateEntries(stateBlockNIDs []types.StateBlockNID) ([]types.StateEntryList, error) - // Lookup the state data for the state key tuples for each numeric state block ID + // Look up the state data for the state key tuples for each numeric state block ID // This is used to fetch a subset of the room state at a snapshot. // If a block doesn't contain any of the requested tuples then it can be discarded from the result. // The returned slice is sorted by numeric state block ID. StateEntriesForTuples(stateBlockNIDs []types.StateBlockNID, stateKeyTuples []types.StateKeyTuple) ( []types.StateEntryList, error, ) - // Lookup the Events for a list of numeric event IDs. + // Look up the Events for a list of numeric event IDs. // Returns a sorted list of events. Events(eventNIDs []types.EventNID) ([]types.Event, error) } diff --git a/src/github.com/matrix-org/dendrite/roomserver/storage/storage.go b/src/github.com/matrix-org/dendrite/roomserver/storage/storage.go index fbbc723e..7e90aebb 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/storage/storage.go +++ b/src/github.com/matrix-org/dendrite/roomserver/storage/storage.go @@ -161,7 +161,12 @@ func (d *Database) EventStateKeyNIDs(eventStateKeys []string) (map[string]types. return d.statements.bulkSelectEventStateKeyNID(eventStateKeys) } -// EventNIDs implements query.RoomQueryDatabase +// EventStateKeys implements query.RoomserverQueryAPIDatabase +func (d *Database) EventStateKeys(eventStateKeyNIDs []types.EventStateKeyNID) (map[types.EventStateKeyNID]string, error) { + return d.statements.bulkSelectEventStateKey(eventStateKeyNIDs) +} + +// EventNIDs implements query.RoomserverQueryAPIDatabase func (d *Database) EventNIDs(eventIDs []string) (map[string]types.EventNID, error) { return d.statements.bulkSelectEventNID(eventIDs) } @@ -336,7 +341,7 @@ func (d *Database) RoomNID(roomID string) (types.RoomNID, error) { return roomNID, err } -// LatestEventIDs implements query.RoomserverQueryAPIDB +// LatestEventIDs implements query.RoomserverQueryAPIDatabase func (d *Database) LatestEventIDs(roomNID types.RoomNID) ([]gomatrixserverlib.EventReference, types.StateSnapshotNID, int64, error) { eventNIDs, currentStateSnapshotNID, err := d.statements.selectLatestEventNIDs(roomNID) if err != nil { @@ -353,6 +358,13 @@ func (d *Database) LatestEventIDs(roomNID types.RoomNID) ([]gomatrixserverlib.Ev return references, currentStateSnapshotNID, depth, nil } +// GetInvitesForUser implements query.RoomserverQueryAPIDatabase +func (d *Database) GetInvitesForUser( + roomNID types.RoomNID, targetUserNID types.EventStateKeyNID, +) (senderUserIDs []types.EventStateKeyNID, err error) { + return d.statements.selectInviteActiveForUserInRoom(targetUserNID, roomNID) +} + // SetRoomAlias implements alias.RoomserverAliasAPIDB func (d *Database) SetRoomAlias(alias string, roomID string) error { return d.statements.insertRoomAlias(alias, roomID) @@ -494,7 +506,7 @@ func (u *membershipUpdater) SetToJoin(senderUserID string, eventID string, isUpd } } - // Lookup the NID of the new join event + // Look up the NID of the new join event nIDs, err := u.d.EventNIDs([]string{eventID}) if err != nil { return nil, err @@ -524,7 +536,7 @@ func (u *membershipUpdater) SetToLeave(senderUserID string, eventID string) ([]s return nil, err } - // Lookup the NID of the new leave event + // Look up the NID of the new leave event nIDs, err := u.d.EventNIDs([]string{eventID}) if err != nil { return nil, err