def verifyOtp(self, user, otpToken): lastCounterKey = 'girder.models.user.%s.otp.totp.counter' % user['_id'] # The last successfully-authenticated key (which is blacklisted from reuse) lastCounter = rateLimitBuffer.get(lastCounterKey) or None try: totpMatch = self._TotpFactory.verify( otpToken, user['otp']['totp'], last_counter=lastCounter) except TokenError as e: raise AccessException('One-time password validation failed: %s' % e) # The totpMatch.cache_seconds tells us prospectively how long the counter needs to be cached # for, but dogpile.cache expiration times work retrospectively (on "get"), so there's no # point to using it (over-caching just wastes cache resources, but does not impact # "totp.verify" security) rateLimitBuffer.set(lastCounterKey, totpMatch.counter)