[Repoze-checkins] r1146 - in repoze.browserid/trunk: . repoze/browserid
Chris McDonough
chrism at agendaless.com
Fri Jun 27 15:13:01 EDT 2008
Author: Chris McDonough <chrism at agendaless.com>
Date: Fri Jun 27 15:13:00 2008
New Revision: 1146
Log:
Initial release
Modified:
repoze.browserid/trunk/CHANGES.txt
repoze.browserid/trunk/README.txt
repoze.browserid/trunk/repoze/browserid/middleware.py
repoze.browserid/trunk/repoze/browserid/tests.py
repoze.browserid/trunk/setup.py
Modified: repoze.browserid/trunk/CHANGES.txt
==============================================================================
--- repoze.browserid/trunk/CHANGES.txt (original)
+++ repoze.browserid/trunk/CHANGES.txt Fri Jun 27 15:13:00 2008
@@ -1,3 +1,4 @@
-Unreleased (some date)
+0.1 (2008-06-27)
+
+ First release.
- First release
Modified: repoze.browserid/trunk/README.txt
==============================================================================
--- repoze.browserid/trunk/README.txt (original)
+++ repoze.browserid/trunk/README.txt Fri Jun 27 15:13:00 2008
@@ -1,69 +1,113 @@
+*************************
repoze.browserid Overview
+*************************
- Browser id middleware for WSGI, loosely based on the Zope 2 concept
- of browser ids, which are cookies which represent a browser, for use
- by sessioning libraries.
-
-Browser Ids
-
- The concept of a browser id is simple: every request to an
- application which is fronted by the browser id middleware will
- include a browser id within the WSGI environment. A browser id is
- an opaque string that is guaranteed to be unique within the set of
- all individual user agents which visit the application over the
- lifetime of that application. This string is most useful as a key
- in a sessioning system.
-
- If a user agent contacts the application but does not supply a
- browser id, one will be manufactured for the current request, and a
- Set-Cookie header will be returned to the user agent, which it will
- (hopefully) return on subsequent requests.
-
- If the user agent does supply a cookie containing a browser id but
- the cookie value is tampered with by the user or by some middleman,
- it will be rejected, and a new browser id will be constructed for
- the current request.
-
- We set the browser id value as 'repoze.browserid' in the WSGI
- environ before we call the downstream application. It is a
- 40-character string.
+Browser id middleware for WSGI, loosely based on the Zope 2 concept
+of browser ids, which are cookies which represent a browser, for use
+by sessioning libraries.
+
+Browser Id
+==========
+
+The concept of a browser id is simple: every request to an application
+which is fronted by the browser id middleware will include a browser
+id within the WSGI environment. A browser id is an opaque string that
+is guaranteed to be unique within the set of all individual user
+agents which visit the application over the lifetime of that
+application. This string is most useful as a key in a sessioning
+system.
+
+If a user agent contacts the application but does not supply a browser
+id, one will be manufactured for the current request, and a Set-Cookie
+header will be returned to the user agent, which it will (hopefully)
+return on subsequent requests.
+
+If the user agent does supply a cookie containing a browser id but the
+cookie value is tampered with by the user or by some middleman, it
+will be rejected, and a new browser id will be constructed for the
+current request.
+
+We set the browser id value as ``repoze.browserid`` in the WSGI environ
+before we call the downstream application. It is a 40-character
+string.
Uniqueness
+==========
- The browser id machinery guarantees uniqueness of browser ids by
- composing the browser id out of three coponents: a random component,
- a time component, and a component representing the pid of the
- process serving the application. The "true" randomness of the
- random component is guaranteed within a one-second window by
- specialized code, which, when coupled with the time component,
- guarantees good uniqueness of browser ids.
+The browser id machinery guarantees uniqueness of browser ids by
+composing the browser id out of three coponents: a random component, a
+time component, and a component representing the pid of the process
+serving the application. The "true" randomness of the random
+component is guaranteed within a one-second window by specialized
+code, which, when coupled with the time component, guarantees good
+uniqueness of browser ids.
Tamper Checking and Varying
+===========================
- The cookie set by the browser id middleware is forgery-resistant.
+The cookie set by the browser id middleware is forgery-resistant.
- The cookie value of Set-Cookie headers created by the middleware is
- composed of three parts: the browser id (a unique 40-character
- string), a delimiter ("!"), and an HMAC of the browser id serialized
- as a 32-character string.
-
- When configuring the browserid middleware, you must supply a secret
- key. The middleware uses the secret key and "vary" values to
- compose the "tamper key" when creating a browser id. The tamper key
- is composed of the secret key concatenated with values provided in
- the environment. Varying allows a configurer to vary the tamper key
- on, e.g. 'REMOTE_ADDR' if he believes that the same browser id
- should always be sent from the same IP address, or 'HTTP_USER_AGENT'
- if he believes it should always come from the same user agent, or
- some arbitrary combination thereof made out of environ keys.
-
- When the cookie is composed, An HMAC of the browser id is computed
- using the tamper key. The HMAC is appended to the browser id after
- a delimiter character. When a browser id is retrieved from a user
- agent, the HMAC portion is separated from the browser id and a new
- HMAC using the same secret key and vary values is computed. If the
- cookie HMAC matches the computed HMAC, the cookie hasn't been
- tampered with, and the browser id portion of the cookie becomes the
- browser id for the current request. If they differ, a new browser
- id is generated.
+The cookie value of Set-Cookie headers created by the middleware is
+composed of three parts: the browser id (a unique 40-character
+string), a delimiter ("!"), and an HMAC of the browser id serialized
+as a 32-character string.
+
+When configuring the browserid middleware, you must supply a secret
+key. The middleware uses the secret key and "vary" values to compose
+the "tamper key" when creating a browser id. The tamper key is
+composed of the secret key concatenated with values provided in the
+environment. Varying allows a configurer to vary the tamper key on,
+e.g. ``REMOTE_ADDR`` if he believes that the same browser id should
+always be sent from the same IP address, or ``HTTP_USER_AGENT`` if he
+believes it should always come from the same user agent, or some
+arbitrary combination thereof made out of environ keys.
+
+When the cookie is composed, An HMAC of the browser id is computed
+using the tamper key. The HMAC is appended to the browser id after a
+delimiter character. When a browser id is retrieved from a user
+agent, the HMAC portion is separated from the browser id and a new
+HMAC using the same secret key and vary values is computed. If the
+cookie HMAC matches the computed HMAC, the cookie hasn't been tampered
+with, and the browser id portion of the cookie becomes the browser id
+for the current request. If they differ, a new browser id is
+generated.
+
+Configuration
+=============
+
+Configuration via Python
+------------------------
+
+Wire up the middleware in your application::
+
+ from repoze.browserid.middleware import BrowserIdMiddleware
+ middleware = BrowserIdMiddleware(app, secret_key='foo,
+ cookie_name='repoze.browserid',
+ cookie_path='/',
+ cookie_domain=None,
+ cookie_lifetime=None,
+ cookie_secure=None,
+ vary=())
+
+
+Configuration via Paste
+------------------------
+
+Use the ``egg:repoze.browserid#browserid`` entry point in your Paste
+configuration, eg.::
+
+ [filter:browserid]
+ use = egg:repoze.browserid#browserid
+ secret_key = foo
+
+ [pipeline:main]
+ pipeline = egg:Paste#cgitb
+ browserid
+ myapp
+
+Reporting Bugs / Development Versions
+=====================================
+
+Visit http://bugs.repoze.org to report bugs. Visit
+http://svn.repoze.org to download development or tagged versions.
Modified: repoze.browserid/trunk/repoze/browserid/middleware.py
==============================================================================
--- repoze.browserid/trunk/repoze/browserid/middleware.py (original)
+++ repoze.browserid/trunk/repoze/browserid/middleware.py Fri Jun 27 15:13:00 2008
@@ -206,3 +206,27 @@
if hasattr(write, 'close'):
write.close()
+def asbool(val):
+ if isinstance(val, bool):
+ return val
+ val= str(val)
+ if val.lower() in ('y', 'yes', 'true', 't'):
+ return True
+ return False
+
+def make_middleware(app, global_conf, secret_key,
+ cookie_name='repoze.browserid',
+ cookie_path='/', cookie_domain=None,
+ cookie_lifetime=None, cookie_secure=False,
+ vary=None):
+ if cookie_lifetime:
+ cookie_lifetime = int(cookie_lifetime)
+ cookie_secure = asbool(cookie_secure)
+ if vary:
+ vary = tuple([ x.strip() for x in vary.split() ])
+ else:
+ vary = ()
+ return BrowserIdMiddleware(app, secret_key, cookie_name, cookie_path,
+ cookie_domain, cookie_lifetime, cookie_secure,
+ vary)
+
Modified: repoze.browserid/trunk/repoze/browserid/tests.py
==============================================================================
--- repoze.browserid/trunk/repoze/browserid/tests.py (original)
+++ repoze.browserid/trunk/repoze/browserid/tests.py Fri Jun 27 15:13:00 2008
@@ -240,6 +240,31 @@
self.assertEqual(datases[0], 'written')
self.assertEqual(closededs[0], True)
+class TestMakeMiddleware(unittest.TestCase):
+ def _getFUT(self):
+ from repoze.browserid.middleware import make_middleware
+ return make_middleware
+
+ def test_defaults(self):
+ f = self._getFUT()
+ mw = f(None, None, 'secret')
+ self.assertEqual(mw.secret_key, 'secret')
+ self.assertEqual(mw.vary, ())
+
+ def test_overrides(self):
+ f = self._getFUT()
+ mw = f(None, None, 'secret', cookie_name='jar',
+ cookie_path='/foo', cookie_domain='.foo.com',
+ cookie_lifetime = '10',
+ cookie_secure = 'true',
+ )
+ self.assertEqual(mw.secret_key, 'secret')
+ self.assertEqual(mw.vary, ())
+ self.assertEqual(mw.cookie_name, 'jar')
+ self.assertEqual(mw.cookie_path, '/foo')
+ self.assertEqual(mw.cookie_lifetime, 10)
+ self.assertEqual(mw.cookie_secure, True)
+
class DummyTime:
def __init__(self, timetime, gmtime=None, strftime=None):
self._timetime = timetime
Modified: repoze.browserid/trunk/setup.py
==============================================================================
--- repoze.browserid/trunk/setup.py (original)
+++ repoze.browserid/trunk/setup.py Fri Jun 27 15:13:00 2008
@@ -23,22 +23,24 @@
here = os.path.abspath(os.path.dirname(__file__))
README = open(os.path.join(here, 'README.txt')).read()
+CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
setup(name='repoze.browserid',
version=__version__,
- description=('repoze.browserid is a browser identification system for '
- 'WSGI.'),
- long_description=README,
+ description=('repoze.browserid WSGI middleware tags browsers with an '
+ 'identifier cookie for use in sessioning and other'
+ 'browser-identity-sensitive systems.'),
+ long_description=README + '\n\n' + CHANGES,
classifiers=[
- "Development Status :: 1 - Planning",
+ "Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Programming Language :: Python",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
"Topic :: Internet :: WWW/HTTP :: WSGI",
- "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
+ "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware",
],
- keywords='web application server wsgi zope',
+ keywords='application server wsgi middleware sessions browserid',
author="Agendaless Consulting",
author_email="repoze-dev at lists.repoze.org",
url="http://www.repoze.org",
@@ -51,6 +53,8 @@
install_requires=['Paste'],
test_suite="repoze.browserid.tests",
entry_points = """\
+ [paste.filter_app_factory]
+ browserid = repoze.browserid.middleware:make_middleware
"""
)
More information about the Repoze-checkins
mailing list