mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-21 22:03:10 -06:00
Add tests, tweaks to behaviour
This commit is contained in:
parent
2c729c7628
commit
1c071d4e5b
|
|
@ -1,3 +1,17 @@
|
||||||
|
// 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 acls
|
package acls
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -57,6 +71,13 @@ type serverACL struct {
|
||||||
deniedRegexes []*regexp.Regexp
|
deniedRegexes []*regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func compileACLRegex(orig string) (*regexp.Regexp, error) {
|
||||||
|
escaped := regexp.QuoteMeta(orig)
|
||||||
|
escaped = strings.Replace(escaped, "\\?", ".", -1)
|
||||||
|
escaped = strings.Replace(escaped, "\\*", ".*", -1)
|
||||||
|
return regexp.Compile(escaped)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *ServerACLs) OnServerACLUpdate(state *gomatrixserverlib.Event) {
|
func (s *ServerACLs) OnServerACLUpdate(state *gomatrixserverlib.Event) {
|
||||||
acls := &serverACL{}
|
acls := &serverACL{}
|
||||||
if err := json.Unmarshal(state.Content(), &acls.ServerACL); err != nil {
|
if err := json.Unmarshal(state.Content(), &acls.ServerACL); err != nil {
|
||||||
|
|
@ -68,20 +89,14 @@ func (s *ServerACLs) OnServerACLUpdate(state *gomatrixserverlib.Event) {
|
||||||
// special characters and then replace * and ? with their regex counterparts.
|
// special characters and then replace * and ? with their regex counterparts.
|
||||||
// https://matrix.org/docs/spec/client_server/r0.6.1#m-room-server-acl
|
// https://matrix.org/docs/spec/client_server/r0.6.1#m-room-server-acl
|
||||||
for _, orig := range acls.Allowed {
|
for _, orig := range acls.Allowed {
|
||||||
escaped := regexp.QuoteMeta(orig)
|
if expr, err := compileACLRegex(orig); err != nil {
|
||||||
escaped = strings.Replace(escaped, "\\?", "(.)", -1)
|
|
||||||
escaped = strings.Replace(escaped, "\\*", "(.*)", -1)
|
|
||||||
if expr, err := regexp.Compile(escaped); err != nil {
|
|
||||||
logrus.WithError(err).Errorf("Failed to compile allowed regex")
|
logrus.WithError(err).Errorf("Failed to compile allowed regex")
|
||||||
} else {
|
} else {
|
||||||
acls.allowedRegexes = append(acls.allowedRegexes, expr)
|
acls.allowedRegexes = append(acls.allowedRegexes, expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, orig := range acls.Denied {
|
for _, orig := range acls.Denied {
|
||||||
escaped := regexp.QuoteMeta(orig)
|
if expr, err := compileACLRegex(orig); err != nil {
|
||||||
escaped = strings.Replace(escaped, "\\?", "(.)", -1)
|
|
||||||
escaped = strings.Replace(escaped, "\\*", "(.*)", -1)
|
|
||||||
if expr, err := regexp.Compile(escaped); err != nil {
|
|
||||||
logrus.WithError(err).Errorf("Failed to compile denied regex")
|
logrus.WithError(err).Errorf("Failed to compile denied regex")
|
||||||
} else {
|
} else {
|
||||||
acls.deniedRegexes = append(acls.deniedRegexes, expr)
|
acls.deniedRegexes = append(acls.deniedRegexes, expr)
|
||||||
|
|
@ -97,7 +112,7 @@ func (s *ServerACLs) OnServerACLUpdate(state *gomatrixserverlib.Event) {
|
||||||
s.acls[state.RoomID()] = acls
|
s.acls[state.RoomID()] = acls
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServerACLs) IsServerBannedFromRoom(serverNameAndPort gomatrixserverlib.ServerName, roomID string) bool {
|
func (s *ServerACLs) IsServerBannedFromRoom(serverName gomatrixserverlib.ServerName, roomID string) bool {
|
||||||
s.aclsMutex.RLock()
|
s.aclsMutex.RLock()
|
||||||
// First of all check if we have an ACL for this room. If we don't then
|
// First of all check if we have an ACL for this room. If we don't then
|
||||||
// no servers are banned from the room.
|
// no servers are banned from the room.
|
||||||
|
|
@ -109,9 +124,8 @@ func (s *ServerACLs) IsServerBannedFromRoom(serverNameAndPort gomatrixserverlib.
|
||||||
s.aclsMutex.RUnlock()
|
s.aclsMutex.RUnlock()
|
||||||
// Split the host and port apart. This is because the spec calls on us to
|
// Split the host and port apart. This is because the spec calls on us to
|
||||||
// validate the hostname only in cases where the port is also present.
|
// validate the hostname only in cases where the port is also present.
|
||||||
serverName, _, err := net.SplitHostPort(string(serverNameAndPort))
|
if serverNameOnly, _, err := net.SplitHostPort(string(serverName)); err == nil {
|
||||||
if err != nil {
|
serverName = gomatrixserverlib.ServerName(serverNameOnly)
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
// Check if the hostname is an IPv4 or IPv6 literal. We cheat here by adding
|
// Check if the hostname is an IPv4 or IPv6 literal. We cheat here by adding
|
||||||
// a /0 prefix length just to trick ParseCIDR into working. If we find that
|
// a /0 prefix length just to trick ParseCIDR into working. If we find that
|
||||||
|
|
|
||||||
105
currentstateserver/acls/acls_test.go
Normal file
105
currentstateserver/acls/acls_test.go
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
// 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 acls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOpenACLsWithBlacklist(t *testing.T) {
|
||||||
|
roomID := "!test:test.com"
|
||||||
|
allowRegex, err := compileACLRegex("*")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
denyRegex, err := compileACLRegex("foo.com")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
acls := ServerACLs{
|
||||||
|
acls: make(map[string]*serverACL),
|
||||||
|
}
|
||||||
|
|
||||||
|
acls.acls[roomID] = &serverACL{
|
||||||
|
ServerACL: ServerACL{
|
||||||
|
AllowIPLiterals: true,
|
||||||
|
},
|
||||||
|
allowedRegexes: []*regexp.Regexp{allowRegex},
|
||||||
|
deniedRegexes: []*regexp.Regexp{denyRegex},
|
||||||
|
}
|
||||||
|
|
||||||
|
if acls.IsServerBannedFromRoom("1.2.3.4", roomID) {
|
||||||
|
t.Fatal("Expected 1.2.3.4 to be allowed but wasn't")
|
||||||
|
}
|
||||||
|
if acls.IsServerBannedFromRoom("1.2.3.4:2345", roomID) {
|
||||||
|
t.Fatal("Expected 1.2.3.4 to be allowed but wasn't")
|
||||||
|
}
|
||||||
|
if !acls.IsServerBannedFromRoom("foo.com", roomID) {
|
||||||
|
t.Fatal("Expected foo.com to be banned but wasn't")
|
||||||
|
}
|
||||||
|
if !acls.IsServerBannedFromRoom("foo.com:3456", roomID) {
|
||||||
|
t.Fatal("Expected foo.com:3456 to be banned but wasn't")
|
||||||
|
}
|
||||||
|
if acls.IsServerBannedFromRoom("bar.com", roomID) {
|
||||||
|
t.Fatal("Expected bar.com to be allowed but wasn't")
|
||||||
|
}
|
||||||
|
if acls.IsServerBannedFromRoom("bar.com:4567", roomID) {
|
||||||
|
t.Fatal("Expected bar.com to be allowed but wasn't")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDefaultACLsWithWhitelist(t *testing.T) {
|
||||||
|
roomID := "!test:test.com"
|
||||||
|
allowRegex, err := compileACLRegex("foo.com")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
acls := ServerACLs{
|
||||||
|
acls: make(map[string]*serverACL),
|
||||||
|
}
|
||||||
|
|
||||||
|
acls.acls[roomID] = &serverACL{
|
||||||
|
ServerACL: ServerACL{
|
||||||
|
AllowIPLiterals: false,
|
||||||
|
},
|
||||||
|
allowedRegexes: []*regexp.Regexp{allowRegex},
|
||||||
|
deniedRegexes: []*regexp.Regexp{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !acls.IsServerBannedFromRoom("1.2.3.4", roomID) {
|
||||||
|
t.Fatal("Expected 1.2.3.4 to be banned but wasn't")
|
||||||
|
}
|
||||||
|
if !acls.IsServerBannedFromRoom("1.2.3.4:2345", roomID) {
|
||||||
|
t.Fatal("Expected 1.2.3.4 to be banned but wasn't")
|
||||||
|
}
|
||||||
|
if acls.IsServerBannedFromRoom("foo.com", roomID) {
|
||||||
|
t.Fatal("Expected foo.com to be allowed but wasn't")
|
||||||
|
}
|
||||||
|
if acls.IsServerBannedFromRoom("foo.com:3456", roomID) {
|
||||||
|
t.Fatal("Expected foo.com:3456 to be allowed but wasn't")
|
||||||
|
}
|
||||||
|
if !acls.IsServerBannedFromRoom("bar.com", roomID) {
|
||||||
|
t.Fatal("Expected bar.com to be allowed but wasn't")
|
||||||
|
}
|
||||||
|
if !acls.IsServerBannedFromRoom("baz.com", roomID) {
|
||||||
|
t.Fatal("Expected baz.com to be allowed but wasn't")
|
||||||
|
}
|
||||||
|
if !acls.IsServerBannedFromRoom("qux.com:4567", roomID) {
|
||||||
|
t.Fatal("Expected baz.com to be allowed but wasn't")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,17 @@
|
||||||
|
// 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 api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ func (c *OutputRoomEventConsumer) onNewRoomEvent(
|
||||||
) error {
|
) error {
|
||||||
ev := msg.Event
|
ev := msg.Event
|
||||||
|
|
||||||
if ev.Type() == "m.room.server_acl" {
|
if ev.Type() == "m.room.server_acl" && ev.StateKeyEquals("") {
|
||||||
defer c.acls.OnServerACLUpdate(&ev.Event)
|
defer c.acls.OnServerACLUpdate(&ev.Event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ func (h *httpCurrentStateInternalAPI) QueryKnownUsers(
|
||||||
func (h *httpCurrentStateInternalAPI) QueryServerBannedFromRoom(
|
func (h *httpCurrentStateInternalAPI) QueryServerBannedFromRoom(
|
||||||
ctx context.Context, req *api.QueryServerBannedFromRoomRequest, res *api.QueryServerBannedFromRoomResponse,
|
ctx context.Context, req *api.QueryServerBannedFromRoomRequest, res *api.QueryServerBannedFromRoomResponse,
|
||||||
) error {
|
) error {
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryKnownUsers")
|
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryServerBannedFromRoom")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
apiURL := h.apiURL + QueryServerBannedFromRoomPath
|
apiURL := h.apiURL + QueryServerBannedFromRoomPath
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ func AddRoutes(internalAPIMux *mux.Router, intAPI api.CurrentStateInternalAPI) {
|
||||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(QuerySharedUsersPath,
|
internalAPIMux.Handle(QueryServerBannedFromRoomPath,
|
||||||
httputil.MakeInternalAPI("queryServerBannedFromRoom", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("queryServerBannedFromRoom", func(req *http.Request) util.JSONResponse {
|
||||||
request := api.QueryServerBannedFromRoomRequest{}
|
request := api.QueryServerBannedFromRoomRequest{}
|
||||||
response := api.QueryServerBannedFromRoomResponse{}
|
response := api.QueryServerBannedFromRoomResponse{}
|
||||||
|
|
|
||||||
|
|
@ -447,3 +447,4 @@ Banned servers cannot /event_auth
|
||||||
Banned servers cannot get missing events
|
Banned servers cannot get missing events
|
||||||
Banned servers cannot get room state ids
|
Banned servers cannot get room state ids
|
||||||
Banned servers cannot backfill
|
Banned servers cannot backfill
|
||||||
|
Inbound /v1/send_leave rejects leaves from other servers
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue