class ConnectionPool(object): def __init__(self, resolver, contextFactory, keyStore, storage): self.connections = {} self.resolver = resolver self.contextFactory = contextFactory self.keyStore = keyStore self.storage = storage self.log = Logger(system=self) def send(self, keyId, cmd, *args): if keyId in self.connections: return self.sendOnConnection(self.connections[keyId], cmd, args) d = self.resolver.resolve(keyId) d.addCallback(self.createConnection, keyId) return d.addCallback(self.sendOnConnection, cmd, args) def sendOnConnection(self, connection, cmd, args): if connection is None: return False return connection.sendCommand(cmd, args) def createConnection(self, addrs, keyId): if len(addrs) == 0: raise HostUnreachableError("Cannot connect to %s" % keyId) host, port = addrs.pop() self.log.debug("Attempting to create connection to %s:%i" % (host, port)) cc = ClientCreator(reactor, TintProtocol, self) d = cc.connectSSL(host, port, self.contextFactory, timeout=5) d.addCallback(self.saveConnection, keyId) if len(addrs) > 0: d.addErrback(lambda _: self.createConnection(addrs, keyId)) return d def forgetConnection(self, keyId): self.log.info("removing connection %s from pool" % keyId) if keyId in self.connections: del self.connections[keyId] def saveConnection(self, connection, keyId): self.connections[keyId] = connection self.log.info("saving connection %s in pool" % keyId) return connection
class DefaultPermissions(object): def __init__(self, storage): self.storage = storage self.log = Logger(system=self) def accessAvailable(self, requestor, key): def gather(results): access = set() for result in results: if result is not None: access.update(result.split(',')) return list(access) self.log.info("Testing access for %s to %s" % (requestor, key)) ds = [] for path in Path(key).ancestors(): path = str(Path('a').join(requestor).join(path)) ds.append(self.storage.get(path, None)) return defer.gatherResults(ds).addCallback(gather) def canAccess(self, requestor, key, optype='*'): """ @param key The path to the storage. Should always start with a '/'. """ def test(access): return '*' in access or optype in access d = self.accessAvailable(requestor, key) return d.addCallback(test) def grantAccess(self, requestor, key, optype="*"): def test(access): if not access: path = Path('a').join(requestor).join(Path(key)) return self.storage.set(str(path), optype) return defer.succeed(optype) d = self.canAccess(requestor, key, optype) return d.addCallback(test)
class ConnectionPool(object): def __init__(self, resolver, contextFactory, keyStore, storage): self.connections = {} self.resolver = resolver self.contextFactory = contextFactory self.keyStore = keyStore self.storage = storage self.log = Logger(system=self) def send(self, keyId, cmd, *args): if keyId in self.connections: return self.sendOnConnection(self.connections[keyId], cmd) d = self.resolver.resolve(keyId) d.addCallback(self.createConnection, keyId) return d.addCallback(self.sendOnConnection, cmd, args) def sendOnConnection(self, connection, cmd, args): if connection is None: return False return connection.sendCommand(cmd, args) def createConnection(self, addr, keyId): if addr is None: return False host, port = addr cc = ClientCreator(reactor, TintProtocol, self) d = cc.connectSSL(host, port, self.contextFactory) return d.addCallback(self.saveConnection, keyId) def forgetConnection(self, keyId): self.log.info("removing connection %s from pool" % keyId) del self.connections[keyId] def saveConnection(self, connection, keyId): self.connections[keyId] = connection self.log.info("saving connection %s in pool" % keyId) return connection