snappass/tests.py

139 lines
5.2 KiB
Python
Raw Normal View History

2018-05-06 23:28:46 +02:00
from mock import patch
2016-10-25 01:21:08 +02:00
import time
2013-10-05 23:12:31 +02:00
import unittest
import uuid
2013-10-05 23:12:31 +02:00
from unittest import TestCase
from cryptography.fernet import Fernet
2016-07-18 22:36:06 +02:00
from werkzeug.exceptions import BadRequest
2018-05-06 23:28:46 +02:00
from mockredis import mock_strict_redis_client
2013-10-05 23:12:31 +02:00
2016-07-18 20:52:37 +02:00
# noinspection PyPep8Naming
2013-10-05 23:12:31 +02:00
import snappass.main as snappass
__author__ = 'davedash'
class SnapPassTestCase(TestCase):
2018-05-06 23:28:46 +02:00
@patch('redis.client.StrictRedis', mock_strict_redis_client)
2013-10-05 23:12:31 +02:00
def test_get_password(self):
password = "melatonin overdose 1337!$"
key = snappass.set_password(password, 30)
self.assertEqual(password, snappass.get_password(key))
# Assert that we can't look this up a second time.
self.assertIsNone(snappass.get_password(key))
2013-10-05 23:12:31 +02:00
def test_password_is_not_stored_in_plaintext(self):
password = "trustno1"
token = snappass.set_password(password, 30)
redis_key = token.split(snappass.TOKEN_SEPARATOR)[0]
stored_password_text = snappass.redis_client.get(redis_key).decode('utf-8')
self.assertNotIn(password, stored_password_text)
def test_returned_token_format(self):
password = "trustsome1"
token = snappass.set_password(password, 30)
token_fragments = token.split(snappass.TOKEN_SEPARATOR)
self.assertEqual(2, len(token_fragments))
redis_key, encryption_key = token_fragments
2018-07-01 19:19:56 +02:00
self.assertEqual(32 + len(snappass.REDIS_PREFIX), len(redis_key))
try:
Fernet(encryption_key.encode('utf-8'))
except ValueError:
self.fail('the encryption key is not valid')
def test_encryption_key_is_returned(self):
password = "trustany1"
token = snappass.set_password(password, 30)
token_fragments = token.split(snappass.TOKEN_SEPARATOR)
redis_key, encryption_key = token_fragments
stored_password = snappass.redis_client.get(redis_key)
fernet = Fernet(encryption_key.encode('utf-8'))
decrypted_password = fernet.decrypt(stored_password).decode('utf-8')
self.assertEqual(password, decrypted_password)
def test_unencrypted_passwords_still_work(self):
unencrypted_password = "trustevery1"
storage_key = uuid.uuid4().hex
snappass.redis_client.setex(storage_key, 30, unencrypted_password)
retrieved_password = snappass.get_password(storage_key)
self.assertEqual(unencrypted_password, retrieved_password)
def test_password_is_decoded(self):
password = "correct horse battery staple"
key = snappass.set_password(password, 30)
self.assertFalse(isinstance(snappass.get_password(key), bytes))
2013-10-05 23:12:31 +02:00
def test_clean_input(self):
# Test Bad Data
with snappass.app.test_request_context(
"/", data={'password': 'foo', 'ttl': 'bar'}, method='POST'):
2016-07-18 22:36:06 +02:00
self.assertRaises(BadRequest, snappass.clean_input)
2013-10-05 23:12:31 +02:00
# No Password
with snappass.app.test_request_context(
"/", method='POST'):
2016-07-18 22:36:06 +02:00
self.assertRaises(BadRequest, snappass.clean_input)
2013-10-05 23:12:31 +02:00
# No TTL
with snappass.app.test_request_context(
"/", data={'password': 'foo'}, method='POST'):
2016-07-18 22:36:06 +02:00
self.assertRaises(BadRequest, snappass.clean_input)
2013-10-05 23:12:31 +02:00
with snappass.app.test_request_context(
"/", data={'password': 'foo', 'ttl': 'hour'}, method='POST'):
self.assertEqual((3600, 'foo'), snappass.clean_input())
2016-10-25 01:21:08 +02:00
def test_password_before_expiration(self):
password = 'fidelio'
key = snappass.set_password(password, 1)
self.assertEqual(password, snappass.get_password(key))
def test_password_after_expiration(self):
password = 'open sesame'
key = snappass.set_password(password, 1)
time.sleep(1.5)
2018-05-06 23:28:46 +02:00
# Expire functionality must be explicitly invoked using do_expire(time).
# mockredis does not support automatic expiration at this time
snappass.redis_client.do_expire()
self.assertIsNone(snappass.get_password(key))
2016-10-25 01:21:08 +02:00
2013-10-05 23:12:31 +02:00
class SnapPassRoutesTestCase(TestCase):
2016-07-18 20:52:37 +02:00
# noinspection PyPep8Naming
2013-10-05 23:12:31 +02:00
def setUp(self):
snappass.app.config['TESTING'] = True
self.app = snappass.app.test_client()
def test_show_password(self):
password = "I like novelty kitten statues!"
key = snappass.set_password(password, 30)
rv = self.app.get('/{0}'.format(key))
self.assertIn(password, rv.get_data(as_text=True))
2013-10-05 23:12:31 +02:00
def test_bots_denial(self):
"""
Main known bots User-Agent should be denied access
"""
password = "Bots can't access this"
key = snappass.set_password(password, 30)
a_few_sneaky_bots = [
"Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots)",
"facebookexternalhit/1.1",
"Facebot/1.0",
"Twitterbot/1.0",
"_WhatsApp/2.12.81 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00",
2017-02-18 04:48:10 +01:00
"WhatsApp/2.16.6/i",
"SkypeUriPreview Preview/0.5",
"Iframely/0.8.5 (+http://iframely.com/;)",
]
for ua in a_few_sneaky_bots:
2018-07-01 19:19:56 +02:00
rv = self.app.get('/{0}'.format(key), headers={'User-Agent': ua})
self.assertEqual(404, rv.status_code)
2013-10-05 23:12:31 +02:00
if __name__ == '__main__':
unittest.main()