def test_useToken(self): """ You can use tokens. """ d = TimedTokenDispenser(store=MemoryStore(task.Clock()), clock=task.Clock()) t1 = yield d.getToken('foo') yield d.useToken(t1)
def test_getToken_unique(self): """ You can get tokens from the dispenser which are unique. """ d = TimedTokenDispenser(store=MemoryStore(task.Clock()), clock=task.Clock()) t1 = yield d.getToken('foo') t2 = yield d.getToken('foo') self.assertNotEqual(t1, t2)
def test_tokenExpires(self): """ Tokens expire after a certain amount of time. """ clock = task.Clock() d = TimedTokenDispenser(expiration=50, store=MemoryStore(clock), clock=clock) token = yield d.getToken('foo') clock.advance(50) yield self.assertFailure(d.useToken(token), InvalidToken)
def test_getToken_limitByKey(self): """ Tokens are limited in number according to the key. """ clock = task.Clock() d = TimedTokenDispenser(available=2, store=MemoryStore(clock), clock=clock) yield d.getToken('foo') yield d.getToken('foo') yield self.assertFailure(d.getToken('foo'), NoTokensLeft) yield d.getToken('bar')
def test_getToken_replenish(self): """ Tokens are replenished over time. """ clock = task.Clock() d = TimedTokenDispenser(available=2, refresh=10, store=MemoryStore(clock), clock=clock) a = yield d.getToken('foo') clock.advance(5) a = yield d.getToken('foo') yield self.assertFailure(d.getToken('foo'), NoTokensLeft) clock.advance(5) yield d.getToken('foo') yield self.assertFailure(d.getToken('foo'), NoTokensLeft) clock.advance(5) yield d.getToken('foo')
def start(reactor): log.startLogging(sys.stdout) url = os.environ.get('DATABASE_URL', None) if url is None: raise Exception('You must set DATABASE_URL') captcha_private = os.environ.get('CAPTCHA_PRIVATE_KEY', None) if captcha_private is None: raise Exception("You must provide a CAPTCHA_PRIVATE_KEY") options = os.environ.get('VOTING_OPTIONS', '').split() if not options: raise Exception("You must provide a space-separated list of VOTING_OPTIONS") port = int(os.environ.get('PORT', 9003)) # Number of tokens per IP. In other words, you can have this many people # vote from the same IP for ever TOKEN_REFRESH_RATE seconds. tokens_per_ip = int(os.environ.get('TOKENS_PER_IP', 4)) # This is the number of seconds after which a token for a particular IP # can be used again. token_refresh_rate = int(os.environ.get('TOKEN_REFRESH_RATE', 60)) # Number of votes that can be cast per voting token. use_limit = len(options) / 2 # After a user gets a voting token, they have this many seconds to use it # before it won't work anymore. token_expiration = int(os.environ.get('TOKEN_EXPIRATION', 240)) engine = create_engine(url, reactor=reactor, strategy=TWISTED_STRATEGY) store = SQLVoteStore(engine, options) yield store.upgradeSchema() captcha_verifier = RecaptchaVerifier(captcha_private) dispenser = TimedTokenDispenser( available=tokens_per_ip, refresh=token_refresh_rate, use_limit=use_limit, expiration=token_expiration, store=MemoryStore(reactor), ) app = VoteCounter(store, dispenser, captcha_verifier, 'example.html') site = Site(app.app.resource()) reactor.listenTCP(port, site) yield defer.Deferred()
def test_useToken_uses(self): """ Tokens may only be used a certain number of times. """ d = TimedTokenDispenser(use_limit=3, store=MemoryStore(task.Clock()), clock=task.Clock()) token = yield d.getToken('foo') yield d.useToken(token) yield d.useToken(token) yield d.useToken(token) yield self.assertFailure(d.useToken(token), InvalidToken)
def test_getToken_bypass(self): """ You can bypass the getToken available amount. """ clock = task.Clock() d = TimedTokenDispenser(available=2, refresh=10, store=MemoryStore(clock), clock=clock) yield d.getToken('foo') clock.advance(5) yield d.getToken('foo') yield self.assertFailure(d.getToken('foo'), NoTokensLeft) yield d.getToken('foo', check_available=False)