Commit 33444d0e authored by Tres Seaver's avatar Tres Seaver

Extended BrowserIdManager to expose the 'HTTPOnly' attribute for its cookie.

o Via https://bugs.launchpad.net/zope2/+bug/367393 
parent fc6779e8
......@@ -21,6 +21,9 @@ Restructuring
Features Added
++++++++++++++
- Extended BrowserIdManager to expose the 'HTTPOnly' attribute for its
cookie. Also via https://bugs.launchpad.net/zope2/+bug/367393 .
- Addeed support for an optional 'HTTPOnly' attribute of cookies (see
http://www.owasp.org/index.php/HTTPOnly). Patch from Stephan Hofmockel,
via https://bugs.launchpad.net/zope2/+bug/367393 .
......
......@@ -70,12 +70,13 @@ LOG = logging.getLogger('Zope.BrowserIdManager')
def constructBrowserIdManager(
self, id=BROWSERID_MANAGER_NAME, title='', idname='_ZopeId',
location=('cookies', 'form'), cookiepath='/', cookiedomain='',
cookielifedays=0, cookiesecure=0, auto_url_encoding=0, REQUEST=None
cookielifedays=0, cookiesecure=0, cookiehttponly=0, auto_url_encoding=0,
REQUEST=None
):
""" """
ob = BrowserIdManager(id, title, idname, location, cookiepath,
cookiedomain, cookielifedays, cookiesecure,
auto_url_encoding)
cookiehttponly, auto_url_encoding)
self._setObject(id, ob)
ob = self._getOb(id)
if REQUEST is not None:
......@@ -115,7 +116,7 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
def __init__(self, id, title='', idname='_ZopeId',
location=('cookies', 'form'), cookiepath=('/'),
cookiedomain='', cookielifedays=0, cookiesecure=0,
auto_url_encoding=0):
cookiehttponly=0, auto_url_encoding=0):
self.id = str(id)
self.title = str(title)
self.setBrowserIdName(idname)
......@@ -124,6 +125,7 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
self.setCookieDomain(cookiedomain)
self.setCookieLifeDays(cookielifedays)
self.setCookieSecure(cookiesecure)
self.setCookieHTTPOnly(cookiehttponly)
self.setAutoUrlEncoding(auto_url_encoding)
def manage_afterAdd(self, item, container):
......@@ -278,7 +280,7 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
def manage_changeBrowserIdManager(
self, title='', idname='_ZopeId', location=('cookies', 'form'),
cookiepath='/', cookiedomain='', cookielifedays=0, cookiesecure=0,
auto_url_encoding=0, REQUEST=None
cookiehttponly=0, auto_url_encoding=0, REQUEST=None
):
""" """
self.title = str(title)
......@@ -287,6 +289,7 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
self.setCookieDomain(cookiedomain)
self.setCookieLifeDays(cookielifedays)
self.setCookieSecure(cookiesecure)
self.setCookieHTTPOnly(cookiehttponly)
self.setBrowserIdNamespaces(location)
self.setAutoUrlEncoding(auto_url_encoding)
self.updateTraversalData()
......@@ -377,6 +380,16 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
""" """
return self.cookie_domain
security.declareProtected(CHANGE_IDMGR_PERM, 'setCookieHTTPOnly')
def setCookieHTTPOnly(self, http_only):
""" sets cookie 'HTTPOnly' on or off """
self.cookie_http_only = bool(http_only)
security.declareProtected(ACCESS_CONTENTS_PERM, 'getCookieHTTPOnly')
def getCookieHTTPOnly(self):
""" retrieve the 'HTTPOnly' flag """
return self.cookie_http_only
security.declareProtected(CHANGE_IDMGR_PERM, 'setCookieSecure')
def setCookieSecure(self, secure):
""" sets cookie 'secure' element for id cookie """
......@@ -387,7 +400,7 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
""" """
return self.cookie_secure
security.declareProtected(CHANGE_IDMGR_PERM, 'setCookieSecure')
security.declareProtected(CHANGE_IDMGR_PERM, 'setAutoUrlEncoding')
def setAutoUrlEncoding(self, auto_url_encoding):
""" sets 'auto url encoding' on or off """
self.auto_url_encoding = not not auto_url_encoding
......@@ -424,8 +437,11 @@ class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
expires = now() + self.cookie_life_days * 86400
# Wdy, DD-Mon-YYYY HH:MM:SS GMT
expires = strftime('%a %d-%b-%Y %H:%M:%S GMT',gmtime(expires))
# cookie attributes managed by BrowserIdManager
d = {'domain':self.cookie_domain,'path':self.cookie_path,
'secure':self.cookie_secure,'expires':expires}
'secure':self.cookie_secure,'http_only': self.cookie_http_only,
'expires':expires}
if self.cookie_secure:
URL1 = REQUEST.get('URL1', None)
......
......@@ -150,6 +150,16 @@ by interacting with the Zope sessioning machinery.
<INPUT TYPE="checkbox" NAME="cookiesecure">
</TD>
</TR>
<TR>
<TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label">
Make cookie not aviable from JavaScript
</div>
</TD>
<TD ALIGN="LEFT" VALIGN="TOP">
<INPUT TYPE="checkbox" NAME="cookiehttponly">
</TD>
</TR>
</TR> <TR> <TD></TD> <TD>
......
......@@ -134,6 +134,19 @@
<dtml-if getCookieSecure>CHECKED</dtml-if>>
</TD>
</TR>
<TR>
<TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label">
Make cookie not aviable from JavaScript
</div>
</TD>
<TD ALIGN="LEFT" VALIGN="TOP">
<INPUT TYPE="checkbox" NAME="cookiehttponly"
<dtml-if getCookieHTTPOnly>CHECKED</dtml-if>>
</TD>
</TR>
<TR>
<TD></TD>
<TD><BR><INPUT class="form-element" TYPE="SUBMIT" VALUE=" Change "></TD>
......@@ -141,4 +154,3 @@
</TABLE>
</FORM>
<dtml-var manage_page_footer>
......@@ -116,6 +116,10 @@ class TestBrowserIdManager(TestCase):
self.m.setCookieSecure(1)
self.failUnless( self.m.getCookieSecure() == 1 )
def testSetCookieHTTPOnly(self):
self.m.setCookieHTTPOnly(True)
self.assertEqual( self.m.getCookieHTTPOnly(), True )
def testGetBrowserIdCookie(self):
token = self.m.getBrowserId()
self.m.REQUEST.browser_id_ = token
......@@ -223,6 +227,29 @@ class TestBrowserIdManager(TestCase):
(keystring, key))
self.failUnless( html == expected )
def testHTTPOnlyCookieAttribute(self):
self.m.setCookieHTTPOnly(True)
self.failUnless(self.m.getBrowserId())
resp_cookies = self.req.RESPONSE.cookies
session_cookie = resp_cookies[self.m.browserid_name]
self.assertEqual(session_cookie['http_only'], True)
def testSecureCookieAttribute_correct_url(self):
self.m.setCookieSecure(1)
self.req['URL1'] = 'https://www.test.org'
self.failUnless(self.m.getBrowserId())
resp_cookies = self.req.RESPONSE.cookies
session_cookie = resp_cookies[self.m.browserid_name]
self.assertEqual(session_cookie['secure'], True)
# This test document the 'feature':
# return a browser ID but dont set the cookie
def testSecureCookieAttribute_wrong_url(self):
self.m.setCookieSecure(1)
self.req['URL1'] = 'http://www.test.org'
self.failUnless(self.m.getBrowserId())
self.assertEqual( self.req.RESPONSE.cookies, {} )
def testAutoUrlEncoding(self):
self.m.setAutoUrlEncoding(1)
self.m.setBrowserIdNamespaces(('url',))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment