# HG changeset patch # User Daniele Nicolodi # Date 1313935823 -7200 # Node ID 5a3c9177191453f461c90cf97887dc441f71f6c5 # Parent da7cab4398c3e592eee59b9329dc3b1d4ae7d8e3 Add message signing and timestamping utility. Based on itsdangerous: http://packages.python.org/itsdangerous/ diff -r da7cab4398c3 -r 5a3c91771914 buildout.cfg --- a/buildout.cfg Sun Aug 21 16:10:23 2011 +0200 +++ b/buildout.cfg Sun Aug 21 16:10:23 2011 +0200 @@ -9,6 +9,7 @@ WTForms ordereddict argparse + itsdangerous ltpdarepo interpreter = python diff -r da7cab4398c3 -r 5a3c91771914 src/ltpdarepo/sign.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ltpdarepo/sign.py Sun Aug 21 16:10:23 2011 +0200 @@ -0,0 +1,24 @@ +from flask import current_app as app, request +from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired + + +class Signer(URLSafeTimedSerializer): + """Subclass `itsdangerouns.URLSafeTimedSerializer` setting the + default secret to the application secret key and the salt to + `request.host`. Overrides `dumps()` and `loads()` methods with + custom versions that substitute `~` for `_` in the signed string.""" + + def __init__(self, secret=None, salt=None): + if secret is None: + secret = app.config['SECRET_KEY'] + if salt is None: + salt = request.host + super(Signer, self).__init__(secret, salt) + + def dumps(self, obj): + string = super(Signer, self).dumps(obj) + return string.replace('_', '~') + + def loads(self, string, maxage=None): + string = string.replace('~', '_') + return super(Signer, self).loads(string, max_age=maxage) diff -r da7cab4398c3 -r 5a3c91771914 src/ltpdarepo/tests/test_sign.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ltpdarepo/tests/test_sign.py Sun Aug 21 16:10:23 2011 +0200 @@ -0,0 +1,23 @@ +import unittest2 as unittest + +from ltpdarepo.sign import Signer, BadSignature + +class TestCase(unittest.TestCase): + + def test_signer(self): + s = Signer('secret', 'salt') + value = 'foo' + token = s.dumps(value) + self.assertEqual(s.loads(token), value) + + def test_tempering(self): + s = Signer('secret', 'salt') + value = 'foo' + token = s.dumps(value) + val, timestamp, signature = token.split('.') + val = val.replace(val[0], val[1]) + self.assertRaises(BadSignature, lambda: s.loads('.'.join((val, timestamp, signature)))) + timestamp = timestamp.replace(timestamp[0], timestamp[1]) + self.assertRaises(BadSignature, lambda: s.loads('.'.join((val, timestamp, signature)))) + signature = signature.replace(signature[0], signature[1]) + self.assertRaises(BadSignature, lambda: s.loads('.'.join((val, timestamp, signature))))