Stub APIs needed to let riot join a room (#147)

* Stub APIs needed to let riot join a room

* Fix comments
main
Mark Haines 2017-06-27 12:37:25 +01:00 committed by GitHub
parent eb029116b0
commit 524475f8a3
3 changed files with 192 additions and 0 deletions

View File

@ -85,6 +85,12 @@ func WeakPassword(msg string) *MatrixError {
return &MatrixError{"M_WEAK_PASSWORD", msg}
}
// GuestAccessForbidden is an error which is returned when the client is
// forbidden from accessing a resource as a guest.
func GuestAccessForbidden(msg string) *MatrixError {
return &MatrixError{"M_GUEST_ACCESS_FORBIDDEN", msg}
}
// LimitExceededError is a rate-limiting error.
type LimitExceededError struct {
MatrixError

View File

@ -0,0 +1,87 @@
// Copyright 2017 Vector Creations Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package readers
import (
"fmt"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/common/config"
"github.com/matrix-org/gomatrix"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util"
"net/http"
"strings"
)
// DirectoryRoom looks up a room alias
func DirectoryRoom(
req *http.Request,
device *authtypes.Device,
roomAlias string,
federation *gomatrixserverlib.FederationClient,
cfg *config.Dendrite,
) util.JSONResponse {
domain, err := domainFromID(roomAlias)
if err != nil {
return util.JSONResponse{
Code: 400,
JSON: jsonerror.BadJSON("Room alias must be in the form '#localpart:domain'"),
}
}
if domain == cfg.Matrix.ServerName {
// TODO: Implement lookup up local room aliases.
panic(fmt.Errorf("Looking up local room aliases is not implemented"))
} else {
resp, err := federation.LookupRoomAlias(domain, roomAlias)
if err != nil {
switch x := err.(type) {
case gomatrix.HTTPError:
if x.Code == 404 {
return util.JSONResponse{
Code: 404,
JSON: jsonerror.NotFound("Room alias not found"),
}
}
}
// TODO: Return 502 if the remote server errored.
// TODO: Return 504 if the remote server timed out.
return httputil.LogThenError(req, err)
}
return util.JSONResponse{
Code: 200,
JSON: resp,
}
}
}
// domainFromID returns everything after the first ":" character to extract
// the domain part of a matrix ID.
// TODO: duplicated from gomatrixserverlib.
func domainFromID(id string) (gomatrixserverlib.ServerName, error) {
// IDs have the format: SIGIL LOCALPART ":" DOMAIN
// Split on the first ":" character since the domain can contain ":"
// characters.
parts := strings.SplitN(id, ":", 2)
if len(parts) != 2 {
// The ID must have a ":" character.
return "", fmt.Errorf("invalid ID: %q", id)
}
// Return everything after the first ":" character.
return gomatrixserverlib.ServerName(parts[1]), nil
}

View File

@ -22,6 +22,7 @@ import (
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/producers"
"github.com/matrix-org/dendrite/clientapi/readers"
"github.com/matrix-org/dendrite/clientapi/writers"
@ -34,6 +35,7 @@ import (
)
const pathPrefixR0 = "/_matrix/client/r0"
const pathPrefixUnstable = "/_matrix/client/unstable"
// Setup registers HTTP handlers with the given ServeMux. It also supplies the given http.Client
// to clients which need to make outbound HTTP requests.
@ -46,7 +48,25 @@ func Setup(
keyRing gomatrixserverlib.KeyRing,
) {
apiMux := mux.NewRouter()
apiMux.Handle("/_matrix/client/versions",
common.MakeAPI("versions", func(req *http.Request) util.JSONResponse {
return util.JSONResponse{
Code: 200,
JSON: struct {
Versions []string `json:"versions"`
}{[]string{
"r0.0.1",
"r0.1.0",
"r0.2.0",
}},
}
}),
)
r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter()
unstableMux := apiMux.PathPrefix(pathPrefixUnstable).Subrouter()
r0mux.Handle("/createRoom",
common.MakeAuthAPI("createRoom", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
return writers.CreateRoom(req, device, cfg, producer)
@ -85,6 +105,13 @@ func Setup(
return writers.Register(req, accountDB, deviceDB)
}))
r0mux.Handle("/directory/room/{roomAlias}",
common.MakeAuthAPI("directory_room", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
vars := mux.Vars(req)
return readers.DirectoryRoom(req, device, vars["roomAlias"], federation, &cfg)
}),
)
// Stub endpoints required by Riot
r0mux.Handle("/login",
@ -166,6 +193,78 @@ func Setup(
}),
)
r0mux.Handle("/voip/turnServer",
common.MakeAPI("turn_server", func(req *http.Request) util.JSONResponse {
// TODO: Return credentials for a turn server if one is configured.
return util.JSONResponse{
Code: 200,
JSON: struct{}{},
}
}),
)
r0mux.Handle("/publicRooms",
common.MakeAPI("public_rooms", func(req *http.Request) util.JSONResponse {
// TODO: Return a list of public rooms
return util.JSONResponse{
Code: 200,
JSON: struct {
Chunk []struct{} `json:"chunk"`
Start string `json:"start"`
End string `json:"end"`
}{[]struct{}{}, "", ""},
}
}),
)
unstableMux.Handle("/thirdparty/protocols",
common.MakeAPI("thirdparty_protocols", func(req *http.Request) util.JSONResponse {
// TODO: Return the third party protcols
return util.JSONResponse{
Code: 200,
JSON: struct{}{},
}
}),
)
r0mux.Handle("/rooms/{roomID}/initialSync",
common.MakeAPI("rooms_initial_sync", func(req *http.Request) util.JSONResponse {
// TODO: Allow people to peek into rooms.
return util.JSONResponse{
Code: 403,
JSON: jsonerror.GuestAccessForbidden("Guest access not implemented"),
}
}),
)
r0mux.Handle("/profile/{userID}/displayname",
common.MakeAPI("profile_displayname", func(req *http.Request) util.JSONResponse {
// TODO: Set and get the displayname
return util.JSONResponse{Code: 200, JSON: struct{}{}}
}),
)
r0mux.Handle("/user/{userID}/account_data/{type}",
common.MakeAPI("user_account_data", func(req *http.Request) util.JSONResponse {
// TODO: Set and get the account_data
return util.JSONResponse{Code: 200, JSON: struct{}{}}
}),
)
r0mux.Handle("/rooms/{roomID}/read_markers",
common.MakeAPI("rooms_read_markers", func(req *http.Request) util.JSONResponse {
// TODO: return the read_markers.
return util.JSONResponse{Code: 200, JSON: struct{}{}}
}),
)
r0mux.Handle("/rooms/{roomID}/typing/{userID}",
common.MakeAPI("rooms_typing", func(req *http.Request) util.JSONResponse {
// TODO: handling typing
return util.JSONResponse{Code: 200, JSON: struct{}{}}
}),
)
servMux.Handle("/metrics", prometheus.Handler())
servMux.Handle("/api/", http.StripPrefix("/api", apiMux))
}