Back to index

plone3  3.1.7
session.py
Go to the documentation of this file.
00001 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
00002 from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
00003 from Products.PluggableAuthService.utils import classImplements
00004 from Products.PluggableAuthService.interfaces.plugins \
00005         import IExtractionPlugin, IAuthenticationPlugin, \
00006                 ICredentialsResetPlugin, ICredentialsUpdatePlugin
00007 from AccessControl.SecurityInfo import ClassSecurityInfo
00008 from plone.session.interfaces import ISessionPlugin, ISessionSource
00009 import binascii
00010 
00011 try:
00012     from AccessControl.requestmethod import postonly
00013 except ImportError:
00014     # For Zope <2.8.9, <2.9.7 and <2.10.3
00015     def postonly(func):
00016         return func
00017 
00018 # Temporary imports
00019 from Products.PluggableAuthService.permissions import ManageUsers
00020 
00021 
00022 manage_addSessionPluginForm = PageTemplateFile('session', globals())
00023     
00024 
00025 def manage_addSessionPlugin(dispatcher, id, title=None, path='/', REQUEST=None):
00026     """Add a session plugin."""
00027     sp=SessionPlugin(id, title=title, path=path)
00028     dispatcher._setObject(id, sp)
00029 
00030     if REQUEST is not None:
00031         REQUEST.RESPONSE.redirect('%s/manage_workspace?'
00032                                'manage_tabs_message=Session+plugin+created.' %
00033                                dispatcher.absolute_url())
00034 
00035 
00036 
00037 class SessionPlugin(BasePlugin):
00038     """Session authentication plugin.
00039     """
00040 
00041     meta_type = "Plone Session Plugin"
00042     security = ClassSecurityInfo()
00043     cookie_name = "__ac"
00044 
00045     _properties = (
00046             {
00047                 "id"    : "title",
00048                 "label" : "Title",
00049                 "type"  : "string",
00050                 "mode"  : "w",
00051             },
00052             {
00053                 "id"    : "cookie_name",
00054                 "label" : "Cookie Name root",
00055                 "type"  : "string",
00056                 "mode"  : "w",
00057             },
00058             )
00059 
00060     def __init__(self, id, title=None, path="/"):
00061         self._setId(id)
00062         self.title=title
00063         self.path=path
00064 
00065     @property
00066     def source(self):
00067         return ISessionSource(self)
00068 
00069 
00070     def manage_options(self):
00071         """Splice in mangae options from our source if it has them."""
00072 
00073         more = getattr(self.source, 'manage_options', ()) 
00074         if more:
00075             try:
00076                 more = tuple(more)
00077             except TypeError:
00078                 more = more()
00079 
00080         return more  + BasePlugin.manage_options
00081 
00082 
00083     # ISessionPlugin implementation
00084     def setupSession(self, userid, response):
00085         cookie=self.source.createIdentifier(userid)
00086         cookie=binascii.b2a_base64(cookie).rstrip()
00087 
00088         response.setCookie(self.cookie_name, cookie, path=self.path)
00089 
00090 
00091     # IExtractionPlugin implementation
00092     def extractCredentials(self, request):
00093         creds={}
00094 
00095         if not self.cookie_name in request:
00096             return creds
00097 
00098         try:
00099             creds["cookie"]=binascii.a2b_base64(request.get(self.cookie_name))
00100         except binascii.Error:
00101             # If we have a cookie which is not properly base64 encoded it
00102             # can not be ours.
00103             return creds
00104 
00105         creds["source"]="plone.session" # XXX should this be the id?
00106 
00107         return creds
00108 
00109 
00110     # IAuthenticationPlugin implementation
00111     def authenticateCredentials(self, credentials):
00112         if not credentials.get("source", None)=="plone.session":
00113             return None
00114 
00115         source=self.source
00116         identifier=credentials["cookie"]
00117         if source.verifyIdentifier(identifier):
00118             userid=source.extractUserId(identifier)
00119             pas=self._getPAS()
00120             info=pas._verifyUser(pas.plugins, user_id=userid)
00121             if info is not None:
00122                 return (info['id'], info['login'])
00123 
00124         return None
00125 
00126 
00127     # ICredentialsUpdatePlugin implementation
00128     def updateCredentials(self, request, response, login, new_password):
00129         pas=self._getPAS()
00130         info=pas._verifyUser(pas.plugins, login=login)
00131         if info is not None:
00132             # Only setup a session for users in our own user folder.
00133             self.setupSession(info["id"], response)
00134 
00135 
00136     # ICredentialsResetPlugin implementation
00137     def resetCredentials(self, request, response):
00138         source=self.source
00139 
00140         response=self.REQUEST["RESPONSE"]
00141         response.expireCookie(self.cookie_name, path=self.path)
00142 
00143 # XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX
00144 # This should be in HashSource !
00145 
00146     manage_secret = PageTemplateFile("../sources/hash.pt", globals())
00147 
00148     security.declareProtected(ManageUsers, 'manage_clearSecrets')
00149     @postonly
00150     def manage_clearSecrets(self, REQUEST):
00151         """Clear all secrets from this source.
00152 
00153         This invalidates all current sessions and requires users to login again.
00154         """
00155         self.source.clearSecrets()
00156         REQUEST.RESPONSE.redirect('%s/manage_secret?manage_tabs_message=%s'
00157                                      % (self.absolute_url(), 'All+secrets+cleared.'))
00158 
00159 
00160     security.declareProtected(ManageUsers, 'manage_createNewSecret')
00161     @postonly
00162     def manage_createNewSecret(self, REQUEST):
00163         """Create a new (signing) secret.
00164         """
00165         self.source.createNewSecret()
00166         REQUEST.RESPONSE.redirect('%s/manage_secret?manage_tabs_message=%s'
00167                                      % (self.absolute_url(), 'New+secret+created.'))
00168 
00169 classImplements(SessionPlugin, ISessionPlugin,
00170                 IExtractionPlugin, IAuthenticationPlugin,
00171                 ICredentialsResetPlugin, ICredentialsUpdatePlugin)
00172