mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-08-02 22:22:46 +00:00
Update gomatrixserverlib dep and add basic /createRoom validation (#31)
This commit is contained in:
parent
1d18da1189
commit
e82090e277
7 changed files with 250 additions and 102 deletions
|
@ -2,9 +2,10 @@ package common
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/util"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// UnmarshalJSONRequest into the given interface pointer. Returns an error JSON response if
|
||||
|
@ -12,9 +13,12 @@ import (
|
|||
func UnmarshalJSONRequest(req *http.Request, iface interface{}) *util.JSONResponse {
|
||||
defer req.Body.Close()
|
||||
if err := json.NewDecoder(req.Body).Decode(iface); err != nil {
|
||||
// TODO: We may want to suppress the Error() return in production? It's useful when
|
||||
// debugging because an error will be produced for both invalid/malformed JSON AND
|
||||
// valid JSON with incorrect types for values.
|
||||
return &util.JSONResponse{
|
||||
Code: 400,
|
||||
JSON: jsonerror.NotJSON("The request body was not JSON"),
|
||||
JSON: jsonerror.BadJSON("The request body could not be decoded into valid JSON. " + err.Error()),
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -2,11 +2,14 @@ package writers
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/matrix-org/dendrite/clientapi/auth"
|
||||
"github.com/matrix-org/dendrite/clientapi/common"
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
||||
|
@ -22,8 +25,56 @@ type createRoomRequest struct {
|
|||
RoomAliasName string `json:"room_alias_name"`
|
||||
}
|
||||
|
||||
func (r createRoomRequest) Validate() *util.JSONResponse {
|
||||
whitespace := "\t\n\x0b\x0c\r " // https://docs.python.org/2/library/string.html#string.whitespace
|
||||
// https://github.com/matrix-org/synapse/blob/v0.19.2/synapse/handlers/room.py#L81
|
||||
// Synapse doesn't check for ':' but we will else it will break parsers badly which split things into 2 segments.
|
||||
if strings.ContainsAny(r.RoomAliasName, whitespace+":") {
|
||||
return &util.JSONResponse{
|
||||
Code: 400,
|
||||
JSON: jsonerror.BadJSON("room_alias_name cannot contain whitespace"),
|
||||
}
|
||||
}
|
||||
for _, userID := range r.Invite {
|
||||
// TODO: We should put user ID parsing code into gomatrixserverlib and use that instead
|
||||
// (see https://github.com/matrix-org/gomatrixserverlib/blob/3394e7c7003312043208aa73727d2256eea3d1f6/eventcontent.go#L347 )
|
||||
// It should be a struct (with pointers into a single string to avoid copying) and
|
||||
// we should update all refs to use UserID types rather than strings.
|
||||
// https://github.com/matrix-org/synapse/blob/v0.19.2/synapse/types.py#L92
|
||||
if len(userID) == 0 || userID[0] != '@' {
|
||||
return &util.JSONResponse{
|
||||
Code: 400,
|
||||
JSON: jsonerror.BadJSON("user id must start with '@'"),
|
||||
}
|
||||
}
|
||||
parts := strings.SplitN(userID[1:], ":", 2)
|
||||
if len(parts) != 2 {
|
||||
return &util.JSONResponse{
|
||||
Code: 400,
|
||||
JSON: jsonerror.BadJSON("user id must be in the form @localpart:domain"),
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-createroom
|
||||
type createRoomResponse struct {
|
||||
RoomID string `json:"room_id"`
|
||||
RoomAlias string `json:"room_alias,omitempty"` // in synapse not spec
|
||||
}
|
||||
|
||||
// CreateRoom implements /createRoom
|
||||
func CreateRoom(req *http.Request) util.JSONResponse {
|
||||
serverName := "localhost"
|
||||
// TODO: Check room ID doesn't clash with an existing one, and we
|
||||
// probably shouldn't be using pseudo-random strings, maybe GUIDs?
|
||||
roomID := fmt.Sprintf("!%s:%s", util.RandomString(16), serverName)
|
||||
return createRoom(req, roomID)
|
||||
}
|
||||
|
||||
// createRoom implements /createRoom
|
||||
func createRoom(req *http.Request, roomID string) util.JSONResponse {
|
||||
logger := util.GetLogger(req.Context())
|
||||
userID, resErr := auth.VerifyAccessToken(req)
|
||||
if resErr != nil {
|
||||
|
@ -34,9 +85,44 @@ func CreateRoom(req *http.Request) util.JSONResponse {
|
|||
if resErr != nil {
|
||||
return *resErr
|
||||
}
|
||||
// TODO: apply rate-limit
|
||||
|
||||
if resErr = r.Validate(); resErr != nil {
|
||||
return *resErr
|
||||
}
|
||||
|
||||
// TODO: visibility/presets/raw initial state/creation content
|
||||
|
||||
// TODO: Create room alias association
|
||||
|
||||
logger.WithFields(log.Fields{
|
||||
"userID": userID,
|
||||
"roomID": roomID,
|
||||
}).Info("Creating room")
|
||||
|
||||
// send events into the room in order of:
|
||||
// 1- m.room.create
|
||||
// 2- room creator join member
|
||||
// 3- m.room.power_levels
|
||||
// 4- m.room.canonical_alias (opt) TODO
|
||||
// 5- m.room.join_rules
|
||||
// 6- m.room.history_visibility
|
||||
// 7- m.room.guest_access (opt) TODO
|
||||
// 8- other initial state items TODO
|
||||
// 9- m.room.name (opt)
|
||||
// 10- m.room.topic (opt)
|
||||
// 11- invite events (opt) - with is_direct flag if applicable TODO
|
||||
// 12- 3pid invite events (opt) TODO
|
||||
// 13- m.room.aliases event for HS (if alias specified) TODO
|
||||
// This differs from Synapse slightly. Synapse would vary the ordering of 3-7
|
||||
// depending on if those events were in "initial_state" or not. This made it
|
||||
// harder to reason about, hence sticking to a strict static ordering.
|
||||
|
||||
// f.e event:
|
||||
// - validate required keys/types (EventValidator in synapse)
|
||||
// - set additional keys (displayname/avatar_url for m.room.member)
|
||||
// - set token(?) and txn id
|
||||
// - then https://github.com/matrix-org/synapse/blob/v0.19.2/synapse/handlers/message.py#L419
|
||||
|
||||
return util.MessageResponse(404, "Not implemented yet")
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue