def test_ctor_w_period(self): self.assertEqual(TOTP(KEY1).period, 30) self.assertEqual(TOTP(KEY1, period=63).period, 63) self.assertRaises(TypeError, TOTP, KEY1, period=1.5) self.assertRaises(TypeError, TOTP, KEY1, period='abc') self.assertRaises(ValueError, TOTP, KEY1, period=0) self.assertRaises(ValueError, TOTP, KEY1, period=-1)
def test_to_uri(self): otp = TOTP(KEY4, alg='sha1', digits=6, period=30) self.assertEqual( otp.to_uri('*****@*****.**', 'Example Org'), 'otpauth://totp/[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example%20Org' ) self.assertRaises(ValueError, otp.to_uri, None, 'Example Org') self.assertEqual( otp.to_uri('*****@*****.**'), 'otpauth://totp/[email protected]?secret=JBSWY3DPEHPK3PXP') otp.label = '*****@*****.**' self.assertEqual( otp.to_uri(), 'otpauth://totp/[email protected]?secret=JBSWY3DPEHPK3PXP') otp.issuer = 'Example Org' self.assertEqual( otp.to_uri(), 'otpauth://totp/[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example%20Org' ) self.assertRaises(ValueError, otp.to_uri, 'label:with:semicolons') self.assertRaises(ValueError, otp.to_uri, '*****@*****.**', 'issuer:with:semicolons') self.assertEqual( TOTP(KEY4, alg='sha256').to_uri('*****@*****.**'), 'otpauth://totp/[email protected]?secret=JBSWY3DPEHPK3PXP&algorithm=SHA256' ) self.assertEqual( TOTP(KEY4, digits=8).to_uri('*****@*****.**'), 'otpauth://totp/[email protected]?secret=JBSWY3DPEHPK3PXP&digits=8') self.assertEqual( TOTP(KEY4, period=63).to_uri('*****@*****.**'), 'otpauth://totp/[email protected]?secret=JBSWY3DPEHPK3PXP&period=63' ) return
def test_ctor_w_key_and_format(self): self.assertEqual(TOTP(KEY1).key, KEY1_RAW) self.assertEqual(TOTP(KEY1.lower()).key, KEY1_RAW) self.assertEqual(TOTP(' 4aog gdbb qsyh ntuz ').key, KEY1_RAW) self.assertRaises(Base32DecodeError, TOTP, 'ao!ggdbbqsyhntuz') self.assertEqual(TOTP('e01c630c2184b076ce99', 'hex').key, KEY1_RAW) self.assertRaises(Base16DecodeError, TOTP, 'X01c630c2184b076ce99', 'hex') self.assertEqual(TOTP(KEY1_RAW, 'raw').key, KEY1_RAW)
def test_key_attrs(self): rng = self.getRandom() otp = TOTP(KEY1_RAW, 'raw') self.assertEqual(otp.key, KEY1_RAW) self.assertEqual(otp.hex_key, 'e01c630c2184b076ce99') self.assertEqual(otp.base32_key, KEY1) self.assertEqual(otp.pretty_key(), '4AOG-GDBB-QSYH-NTUZ') self.assertEqual(otp.pretty_key(sep=' '), '4AOG GDBB QSYH NTUZ') self.assertEqual(otp.pretty_key(sep=False), KEY1) self.assertEqual(otp.pretty_key(format='hex'), 'e01c-630c-2184-b076-ce99') otp = TOTP(new=True, size=rng.randint(10, 20)) _ = otp.hex_key _ = otp.base32_key _ = otp.pretty_key()
def test_totp_token(self): from otp.ai.passlib.totp import TOTP, TotpToken otp = TOTP('s3jdvb7qd2r7jpxx') result = otp.generate(1419622739) self.assertIsInstance(result, TotpToken) self.assertEqual(result.token, '897212') self.assertEqual(result.counter, 47320757) self.assertEqual(result.expire_time, 1419622740) self.assertEqual(result, ('897212', 1419622740)) self.assertEqual(len(result), 2) self.assertEqual(result[0], '897212') self.assertEqual(result[1], 1419622740) self.assertRaises(IndexError, result.__getitem__, -3) self.assertRaises(IndexError, result.__getitem__, 2) self.assertTrue(result) otp.now = lambda: 1419622739.5 self.assertEqual(result.remaining, 0.5) self.assertTrue(result.valid) otp.now = lambda: 1419622741 self.assertEqual(result.remaining, 0) self.assertFalse(result.valid) result2 = otp.generate(1419622739) self.assertIsNot(result2, result) self.assertEqual(result2, result) result3 = otp.generate(1419622711) self.assertIsNot(result3, result) self.assertEqual(result3, result) result4 = otp.generate(1419622999) self.assertNotEqual(result4, result)
def test_using_w_period(self): self.assertEqual(TOTP(KEY1).period, 30) self.assertEqual(TOTP.using(period=63)(KEY1).period, 63) self.assertRaises(TypeError, TOTP.using, period=1.5) self.assertRaises(TypeError, TOTP.using, period='abc') self.assertRaises(ValueError, TOTP.using, period=0) self.assertRaises(ValueError, TOTP.using, period=-1)
def test_match_w_token_normalization(self): otp = TOTP('otxl2f5cctbprpzx') match = otp.match time = 1412889861 self.assertTrue(match(' 3 32-136 ', time)) self.assertTrue(match('332136', time)) self.assertRaises(exc.MalformedTokenError, match, '12345', time) self.assertRaises(exc.MalformedTokenError, match, '12345X', time) self.assertRaises(exc.MalformedTokenError, match, '0123456', time)
def test_generate(self): from otp.ai.passlib.totp import TOTP otp = TOTP(new=True) time = self.randtime() result = otp.generate(time) token = result.token self.assertIsInstance(token, unicode) start_time = result.counter * 30 self.assertEqual(otp.generate(start_time + 29).token, token) self.assertNotEqual(otp.generate(start_time + 30).token, token) dt = datetime.datetime.utcfromtimestamp(time) self.assertEqual(int(otp.normalize_time(dt)), int(time)) self.assertEqual(otp.generate(dt).token, token) otp2 = TOTP.using(now=lambda: time)(key=otp.base32_key) self.assertEqual(otp2.generate().token, token) self.assertRaises(ValueError, otp.generate, -1)
def iter_test_vectors(self): from otp.ai.passlib.totp import TOTP for row in self.vectors: kwds = self.vector_defaults.copy() kwds.update(row[0]) for entry in row[1:]: if len(entry) == 3: time, token, expires = entry else: time, token = entry expires = None log.debug('test vector: %r time=%r token=%r expires=%r', kwds, time, token, expires) otp = TOTP(**kwds) prefix = 'alg=%r time=%r token=%r: ' % (otp.alg, time, token) yield (otp, time, token, expires, prefix) return
def test_ctor_w_size(self): self.assertEqual(len(TOTP(new=True, alg='sha1').key), 20) self.assertEqual(len(TOTP(new=True, alg='sha256').key), 32) self.assertEqual(len(TOTP(new=True, alg='sha512').key), 64) self.assertEqual(len(TOTP(new=True, size=10).key), 10) self.assertEqual(len(TOTP(new=True, size=16).key), 16) self.assertRaises(ValueError, TOTP, new=True, size=21, alg='sha1') self.assertRaises(ValueError, TOTP, new=True, size=9) with self.assertWarningList([ dict( category=exc.PasslibSecurityWarning, message_re='.*for security purposes, secret key must be.*') ]): _ = TOTP('0A0A0A0A0A0A0A0A0A', 'hex')
def test_to_dict(self): otp = TOTP(KEY4, alg='sha1', digits=6, period=30) self.assertEqual(otp.to_dict(), dict(v=1, type='totp', key=KEY4)) otp = TOTP(KEY4, alg='sha1', digits=6, period=30, label='*****@*****.**', issuer='Example Org') self.assertEqual( otp.to_dict(), dict(v=1, type='totp', key=KEY4, label='*****@*****.**', issuer='Example Org')) otp = TOTP(KEY4, alg='sha1', digits=6, period=30, label='*****@*****.**') self.assertEqual( otp.to_dict(), dict(v=1, type='totp', key=KEY4, label='*****@*****.**')) otp = TOTP(KEY4, alg='sha1', digits=6, period=30, issuer='Example Org') self.assertEqual( otp.to_dict(), dict(v=1, type='totp', key=KEY4, issuer='Example Org')) TotpFactory = TOTP.using(issuer='Example Org') otp = TotpFactory(KEY4) self.assertEqual(otp.to_dict(), dict(v=1, type='totp', key=KEY4)) otp = TotpFactory(KEY4, issuer='Example Org') self.assertEqual(otp.to_dict(), dict(v=1, type='totp', key=KEY4)) self.assertEqual( TOTP(KEY4, alg='sha256').to_dict(), dict(v=1, type='totp', key=KEY4, alg='sha256')) self.assertEqual( TOTP(KEY4, digits=8).to_dict(), dict(v=1, type='totp', key=KEY4, digits=8)) self.assertEqual( TOTP(KEY4, period=63).to_dict(), dict(v=1, type='totp', key=KEY4, period=63))
def test_ctor_w_issuer(self): self.assertEqual(TOTP(KEY1).issuer, None) self.assertEqual(TOTP(KEY1, issuer='foo.com').issuer, 'foo.com') self.assertRaises(ValueError, TOTP, KEY1, issuer='foo.com:bar') return
def test_ctor_w_label(self): self.assertEqual(TOTP(KEY1).label, None) self.assertEqual(TOTP(KEY1, label='foo@bar').label, 'foo@bar') self.assertRaises(ValueError, TOTP, KEY1, label='foo:bar') return
def test_ctor_w_digits(self): self.assertRaises(ValueError, TOTP, KEY1, digits=5) self.assertEqual(TOTP(KEY1, digits=6).digits, 6) self.assertEqual(TOTP(KEY1, digits=10).digits, 10) self.assertRaises(ValueError, TOTP, KEY1, digits=11)
def test_ctor_w_alg(self): self.assertEqual(TOTP(KEY1, alg='SHA-256').alg, 'sha256') self.assertEqual(TOTP(KEY1, alg='SHA256').alg, 'sha256') self.assertRaises(ValueError, TOTP, KEY1, alg='SHA-333')
def test_ctor_w_new(self): self.assertRaises(TypeError, TOTP) self.assertRaises(TypeError, TOTP, key='4aoggdbbqsyhntuz', new=True) otp = TOTP(new=True) otp2 = TOTP(new=True) self.assertNotEqual(otp.key, otp2.key)