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).
This commit is contained in:
Jeremiah Lee 2020-05-08 11:43:54 -07:00 committed by GitHub
parent 9cb554ca7e
commit 2af7037feb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 70 additions and 28 deletions

View file

@ -77,7 +77,7 @@ Here's how to set up ``snappass`` for local development.
$ mkvirtualenv snappass $ mkvirtualenv snappass
$ cd snappass/ $ cd snappass/
$ python setup.py develop $ python setup.py develop
$ pip install -r dev-requirements.txt $ make dev
4. Create a branch for local development:: 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. 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 $ docker run -d --name redis-server -p 6379:6379 redis
$ export FLASK_DEBUG=1 && \ $ make run
export FLASK_APP=snappass.main && \
export NO_SSL=True
$ flask run
You now have a running instance on localhost:5000/ 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::
$ flake8 snappass tests.py setup.py $ flake8 snappass tests.py setup.py
$ tox $ 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:: 8. Check that the test coverage hasn't dropped::
$ coverage run --source snappass tests.py $ coverage run --source snappass tests.py
$ coverage report -m $ coverage report -m
$ coverage html $ 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 Pull Request Guidelines
----------------------- -----------------------

13
Makefile Normal file
View file

@ -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

View file

@ -1,6 +1,9 @@
pytest==3.6.3
pytest-cov==2.5.1
fakeredis==0.7.0
coverage==4.5.1 coverage==4.5.1
fakeredis==0.7.0
flake8==3.5.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 tox==3.1.2

View file

@ -1,8 +1,13 @@
Flask==1.0.2 asn1crypto==1.3.0
Jinja2==2.10.1 cffi==1.14.0
MarkupSafe==1.0 click==7.1.2
Werkzeug==0.15.6
itsdangerous==0.24
redis==2.10.6
cryptography==2.3.1 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

View file

@ -1,5 +1,4 @@
import os import os
import re
import sys import sys
import uuid import uuid
@ -38,7 +37,7 @@ else:
host=redis_host, port=redis_port, db=redis_db) host=redis_host, port=redis_port, db=redis_db)
REDIS_PREFIX = os.environ.get('REDIS_PREFIX', 'snappass') 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): def check_redis_alive(fn):
@ -129,6 +128,7 @@ def password_exists(token):
storage_key, decryption_key = parse_token(token) storage_key, decryption_key = parse_token(token)
return redis_client.exists(storage_key) return redis_client.exists(storage_key)
def empty(value): def empty(value):
if not value: if not value:
return True return True

View file

@ -15,7 +15,8 @@
<div class="col-sm-2 margin-bottom-10"> <div class="col-sm-2 margin-bottom-10">
<select class="form-control" name="ttl"> <select class="form-control" name="ttl">
<option value="Week">Week</option> <option value="Two Weeks">Two Weeks</option>
<option value="Week" selected="selected">Week</option>
<option value="Day">Day</option> <option value="Day">Day</option>
<option value="Hour">Hour</option> <option value="Hour">Hour</option>
</select> </select>

View file

@ -1,10 +1,13 @@
from mock import patch from mock import patch
import re
import time import time
import unittest import unittest
import uuid import uuid
from unittest import TestCase from unittest import TestCase
from urllib.parse import unquote
from cryptography.fernet import Fernet from cryptography.fernet import Fernet
from freezegun import freeze_time
from werkzeug.exceptions import BadRequest from werkzeug.exceptions import BadRequest
from fakeredis import FakeStrictRedis from fakeredis import FakeStrictRedis
@ -117,9 +120,25 @@ class SnapPassRoutesTestCase(TestCase):
def test_url_prefix(self): def test_url_prefix(self):
password = "I like novelty kitten statues!" 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'}) rv = self.app.post('/', data={'password': password, 'ttl': 'hour'})
self.assertIn("localhost/test/prefix/", rv.get_data(as_text=True)) 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__': if __name__ == '__main__':
unittest.main() unittest.main()