Check if user has the power level to edit the room visibility (#900)
* Check if user has the power level to edit the room visibility * fix review changes * Add nil check for queryEventsRes.StateEvents Co-authored-by: Alex Chen <Cnly@users.noreply.github.com> Co-authored-by: Neil Alexander <neilalexander@users.noreply.github.com>main
parent
d359851708
commit
1321f8da80
|
@ -17,6 +17,9 @@ package directory
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
"github.com/matrix-org/dendrite/publicroomsapi/storage"
|
"github.com/matrix-org/dendrite/publicroomsapi/storage"
|
||||||
|
@ -54,11 +57,51 @@ func GetVisibility(
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVisibility implements PUT /directory/list/room/{roomID}
|
// SetVisibility implements PUT /directory/list/room/{roomID}
|
||||||
// TODO: Check if user has the power level to edit the room visibility
|
// TODO: Allow admin users to edit the room visibility
|
||||||
func SetVisibility(
|
func SetVisibility(
|
||||||
req *http.Request, publicRoomsDatabase storage.Database,
|
req *http.Request, publicRoomsDatabase storage.Database, queryAPI api.RoomserverQueryAPI, dev *authtypes.Device,
|
||||||
roomID string,
|
roomID string,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
|
queryMembershipReq := api.QueryMembershipForUserRequest{
|
||||||
|
RoomID: roomID,
|
||||||
|
UserID: dev.UserID,
|
||||||
|
}
|
||||||
|
var queryMembershipRes api.QueryMembershipForUserResponse
|
||||||
|
err := queryAPI.QueryMembershipForUser(req.Context(), &queryMembershipReq, &queryMembershipRes)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("could not query membership for user")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
// Check if user id is in room
|
||||||
|
if !queryMembershipRes.IsInRoom {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusForbidden,
|
||||||
|
JSON: jsonerror.Forbidden("user does not belong to room"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queryEventsReq := api.QueryLatestEventsAndStateRequest{
|
||||||
|
RoomID: roomID,
|
||||||
|
StateToFetch: []gomatrixserverlib.StateKeyTuple{{
|
||||||
|
EventType: gomatrixserverlib.MRoomPowerLevels,
|
||||||
|
StateKey: "",
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
var queryEventsRes api.QueryLatestEventsAndStateResponse
|
||||||
|
err = queryAPI.QueryLatestEventsAndState(req.Context(), &queryEventsReq, &queryEventsRes)
|
||||||
|
if err != nil || len(queryEventsRes.StateEvents) == 0 {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("could not query events from room")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
power, _ := gomatrixserverlib.NewPowerLevelContentFromEvent(queryEventsRes.StateEvents[0].Event)
|
||||||
|
|
||||||
|
// Check if the user's power is greater than power required to change m.room.aliases event
|
||||||
|
if power.UserLevel(dev.UserID) < power.EventLevel(gomatrixserverlib.MRoomAliases, true) {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusForbidden,
|
||||||
|
JSON: jsonerror.Forbidden("userID doesn't have power level to change visibility"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var v roomVisibility
|
var v roomVisibility
|
||||||
if reqErr := httputil.UnmarshalJSONRequest(req, &v); reqErr != nil {
|
if reqErr := httputil.UnmarshalJSONRequest(req, &v); reqErr != nil {
|
||||||
return *reqErr
|
return *reqErr
|
||||||
|
|
|
@ -47,5 +47,5 @@ func SetupPublicRoomsAPIComponent(
|
||||||
logrus.WithError(err).Panic("failed to start public rooms server consumer")
|
logrus.WithError(err).Panic("failed to start public rooms server consumer")
|
||||||
}
|
}
|
||||||
|
|
||||||
routing.Setup(base.APIMux, deviceDB, publicRoomsDB, fedClient, extRoomsProvider)
|
routing.Setup(base.APIMux, deviceDB, publicRoomsDB, rsQueryAPI, fedClient, extRoomsProvider)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ package routing
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth"
|
"github.com/matrix-org/dendrite/clientapi/auth"
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||||
|
@ -37,7 +39,7 @@ const pathPrefixR0 = "/_matrix/client/r0"
|
||||||
// applied:
|
// applied:
|
||||||
// nolint: gocyclo
|
// nolint: gocyclo
|
||||||
func Setup(
|
func Setup(
|
||||||
apiMux *mux.Router, deviceDB devices.Database, publicRoomsDB storage.Database,
|
apiMux *mux.Router, deviceDB devices.Database, publicRoomsDB storage.Database, queryAPI api.RoomserverQueryAPI,
|
||||||
fedClient *gomatrixserverlib.FederationClient, extRoomsProvider types.ExternalPublicRoomsProvider,
|
fedClient *gomatrixserverlib.FederationClient, extRoomsProvider types.ExternalPublicRoomsProvider,
|
||||||
) {
|
) {
|
||||||
r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter()
|
r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter()
|
||||||
|
@ -64,7 +66,7 @@ func Setup(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.ErrorResponse(err)
|
return util.ErrorResponse(err)
|
||||||
}
|
}
|
||||||
return directory.SetVisibility(req, publicRoomsDB, vars["roomID"])
|
return directory.SetVisibility(req, publicRoomsDB, queryAPI, device, vars["roomID"])
|
||||||
}),
|
}),
|
||||||
).Methods(http.MethodPut, http.MethodOptions)
|
).Methods(http.MethodPut, http.MethodOptions)
|
||||||
r0mux.Handle("/publicRooms",
|
r0mux.Handle("/publicRooms",
|
||||||
|
|
Loading…
Reference in New Issue