Skip to content

Commit

Permalink
Merge pull request #156 from colab/midleware_cookies
Browse files Browse the repository at this point in the history
Cookie Handle Middleware
  • Loading branch information
lucasmoura committed Feb 18, 2016
2 parents ba42c23 + 6243ae5 commit 98938fa
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 0 deletions.
Empty file added colab/middlewares/__init__.py
Empty file.
93 changes: 93 additions & 0 deletions colab/middlewares/cookie_middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from Cookie import SimpleCookie, Morsel
import copy


class CookiePreHandlerMiddleware(object):
"""
This middleware modifies request.COOKIES and adds a set and delete method.
`set` matches django.http.HttpResponse.set_cookie
`delete` matches django.http.HttpResponse.delete_cookie
This should be the first middleware you load.
"""

def process_request(self, request):
cookies = CookieHandler()
for k, v in request.COOKIES.iteritems():
cookies[k] = str(v)
request.COOKIES = cookies
request._orig_cookies = copy.deepcopy(request.COOKIES)


class CookiePostHandlerMiddleware(object):
"""
This middleware modifies updates the response with all modified cookies.
This should be the last middleware you load.
"""

def process_response(self, request, response):
if hasattr(request, '_orig_cookies') and \
request.COOKIES != request._orig_cookies:
for k, v in request.COOKIES.iteritems():
if request._orig_cookies.get(k) != v:
dict.__setitem__(response.cookies, k, v)
return response


class StringMorsel(Morsel):

def __str__(self):
return self.value

def __eq__(self, a):
if isinstance(a, str):
return str(self) == a
elif isinstance(a, Morsel):
return a.output() == self.output()
return False

def __ne__(self, a):
if isinstance(a, str):
return str(self) != a
elif isinstance(a, Morsel):
return a.output() != self.output()
return True

def __repr__(self):
return str(self)

def split(self, *args):
return self.value.split(*args)


class CookieHandler(SimpleCookie):

def __set(self, key, real_value, coded_value):
"""Private method for setting a cookie's value"""
morse_set = self.get(key, StringMorsel())
morse_set.set(key, real_value, coded_value)
dict.__setitem__(self, key, morse_set)

def __setitem__(self, key, value):
"""Dictionary style assignment."""
rval, cval = self.value_encode(value)
self.__set(key, rval, cval)

def set(self, key, value='', max_age=None, expires=None,
path='/', domain=None, secure=None):
self[key] = value
for var in ('max_age', 'path', 'domain', 'secure', 'expires'):
val = locals()[var]
if val is not None:
self[key][var.replace('_', '-')] = val

def delete(self, key, path='/', domain=None):
self[key] = ''
if path is not None:
self[key]['path'] = path
if domain is not None:
self[key]['domain'] = domain
self[key]['expires'] = 0
self[key]['max-age'] = 0
Empty file added colab/middlewares/models.py
Empty file.
Empty file.
80 changes: 80 additions & 0 deletions colab/middlewares/tests/test_cookie_middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from django.test import TestCase
from django import http
from colab.middlewares.cookie_middleware import (StringMorsel,
CookiePostHandlerMiddleware,
CookiePreHandlerMiddleware,
CookieHandler)


class StringMorselTest(TestCase):

def setUp(self):
self.morsel = StringMorsel()
self.morsel.set("cookie_name", "cookie_value", "coded_value")

def test_string_morsel_str(self):
self.assertEquals("cookie_value", self.morsel.__repr__())

def test_string_morsel_eq(self):
self.assertTrue(self.morsel == "cookie_value")
other_morsel = StringMorsel()
other_morsel.set("cookie_name", "cookie_value", "other_coded_value")
self.assertFalse(other_morsel == self.morsel)
self.assertFalse(other_morsel == 42)

def test_string_morsel_ne(self):
self.assertFalse(self.morsel != "cookie_value")
other_morsel = StringMorsel()
other_morsel.set("cookie_name", "cookie_value", "other_coded_value")
self.assertTrue(other_morsel != self.morsel)
self.assertTrue(other_morsel != 42)

def test_string_morsel_split(self):
self.assertIsInstance(self.morsel.split(), list)


class CookiePostHandlerTest(TestCase):

def test_process_response(self):
pre_handler = CookiePreHandlerMiddleware()
post_handler = CookiePostHandlerMiddleware()

request = http.HttpRequest()
response = http.HttpResponse()

pre_handler.process_request(request)
request.COOKIES.set('cookie1', 'cookie_value1')
request.COOKIES.set('cookie2', 'cookie_value2')

response = post_handler.process_response(request, response)
self.assertEquals(2, len(response.cookies))


class CookiePreHandlerTest(TestCase):

def test_process_request(self):
pre_handler = CookiePreHandlerMiddleware()
request = http.HttpRequest()

request.COOKIES['cookie1'] = 'cookie_value1'
pre_handler.process_request(request)

self.assertEquals('cookie_value1', request.COOKIES.get('cookie1'))


class CookieHandlerTest(TestCase):

def setUp(self):
self.cookie_handler = CookieHandler()

def test_set(self):
self.cookie_handler.set('key', 'value')
self.assertEquals('value', self.cookie_handler.get('key'))
self.cookie_handler.delete('key')
self.assertEquals('', self.cookie_handler.get('key'))

def test_set_with_domain(self):
self.cookie_handler.set('key', 'value', domain="domain")
self.assertEquals('value', self.cookie_handler.get('key'))
self.cookie_handler.delete('key', domain="domain")
self.assertEquals('', self.cookie_handler.get('key'))
2 changes: 2 additions & 0 deletions colab/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
'colab.tz',
'colab.utils',
'colab.signals',
'colab.middlewares',
)

ROOT_URLCONF = 'colab.urls'
Expand Down Expand Up @@ -213,6 +214,7 @@ def get_env_setting(setting):
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'colab.tz.middleware.TimezoneMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
)

AUTHENTICATION_BACKENDS = (
Expand Down

0 comments on commit 98938fa

Please sign in to comment.