[tor-commits] [bridgedb/develop] Refactor getBridgesForEmail() to use EmailBridgeRequests.
isis at torproject.org
isis at torproject.org
Thu Jun 25 07:10:54 UTC 2015
commit 55557c339c18cd3f190521369d5047bbd7ccf369
Author: Isis Lovecruft <isis at torproject.org>
Date: Wed Apr 1 05:54:53 2015 +0000
Refactor getBridgesForEmail() to use EmailBridgeRequests.
* RENAME b.D.EmailBasedDistributor.getBridgesForEmail() â
b.D.EmailBasedDistributor.getBridges().
* CHANGE b.D.EmailBasedDistributor.getBridges() to use
bridgedb.email.request.EmailBridgeRequest.
---
lib/bridgedb/Dist.py | 60 ++++++++++++++++-------------------
lib/bridgedb/email/autoresponder.py | 16 ++++------
lib/bridgedb/test/email_helpers.py | 24 +++++++-------
lib/bridgedb/test/legacy_Tests.py | 6 ++--
4 files changed, 48 insertions(+), 58 deletions(-)
diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py
index 39e70be..26e952e 100644
--- a/lib/bridgedb/Dist.py
+++ b/lib/bridgedb/Dist.py
@@ -473,65 +473,63 @@ class EmailBasedDistributor(Distributor):
"""Assign a bridge to this distributor."""
self.splitter.insert(bridge)
- def getBridgesForEmail(self, emailaddress, epoch, N=1, parameters=None,
- countryCode=None, bridgeFilterRules=None):
+ def getBridges(self, bridgeRequest, epoch, N=1):
"""Return a list of bridges to give to a user.
- :param str emailaddress: The user's email address, as given in a
- :header:`From:` line.
+ :type bridgeRequest: :class:`~bridgedb.email.request.EmailBridgeRequest`
+ :param bridgeRequest: A :class:`~bridgedb.bridgerequest.BridgeRequestBase`
+ with the :data:`~bridgedb.bridgerequest.BridgeRequestBase.client`
+ attribute set to a string containing the client's full, canonicalized
+ email address.
:param epoch: The time period when we got this request. This can be
any string, so long as it changes with every period.
:param int N: The number of bridges to try to give back.
- :param parameters: DOCDOC
- :param countryCode: DOCDOC
- :param bridgeFilterRules: DOCDOC
"""
- if not bridgeFilterRules:
- bridgeFilterRules=[]
- now = time.time()
-
# All checks on the email address, such as checks for whitelisting and
# canonicalization of domain name, are done in
# :meth:`bridgedb.email.autoresponder.getMailTo` and
# :meth:`bridgedb.email.autoresponder.SMTPAutoresponder.runChecks`.
- if not emailaddress:
- logging.error(("%s distributor can't get bridges for blank email "
- "address!") % (self.name, emailaddress))
- return []
+ if (not bridgeRequest.client) or (bridgeRequest.client == 'default'):
+ raise addr.BadEmail(
+ ("%s distributor can't get bridges for invalid email email "
+ " address: %s") % (self.name, bridgeRequest.client))
+
+ now = time.time()
with bridgedb.Storage.getDB() as db:
- wasWarned = db.getWarnedEmail(emailaddress)
- lastSaw = db.getEmailTime(emailaddress)
+ wasWarned = db.getWarnedEmail(bridgeRequest.client)
+ lastSaw = db.getEmailTime(bridgeRequest.client)
logging.info("Attempting to return for %d bridges for %s..."
- % (N, emailaddress))
+ % (N, bridgeRequest.client))
if lastSaw is not None:
- if emailaddress in self.whitelist.keys():
+ if bridgeRequest.client in self.whitelist.keys():
logging.info(("Whitelisted email address %s was last seen "
"%d seconds ago.")
- % (emailaddress, now - lastSaw))
+ % (bridgeRequest.client, now - lastSaw))
elif (lastSaw + MAX_EMAIL_RATE) >= now:
wait = (lastSaw + MAX_EMAIL_RATE) - now
logging.info("Client %s must wait another %d seconds."
- % (emailaddress, wait))
+ % (bridgeRequest.client, wait))
if wasWarned:
- raise IgnoreEmail("Client was warned.", emailaddress)
+ raise IgnoreEmail("Client was warned.",
+ bridgeRequest.client)
else:
logging.info("Sending duplicate request warning.")
- db.setWarnedEmail(emailaddress, True, now)
+ db.setWarnedEmail(bridgeRequest.client, True, now)
db.commit()
raise TooSoonEmail("Must wait %d seconds" % wait,
- emailaddress)
+ bridgeRequest.client)
# warning period is over
elif wasWarned:
- db.setWarnedEmail(emailaddress, False)
+ db.setWarnedEmail(bridgeRequest.client, False)
- pos = self.emailHmac("<%s>%s" % (epoch, emailaddress))
+ pos = self.emailHmac("<%s>%s" % (epoch, bridgeRequest.client))
ring = None
- ruleset = frozenset(bridgeFilterRules)
+ ruleset = frozenset(bridgeRequest.filters)
if ruleset in self.splitter.filterRings.keys():
logging.debug("Cache hit %s" % ruleset)
_, ring = self.splitter.filterRings[ruleset]
@@ -540,19 +538,17 @@ class EmailBasedDistributor(Distributor):
logging.debug("Cache miss %s" % ruleset)
# add new ring
- key1 = getHMAC(self.splitter.key,
- "Order-Bridges-In-Ring")
+ key1 = getHMAC(self.splitter.key, "Order-Bridges-In-Ring")
ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters)
- # debug log: cache miss
self.splitter.addRing(ring, ruleset,
- filterBridgesByRules(bridgeFilterRules),
+ filterBridgesByRules(ruleset),
populate_from=self.splitter.bridges)
numBridgesToReturn = getNumBridgesPerAnswer(ring,
max_bridges_per_answer=N)
result = ring.getBridges(pos, numBridgesToReturn)
- db.setEmailTime(emailaddress, now)
+ db.setEmailTime(bridgeRequest.client, now)
db.commit()
return result
diff --git a/lib/bridgedb/email/autoresponder.py b/lib/bridgedb/email/autoresponder.py
index 0eeb14a..0ab04fa 100644
--- a/lib/bridgedb/email/autoresponder.py
+++ b/lib/bridgedb/email/autoresponder.py
@@ -87,6 +87,7 @@ def createResponseBody(lines, context, client, lang='en'):
bridges = None
try:
bridgeRequest = request.determineBridgeRequestOptions(lines)
+ bridgeRequest.client = str(client)
# The request was invalid, respond with a help email which explains
# valid email commands:
@@ -96,12 +97,10 @@ def createResponseBody(lines, context, client, lang='en'):
# Otherwise they must have requested bridges:
interval = context.schedule.intervalStart(time.time())
- bridges = context.distributor.getBridgesForEmail(
- str(client),
+ bridges = context.distributor.getBridges(
+ bridgeRequest,
interval,
- context.nBridges,
- countryCode=None,
- bridgeFilterRules=bridgeRequest.filters)
+ context.nBridges)
except EmailRequestedHelp as error:
logging.info(error)
return templates.buildWelcomeText(translator, client)
@@ -120,11 +119,8 @@ def createResponseBody(lines, context, client, lang='en'):
answer = "(no bridges currently available)\r\n"
if bridges:
transport = bridgeRequest.justOnePTType()
- answer = "".join(" %s\r\n" % b.getConfigLine(
- includeFingerprint=context.includeFingerprints,
- addressClass=bridgeRequest.addressClass,
- transport=transport,
- request=str(client)) for b in bridges)
+ answer = "".join(" %s\r\n" % b.getBridgeLine(
+ bridgeRequest, context.includeFingerprints) for b in bridges)
return templates.buildAnswerMessage(translator, client, answer)
def generateResponse(fromAddress, client, body, subject=None,
diff --git a/lib/bridgedb/test/email_helpers.py b/lib/bridgedb/test/email_helpers.py
index c80e2ea..28ece91 100644
--- a/lib/bridgedb/test/email_helpers.py
+++ b/lib/bridgedb/test/email_helpers.py
@@ -136,8 +136,7 @@ class DummyEmailDistributor(object):
self.domainrules = domainrules
self.answerParameters = answerParameters
- def getBridgesForEmail(self, emailaddress, epoch, N=1, parameters=None,
- countryCode=None, bridgeFilterRules=None):
+ def getBridges(self, bridgeRequest, epoch, N=1):
return [DummyBridge() for _ in xrange(N)]
def cleanDatabase(self):
@@ -160,22 +159,21 @@ class DummyEmailDistributorWithState(DummyEmailDistributor):
super(DummyEmailDistributorWithState, self).__init__()
self.alreadySeen = {}
- def getBridgesForEmail(self, emailaddress, epoch, N=1, parameters=None,
- countryCode=None, bridgeFilterRules=None):
+ def getBridges(self, bridgeRequest, epoch, N=1):
# Keep track of the number of times we've seen a client.
- if not emailaddress in self.alreadySeen.keys():
- self.alreadySeen[emailaddress] = 0
- self.alreadySeen[emailaddress] += 1
+ if not bridgeRequest.client in self.alreadySeen.keys():
+ self.alreadySeen[bridgeRequest.client] = 0
+ self.alreadySeen[bridgeRequest.client] += 1
- if self.alreadySeen[emailaddress] <= 1:
+ if self.alreadySeen[bridgeRequest.client] <= 1:
return [DummyBridge() for _ in xrange(N)]
- elif self.alreadySeen[emailaddress] == 2:
+ elif self.alreadySeen[bridgeRequest.client] == 2:
raise TooSoonEmail(
"Seen client '%s' %d times"
- % (emailaddress, self.alreadySeen[emailaddress]),
- emailaddress)
+ % (bridgeRequest.client, self.alreadySeen[bridgeRequest.client]),
+ bridgeRequest.client)
else:
raise IgnoreEmail(
"Seen client '%s' %d times"
- % (emailaddress, self.alreadySeen[emailaddress]),
- emailaddress)
+ % (bridgeRequest.client, self.alreadySeen[bridgeRequest.client]),
+ bridgeRequest.client)
diff --git a/lib/bridgedb/test/legacy_Tests.py b/lib/bridgedb/test/legacy_Tests.py
index 0d2512c..2e4d56f 100644
--- a/lib/bridgedb/test/legacy_Tests.py
+++ b/lib/bridgedb/test/legacy_Tests.py
@@ -169,11 +169,11 @@ class EmailBridgeDistTests(unittest.TestCase):
{'example.com': [], 'dkim.example.com': ['dkim']})
for _ in xrange(256):
d.insert(fakeBridge())
- d.getBridgesForEmail('abc at example.com', 1, 3)
+ d.getBridges('abc at example.com', 1, 3)
self.assertRaises(bridgedb.Dist.TooSoonEmail,
- d.getBridgesForEmail, 'abc at example.com', 1, 3)
+ d.getBridges, 'abc at example.com', 1, 3)
self.assertRaises(bridgedb.Dist.IgnoreEmail,
- d.getBridgesForEmail, 'abc at example.com', 1, 3)
+ d.getBridges, 'abc at example.com', 1, 3)
def testUnsupportedDomain(self):
db = self.db
More information about the tor-commits
mailing list