示例#1
0
    def test_EmailDistributor_getBridges_rate_limit_expiry(self):
        """A client's first email should return bridges.  The second should
        return a warning, and the third should receive no response.  After the
        EmailDistributor.emailRateMax is up, the client should be able to
        receive a response again.
        """
        clock = Clock()
        dist = EmailDistributor(self.key, self.domainmap, self.domainrules)
        [dist.hashring.insert(bridge) for bridge in self.bridges]

        bridgeRequest = self.makeClientRequest('*****@*****.**')

        # The first request should get a response with bridges.
        self.assertEqual(len(dist.getBridges(bridgeRequest, 1, clock)), 3)
        # The second gets a warning, and the rest are ignored.
        self.assertRaises(TooSoonEmail, dist.getBridges, bridgeRequest, 1,
                          clock)
        self.assertRaises(IgnoreEmail, dist.getBridges, bridgeRequest, 1,
                          clock)
        self.assertRaises(IgnoreEmail, dist.getBridges, bridgeRequest, 1,
                          clock)
        self.assertRaises(IgnoreEmail, dist.getBridges, bridgeRequest, 1,
                          clock)

        clock.advance(2 * dist.emailRateMax)

        # The client should again a response with bridges.
        self.assertEqual(len(dist.getBridges(bridgeRequest, 1)), 3, clock)
示例#2
0
    def test_EmailDistributor_getBridges_rate_limit_multiple_clients(self):
        """Each client should be rate-limited separately."""
        dist = EmailDistributor(self.key, self.domainmap, self.domainrules)
        [dist.hashring.insert(bridge) for bridge in self.bridges]

        bridgeRequest1 = self.makeClientRequest('*****@*****.**')
        bridgeRequest2 = self.makeClientRequest('*****@*****.**')
        bridgeRequest3 = self.makeClientRequest('*****@*****.**')

        # The first request from 'abc' should get a response with bridges.
        self.assertEqual(len(dist.getBridges(bridgeRequest1, 1)), 3)
        # The second from 'abc' gets a warning.
        self.assertRaises(TooSoonEmail, dist.getBridges, bridgeRequest1, 1)
        # The first request from 'def' should get a response with bridges.
        self.assertEqual(len(dist.getBridges(bridgeRequest2, 1)), 3)
        # The third from 'abc' is ignored.
        self.assertRaises(IgnoreEmail, dist.getBridges, bridgeRequest1, 1)
        # The second from 'def' gets a warning.
        self.assertRaises(TooSoonEmail, dist.getBridges, bridgeRequest2, 1)
        # The third from 'def' is ignored.
        self.assertRaises(IgnoreEmail, dist.getBridges, bridgeRequest2, 1)
        # The fourth from 'abc' is ignored.
        self.assertRaises(IgnoreEmail, dist.getBridges, bridgeRequest1, 1)
        # The first request from 'ghi' should get a response with bridges.
        self.assertEqual(len(dist.getBridges(bridgeRequest3, 1)), 3)
        # The second from 'ghi' gets a warning.
        self.assertRaises(TooSoonEmail, dist.getBridges, bridgeRequest3, 1)
        # The third from 'ghi' is ignored.
        self.assertRaises(IgnoreEmail, dist.getBridges, bridgeRequest3, 1)
        # The fourth from 'ghi' is ignored.
        self.assertRaises(IgnoreEmail, dist.getBridges, bridgeRequest3, 1)
示例#3
0
    def test_EmailDistributor_getBridges_rate_limit(self):
        """A client's first email should return bridges.  The second should
        return a warning, and the third should receive no response.
        """
        dist = EmailDistributor(self.key, self.domainmap, self.domainrules)
        [dist.hashring.insert(bridge) for bridge in self.bridges]

        bridgeRequest = self.makeClientRequest('*****@*****.**')

        # The first request should get a response with bridges.
        bridges = dist.getBridges(bridgeRequest, 1)
        self.assertGreater(len(bridges), 0)
        [self.assertIsInstance(b, Bridge) for b in bridges]
        self.assertEqual(len(bridges), 3)

        # The second gets a warning, and the third is ignored.
        self.assertRaises(TooSoonEmail, dist.getBridges, bridgeRequest, 1)
        self.assertRaises(IgnoreEmail, dist.getBridges, bridgeRequest, 1)
示例#4
0
    def test_EmailDistributor_getBridges_with_whitelist(self):
        """If an email address is in the whitelist, it should get a response
        every time it asks (i.e. no rate-limiting).
        """
        # The whitelist should be in the form {EMAIL: GPG_FINGERPRINT}
        whitelist = {
            '*****@*****.**': '0123456789ABCDEF0123456789ABCDEF01234567'
        }
        dist = EmailDistributor(self.key,
                                self.domainmap,
                                self.domainrules,
                                whitelist=whitelist)
        [dist.hashring.insert(bridge) for bridge in self.bridges]

        # A request from a whitelisted address should always get a response.
        bridgeRequest = self.makeClientRequest('*****@*****.**')
        for i in range(5):
            bridges = dist.getBridges(bridgeRequest, 1)
            self.assertEqual(len(bridges), 3)
示例#5
0
    def test_EmailDistributor_cleanDatabase(self):
        """Calling cleanDatabase() should cleanup email times in database, but
        not allow clients who have been recently warned and/or ignored to
        receive a response again until the remainder of their MAX_EMAIL_RATE
        time is up.
        """
        dist = EmailDistributor(self.key, self.domainmap, self.domainrules)
        [dist.hashring.insert(bridge) for bridge in self.bridges]

        bridgeRequest = self.makeClientRequest('*****@*****.**')

        # The first request should get a response with bridges.
        self.assertEqual(len(dist.getBridges(bridgeRequest, 1)), 3)
        # The second gets a warning, and the third is ignored.
        self.assertRaises(TooSoonEmail, dist.getBridges, bridgeRequest, 1)
        self.assertRaises(IgnoreEmail, dist.getBridges, bridgeRequest, 1)

        dist.cleanDatabase()

        # Cleaning the warning email times in the database shouldn't cause
        # '*****@*****.**' to be able to email again, because only the times
        # which aren't older than EMAIL_MAX_RATE should be cleared.
        self.assertRaises(IgnoreEmail, dist.getBridges, bridgeRequest, 1)