Add query API for listing active invites
* Add query API for listing active invites
This lists the invites for a user in a room that could be used to
join the room over federation.
* s/Lookup/Look up/
* Fix implements comments
MODIFY
src/github.com/matrix-org/dendrite/roomserver/api/query.go
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 {

MODIFY
src/github.com/matrix-org/dendrite/roomserver/query/query.go
src/github.com/matrix-org/dendrite/roomserver/query/query.go
@@ -40,18 +40,6 @@ type RoomserverQueryAPIDatabase interface {
// 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
// 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)
@@ -59,6 +47,13 @@ type RoomserverQueryAPIDatabase interface {
// 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
@@ -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}
+ }),
+ )
}

MODIFY
src/github.com/matrix-org/dendrite/roomserver/storage/storage.go
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)

Add query API for listing active invites (#196)

* Add query API for listing active invites

This lists the invites for a user in a room that could be used to
join the room over federation.

* s/Lookup/Look up/

* Fix implements comments