diff --git a/dim-testsuite/t/pool-list-rights.t b/dim-testsuite/t/pool-list-rights.t index 1d65f50..50f734c 100644 --- a/dim-testsuite/t/pool-list-rights.t +++ b/dim-testsuite/t/pool-list-rights.t @@ -18,6 +18,36 @@ action object group allocate some-pool all_users allocate some-pool testgroup +# Test granting and revoking attr rights (dot-suffix and prefix symmetry) +$ ndcli modify user-group testgroup grant attr audit some-pool +$ ndcli modify user-group testgroup grant attr audit. some-pool +$ ndcli list pool some-pool rights +action object group +allocate some-pool all_users +allocate some-pool testgroup +attr.audit some-pool testgroup +attr.audit. some-pool testgroup + +# Revoke using the short name without prefix or trailing dot +$ ndcli modify user-group testgroup revoke attr audit some-pool +$ ndcli list pool some-pool rights +action object group +allocate some-pool all_users +allocate some-pool testgroup +attr.audit. some-pool testgroup + +# Revoke using the full right name including dot +$ ndcli modify user-group testgroup revoke attr attr.audit. some-pool +$ ndcli list pool some-pool rights +action object group +allocate some-pool all_users +allocate some-pool testgroup + +# Test our second fix: warning/error on remove attrs with colon +$ ndcli modify pool some-pool set attrs mykey:myvalue +$ ndcli modify pool some-pool remove attrs mykey:myvalue +ERROR - Attribute name 'mykey:myvalue' contains ':'. Did you mean to specify only the attribute name? + $ ndcli modify pool some-pool remove subnet 10.0.0.0/24 INFO - Deleting zone 0.0.10.in-addr.arpa $ ndcli delete pool some-pool diff --git a/dim-testsuite/tests/pool_test.py b/dim-testsuite/tests/pool_test.py index 03f6248..190f98e 100644 --- a/dim-testsuite/tests/pool_test.py +++ b/dim-testsuite/tests/pool_test.py @@ -110,6 +110,10 @@ def test_attrs(self): self.r.ippool_delete_attrs('pool_attrs', ['team']) assert 'team' not in self.r.ippool_get_attrs('pool_attrs') + # Test that deleting an attribute with a colon raises an exception + with raises(Exception): + self.r.ippool_delete_attrs('pool_attrs', ['team:value']) + assert self.r.ippool_get_attrs('control')['team'] == '1' assert 'country' not in self.r.ippool_get_attrs('control') diff --git a/dim/CHANGES b/dim/CHANGES index 1dc85a0..b14ecd2 100644 --- a/dim/CHANGES +++ b/dim/CHANGES @@ -1,5 +1,6 @@ unreleased ---------- +* reject attribute names containing colons during deletion to prevent silent failure from incorrect key-value input * fix revoking attribute rights on pools when utilizing trailing dots or prefix strings * add support for ALIAS resource records (coexists with other types at zone apex, mutually exclusive with CNAME, disabled in DNSSEC-enabled zones) * add support for DNAME resource records according to RFC 6672 (prevents DNAME at zone apex, prevents records under DNAME subtrees) diff --git a/dim/dim/models/util.py b/dim/dim/models/util.py index 7654f54..2a00cb4 100644 --- a/dim/dim/models/util.py +++ b/dim/dim/models/util.py @@ -81,6 +81,9 @@ def delete_attrs(self, attribute_names): from .history import record_history if not attribute_names: return + for name in attribute_names: + if ':' in name: + raise Exception("Attribute name '%s' contains ':'. Did you mean to specify only the attribute name?" % name) current = self.AttrClass.query\ .filter_by(**{self.attr_backref: self})\ .join(self.AttrNameClass)\