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:
Andrew Morgan 2018-05-29 14:38:52 +01:00
parent 927166ff8a
commit 7ba8629717
3 changed files with 38 additions and 28 deletions

View file

@ -105,12 +105,15 @@ func (s *OutputRoomEventConsumer) onMessage(msg *sarama.ConsumerMessage) error {
return err
}
if err = s.db.UpdateMemberships(context.TODO(), events, output.NewRoomEvent.RemovesStateEventIDs); err != nil {
// 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(append(events, ev))
return s.filterRoomserverEvents(ctx, append(events, ev))
}
// lookupStateEvents looks up the state events that are added by a new event.
@ -162,11 +165,11 @@ func (s *OutputRoomEventConsumer) lookupStateEvents(
// 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(events []gomatrixserverlib.Event) error {
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(event, appservice) {
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())
}
@ -178,7 +181,7 @@ func (s *OutputRoomEventConsumer) filterRoomserverEvents(events []gomatrixserver
// appserviceIsInterestedInEvent returns a boolean depending on whether a given
// event falls within one of a given application service's namespaces.
func (s *OutputRoomEventConsumer) appserviceIsInterestedInEvent(event gomatrixserverlib.Event, appservice config.ApplicationService) bool {
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()) {
@ -196,7 +199,7 @@ func (s *OutputRoomEventConsumer) appserviceIsInterestedInEvent(event gomatrixse
// 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(context.TODO(), &queryReq, &queryRes); err == nil {
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) {
@ -205,7 +208,9 @@ func (s *OutputRoomEventConsumer) appserviceIsInterestedInEvent(event gomatrixse
}
}
} else {
log.WithError(err).Errorf("Unable to get aliases for Room with ID: %s", event.RoomID())
log.WithFields(log.Fields{
"room_id": event.RoomID(),
}).WithError(err).Errorf("Unable to get aliases for room")
}
return false

View file

@ -92,10 +92,11 @@ func loadAppservices(config *Dendrite) error {
// methods can quickly check if a particular string matches any of them.
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 {
@ -103,19 +104,18 @@ func setupRegexps(cfg *Dendrite) (err error) {
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, "|")
exclusiveRooms := strings.Join(exclusiveRoomStrings, "|")
// If there are no exclusive regexes, compile string so that it will not match
// any valid usernames/aliases/roomIDs
@ -125,9 +125,6 @@ func setupRegexps(cfg *Dendrite) (err error) {
if exclusiveAliases == "" {
exclusiveAliases = "^$"
}
if exclusiveRooms == "" {
exclusiveRooms = "^$"
}
// Store compiled Regex
if cfg.Derived.ExclusiveApplicationServicesUsernameRegexp, err = regexp.Compile(exclusiveUsernames); err != nil {
@ -136,9 +133,6 @@ func setupRegexps(cfg *Dendrite) (err error) {
if cfg.Derived.ExclusiveApplicationServicesAliasRegexp, err = regexp.Compile(exclusiveAliases); err != nil {
return err
}
if cfg.Derived.ExclusiveApplicationServicesRoomRegexp, err = regexp.Compile(exclusiveRooms); err != nil {
return err
}
return nil
}
@ -167,14 +161,16 @@ 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,
@ -185,6 +181,18 @@ func checkErrors(config *Dendrite) (err 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
@ -200,8 +208,7 @@ func checkErrors(config *Dendrite) (err error) {
}
}
err = setupRegexps(config)
return err
return setupRegexps(config)
}
// IsValidRegex returns true or false based on whether the

View file

@ -244,10 +244,8 @@ type Dendrite struct {
// When a user creates a room alias, we check that it isn't already
// reserved by an application service
ExclusiveApplicationServicesAliasRegexp *regexp.Regexp
// TODO: Huh? When a room ID is created, we block the client from
// creating it if it falls under an application service's exclusive
// roomID regex? But why tho
ExclusiveApplicationServicesRoomRegexp *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:"-"`
}