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
Prateek Sachan 2020-04-14 18:37:03 +05:30 committed by GitHub
parent d359851708
commit 1321f8da80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 5 deletions

View File

@ -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

View File

@ -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)
} }

View File

@ -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",