[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