Filter Roomserver Events Based on Application Service (#467)
* Compile room and alias namespace regexs We'll be needing these for event filtering in the appservice component. Signed-off-by: Andrew Morgan <andrewm@matrix.org> * App service filters roomserver events Doing so based on namespace regexes that each app service has defined. To get the aliases for a roomID a new aliasAPI endpoint was defined, GetAliasesFromRoomID, which does exactly what it says on the tin. Next step is to queue events to be sent off to each homeserver. * Additionally filter state events for app services * Fixed context, logging, derps, config handling * Prevented user from creating more than one regex per namespace type Got caught out by realizing I had an extra '-' in the config file. This prevents anyone from making the same mistake :) * Removed exclusive RoomID namespace regex, as we won't need to check upon room creation if the ID is reserved exclusively by an AS (as this is silly and horribly inefficient). * Fixed all else mentioned
This commit is contained in:
parent
60e77959ee
commit
04551becb4
10 changed files with 229 additions and 76 deletions
|
@ -36,10 +36,10 @@ func SetupAppServiceAPIComponent(
|
|||
transactionsCache *transactions.Cache,
|
||||
) {
|
||||
consumer := consumers.NewOutputRoomEventConsumer(
|
||||
base.Cfg, base.KafkaConsumer, accountsDB, queryAPI,
|
||||
base.Cfg, base.KafkaConsumer, accountsDB, queryAPI, aliasAPI,
|
||||
)
|
||||
if err := consumer.Start(); err != nil {
|
||||
logrus.WithError(err).Panicf("failed to start app service's room server consumer")
|
||||
logrus.WithError(err).Panicf("failed to start app service roomserver consumer")
|
||||
}
|
||||
|
||||
// Set up HTTP Endpoints
|
||||
|
|
|
@ -17,6 +17,7 @@ package consumers
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
|
||||
"github.com/matrix-org/dendrite/common"
|
||||
|
@ -28,11 +29,16 @@ import (
|
|||
sarama "gopkg.in/Shopify/sarama.v1"
|
||||
)
|
||||
|
||||
var (
|
||||
appServices []config.ApplicationService
|
||||
)
|
||||
|
||||
// OutputRoomEventConsumer consumes events that originated in the room server.
|
||||
type OutputRoomEventConsumer struct {
|
||||
roomServerConsumer *common.ContinualConsumer
|
||||
db *accounts.Database
|
||||
query api.RoomserverQueryAPI
|
||||
alias api.RoomserverAliasAPI
|
||||
serverName string
|
||||
}
|
||||
|
||||
|
@ -42,7 +48,9 @@ func NewOutputRoomEventConsumer(
|
|||
kafkaConsumer sarama.Consumer,
|
||||
store *accounts.Database,
|
||||
queryAPI api.RoomserverQueryAPI,
|
||||
aliasAPI api.RoomserverAliasAPI,
|
||||
) *OutputRoomEventConsumer {
|
||||
appServices = cfg.Derived.ApplicationServices
|
||||
|
||||
consumer := common.ContinualConsumer{
|
||||
Topic: string(cfg.Kafka.Topics.OutputRoomEvent),
|
||||
|
@ -53,6 +61,7 @@ func NewOutputRoomEventConsumer(
|
|||
roomServerConsumer: &consumer,
|
||||
db: store,
|
||||
query: queryAPI,
|
||||
alias: aliasAPI,
|
||||
serverName: string(cfg.Matrix.ServerName),
|
||||
}
|
||||
consumer.ProcessMessage = s.onMessage
|
||||
|
@ -96,7 +105,15 @@ func (s *OutputRoomEventConsumer) onMessage(msg *sarama.ConsumerMessage) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return s.db.UpdateMemberships(context.TODO(), events, output.NewRoomEvent.RemovesStateEventIDs)
|
||||
// Create a context to thread through the whole filtering process
|
||||
ctx := context.TODO()
|
||||
|
||||
if err = s.db.UpdateMemberships(ctx, events, output.NewRoomEvent.RemovesStateEventIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if any events need to passed on to external application services
|
||||
return s.filterRoomserverEvents(ctx, append(events, ev))
|
||||
}
|
||||
|
||||
// lookupStateEvents looks up the state events that are added by a new event.
|
||||
|
@ -142,3 +159,59 @@ func (s *OutputRoomEventConsumer) lookupStateEvents(
|
|||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// filterRoomserverEvents takes in events and decides whether any of them need
|
||||
// to be passed on to an external application service. It does this by checking
|
||||
// each namespace of each registered application service, and if there is a
|
||||
// match, adds the event to the queue for events to be sent to a particular
|
||||
// application service.
|
||||
func (s *OutputRoomEventConsumer) filterRoomserverEvents(ctx context.Context, events []gomatrixserverlib.Event) error {
|
||||
for _, event := range events {
|
||||
for _, appservice := range appServices {
|
||||
// Check if this event is interesting to this application service
|
||||
if s.appserviceIsInterestedInEvent(ctx, event, appservice) {
|
||||
// TODO: Queue this event to be sent off to the application service
|
||||
fmt.Println(appservice.ID, "was interested in", event.Sender(), event.Type(), event.RoomID())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// appserviceIsInterestedInEvent returns a boolean depending on whether a given
|
||||
// event falls within one of a given application service's namespaces.
|
||||
func (s *OutputRoomEventConsumer) appserviceIsInterestedInEvent(ctx context.Context, event gomatrixserverlib.Event, appservice config.ApplicationService) bool {
|
||||
// Check sender of the event
|
||||
for _, userNamespace := range appservice.NamespaceMap["users"] {
|
||||
if userNamespace.RegexpObject.MatchString(event.Sender()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Check room id of the event
|
||||
for _, roomNamespace := range appservice.NamespaceMap["rooms"] {
|
||||
if roomNamespace.RegexpObject.MatchString(event.RoomID()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Check all known room aliases of the room the event came from
|
||||
queryReq := api.GetAliasesForRoomIDRequest{RoomID: event.RoomID()}
|
||||
var queryRes api.GetAliasesForRoomIDResponse
|
||||
if err := s.alias.GetAliasesForRoomID(ctx, &queryReq, &queryRes); err == nil {
|
||||
for _, alias := range queryRes.Aliases {
|
||||
for _, aliasNamespace := range appservice.NamespaceMap["aliases"] {
|
||||
if aliasNamespace.RegexpObject.MatchString(alias) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.WithFields(log.Fields{
|
||||
"room_id": event.RoomID(),
|
||||
}).WithError(err).Errorf("Unable to get aliases for room")
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -46,9 +46,9 @@ func DirectoryRoom(
|
|||
var resp gomatrixserverlib.RespDirectory
|
||||
|
||||
if domain == cfg.Matrix.ServerName {
|
||||
queryReq := api.GetAliasRoomIDRequest{Alias: roomAlias}
|
||||
var queryRes api.GetAliasRoomIDResponse
|
||||
if err = aliasAPI.GetAliasRoomID(req.Context(), &queryReq, &queryRes); err != nil {
|
||||
queryReq := api.GetRoomIDForAliasRequest{Alias: roomAlias}
|
||||
var queryRes api.GetRoomIDForAliasResponse
|
||||
if err = aliasAPI.GetRoomIDForAlias(req.Context(), &queryReq, &queryRes); err != nil {
|
||||
return httputil.LogThenError(req, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -145,9 +145,9 @@ func (r joinRoomReq) joinRoomByAlias(roomAlias string) util.JSONResponse {
|
|||
}
|
||||
}
|
||||
if domain == r.cfg.Matrix.ServerName {
|
||||
queryReq := api.GetAliasRoomIDRequest{Alias: roomAlias}
|
||||
var queryRes api.GetAliasRoomIDResponse
|
||||
if err = r.aliasAPI.GetAliasRoomID(r.req.Context(), &queryReq, &queryRes); err != nil {
|
||||
queryReq := api.GetRoomIDForAliasRequest{Alias: roomAlias}
|
||||
var queryRes api.GetRoomIDForAliasResponse
|
||||
if err = r.aliasAPI.GetRoomIDForAlias(r.req.Context(), &queryReq, &queryRes); err != nil {
|
||||
return httputil.LogThenError(r.req, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// ApplicationServiceNamespace is the namespace that a specific application
|
||||
|
@ -48,7 +48,8 @@ type ApplicationService struct {
|
|||
HSToken string `yaml:"hs_token"`
|
||||
// Localpart of application service user
|
||||
SenderLocalpart string `yaml:"sender_localpart"`
|
||||
// Information about an application service's namespaces
|
||||
// Information about an application service's namespaces. Key is either
|
||||
// "users", "aliases" or "rooms"
|
||||
NamespaceMap map[string][]ApplicationServiceNamespace `yaml:"namespaces"`
|
||||
}
|
||||
|
||||
|
@ -78,7 +79,8 @@ func loadAppservices(config *Dendrite) error {
|
|||
|
||||
// Append the parsed application service to the global config
|
||||
config.Derived.ApplicationServices = append(
|
||||
config.Derived.ApplicationServices, appservice)
|
||||
config.Derived.ApplicationServices, appservice,
|
||||
)
|
||||
}
|
||||
|
||||
// Check for any errors in the loaded application services
|
||||
|
@ -88,12 +90,13 @@ func loadAppservices(config *Dendrite) error {
|
|||
// setupRegexps will create regex objects for exclusive and non-exclusive
|
||||
// usernames, aliases and rooms of all application services, so that other
|
||||
// methods can quickly check if a particular string matches any of them.
|
||||
func setupRegexps(cfg *Dendrite) {
|
||||
func setupRegexps(cfg *Dendrite) (err error) {
|
||||
// Combine all exclusive namespaces for later string checking
|
||||
var exclusiveUsernameStrings, exclusiveAliasStrings, exclusiveRoomStrings []string
|
||||
var exclusiveUsernameStrings, exclusiveAliasStrings []string
|
||||
|
||||
// If an application service's regex is marked as exclusive, add
|
||||
// it's contents to the overall exlusive regex string
|
||||
// its contents to the overall exlusive regex string. Room regex
|
||||
// not necessary as we aren't denying exclusive room ID creation
|
||||
for _, appservice := range cfg.Derived.ApplicationServices {
|
||||
for key, namespaceSlice := range appservice.NamespaceMap {
|
||||
switch key {
|
||||
|
@ -101,38 +104,46 @@ func setupRegexps(cfg *Dendrite) {
|
|||
appendExclusiveNamespaceRegexs(&exclusiveUsernameStrings, namespaceSlice)
|
||||
case "aliases":
|
||||
appendExclusiveNamespaceRegexs(&exclusiveAliasStrings, namespaceSlice)
|
||||
case "rooms":
|
||||
appendExclusiveNamespaceRegexs(&exclusiveRoomStrings, namespaceSlice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(exclusiveUsernameStrings, exclusiveAliasStrings)
|
||||
|
||||
// Join the regexes together into one big regex.
|
||||
// i.e. "app1.*", "app2.*" -> "(app1.*)|(app2.*)"
|
||||
// Later we can check if a username or some other string matches any exclusive
|
||||
// regex and deny access if it isn't from an application service
|
||||
// Later we can check if a username or alias matches any exclusive regex and
|
||||
// deny access if it isn't from an application service
|
||||
exclusiveUsernames := strings.Join(exclusiveUsernameStrings, "|")
|
||||
exclusiveAliases := strings.Join(exclusiveAliasStrings, "|")
|
||||
|
||||
// If there are no exclusive username regexes, compile string so that it
|
||||
// will not match any valid usernames
|
||||
// If there are no exclusive regexes, compile string so that it will not match
|
||||
// any valid usernames/aliases/roomIDs
|
||||
if exclusiveUsernames == "" {
|
||||
exclusiveUsernames = "^$"
|
||||
}
|
||||
if exclusiveAliases == "" {
|
||||
exclusiveAliases = "^$"
|
||||
}
|
||||
|
||||
// TODO: Aliases and rooms. Needed?
|
||||
//exclusiveAliases := strings.Join(exclusiveAliasStrings, "|")
|
||||
//exclusiveRooms := strings.Join(exclusiveRoomStrings, "|")
|
||||
// Store compiled Regex
|
||||
if cfg.Derived.ExclusiveApplicationServicesUsernameRegexp, err = regexp.Compile(exclusiveUsernames); err != nil {
|
||||
return err
|
||||
}
|
||||
if cfg.Derived.ExclusiveApplicationServicesAliasRegexp, err = regexp.Compile(exclusiveAliases); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.Derived.ExclusiveApplicationServicesUsernameRegexp, _ = regexp.Compile(exclusiveUsernames)
|
||||
return nil
|
||||
}
|
||||
|
||||
// concatenateExclusiveNamespaces takes a slice of strings and a slice of
|
||||
// appendExclusiveNamespaceRegexs takes a slice of strings and a slice of
|
||||
// namespaces and will append the regexes of only the exclusive namespaces
|
||||
// into the string slice
|
||||
func appendExclusiveNamespaceRegexs(
|
||||
exclusiveStrings *[]string, namespaces []ApplicationServiceNamespace,
|
||||
) {
|
||||
for _, namespace := range namespaces {
|
||||
for index, namespace := range namespaces {
|
||||
if namespace.Exclusive {
|
||||
// We append parenthesis to later separate each regex when we compile
|
||||
// i.e. "app1.*", "app2.*" -> "(app1.*)|(app2.*)"
|
||||
|
@ -140,24 +151,26 @@ func appendExclusiveNamespaceRegexs(
|
|||
}
|
||||
|
||||
// Compile this regex into a Regexp object for later use
|
||||
namespace.RegexpObject, _ = regexp.Compile(namespace.Regex)
|
||||
namespaces[index].RegexpObject, _ = regexp.Compile(namespace.Regex)
|
||||
}
|
||||
}
|
||||
|
||||
// checkErrors checks for any configuration errors amongst the loaded
|
||||
// application services according to the application service spec.
|
||||
func checkErrors(config *Dendrite) error {
|
||||
func checkErrors(config *Dendrite) (err error) {
|
||||
var idMap = make(map[string]bool)
|
||||
var tokenMap = make(map[string]bool)
|
||||
|
||||
// Check that no two application services have the same as_token or id
|
||||
// Check each application service for any config errors
|
||||
for _, appservice := range config.Derived.ApplicationServices {
|
||||
// Check if we've already seen this ID
|
||||
// Check if we've already seen this ID. No two application services
|
||||
// can have the same ID or token.
|
||||
if idMap[appservice.ID] {
|
||||
return configErrors([]string{fmt.Sprintf(
|
||||
"Application Service ID %s must be unique", appservice.ID,
|
||||
)})
|
||||
}
|
||||
// Check if we've already seen this token
|
||||
if tokenMap[appservice.ASToken] {
|
||||
return configErrors([]string{fmt.Sprintf(
|
||||
"Application Service Token %s must be unique", appservice.ASToken,
|
||||
|
@ -168,6 +181,18 @@ func checkErrors(config *Dendrite) error {
|
|||
// seen them.
|
||||
idMap[appservice.ID] = true
|
||||
tokenMap[appservice.ID] = true
|
||||
|
||||
// Check if more than one regex exists per namespace
|
||||
for _, namespace := range appservice.NamespaceMap {
|
||||
if len(namespace) > 1 {
|
||||
// It's quite easy to accidentally make multiple regex objects per
|
||||
// namespace, which often ends up in an application service receiving events
|
||||
// it doesn't want, as an empty regex will match all events.
|
||||
return configErrors([]string{fmt.Sprintf(
|
||||
"Application Service namespace can only contain a single regex tuple. Check your YAML.",
|
||||
)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that namespace(s) are valid regex
|
||||
|
@ -182,9 +207,8 @@ func checkErrors(config *Dendrite) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
setupRegexps(config)
|
||||
|
||||
return nil
|
||||
return setupRegexps(config)
|
||||
}
|
||||
|
||||
// IsValidRegex returns true or false based on whether the
|
||||
|
|
|
@ -30,7 +30,7 @@ import (
|
|||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"gopkg.in/yaml.v2"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
jaegerconfig "github.com/uber/jaeger-client-go/config"
|
||||
jaegermetrics "github.com/uber/jaeger-lib/metrics"
|
||||
|
@ -235,12 +235,17 @@ type Dendrite struct {
|
|||
// The paths of which were given above in the main config file
|
||||
ApplicationServices []ApplicationService
|
||||
|
||||
// A meta-regex compiled from all exclusive Application Service
|
||||
// Regexes. When a user registers, we check that their username
|
||||
// does not match any exclusive Application Service namespaces
|
||||
// Meta-regexes compiled from all exclusive Application Service
|
||||
// Regexes.
|
||||
//
|
||||
// When a user registers, we check that their username does not match any
|
||||
// exclusive Application Service namespaces
|
||||
ExclusiveApplicationServicesUsernameRegexp *regexp.Regexp
|
||||
|
||||
// TODO: Exclusive alias, room regexp's
|
||||
// When a user creates a room alias, we check that it isn't already
|
||||
// reserved by an application service
|
||||
ExclusiveApplicationServicesAliasRegexp *regexp.Regexp
|
||||
// Note: An Exclusive Regex for room ID isn't necessary as we aren't blocking
|
||||
// servers from creating RoomIDs in exclusive application service namespaces
|
||||
} `yaml:"-"`
|
||||
}
|
||||
|
||||
|
|
|
@ -52,9 +52,9 @@ func RoomAliasToID(
|
|||
var resp gomatrixserverlib.RespDirectory
|
||||
|
||||
if domain == cfg.Matrix.ServerName {
|
||||
queryReq := api.GetAliasRoomIDRequest{Alias: roomAlias}
|
||||
var queryRes api.GetAliasRoomIDResponse
|
||||
if err = aliasAPI.GetAliasRoomID(httpReq.Context(), &queryReq, &queryRes); err != nil {
|
||||
queryReq := api.GetRoomIDForAliasRequest{Alias: roomAlias}
|
||||
var queryRes api.GetRoomIDForAliasResponse
|
||||
if err = aliasAPI.GetRoomIDForAlias(httpReq.Context(), &queryReq, &queryRes); err != nil {
|
||||
return httputil.LogThenError(httpReq, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -35,10 +35,10 @@ type RoomserverAliasAPIDatabase interface {
|
|||
SetRoomAlias(ctx context.Context, alias string, roomID string) error
|
||||
// Look up the room ID a given alias refers to.
|
||||
// Returns an error if there was a problem talking to the database.
|
||||
GetRoomIDFromAlias(ctx context.Context, alias string) (string, error)
|
||||
GetRoomIDForAlias(ctx context.Context, alias string) (string, error)
|
||||
// Look up all aliases referring to a given room ID.
|
||||
// Returns an error if there was a problem talking to the database.
|
||||
GetAliasesFromRoomID(ctx context.Context, roomID string) ([]string, error)
|
||||
GetAliasesForRoomID(ctx context.Context, roomID string) ([]string, error)
|
||||
// Remove a given room alias.
|
||||
// Returns an error if there was a problem talking to the database.
|
||||
RemoveRoomAlias(ctx context.Context, alias string) error
|
||||
|
@ -59,7 +59,7 @@ func (r *RoomserverAliasAPI) SetRoomAlias(
|
|||
response *api.SetRoomAliasResponse,
|
||||
) error {
|
||||
// Check if the alias isn't already referring to a room
|
||||
roomID, err := r.DB.GetRoomIDFromAlias(ctx, request.Alias)
|
||||
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -82,14 +82,14 @@ func (r *RoomserverAliasAPI) SetRoomAlias(
|
|||
return r.sendUpdatedAliasesEvent(context.TODO(), request.UserID, request.RoomID)
|
||||
}
|
||||
|
||||
// GetAliasRoomID implements api.RoomserverAliasAPI
|
||||
func (r *RoomserverAliasAPI) GetAliasRoomID(
|
||||
// GetRoomIDForAlias implements api.RoomserverAliasAPI
|
||||
func (r *RoomserverAliasAPI) GetRoomIDForAlias(
|
||||
ctx context.Context,
|
||||
request *api.GetAliasRoomIDRequest,
|
||||
response *api.GetAliasRoomIDResponse,
|
||||
request *api.GetRoomIDForAliasRequest,
|
||||
response *api.GetRoomIDForAliasResponse,
|
||||
) error {
|
||||
// Look up the room ID in the database
|
||||
roomID, err := r.DB.GetRoomIDFromAlias(ctx, request.Alias)
|
||||
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -98,6 +98,22 @@ func (r *RoomserverAliasAPI) GetAliasRoomID(
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetAliasesForRoomID implements api.RoomserverAliasAPI
|
||||
func (r *RoomserverAliasAPI) GetAliasesForRoomID(
|
||||
ctx context.Context,
|
||||
request *api.GetAliasesForRoomIDRequest,
|
||||
response *api.GetAliasesForRoomIDResponse,
|
||||
) error {
|
||||
// Look up the aliases in the database for the given RoomID
|
||||
aliases, err := r.DB.GetAliasesForRoomID(ctx, request.RoomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
response.Aliases = aliases
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveRoomAlias implements api.RoomserverAliasAPI
|
||||
func (r *RoomserverAliasAPI) RemoveRoomAlias(
|
||||
ctx context.Context,
|
||||
|
@ -105,7 +121,7 @@ func (r *RoomserverAliasAPI) RemoveRoomAlias(
|
|||
response *api.RemoveRoomAliasResponse,
|
||||
) error {
|
||||
// Look up the room ID in the database
|
||||
roomID, err := r.DB.GetRoomIDFromAlias(ctx, request.Alias)
|
||||
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -142,7 +158,7 @@ func (r *RoomserverAliasAPI) sendUpdatedAliasesEvent(
|
|||
|
||||
// Retrieve the updated list of aliases, marhal it and set it as the
|
||||
// event's content
|
||||
aliases, err := r.DB.GetAliasesFromRoomID(ctx, roomID)
|
||||
aliases, err := r.DB.GetAliasesForRoomID(ctx, roomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -229,14 +245,14 @@ func (r *RoomserverAliasAPI) SetupHTTP(servMux *http.ServeMux) {
|
|||
}),
|
||||
)
|
||||
servMux.Handle(
|
||||
api.RoomserverGetAliasRoomIDPath,
|
||||
common.MakeInternalAPI("getAliasRoomID", func(req *http.Request) util.JSONResponse {
|
||||
var request api.GetAliasRoomIDRequest
|
||||
var response api.GetAliasRoomIDResponse
|
||||
api.RoomserverGetRoomIDForAliasPath,
|
||||
common.MakeInternalAPI("GetRoomIDForAlias", func(req *http.Request) util.JSONResponse {
|
||||
var request api.GetRoomIDForAliasRequest
|
||||
var response api.GetRoomIDForAliasResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.GetAliasRoomID(req.Context(), &request, &response); err != nil {
|
||||
if err := r.GetRoomIDForAlias(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
|
|
|
@ -37,18 +37,30 @@ type SetRoomAliasResponse struct {
|
|||
AliasExists bool `json:"alias_exists"`
|
||||
}
|
||||
|
||||
// GetAliasRoomIDRequest is a request to GetAliasRoomID
|
||||
type GetAliasRoomIDRequest struct {
|
||||
// GetRoomIDForAliasRequest is a request to GetRoomIDForAlias
|
||||
type GetRoomIDForAliasRequest struct {
|
||||
// Alias we want to lookup
|
||||
Alias string `json:"alias"`
|
||||
}
|
||||
|
||||
// GetAliasRoomIDResponse is a response to GetAliasRoomID
|
||||
type GetAliasRoomIDResponse struct {
|
||||
// GetRoomIDForAliasResponse is a response to GetRoomIDForAlias
|
||||
type GetRoomIDForAliasResponse struct {
|
||||
// The room ID the alias refers to
|
||||
RoomID string `json:"room_id"`
|
||||
}
|
||||
|
||||
// GetAliasesForRoomIDRequest is a request to GetAliasesForRoomID
|
||||
type GetAliasesForRoomIDRequest struct {
|
||||
// The room ID we want to find aliases for
|
||||
RoomID string `json:"room_id"`
|
||||
}
|
||||
|
||||
// GetAliasesForRoomIDResponse is a response to GetAliasesForRoomID
|
||||
type GetAliasesForRoomIDResponse struct {
|
||||
// The aliases the alias refers to
|
||||
Aliases []string `json:"aliases"`
|
||||
}
|
||||
|
||||
// RemoveRoomAliasRequest is a request to RemoveRoomAlias
|
||||
type RemoveRoomAliasRequest struct {
|
||||
// ID of the user removing the alias
|
||||
|
@ -70,10 +82,17 @@ type RoomserverAliasAPI interface {
|
|||
) error
|
||||
|
||||
// Get the room ID for an alias
|
||||
GetAliasRoomID(
|
||||
GetRoomIDForAlias(
|
||||
ctx context.Context,
|
||||
req *GetAliasRoomIDRequest,
|
||||
response *GetAliasRoomIDResponse,
|
||||
req *GetRoomIDForAliasRequest,
|
||||
response *GetRoomIDForAliasResponse,
|
||||
) error
|
||||
|
||||
// Get all known aliases for a room ID
|
||||
GetAliasesForRoomID(
|
||||
ctx context.Context,
|
||||
req *GetAliasesForRoomIDRequest,
|
||||
response *GetAliasesForRoomIDResponse,
|
||||
) error
|
||||
|
||||
// Remove a room alias
|
||||
|
@ -87,8 +106,11 @@ type RoomserverAliasAPI interface {
|
|||
// RoomserverSetRoomAliasPath is the HTTP path for the SetRoomAlias API.
|
||||
const RoomserverSetRoomAliasPath = "/api/roomserver/setRoomAlias"
|
||||
|
||||
// RoomserverGetAliasRoomIDPath is the HTTP path for the GetAliasRoomID API.
|
||||
const RoomserverGetAliasRoomIDPath = "/api/roomserver/getAliasRoomID"
|
||||
// RoomserverGetRoomIDForAliasPath is the HTTP path for the GetRoomIDForAlias API.
|
||||
const RoomserverGetRoomIDForAliasPath = "/api/roomserver/GetRoomIDForAlias"
|
||||
|
||||
// RoomserverGetAliasesForRoomIDPath is the HTTP path for the GetAliasesForRoomID API.
|
||||
const RoomserverGetAliasesForRoomIDPath = "/api/roomserver/GetAliasesForRoomID"
|
||||
|
||||
// RoomserverRemoveRoomAliasPath is the HTTP path for the RemoveRoomAlias API.
|
||||
const RoomserverRemoveRoomAliasPath = "/api/roomserver/removeRoomAlias"
|
||||
|
@ -120,16 +142,29 @@ func (h *httpRoomserverAliasAPI) SetRoomAlias(
|
|||
return postJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
}
|
||||
|
||||
// GetAliasRoomID implements RoomserverAliasAPI
|
||||
func (h *httpRoomserverAliasAPI) GetAliasRoomID(
|
||||
// GetRoomIDForAlias implements RoomserverAliasAPI
|
||||
func (h *httpRoomserverAliasAPI) GetRoomIDForAlias(
|
||||
ctx context.Context,
|
||||
request *GetAliasRoomIDRequest,
|
||||
response *GetAliasRoomIDResponse,
|
||||
request *GetRoomIDForAliasRequest,
|
||||
response *GetRoomIDForAliasResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "GetAliasRoomID")
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "GetRoomIDForAlias")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverGetAliasRoomIDPath
|
||||
apiURL := h.roomserverURL + RoomserverGetRoomIDForAliasPath
|
||||
return postJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
}
|
||||
|
||||
// GetAliasesForRoomID implements RoomserverAliasAPI
|
||||
func (h *httpRoomserverAliasAPI) GetAliasesForRoomID(
|
||||
ctx context.Context,
|
||||
request *GetAliasesForRoomIDRequest,
|
||||
response *GetAliasesForRoomIDResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "GetAliasesForRoomID")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverGetAliasesForRoomIDPath
|
||||
return postJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
}
|
||||
|
||||
|
|
|
@ -445,13 +445,13 @@ func (d *Database) SetRoomAlias(ctx context.Context, alias string, roomID string
|
|||
return d.statements.insertRoomAlias(ctx, alias, roomID)
|
||||
}
|
||||
|
||||
// GetRoomIDFromAlias implements alias.RoomserverAliasAPIDB
|
||||
func (d *Database) GetRoomIDFromAlias(ctx context.Context, alias string) (string, error) {
|
||||
// GetRoomIDForAlias implements alias.RoomserverAliasAPIDB
|
||||
func (d *Database) GetRoomIDForAlias(ctx context.Context, alias string) (string, error) {
|
||||
return d.statements.selectRoomIDFromAlias(ctx, alias)
|
||||
}
|
||||
|
||||
// GetAliasesFromRoomID implements alias.RoomserverAliasAPIDB
|
||||
func (d *Database) GetAliasesFromRoomID(ctx context.Context, roomID string) ([]string, error) {
|
||||
// GetAliasesForRoomID implements alias.RoomserverAliasAPIDB
|
||||
func (d *Database) GetAliasesForRoomID(ctx context.Context, roomID string) ([]string, error) {
|
||||
return d.statements.selectAliasesFromRoomID(ctx, roomID)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue