aboutsummaryrefslogtreecommitdiff
path: root/clientapi
diff options
context:
space:
mode:
authorLoïck Bonniot <git@lesterpig.com>2020-10-09 10:15:35 +0200
committerGitHub <noreply@github.com>2020-10-09 09:15:35 +0100
commitf3e8ae01efb0abd0904509ddaa2ae85017ca4aa5 (patch)
treef69009e4664e1ac9d50bfaf707236f2a3d63249d /clientapi
parent009401ad4df2e8f5c0c2f08b8c73f807e99b2c13 (diff)
Implement fully read markers (#1475)
See #653 Signed-off-by: Loïck Bonniot <git@lesterpig.com> Co-authored-by: Kegsay <kegan@matrix.org>
Diffstat (limited to 'clientapi')
-rw-r--r--clientapi/routing/account_data.go75
-rw-r--r--clientapi/routing/routing.go9
2 files changed, 80 insertions, 4 deletions
diff --git a/clientapi/routing/account_data.go b/clientapi/routing/account_data.go
index d5fafedb..48303c97 100644
--- a/clientapi/routing/account_data.go
+++ b/clientapi/routing/account_data.go
@@ -20,8 +20,10 @@ import (
"io/ioutil"
"net/http"
+ "github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/producers"
+ roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/util"
@@ -91,6 +93,13 @@ func SaveAccountData(
}
}
+ if dataType == "m.fully_read" {
+ return util.JSONResponse{
+ Code: http.StatusForbidden,
+ JSON: jsonerror.Forbidden("Unable to set read marker"),
+ }
+ }
+
body, err := ioutil.ReadAll(req.Body)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("ioutil.ReadAll failed")
@@ -112,7 +121,7 @@ func SaveAccountData(
}
dataRes := api.InputAccountDataResponse{}
if err := userAPI.InputAccountData(req.Context(), &dataReq, &dataRes); err != nil {
- util.GetLogger(req.Context()).WithError(err).Error("userAPI.QueryAccountData failed")
+ util.GetLogger(req.Context()).WithError(err).Error("userAPI.InputAccountData failed")
return util.ErrorResponse(err)
}
@@ -127,3 +136,67 @@ func SaveAccountData(
JSON: struct{}{},
}
}
+
+type readMarkerJSON struct {
+ FullyRead string `json:"m.fully_read"`
+ Read string `json:"m.read"`
+}
+
+type fullyReadEvent struct {
+ EventID string `json:"event_id"`
+}
+
+// SaveReadMarker implements POST /rooms/{roomId}/read_markers
+func SaveReadMarker(
+ req *http.Request, userAPI api.UserInternalAPI, rsAPI roomserverAPI.RoomserverInternalAPI,
+ syncProducer *producers.SyncAPIProducer, device *api.Device, roomID string,
+) util.JSONResponse {
+ // Verify that the user is a member of this room
+ resErr := checkMemberInRoom(req.Context(), rsAPI, device.UserID, roomID)
+ if resErr != nil {
+ return *resErr
+ }
+
+ var r readMarkerJSON
+ resErr = httputil.UnmarshalJSONRequest(req, &r)
+ if resErr != nil {
+ return *resErr
+ }
+
+ if r.FullyRead == "" {
+ return util.JSONResponse{
+ Code: http.StatusBadRequest,
+ JSON: jsonerror.BadJSON("Missing m.fully_read mandatory field"),
+ }
+ }
+
+ data, err := json.Marshal(fullyReadEvent{EventID: r.FullyRead})
+ if err != nil {
+ return jsonerror.InternalServerError()
+ }
+
+ dataReq := api.InputAccountDataRequest{
+ UserID: device.UserID,
+ DataType: "m.fully_read",
+ RoomID: roomID,
+ AccountData: data,
+ }
+ dataRes := api.InputAccountDataResponse{}
+ if err := userAPI.InputAccountData(req.Context(), &dataReq, &dataRes); err != nil {
+ util.GetLogger(req.Context()).WithError(err).Error("userAPI.InputAccountData failed")
+ return util.ErrorResponse(err)
+ }
+
+ if err := syncProducer.SendData(device.UserID, roomID, "m.fully_read"); err != nil {
+ util.GetLogger(req.Context()).WithError(err).Error("syncProducer.SendData failed")
+ return jsonerror.InternalServerError()
+ }
+
+ // TODO handle the read receipt that may be included in the read marker
+ // See https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-read-markers
+
+ return util.JSONResponse{
+ Code: http.StatusOK,
+ JSON: struct{}{},
+ }
+}
diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go
index 8606f69c..b547efb4 100644
--- a/clientapi/routing/routing.go
+++ b/clientapi/routing/routing.go
@@ -695,12 +695,15 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/read_markers",
- httputil.MakeExternalAPI("rooms_read_markers", func(req *http.Request) util.JSONResponse {
+ httputil.MakeAuthAPI("rooms_read_markers", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
if r := rateLimits.rateLimit(req); r != nil {
return *r
}
- // TODO: return the read_markers.
- return util.JSONResponse{Code: http.StatusOK, JSON: struct{}{}}
+ vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
+ return SaveReadMarker(req, userAPI, rsAPI, syncProducer, device, vars["roomID"])
}),
).Methods(http.MethodPost, http.MethodOptions)