示例#1
0
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
示例#2
0
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)
示例#3
0
文件: tintp.py 项目: krahimian/tint
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