From 2af7037febd52150acf5f957f6de7c9968cd4d85 Mon Sep 17 00:00:00 2001 From: Jeremiah Lee Date: Fri, 8 May 2020 11:43:54 -0700 Subject: [PATCH] Adds option for two-week timeout. (#120) Also includes: - Updated the versions in the requirements, as MarkupSafe did not install cleanly. - Integration test that sets a password via the website, and then verifies the timeout on the backend. - Basic Makefile, updates to the docs to use the Makefile. The requirements file was updated using pip freeze after I had updated the version of MarkupSafe. I don't know what the usual process is for this repo, so please let me know if I should use a different process there (that is why there are a few additions). --- CONTRIBUTING.rst | 29 ++++++++++++++-------------- Makefile | 13 +++++++++++++ dev-requirements.txt | 9 ++++++--- requirements.txt | 19 +++++++++++------- snappass/main.py | 4 ++-- snappass/templates/set_password.html | 3 ++- tests.py | 21 +++++++++++++++++++- 7 files changed, 70 insertions(+), 28 deletions(-) create mode 100644 Makefile diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index eb86ba9..1698507 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -77,7 +77,7 @@ Here's how to set up ``snappass`` for local development. $ mkvirtualenv snappass $ cd snappass/ $ python setup.py develop - $ pip install -r dev-requirements.txt + $ make dev 4. Create a branch for local development:: @@ -85,35 +85,36 @@ Here's how to set up ``snappass`` for local development. Now you can make your changes locally. -5. You can test your changes in a development server with debug and autoreload:: +5. You run a development server with debug and autoreload to manually verify:: $ docker run -d --name redis-server -p 6379:6379 redis - $ export FLASK_DEBUG=1 && \ - export FLASK_APP=snappass.main && \ - export NO_SSL=True - $ flask run + $ make run You now have a running instance on localhost:5000/ -6. When you're done making changes, check that your changes pass the tests and +6. Please add some tests to tests.py and run tests:: + + $ make test + +7. When you're done making changes, check that your changes pass the tests and flake8:: $ flake8 snappass tests.py setup.py $ tox -7. Commit your changes and push your branch to GitHub:: - - $ git add . - $ git commit -m "Your detailed description of your changes." - $ git push origin name-of-your-bugfix-or-feature - 8. Check that the test coverage hasn't dropped:: $ coverage run --source snappass tests.py $ coverage report -m $ coverage html -9. Submit a pull request through the GitHub website. +9. Commit your changes and push your branch to GitHub:: + + $ git add . + $ git commit -m "Your detailed description of your changes." + $ git push origin name-of-your-bugfix-or-feature + +10. Submit a pull request through the GitHub website. Pull Request Guidelines ----------------------- diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..aa0c805 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +.PHONY: dev prod run test + +dev: dev-requirements.txt + pip install -r dev-requirements.txt + +prod: requirements.txt + pip install -r requirements.txt + +run: prod + FLASK_DEBUG=1 FLASK_APP=snappass.main NO_SSL=True venv/bin/flask run + +test: + PYTHONPATH=snappass venv/bin/nosetests -s tests diff --git a/dev-requirements.txt b/dev-requirements.txt index e3f9eb1..99d441b 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,6 +1,9 @@ -pytest==3.6.3 -pytest-cov==2.5.1 -fakeredis==0.7.0 coverage==4.5.1 +fakeredis==0.7.0 flake8==3.5.0 +freezegun==0.3.15 +mock==2.0.0 +nose==1.3.7 +pytest-cov==2.5.1 +pytest==3.6.3 tox==3.1.2 diff --git a/requirements.txt b/requirements.txt index e8345c2..2d820b1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,13 @@ -Flask==1.0.2 -Jinja2==2.10.1 -MarkupSafe==1.0 -Werkzeug==0.15.6 -itsdangerous==0.24 -redis==2.10.6 +asn1crypto==1.3.0 +cffi==1.14.0 +click==7.1.2 cryptography==2.3.1 -mock==2.0.0 +Flask==1.0.2 +idna==2.9 +itsdangerous==0.24 +Jinja2==2.10.1 +MarkupSafe==1.1.1 +pycparser==2.20 +redis==2.10.6 +six==1.14.0 +Werkzeug==0.15.6 diff --git a/snappass/main.py b/snappass/main.py index 17f72e5..7339333 100644 --- a/snappass/main.py +++ b/snappass/main.py @@ -1,5 +1,4 @@ import os -import re import sys import uuid @@ -38,7 +37,7 @@ else: host=redis_host, port=redis_port, db=redis_db) REDIS_PREFIX = os.environ.get('REDIS_PREFIX', 'snappass') -TIME_CONVERSION = {'week': 604800, 'day': 86400, 'hour': 3600} +TIME_CONVERSION = {'two weeks': 1209600, 'week': 604800, 'day': 86400, 'hour': 3600} def check_redis_alive(fn): @@ -129,6 +128,7 @@ def password_exists(token): storage_key, decryption_key = parse_token(token) return redis_client.exists(storage_key) + def empty(value): if not value: return True diff --git a/snappass/templates/set_password.html b/snappass/templates/set_password.html index 0282c51..d332ace 100644 --- a/snappass/templates/set_password.html +++ b/snappass/templates/set_password.html @@ -15,7 +15,8 @@
diff --git a/tests.py b/tests.py index b8e147d..759cea9 100644 --- a/tests.py +++ b/tests.py @@ -1,10 +1,13 @@ from mock import patch +import re import time import unittest import uuid from unittest import TestCase +from urllib.parse import unquote from cryptography.fernet import Fernet +from freezegun import freeze_time from werkzeug.exceptions import BadRequest from fakeredis import FakeStrictRedis @@ -117,9 +120,25 @@ class SnapPassRoutesTestCase(TestCase): def test_url_prefix(self): password = "I like novelty kitten statues!" - snappass.URL_PREFIX="/test/prefix" + snappass.URL_PREFIX = "/test/prefix" rv = self.app.post('/', data={'password': password, 'ttl': 'hour'}) self.assertIn("localhost/test/prefix/", rv.get_data(as_text=True)) + def test_set_password(self): + with freeze_time("2020-05-08 12:00:00") as frozen_time: + password = 'my name is my passport. verify me.' + rv = self.app.post('/', data={'password': password, 'ttl': 'two weeks'}) + + html_content = rv.data.decode("ascii") + key = re.search(r'id="password-link" value="https://localhost/([^"]+)', html_content).group(1) + key = unquote(key) + + frozen_time.move_to("2020-05-22 11:59:59") + self.assertEqual(snappass.get_password(key), password) + + frozen_time.move_to("2020-05-22 12:00:00") + self.assertIsNone(snappass.get_password(key)) + + if __name__ == '__main__': unittest.main()