Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8b978dfc9 |
No files matched your search
@@ -341,3 +341,48 @@ func TestLiftLiftsEveryActiveBanCoveringTheClient(t *testing.T) {
|
|||||||
|
|
||||||
wantChanged(t, ledger, false)
|
wantChanged(t, ledger, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPermanentBanOnAWiderNetblockIsReturnedOverATemporaryBan(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
client := netip.MustParseAddr("203.0.113.9")
|
||||||
|
ledger := bans.New(defaultRules())
|
||||||
|
|
||||||
|
// The temporary ban is made first, so that its netblock is looked at first.
|
||||||
|
ledger.BanForLimit(netip.MustParsePrefix("203.0.113.9/32"), midnight(), bans.Notes{})
|
||||||
|
ledger.BanForAdmin(netip.MustParsePrefix("203.0.113.0/24"), midnight(), time.Time{},
|
||||||
|
"for good")
|
||||||
|
|
||||||
|
wantPermanentBan(t, ledger, client, midnight().Add(time.Minute))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOlderPermanentBanIsReturnedOverANewerTemporaryBan(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
netblock := netip.MustParsePrefix("203.0.113.0/24")
|
||||||
|
ledger := bans.New(defaultRules())
|
||||||
|
|
||||||
|
ledger.BanForAdmin(netblock, midnight(), time.Time{}, "for good")
|
||||||
|
ledger.BanForAdmin(netblock, midnight().Add(time.Minute), midnight().Add(time.Hour),
|
||||||
|
"for an hour")
|
||||||
|
|
||||||
|
wantPermanentBan(t, ledger, netblock.Addr(), midnight().Add(2*time.Minute))
|
||||||
|
}
|
||||||
|
|
||||||
|
// wantPermanentBan checks that Find and Check return a permanent ban for
|
||||||
|
// client at now.
|
||||||
|
func wantPermanentBan(
|
||||||
|
t *testing.T, ledger *bans.Ledger, client netip.Addr, now time.Time,
|
||||||
|
) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
for name, look := range map[string]func(netip.Addr, time.Time) (bans.Ban, bool, bool){
|
||||||
|
"Find": ledger.Find,
|
||||||
|
"Check": ledger.Check,
|
||||||
|
} {
|
||||||
|
ban, banned, _ := look(client, now)
|
||||||
|
if !banned || !ban.Permanent() {
|
||||||
|
t.Errorf("%s returned %+v and banned %v, want a permanent ban", name, ban, banned)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+29
-7
@@ -274,16 +274,27 @@ func (l *Ledger) Find(client netip.Addr, now time.Time) (Ban, bool, bool) {
|
|||||||
|
|
||||||
// activeBan returns the ban in bans, a netblock's bans oldest first, that
|
// activeBan returns the ban in bans, a netblock's bans oldest first, that
|
||||||
// is active at now, or nil when none is. If several are, it returns the
|
// is active at now, or nil when none is. If several are, it returns the
|
||||||
// one that started last. Every ban is looked at, since a ban an admin adds
|
// newest permanent one, or the newest when none is permanent. Every ban is
|
||||||
// to bans.json can start before the netblock's others and outlast them.
|
// looked at, since a ban an admin adds to bans.json can start before the
|
||||||
|
// netblock's others and outlast them.
|
||||||
func activeBan(bans []Ban, now time.Time) *Ban {
|
func activeBan(bans []Ban, now time.Time) *Ban {
|
||||||
|
var newest *Ban
|
||||||
|
|
||||||
for i := len(bans) - 1; i >= 0; i-- {
|
for i := len(bans) - 1; i >= 0; i-- {
|
||||||
if bans[i].ActiveAt(now) {
|
if !bans[i].ActiveAt(now) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if bans[i].Permanent() {
|
||||||
return &bans[i]
|
return &bans[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if newest == nil {
|
||||||
|
newest = &bans[i]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return newest
|
||||||
}
|
}
|
||||||
|
|
||||||
// BanForLimit bans netblock at now for a broken limit, with notes, and
|
// BanForLimit bans netblock at now for a broken limit, with notes, and
|
||||||
@@ -743,13 +754,16 @@ func (l *Ledger) markChanged() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// active returns the ban active at now on a netblock client is in, or
|
// active returns the ban active at now on a netblock client is in, or
|
||||||
// nil.
|
// nil. If several netblocks have one, it returns a permanent ban when
|
||||||
|
// there is one.
|
||||||
func (l *Ledger) active(client netip.Addr, now time.Time) *Ban {
|
func (l *Ledger) active(client netip.Addr, now time.Time) *Ban {
|
||||||
lengths := l.v6Lengths
|
lengths := l.v6Lengths
|
||||||
if client.Is4() {
|
if client.Is4() {
|
||||||
lengths = l.v4Lengths
|
lengths = l.v4Lengths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var first *Ban
|
||||||
|
|
||||||
for _, length := range lengths {
|
for _, length := range lengths {
|
||||||
bans, found := l.netblocks.Get(netip.PrefixFrom(client, length).Masked())
|
bans, found := l.netblocks.Get(netip.PrefixFrom(client, length).Masked())
|
||||||
if !found {
|
if !found {
|
||||||
@@ -757,12 +771,20 @@ func (l *Ledger) active(client netip.Addr, now time.Time) *Ban {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ban := activeBan(*bans, now)
|
ban := activeBan(*bans, now)
|
||||||
if ban != nil {
|
if ban == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ban.Permanent() {
|
||||||
return ban
|
return ban
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if first == nil {
|
||||||
|
first = ban
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return first
|
||||||
}
|
}
|
||||||
|
|
||||||
// covering returns the bans of each netblock held that client is in,
|
// covering returns the bans of each netblock held that client is in,
|
||||||
|
|||||||
Reference in new issue
Block a user