Hi Folks, I'm trying to use zookeeper via zkpython to set an acl on a node, and then test that acl. I've configured a super user, and create a node with an acl with the all permission and a digest scheme. However i find that i end up not being able to touch the node with the credentials as per the configured acl user, perhaps even more oddly i can't access the node with the super user (passed in via system property on the cli via Dzookeeper.DigestAuthenticationProvider.superDigest). Any attempt to acces the node raises an exception zookeeper.NoAuthException: not authenticated
i've attached a demonstration script that exhibits the problem. Is there something i'm doing wrong here or is it an issue with zkpython? thanks, Kapil
import zookeeper import threading import hashlib import base64 ZOO_OPEN_ACL_UNSAFE = {'scheme': 'world', 'id': 'anyone', 'perms': zookeeper.PERM_ALL} class Connection(object): def __init__(self, servers): self.servers = servers self.connected = False self.timeout = 10000 self.cv = threading.Condition() self.handle = None self.cv.acquire() self.handle = zookeeper.init( servers, self.connection_watcher, self.timeout) self.cv.wait(self.timeout/1000) if not self.connected: raise RuntimeError("unable to connect %s" % servers) def connection_watcher(self, handle, type, state, path): print type, state, path self.handle = handle self.cv.acquire() self.connected = True self.cv.notifyAll() self.cv.release() def close(self): return zookeeper.close(self.handle) def authenticate(self, scheme, credentials): def callback(handle, result): self.cv.acquire() assert self.handle == handle self.cv.notify() self.cv.release() self.cv.acquire() zookeeper.add_auth( self.handle, scheme, credentials, callback) self.cv.wait() def create(self, path, data="", acl=[ZOO_OPEN_ACL_UNSAFE]): return zookeeper.create(self.handle, path, data, acl, zookeeper.EPHEMERAL) def get_children(self, path): return zookeeper.get_children(self.handle, path) def identity(credentials): user, password = credentials.split(":") return "%s:%s" % (user, base64.b64encode(hashlib.new("sha1", password).digest())) USER_ROOT = "super:pass" USER_TRUCKS = "trucks:foobar" def main(): conn = Connection("127.0.0.1:2181") conn.authenticate("digest", USER_ROOT) conn.create("/cars") children = conn.get_children("/cars") assert not children truck_acl = [ {'scheme': 'digest', 'perms': zookeeper.PERM_ALL, 'id': identity(USER_TRUCKS)}, {'scheme': 'digest', 'perms': zookeeper.PERM_ALL, 'id': identity(USER_ROOT)}] # create an ephemeral truck node with the given acl conn.create("/trucks", acl=truck_acl) # this also fails, but demonstrating with another conn for completeness. #conn.get_children("/trucks") conn2 = Connection("127.0.0.1:2181") conn2.authenticate("digest", USER_TRUCKS) try: conn2.get_children("/trucks") finally: conn.close() conn2.close() if __name__ == '__main__': main()