Add mscs/hooks package, begin work for msc2836

This commit is contained in:
Kegan Dougal 2020-10-29 16:08:41 +00:00
parent fe339c8b98
commit b5965eee1a
7 changed files with 220 additions and 1 deletions

View file

@ -23,6 +23,7 @@ import (
"github.com/matrix-org/dendrite/eduserver/cache"
"github.com/matrix-org/dendrite/federationsender"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/mscs"
"github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/keyserver"
"github.com/matrix-org/dendrite/roomserver"
@ -148,6 +149,12 @@ func main() {
base.PublicMediaAPIMux,
)
if len(base.Cfg.MSCs.MSCs) > 0 {
if err := mscs.Enable(base, &monolith); err != nil {
logrus.WithError(err).Fatalf("Failed to enable MSCs")
}
}
// Expose the matrix APIs directly rather than putting them under a /api path.
go func() {
base.SetupAndServeHTTP(

View file

@ -66,6 +66,8 @@ type Dendrite struct {
SyncAPI SyncAPI `yaml:"sync_api"`
UserAPI UserAPI `yaml:"user_api"`
MSCs MSCs `yaml:"mscs"`
// The config for tracing the dendrite servers.
Tracing struct {
// Set to true to enable tracer hooks. If false, no tracing is set up.
@ -306,6 +308,7 @@ func (c *Dendrite) Defaults() {
c.SyncAPI.Defaults()
c.UserAPI.Defaults()
c.AppServiceAPI.Defaults()
c.MSCs.Defaults()
c.Wiring()
}
@ -319,7 +322,7 @@ func (c *Dendrite) Verify(configErrs *ConfigErrors, isMonolith bool) {
&c.EDUServer, &c.FederationAPI, &c.FederationSender,
&c.KeyServer, &c.MediaAPI, &c.RoomServer,
&c.SigningKeyServer, &c.SyncAPI, &c.UserAPI,
&c.AppServiceAPI,
&c.AppServiceAPI, &c.MSCs,
} {
c.Verify(configErrs, isMonolith)
}
@ -337,6 +340,7 @@ func (c *Dendrite) Wiring() {
c.SyncAPI.Matrix = &c.Global
c.UserAPI.Matrix = &c.Global
c.AppServiceAPI.Matrix = &c.Global
c.MSCs.Matrix = &c.Global
c.ClientAPI.Derived = &c.Derived
c.AppServiceAPI.Derived = &c.Derived

View file

@ -0,0 +1,19 @@
package config
type MSCs struct {
Matrix *Global `yaml:"-"`
// The MSCs to enable, currently only `msc2836` is supported.
MSCs []string `yaml:"mscs"`
Database DatabaseOptions `yaml:"database"`
}
func (c *MSCs) Defaults() {
c.Database.Defaults()
c.Database.ConnectionString = "file:mscs.db"
}
func (c *MSCs) Verify(configErrs *ConfigErrors, isMonolith bool) {
checkNotEmpty(configErrs, "mscs.database.connection_string", string(c.Database.ConnectionString))
}

21
internal/hooks/hooks.go Normal file
View file

@ -0,0 +1,21 @@
// Copyright 2020 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 hooks exposes places in Dendrite where custom code can be executed, useful for MSCs.
// Hooks can only be run in monolith mode.
package hooks
func Attach() {
}

View file

@ -0,0 +1,67 @@
// Copyright 2020 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 msc2836 'Threading' implements https://github.com/matrix-org/matrix-doc/pull/2836
package msc2836
import (
"encoding/json"
"fmt"
"net/http"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/setup"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/util"
)
type eventRelationshipRequest struct {
EventID string `json:"event_id"`
MaxDepth int `json:"max_depth"`
MaxBreadth int `json:"max_breadth"`
Limit int `json:"limit"`
DepthFirst bool `json:"depth_first"`
RecentFirst bool `json:"recent_first"`
IncludeParent bool `json:"include_parent"`
IncludeChildren bool `json:"include_children"`
Direction string `json:"direction"`
Batch string `json:"batch"`
}
// Enable this MSC
func Enable(base *setup.BaseDendrite, monolith *setup.Monolith) error {
_, err := NewDatabase(&base.Cfg.MSCs.Database)
if err != nil {
return fmt.Errorf("Cannot enable MSC2836: %w", err)
}
base.PublicClientAPIMux.Handle("/unstable/event_relationships",
httputil.MakeAuthAPI("eventRelationships", monolith.UserAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
var relation eventRelationshipRequest
if err := json.NewDecoder(req.Body).Decode(&relation); err != nil {
util.GetLogger(req.Context()).WithError(err).Error("failed to decode HTTP request as JSON")
return util.JSONResponse{
Code: 400,
JSON: jsonerror.BadJSON(fmt.Sprintf("invalid json: %s", err)),
}
}
return util.JSONResponse{
Code: 200,
JSON: struct{}{},
}
}),
).Methods(http.MethodPost, http.MethodOptions)
return nil
}

View file

@ -0,0 +1,59 @@
package msc2836
import (
"context"
"database/sql"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/gomatrixserverlib"
)
type Database interface {
// StoreRelation stores the parent->child and child->parent relationship for later querying.
StoreRelation(ctx context.Context, ev *gomatrixserverlib.HeaderedEvent) error
}
type Postgres struct {
db *sql.DB
}
func NewPostgresDatabase(dbOpts *config.DatabaseOptions) (Database, error) {
var p Postgres
var err error
if p.db, err = sqlutil.Open(dbOpts); err != nil {
return nil, err
}
return &p, nil
}
func (db *Postgres) StoreRelation(ctx context.Context, ev *gomatrixserverlib.HeaderedEvent) error {
return nil
}
type SQLite struct {
db *sql.DB
writer sqlutil.Writer
}
func NewSQLiteDatabase(dbOpts *config.DatabaseOptions) (Database, error) {
var s SQLite
var err error
if s.db, err = sqlutil.Open(dbOpts); err != nil {
return nil, err
}
s.writer = sqlutil.NewExclusiveWriter()
return &s, nil
}
func (db *SQLite) StoreRelation(ctx context.Context, ev *gomatrixserverlib.HeaderedEvent) error {
return nil
}
// NewDatabase loads the database for msc2836
func NewDatabase(dbOpts *config.DatabaseOptions) (Database, error) {
if dbOpts.ConnectionString.IsPostgres() {
return NewPostgresDatabase(dbOpts)
}
return NewSQLiteDatabase(dbOpts)
}

42
internal/mscs/mscs.go Normal file
View file

@ -0,0 +1,42 @@
// Copyright 2020 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 mscs implements Matrix Spec Changes from https://github.com/matrix-org/matrix-doc
package mscs
import (
"fmt"
"github.com/matrix-org/dendrite/internal/mscs/msc2836"
"github.com/matrix-org/dendrite/internal/setup"
)
// Enable MSCs - returns an error on unknown MSCs
func Enable(base *setup.BaseDendrite, monolith *setup.Monolith) error {
for _, msc := range base.Cfg.MSCs.MSCs {
if err := EnableMSC(base, monolith, msc); err != nil {
return err
}
}
return nil
}
func EnableMSC(base *setup.BaseDendrite, monolith *setup.Monolith, msc string) error {
switch msc {
case "msc2836":
return msc2836.Enable(base, monolith)
default:
return fmt.Errorf("EnableMSC: unknown msc '%s'", msc)
}
}