Back to index

plone3  3.1.7
hash.py
Go to the documentation of this file.
00001 from zope.annotation.interfaces import IAnnotations
00002 from plone.session.sources.base import BaseSource
00003 from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
00004 import random, hmac, sha
00005 
00006 def GenerateSecret(length=64):
00007     secret=""
00008     for i in range(length):
00009         secret+=chr(random.getrandbits(8))
00010 
00011     return secret
00012 
00013 
00014 class HashSession(BaseSource):
00015     """A Hash session source implementation.
00016     """
00017 
00018     # Number of secrets to keep. The first secret is the current signing key
00019     secret_count = 5
00020 
00021     manage_options = (
00022                 { 'label':      'Hash tools',
00023                   'action':     '@@hash_view/manage_secret' },
00024                 { 'label':      'Hash tools',
00025                   'action':     'manage_secret' },
00026               )
00027 
00028     def __init__(self, context):
00029         self.context=context
00030         anno=IAnnotations(self.context)
00031         if not anno.has_key("plone.session.plugins.hash.secrets"):
00032             self.clearSecrets()
00033 
00034 
00035     def clearSecrets(self):
00036         anno=IAnnotations(self.context)
00037         anno["plone.session.plugins.hash.secrets"]=[]
00038         self.createNewSecret()
00039 
00040 
00041     def createNewSecret(self):
00042         anno=IAnnotations(self.context)
00043         anno["plone.session.plugins.hash.secrets"]=[GenerateSecret()] + \
00044                 anno["plone.session.plugins.hash.secrets"][:self.secret_count-1]
00045 
00046 
00047     def getSecrets(self):
00048         anno=IAnnotations(self.context)
00049         return anno["plone.session.plugins.hash.secrets"]
00050 
00051 
00052     def getSigningSecret(self):
00053         return self.getSecrets()[0]
00054 
00055 
00056     def signUserid(self, userid, secret=None):
00057         if secret is None:
00058             secret = self.getSigningSecret()
00059 
00060         return hmac.new(secret, userid, sha).digest()
00061 
00062 
00063     def createIdentifier(self, userid):
00064         signature=self.signUserid(userid)
00065 
00066         return "%s %s" % (signature, userid)
00067 
00068 
00069     def splitIdentifier(self, identifier):
00070         index=identifier.rfind(" ")
00071         if index==-1:
00072             raise ValueError
00073 
00074         return (identifier[:index], identifier[index+1:])
00075 
00076 
00077     def verifyIdentifier(self, identifier):
00078         for secret in self.getSecrets():
00079             try:
00080                 (signature, userid)=self.splitIdentifier(identifier)
00081                 if  signature==self.signUserid(userid, secret):
00082 # XXX if the secret is not the current signing secret we should reset the cookie
00083                     return True
00084             except (AttributeError, ValueError):
00085                 continue
00086 
00087         return False
00088 
00089 
00090     def extractUserId(self, identifier):
00091         (signature, userid)=self.splitIdentifier(identifier)
00092         return userid
00093 
00094 
00095     manage_secret = ViewPageTemplateFile('hash.pt')
00096 
00097