Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Add template tags and key_tuple for manual usage
- Loading branch information
Showing
7 changed files
with
160 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,76 @@ | |||
"""Add {% load cookieless %} after base to use these in a template | |||
NB: settings: Need to add django.core.context_processors.request | |||
if using manual tags so its available for templatetags/cookieless | |||
import django.conf.global_settings as DEFAULT_SETTINGS | |||
TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + ('django.core.context_processors.request', ) | |||
""" | |||
|
|||
from django.conf import settings | |||
from django import template | |||
from django.template.defaultfilters import stringfilter, striptags | |||
from django.utils.safestring import mark_safe | |||
from django.utils.html import escape | |||
|
|||
from cookieless.utils import CryptSession | |||
|
|||
register = template.Library() | |||
|
|||
class BaseSessionNode(template.Node): | |||
|
|||
def __init__(self,): | |||
self.request_var = template.Variable('request') | |||
self._sesh = CryptSession() | |||
|
|||
def get_key(self, context): | |||
request = self.request_var.resolve(context) | |||
if request.session.session_key: | |||
return self._sesh.encrypt(request, | |||
request.session.session_key) | |||
else: | |||
return '' | |||
|
|||
class FormSessionNode(BaseSessionNode): | |||
|
|||
def render(self, context): | |||
session_key = self.get_key(context) | |||
if session_key: | |||
html = '<input type="hidden" name="%s" value="%s" />' | |||
return mark_safe(html % (settings.SESSION_COOKIE_NAME, | |||
session_key)) | |||
else: | |||
return '' | |||
|
|||
def session_form(parser, token): | |||
return FormSessionNode() | |||
|
|||
register.tag('session_token', session_form) | |||
|
|||
class URLSessionNode(BaseSessionNode): | |||
|
|||
def __init__(self, url): | |||
super(URLSessionNode, self).__init__() | |||
self.url = self._sesh.prepare_url(url.replace('"','')) | |||
|
|||
def render(self, context): | |||
session_key = self.get_key(context) | |||
if session_key: | |||
html = '"%s%s=%s"' | |||
return mark_safe(html % (self.url, | |||
settings.SESSION_COOKIE_NAME, | |||
session_key)) | |||
else: | |||
return '' | |||
|
|||
def session_filter(parser, token): | |||
try: | |||
taglist = token.split_contents() # Not really useful | |||
except ValueError: | |||
raise template.TemplateSyntaxError("%r error" % token.contents.split()[0]) | |||
if len(taglist) > 1: | |||
url = taglist[1] | |||
return URLSessionNode(url) | |||
|
|||
register.tag('session_url', session_filter) | |||
|
|||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,61 @@ | |||
""" Obscure the session id when passing it around in HTML """ | |||
from django.conf import settings | |||
from urlparse import urlparse | |||
from cookieless.xteacrypt import crypt | |||
|
|||
class CryptSession(object): | |||
""" Tool to generate encrypted session id for | |||
middleware or templatetags | |||
""" | |||
def __init__(self): | |||
self.secret = settings.SECRET_KEY[:16] | |||
|
|||
def prepare_url(self, url): | |||
patt = None | |||
if url.find('?') == -1: | |||
patt = '%s?' | |||
else: | |||
patt = '%s&' | |||
return patt % (url,) | |||
|
|||
def encrypt(self, request, sessionid): | |||
""" Avoid showing plain sessionids """ | |||
if not sessionid: | |||
return '' | |||
secret = self._secret(request) | |||
return crypt(secret, sessionid).encode('hex') | |||
|
|||
def decrypt(self, request, sessionid): | |||
""" Avoid showing plain sessionids | |||
Optionally require that a referer exists and matches the | |||
whitelist, or reset the session | |||
""" | |||
if not sessionid: | |||
return '' | |||
secret = self._secret(request) | |||
if getattr(settings, 'COOKIELESS_HOSTS', []): | |||
referer = request.META.get('HTTP_REFERER', 'None') | |||
if referer == 'None': | |||
# End session unless a referer is passed | |||
return '' | |||
url = urlparse(referer) | |||
if url.hostname not in settings.COOKIELESS_HOSTS: | |||
err = '%s is unauthorised' % url.hostname | |||
raise Exception(err) | |||
return crypt(secret, sessionid.decode('hex')) | |||
|
|||
def key_tuple(self, request): | |||
""" For use in generated html """ | |||
return (settings.SESSION_COOKIE_NAME, | |||
self.encrypt(request, request.session.session_key)) | |||
|
|||
def _secret(self, request): | |||
""" optionally make secret client dependent | |||
""" | |||
if getattr(settings, 'COOKIELESS_CLIENT_ID', False): | |||
ip = request.META['REMOTE_ADDR'] | |||
agent = request.META['HTTP_USER_AGENT'] | |||
secret = crypt(self.secret, agent + ip)[:16] | |||
return secret | |||
else: | |||
return self.secret |