class TokenDatabaseTest(TestCase): @inlineCallbacks def setUp(self): zookeeper.set_debug_level(0) self.client = yield self.get_zookeeper_client().connect() self.db = TokenDatabase(self.client, "/token-test") def tearDown(self): deleteTree(handle=self.client.handle) self.client.close() @inlineCallbacks def test_add(self): principal = Principal("zebra", "zoo") yield self.db.add(principal) content, stat = yield self.client.get("/token-test") data = yaml.load(content) self.assertEqual(data, {"zebra": principal.get_token()}) @inlineCallbacks def test_remove(self): principal = Principal("zebra", "zoo") yield self.db.add(principal) yield self.db.remove(principal) content, stat = yield self.client.get("/token-test") data = yaml.load(content) self.assertEqual(data, {"zebra": principal.get_token()}) @inlineCallbacks def test_get(self): principal = Principal("zebra", "zoo") yield self.db.add(principal) token = yield self.db.get(principal.name) self.assertEqual(token, principal.get_token()) @inlineCallbacks def test_get_nonexistant(self): principal = Principal("zebra", "zoo") error = yield self.assertFailure(self.db.get(principal.name), PrincipalNotFound) self.assertEquals(str(error), "Principal 'zebra' not found")
class SecureConnectionTest(TestCase): @inlineCallbacks def setUp(self): zookeeper.set_debug_level(0) self.client = yield SecurityPolicyConnection( get_test_zookeeper_address()).connect() admin = Principal("admin", "admin") self.token_db = TokenDatabase(self.client) yield self.token_db.add(admin) self.policy = SecurityPolicy(self.client, self.token_db, owner=admin) attach_defer = admin.attach(self.client) # Trick to speed up the auth response processing (fixed in ZK trunk) self.client.exists("/") yield attach_defer def tearDown(self): deleteTree(handle=self.client.handle) self.client.close() @inlineCallbacks def test_create_without_policy(self): """If no policy is set the connection behaves normally""" def rule(policy, path): return [make_ace(Principal("magic", "not").get_token(), all=True)] self.policy.add_rule(rule) yield self.client.create("/xyz") acl, stat = yield self.client.get_acl("/xyz") self.assertEqual(acl, [ZOO_OPEN_ACL_UNSAFE]) @inlineCallbacks def test_create_with_policy(self): """If a policy is set ACL are determined by the policy.""" def rule(policy, path): return [make_ace(Principal("magic", "not").get_token(), all=True)] self.policy.add_rule(rule) self.client.set_security_policy(self.policy) yield self.client.create("/xyz") acl, stat = yield self.client.get_acl("/xyz") self.assertEqual( acl, [make_ace(Principal("magic", "not").get_token(), all=True), make_ace(Principal("admin", "admin").get_token(), all=True)])
class SecureConnectionTest(TestCase): @inlineCallbacks def setUp(self): zookeeper.set_debug_level(0) self.client = yield SecurityPolicyConnection( get_test_zookeeper_address()).connect() admin = Principal("admin", "admin") self.token_db = TokenDatabase(self.client) yield self.token_db.add(admin) self.policy = SecurityPolicy(self.client, self.token_db, owner=admin) attach_defer = admin.attach(self.client) # Trick to speed up the auth response processing (fixed in ZK trunk) self.client.exists("/") yield attach_defer def tearDown(self): deleteTree(handle=self.client.handle) self.client.close() @inlineCallbacks def test_create_without_policy(self): """If no policy is set the connection behaves normally""" def rule(policy, path): return [make_ace(Principal("magic", "not").get_token(), all=True)] self.policy.add_rule(rule) yield self.client.create("/xyz") acl, stat = yield self.client.get_acl("/xyz") self.assertEqual(acl, [ZOO_OPEN_ACL_UNSAFE]) @inlineCallbacks def test_create_with_policy(self): """If a policy is set ACL are determined by the policy.""" def rule(policy, path): return [make_ace(Principal("magic", "not").get_token(), all=True)] self.policy.add_rule(rule) self.client.set_security_policy(self.policy) yield self.client.create("/xyz") acl, stat = yield self.client.get_acl("/xyz") self.assertEqual(acl, [ make_ace(Principal("magic", "not").get_token(), all=True), make_ace(Principal("admin", "admin").get_token(), all=True) ])
class ACLTest(TestCase): @inlineCallbacks def setUp(self): zookeeper.set_debug_level(0) self.client = yield self.get_zookeeper_client().connect() self.tokens = TokenDatabase(self.client) self.admin = Principal("admin", "admin") yield self.tokens.add(self.admin) self.policy = SecurityPolicy(self.client, self.tokens) attach_deferred = self.admin.attach(self.client) self.client.exists("/") yield attach_deferred def tearDown(self): deleteTree(handle=self.client.handle) self.client.close() @inlineCallbacks def test_acl_on_non_existant_node(self): acl = ACL(self.client, "abc") yield self.assertFailure(acl.grant("admin", all=True), StateNotFound) @inlineCallbacks def test_acl_without_admin(self): """A client needs an attached principle with the admin perm to set acl. """ client = yield self.get_zookeeper_client().connect() principal = Principal("zebra", "stripes") yield self.tokens.add(principal) attach_deferred = principal.attach(client) yield self.client.create( "/abc", acls=[make_ace(self.admin.get_token(), all=True)]) yield attach_deferred acl = ACL(client, "/abc") yield self.assertFailure( acl.grant("zebra", all=True), zookeeper.NoAuthException) @inlineCallbacks def test_grant(self): path = yield self.client.create("/abc") acl = ACL(self.client, path) yield acl.grant("admin", all=True) node_acl, stat = yield self.client.get_acl(path) self.assertEqual( node_acl, [ZOO_OPEN_ACL_UNSAFE, make_ace(self.admin.get_token(), all=True)]) @inlineCallbacks def test_grant_additive(self): path = yield self.client.create("/abc") acl = ACL(self.client, "/abc") yield acl.grant("admin", read=True) yield acl.grant("admin", write=True) test_ace = make_ace(":", read=True, write=True) node_acl, stat = yield self.client.get_acl(path) self.assertEqual(node_acl[-1]["perms"], test_ace["perms"]) @inlineCallbacks def test_grant_not_in_token_database(self): path = yield self.client.create("/abc") acl = ACL(self.client, path) yield self.assertFailure(acl.grant("zebra"), PrincipalNotFound) @inlineCallbacks def test_prohibit(self): principal = Principal("zebra", "stripes") yield self.tokens.add(principal) path = yield self.client.create("/abc", acls=[ make_ace(self.admin.get_token(), all=True), make_ace(principal.get_token(), write=True)]) acl = ACL(self.client, path) yield acl.prohibit("zebra") acl, stat = yield self.client.get_acl(path) self.assertEqual( acl, [make_ace(self.admin.get_token(), all=True)]) @inlineCallbacks def test_prohibit_non_existant_node(self): acl = ACL(self.client, "/abc") yield self.assertFailure( acl.prohibit("zebra"), StateNotFound) @inlineCallbacks def test_prohibit_not_in_acl(self): principal = Principal("zebra", "stripes") yield self.tokens.add(principal) path = yield self.client.create("/abc", acls=[ make_ace(self.admin.get_token(), all=True)]) acl = ACL(self.client, path) # We get to the same end state so its fine. yield acl.prohibit("zebra") acl, stat = yield self.client.get_acl(path) self.assertEqual( acl, [make_ace(self.admin.get_token(), all=True)])
class PolicyTest(TestCase): @inlineCallbacks def setUp(self): zookeeper.set_debug_level(0) self.client = yield self.get_zookeeper_client().connect() self.tokens = TokenDatabase(self.client) yield self.tokens.add(Principal("admin", "admin")) self.policy = SecurityPolicy(self.client, self.tokens) def tearDown(self): deleteTree(handle=self.client.handle) self.client.close() @inlineCallbacks def test_default_no_owner_no_rules_gives_admin_access(self): """By default the policy setups a global access for the cli admins. """ acl = yield self.policy("/random") self.assertIn( make_ace(Principal("admin", "admin").get_token(), all=True), acl) @inlineCallbacks def test_default_no_rules_gives_global_authenticated_access(self): """If no rules match, the default acl gives authenticated users access. XXX/TODO: This is intended as a temporary crutch for integration of the security machinery, not a long term solution. """ acl = yield self.policy("/random") self.assertIn(make_ace("auth", "world", all=True), acl) @inlineCallbacks def test_rule_match_suppress_open_access(self): """If a rule returns an acl, then no default access is given.""" principal = Principal("foobar", "foobar") self.policy.add_rule(lambda policy, path: [ make_ace(principal.get_token(), all=True)]) acl = yield self.policy("/random") # Check for matched rule ACL self.assertIn(make_ace(principal.get_token(), all=True), acl) # Verify no default access self.assertNotIn(make_ace("auth", "world", all=True), acl) @inlineCallbacks def test_rule_that_returns_deferred(self): """If a rule may do additional lookups, resulting in deferred values. """ principal = Principal("foobar", "foobar") self.policy.add_rule(lambda policy, path: succeed([ make_ace(principal.get_token(), all=True)])) acl = yield self.policy("/random") # Check for matched rule ACL self.assertIn(make_ace(principal.get_token(), all=True), acl) # Verify no default access self.assertNotIn(make_ace("auth", "world", all=True), acl) @inlineCallbacks def test_owner_ace(self): """If an owner is set, all nodes ACLs will have an owner ACE. """ owner = Principal("john", "doe") self.policy.set_owner(owner) acl = yield self.policy("/random") self.assertIn(make_ace(owner.get_token(), all=True), acl)
class ACLTest(TestCase): @inlineCallbacks def setUp(self): zookeeper.set_debug_level(0) self.client = yield self.get_zookeeper_client().connect() self.tokens = TokenDatabase(self.client) self.admin = Principal("admin", "admin") yield self.tokens.add(self.admin) self.policy = SecurityPolicy(self.client, self.tokens) attach_deferred = self.admin.attach(self.client) self.client.exists("/") yield attach_deferred def tearDown(self): deleteTree(handle=self.client.handle) self.client.close() @inlineCallbacks def test_acl_on_non_existant_node(self): acl = ACL(self.client, "abc") yield self.assertFailure(acl.grant("admin", all=True), StateNotFound) @inlineCallbacks def test_acl_without_admin(self): """A client needs an attached principle with the admin perm to set acl. """ client = yield self.get_zookeeper_client().connect() principal = Principal("zebra", "stripes") yield self.tokens.add(principal) attach_deferred = principal.attach(client) yield self.client.create( "/abc", acls=[make_ace(self.admin.get_token(), all=True)]) yield attach_deferred acl = ACL(client, "/abc") yield self.assertFailure(acl.grant("zebra", all=True), zookeeper.NoAuthException) @inlineCallbacks def test_grant(self): path = yield self.client.create("/abc") acl = ACL(self.client, path) yield acl.grant("admin", all=True) node_acl, stat = yield self.client.get_acl(path) self.assertEqual( node_acl, [ZOO_OPEN_ACL_UNSAFE, make_ace(self.admin.get_token(), all=True)]) @inlineCallbacks def test_grant_additive(self): path = yield self.client.create("/abc") acl = ACL(self.client, "/abc") yield acl.grant("admin", read=True) yield acl.grant("admin", write=True) test_ace = make_ace(":", read=True, write=True) node_acl, stat = yield self.client.get_acl(path) self.assertEqual(node_acl[-1]["perms"], test_ace["perms"]) @inlineCallbacks def test_grant_not_in_token_database(self): path = yield self.client.create("/abc") acl = ACL(self.client, path) yield self.assertFailure(acl.grant("zebra"), PrincipalNotFound) @inlineCallbacks def test_prohibit(self): principal = Principal("zebra", "stripes") yield self.tokens.add(principal) path = yield self.client.create("/abc", acls=[ make_ace(self.admin.get_token(), all=True), make_ace(principal.get_token(), write=True) ]) acl = ACL(self.client, path) yield acl.prohibit("zebra") acl, stat = yield self.client.get_acl(path) self.assertEqual(acl, [make_ace(self.admin.get_token(), all=True)]) @inlineCallbacks def test_prohibit_non_existant_node(self): acl = ACL(self.client, "/abc") yield self.assertFailure(acl.prohibit("zebra"), StateNotFound) @inlineCallbacks def test_prohibit_not_in_acl(self): principal = Principal("zebra", "stripes") yield self.tokens.add(principal) path = yield self.client.create( "/abc", acls=[make_ace(self.admin.get_token(), all=True)]) acl = ACL(self.client, path) # We get to the same end state so its fine. yield acl.prohibit("zebra") acl, stat = yield self.client.get_acl(path) self.assertEqual(acl, [make_ace(self.admin.get_token(), all=True)])
class PolicyTest(TestCase): @inlineCallbacks def setUp(self): zookeeper.set_debug_level(0) self.client = yield self.get_zookeeper_client().connect() self.tokens = TokenDatabase(self.client) yield self.tokens.add(Principal("admin", "admin")) self.policy = SecurityPolicy(self.client, self.tokens) def tearDown(self): deleteTree(handle=self.client.handle) self.client.close() @inlineCallbacks def test_default_no_owner_no_rules_gives_admin_access(self): """By default the policy setups a global access for the cli admins. """ acl = yield self.policy("/random") self.assertIn( make_ace(Principal("admin", "admin").get_token(), all=True), acl) @inlineCallbacks def test_default_no_rules_gives_global_authenticated_access(self): """If no rules match, the default acl gives authenticated users access. XXX/TODO: This is intended as a temporary crutch for integration of the security machinery, not a long term solution. """ acl = yield self.policy("/random") self.assertIn(make_ace("auth", "world", all=True), acl) @inlineCallbacks def test_rule_match_suppress_open_access(self): """If a rule returns an acl, then no default access is given.""" principal = Principal("foobar", "foobar") self.policy.add_rule( lambda policy, path: [make_ace(principal.get_token(), all=True)]) acl = yield self.policy("/random") # Check for matched rule ACL self.assertIn(make_ace(principal.get_token(), all=True), acl) # Verify no default access self.assertNotIn(make_ace("auth", "world", all=True), acl) @inlineCallbacks def test_rule_that_returns_deferred(self): """If a rule may do additional lookups, resulting in deferred values. """ principal = Principal("foobar", "foobar") self.policy.add_rule(lambda policy, path: succeed( [make_ace(principal.get_token(), all=True)])) acl = yield self.policy("/random") # Check for matched rule ACL self.assertIn(make_ace(principal.get_token(), all=True), acl) # Verify no default access self.assertNotIn(make_ace("auth", "world", all=True), acl) @inlineCallbacks def test_owner_ace(self): """If an owner is set, all nodes ACLs will have an owner ACE. """ owner = Principal("john", "doe") self.policy.set_owner(owner) acl = yield self.policy("/random") self.assertIn(make_ace(owner.get_token(), all=True), acl)