mirror of
https://github.com/hoernschen/dendrite.git
synced 2024-12-28 16:08:27 +00:00
Add API wiring
This commit is contained in:
parent
02997388f5
commit
a5bb2afbb5
7 changed files with 215 additions and 8 deletions
|
@ -125,6 +125,18 @@ func GuestAccessForbidden(msg string) *MatrixError {
|
||||||
return &MatrixError{"M_GUEST_ACCESS_FORBIDDEN", msg}
|
return &MatrixError{"M_GUEST_ACCESS_FORBIDDEN", msg}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InvalidSignature is an error which is returned when the client tries
|
||||||
|
// to upload invalid signatures.
|
||||||
|
func InvalidSignature(msg string) *MatrixError {
|
||||||
|
return &MatrixError{"M_INVALID_SIGNATURE", msg}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MissingParam is an error that is returned when a parameter was incorrect,
|
||||||
|
// traditionally with cross-signing.
|
||||||
|
func MissingParam(msg string) *MatrixError {
|
||||||
|
return &MatrixError{"M_MISSING_PARAM", msg}
|
||||||
|
}
|
||||||
|
|
||||||
type IncompatibleRoomVersionError struct {
|
type IncompatibleRoomVersionError struct {
|
||||||
RoomVersion string `json:"room_version"`
|
RoomVersion string `json:"room_version"`
|
||||||
Error string `json:"error"`
|
Error string `json:"error"`
|
||||||
|
|
89
clientapi/routing/key_crosssigning.go
Normal file
89
clientapi/routing/key_crosssigning.go
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
// Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
//
|
||||||
|
// 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 routing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
|
"github.com/matrix-org/dendrite/keyserver/api"
|
||||||
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
|
"github.com/matrix-org/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UploadCrossSigningDeviceKeys(req *http.Request, keyserverAPI api.KeyInternalAPI, device *userapi.Device) util.JSONResponse {
|
||||||
|
uploadReq := &api.PerformUploadDeviceKeysRequest{}
|
||||||
|
uploadRes := &api.PerformUploadDeviceKeysResponse{}
|
||||||
|
|
||||||
|
if err := httputil.UnmarshalJSONRequest(req, &uploadReq.CrossSigningKeys); err != nil {
|
||||||
|
return *err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyserverAPI.PerformUploadDeviceKeys(req.Context(), uploadReq, uploadRes)
|
||||||
|
if err := uploadRes.Error; err != nil {
|
||||||
|
switch {
|
||||||
|
case err.IsInvalidSignature:
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
JSON: jsonerror.InvalidSignature(err.Error()),
|
||||||
|
}
|
||||||
|
case err.IsMissingParam:
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
JSON: jsonerror.MissingParam(err.Error()),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
JSON: jsonerror.Unknown(err.Error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return util.JSONResponse{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UploadCrossSigningDeviceSignatures(req *http.Request, keyserverAPI api.KeyInternalAPI, device *userapi.Device) util.JSONResponse {
|
||||||
|
uploadReq := &api.PerformUploadDeviceSignaturesRequest{}
|
||||||
|
uploadRes := &api.PerformUploadDeviceSignaturesResponse{}
|
||||||
|
|
||||||
|
if err := httputil.UnmarshalJSONRequest(req, &uploadReq.CrossSigningSignatures); err != nil {
|
||||||
|
return *err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyserverAPI.PerformUploadDeviceSignatures(req.Context(), uploadReq, uploadRes)
|
||||||
|
if err := uploadRes.Error; err != nil {
|
||||||
|
switch {
|
||||||
|
case err.IsInvalidSignature:
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
JSON: jsonerror.InvalidSignature(err.Error()),
|
||||||
|
}
|
||||||
|
case err.IsMissingParam:
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
JSON: jsonerror.MissingParam(err.Error()),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
JSON: jsonerror.Unknown(err.Error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return util.JSONResponse{}
|
||||||
|
}
|
|
@ -1066,6 +1066,22 @@ func Setup(
|
||||||
|
|
||||||
// Deleting E2E Backup Keys
|
// Deleting E2E Backup Keys
|
||||||
|
|
||||||
|
// Cross-signing device keys
|
||||||
|
|
||||||
|
postDeviceSigningKeys := httputil.MakeAuthAPI("post_device_signing_keys", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||||
|
return UploadCrossSigningDeviceKeys(req, keyAPI, device)
|
||||||
|
})
|
||||||
|
|
||||||
|
postDeviceSigningSignatures := httputil.MakeAuthAPI("post_device_signing_signatures", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||||
|
return UploadCrossSigningDeviceSignatures(req, keyAPI, device)
|
||||||
|
})
|
||||||
|
|
||||||
|
r0mux.Handle("/keys/device_signing/upload", postDeviceSigningKeys).Methods(http.MethodPost, http.MethodOptions)
|
||||||
|
r0mux.Handle("/keys/signatures/upload", postDeviceSigningSignatures).Methods(http.MethodPost, http.MethodOptions)
|
||||||
|
|
||||||
|
unstableMux.Handle("/keys/device_signing/upload", postDeviceSigningKeys).Methods(http.MethodPost, http.MethodOptions)
|
||||||
|
unstableMux.Handle("/keys/signatures/upload", postDeviceSigningSignatures).Methods(http.MethodPost, http.MethodOptions)
|
||||||
|
|
||||||
// Supplying a device ID is deprecated.
|
// Supplying a device ID is deprecated.
|
||||||
r0mux.Handle("/keys/upload/{deviceID}",
|
r0mux.Handle("/keys/upload/{deviceID}",
|
||||||
httputil.MakeAuthAPI("keys_upload", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
httputil.MakeAuthAPI("keys_upload", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||||
|
|
|
@ -32,6 +32,8 @@ type KeyInternalAPI interface {
|
||||||
PerformUploadKeys(ctx context.Context, req *PerformUploadKeysRequest, res *PerformUploadKeysResponse)
|
PerformUploadKeys(ctx context.Context, req *PerformUploadKeysRequest, res *PerformUploadKeysResponse)
|
||||||
// PerformClaimKeys claims one-time keys for use in pre-key messages
|
// PerformClaimKeys claims one-time keys for use in pre-key messages
|
||||||
PerformClaimKeys(ctx context.Context, req *PerformClaimKeysRequest, res *PerformClaimKeysResponse)
|
PerformClaimKeys(ctx context.Context, req *PerformClaimKeysRequest, res *PerformClaimKeysResponse)
|
||||||
|
PerformUploadDeviceKeys(ctx context.Context, req *PerformUploadDeviceKeysRequest, res *PerformUploadDeviceKeysResponse)
|
||||||
|
PerformUploadDeviceSignatures(ctx context.Context, req *PerformUploadDeviceSignaturesRequest, res *PerformUploadDeviceSignaturesResponse)
|
||||||
QueryKeys(ctx context.Context, req *QueryKeysRequest, res *QueryKeysResponse)
|
QueryKeys(ctx context.Context, req *QueryKeysRequest, res *QueryKeysResponse)
|
||||||
QueryKeyChanges(ctx context.Context, req *QueryKeyChangesRequest, res *QueryKeyChangesResponse)
|
QueryKeyChanges(ctx context.Context, req *QueryKeyChangesRequest, res *QueryKeyChangesResponse)
|
||||||
QueryOneTimeKeys(ctx context.Context, req *QueryOneTimeKeysRequest, res *QueryOneTimeKeysResponse)
|
QueryOneTimeKeys(ctx context.Context, req *QueryOneTimeKeysRequest, res *QueryOneTimeKeysResponse)
|
||||||
|
@ -40,7 +42,9 @@ type KeyInternalAPI interface {
|
||||||
|
|
||||||
// KeyError is returned if there was a problem performing/querying the server
|
// KeyError is returned if there was a problem performing/querying the server
|
||||||
type KeyError struct {
|
type KeyError struct {
|
||||||
Err string
|
Err string `json:"error"`
|
||||||
|
IsInvalidSignature bool `json:"is_invalid_signature,omitempty"` // M_INVALID_SIGNATURE
|
||||||
|
IsMissingParam bool `json:"is_missing_param,omitempty"` // M_MISSING_PARAM
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *KeyError) Error() string {
|
func (k *KeyError) Error() string {
|
||||||
|
@ -151,6 +155,22 @@ type PerformClaimKeysResponse struct {
|
||||||
Error *KeyError
|
Error *KeyError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PerformUploadDeviceKeysRequest struct {
|
||||||
|
gomatrixserverlib.CrossSigningKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
type PerformUploadDeviceKeysResponse struct {
|
||||||
|
Error *KeyError
|
||||||
|
}
|
||||||
|
|
||||||
|
type PerformUploadDeviceSignaturesRequest struct {
|
||||||
|
gomatrixserverlib.CrossSigningSignatures
|
||||||
|
}
|
||||||
|
|
||||||
|
type PerformUploadDeviceSignaturesResponse struct {
|
||||||
|
Error *KeyError
|
||||||
|
}
|
||||||
|
|
||||||
type QueryKeysRequest struct {
|
type QueryKeysRequest struct {
|
||||||
// Maps user IDs to a list of devices
|
// Maps user IDs to a list of devices
|
||||||
UserToDevices map[string][]string
|
UserToDevices map[string][]string
|
||||||
|
|
|
@ -568,6 +568,18 @@ func (a *KeyInternalAPI) uploadOneTimeKeys(ctx context.Context, req *api.Perform
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.PerformUploadDeviceKeysRequest, res *api.PerformUploadDeviceKeysResponse) {
|
||||||
|
res.Error = &api.KeyError{
|
||||||
|
Err: "Not supported yet",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *KeyInternalAPI) PerformUploadDeviceSignatures(ctx context.Context, req *api.PerformUploadDeviceSignaturesRequest, res *api.PerformUploadDeviceSignaturesResponse) {
|
||||||
|
res.Error = &api.KeyError{
|
||||||
|
Err: "Not supported yet",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func emitDeviceKeyChanges(producer KeyChangeProducer, existing, new []api.DeviceMessage) error {
|
func emitDeviceKeyChanges(producer KeyChangeProducer, existing, new []api.DeviceMessage) error {
|
||||||
// find keys in new that are not in existing
|
// find keys in new that are not in existing
|
||||||
var keysAdded []api.DeviceMessage
|
var keysAdded []api.DeviceMessage
|
||||||
|
|
|
@ -27,13 +27,15 @@ import (
|
||||||
|
|
||||||
// HTTP paths for the internal HTTP APIs
|
// HTTP paths for the internal HTTP APIs
|
||||||
const (
|
const (
|
||||||
InputDeviceListUpdatePath = "/keyserver/inputDeviceListUpdate"
|
InputDeviceListUpdatePath = "/keyserver/inputDeviceListUpdate"
|
||||||
PerformUploadKeysPath = "/keyserver/performUploadKeys"
|
PerformUploadKeysPath = "/keyserver/performUploadKeys"
|
||||||
PerformClaimKeysPath = "/keyserver/performClaimKeys"
|
PerformClaimKeysPath = "/keyserver/performClaimKeys"
|
||||||
QueryKeysPath = "/keyserver/queryKeys"
|
PerformUploadDeviceKeysPath = "/keyserver/performUploadDeviceKeys"
|
||||||
QueryKeyChangesPath = "/keyserver/queryKeyChanges"
|
PerformUploadDeviceSignaturesPath = "/keyserver/performUploadDeviceSignatures"
|
||||||
QueryOneTimeKeysPath = "/keyserver/queryOneTimeKeys"
|
QueryKeysPath = "/keyserver/queryKeys"
|
||||||
QueryDeviceMessagesPath = "/keyserver/queryDeviceMessages"
|
QueryKeyChangesPath = "/keyserver/queryKeyChanges"
|
||||||
|
QueryOneTimeKeysPath = "/keyserver/queryOneTimeKeys"
|
||||||
|
QueryDeviceMessagesPath = "/keyserver/queryDeviceMessages"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewKeyServerClient creates a KeyInternalAPI implemented by talking to a HTTP POST API.
|
// NewKeyServerClient creates a KeyInternalAPI implemented by talking to a HTTP POST API.
|
||||||
|
@ -175,3 +177,37 @@ func (h *httpKeyInternalAPI) QueryKeyChanges(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *httpKeyInternalAPI) PerformUploadDeviceKeys(
|
||||||
|
ctx context.Context,
|
||||||
|
request *api.PerformUploadDeviceKeysRequest,
|
||||||
|
response *api.PerformUploadDeviceKeysResponse,
|
||||||
|
) {
|
||||||
|
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformUploadDeviceKeys")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
apiURL := h.apiURL + PerformUploadDeviceKeysPath
|
||||||
|
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
|
if err != nil {
|
||||||
|
response.Error = &api.KeyError{
|
||||||
|
Err: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *httpKeyInternalAPI) PerformUploadDeviceSignatures(
|
||||||
|
ctx context.Context,
|
||||||
|
request *api.PerformUploadDeviceSignaturesRequest,
|
||||||
|
response *api.PerformUploadDeviceSignaturesResponse,
|
||||||
|
) {
|
||||||
|
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformUploadDeviceSignatures")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
apiURL := h.apiURL + PerformUploadDeviceSignaturesPath
|
||||||
|
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
|
if err != nil {
|
||||||
|
response.Error = &api.KeyError{
|
||||||
|
Err: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -58,6 +58,28 @@ func AddRoutes(internalAPIMux *mux.Router, s api.KeyInternalAPI) {
|
||||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
internalAPIMux.Handle(PerformUploadDeviceKeysPath,
|
||||||
|
httputil.MakeInternalAPI("performUploadDeviceKeys", func(req *http.Request) util.JSONResponse {
|
||||||
|
request := api.PerformUploadDeviceKeysRequest{}
|
||||||
|
response := api.PerformUploadDeviceKeysResponse{}
|
||||||
|
if err := json.NewDecoder(req.Body).Decode(&request.CrossSigningKeys); err != nil {
|
||||||
|
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||||
|
}
|
||||||
|
s.PerformUploadDeviceKeys(req.Context(), &request, &response)
|
||||||
|
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
internalAPIMux.Handle(PerformUploadDeviceSignaturesPath,
|
||||||
|
httputil.MakeInternalAPI("performUploadDeviceSignatures", func(req *http.Request) util.JSONResponse {
|
||||||
|
request := api.PerformUploadDeviceSignaturesRequest{}
|
||||||
|
response := api.PerformUploadDeviceSignaturesResponse{}
|
||||||
|
if err := json.NewDecoder(req.Body).Decode(&request.CrossSigningSignatures); err != nil {
|
||||||
|
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||||
|
}
|
||||||
|
s.PerformUploadDeviceSignatures(req.Context(), &request, &response)
|
||||||
|
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||||
|
}),
|
||||||
|
)
|
||||||
internalAPIMux.Handle(QueryKeysPath,
|
internalAPIMux.Handle(QueryKeysPath,
|
||||||
httputil.MakeInternalAPI("queryKeys", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("queryKeys", func(req *http.Request) util.JSONResponse {
|
||||||
request := api.QueryKeysRequest{}
|
request := api.QueryKeysRequest{}
|
||||||
|
|
Loading…
Reference in a new issue