Back to index

plone3  3.1.7
DelegatingMultiPlugin.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights
00004 # Reserved.
00005 #
00006 # This software is subject to the provisions of the Zope Public License,
00007 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this
00008 # distribution.
00009 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00010 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00011 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00012 # FOR A PARTICULAR PURPOSE.
00013 #
00014 ##############################################################################
00015 """ DelegatingMultiPlugin   Shim to use any User Folder with the
00016                             PluggableAuthenticationService
00017 """
00018 
00019 __doc__     = """ Delegating User Folder shim module """
00020 __version__ = '$Revision: 70857 $'[11:-2]
00021 
00022 # General Python imports
00023 import copy, os
00024 from urllib import quote_plus
00025 
00026 # Zope imports
00027 from Acquisition import aq_base
00028 from OFS.Folder import Folder
00029 from Globals import InitializeClass
00030 from AccessControl import ClassSecurityInfo
00031 from AccessControl.SpecialUsers import emergency_user
00032 
00033 from zope.interface import Interface
00034 from AccessControl import AuthEncoding
00035 
00036 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
00037 
00038 from Products.PluggableAuthService.interfaces.plugins import \
00039     IAuthenticationPlugin
00040 from Products.PluggableAuthService.interfaces.plugins import \
00041     IUserEnumerationPlugin
00042 from Products.PluggableAuthService.interfaces.plugins import \
00043     IRolesPlugin
00044 from Products.PluggableAuthService.interfaces.plugins import \
00045     ICredentialsUpdatePlugin
00046 from Products.PluggableAuthService.interfaces.plugins import \
00047     ICredentialsResetPlugin
00048 from Products.PluggableAuthService.interfaces.plugins import \
00049     IPropertiesPlugin
00050 from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
00051 from Products.PluggableAuthService.utils import classImplements
00052 
00053 class IDelegatingMultiPlugin(Interface):
00054     """ Marker interface.
00055     """
00056 
00057 manage_addDelegatingMultiPluginForm = PageTemplateFile(
00058     'www/dmpAdd', globals(), __name__='manage_addDelegatingMultiPluginForm' )
00059 
00060 
00061 def manage_addDelegatingMultiPlugin( self
00062                                    , id
00063                                    , title=''
00064                                    , delegate_path=''
00065                                    , REQUEST=None
00066                                    ):
00067     """ Factory method to instantiate a DelegatingMultiPlugin """
00068     # Make sure we really are working in our container (the 
00069     # PluggableAuthService object)
00070     self = self.this()
00071 
00072     # Instantiate the folderish adapter object
00073     lmp = DelegatingMultiPlugin( id, title=title
00074                                , delegate_path=delegate_path )
00075     self._setObject(id, lmp)
00076 
00077     if REQUEST is not None:
00078         REQUEST.RESPONSE.redirect('%s/manage_main' % self.absolute_url())
00079 
00080 
00081 
00082 class DelegatingMultiPlugin(Folder, BasePlugin):
00083     """ The adapter that mediates between the PAS and the DelegatingUserFolder
00084     """
00085     security = ClassSecurityInfo()
00086     meta_type = 'Delegating Multi Plugin'
00087 
00088     manage_options = ( BasePlugin.manage_options[:1]
00089                      + Folder.manage_options
00090                      )
00091 
00092     _properties = ( { 'id' : 'delegate'
00093                     , 'label' : ' Delegate Path'
00094                     , 'type' : 'string'
00095                     , 'mode' : 'w'
00096                     }
00097                   ,
00098                   )
00099 
00100     def __init__(self, id, title='', delegate_path=''):
00101         """ Initialize a new instance """
00102         self.id = id
00103         self.title = title
00104         self.delegate = delegate_path
00105 
00106 
00107     security.declarePrivate('_getUserFolder')
00108     def _getUserFolder(self):
00109         """ Safely retrieve a User Folder to work with """
00110         uf = getattr(aq_base(self), 'acl_users', None)
00111 
00112         if uf is None and self.delegate:
00113             uf = self.unrestrictedTraverse(self.delegate)
00114 
00115         return uf
00116 
00117 
00118     security.declarePrivate('authenticateCredentials')
00119     def authenticateCredentials(self, credentials):
00120         """ Fulfill AuthenticationPlugin requirements """
00121         acl = self._getUserFolder()
00122         login = credentials.get('login', '')
00123         password = credentials.get('password', '')
00124 
00125         if not acl or not login or not password:
00126             return (None, None)
00127 
00128         if login == emergency_user.getUserName() and \
00129                 AuthEncoding.pw_validate(emergency_user._getPassword(), password):
00130             return ( login, login )
00131 
00132         user = acl.getUser(login)
00133 
00134         if user is None:
00135             return (None, None)
00136 
00137         elif user and AuthEncoding.pw_validate(user._getPassword(),
00138                                                password):
00139             return ( user.getId(), login )
00140 
00141         return (None, None)
00142 
00143 
00144     security.declarePrivate('updateCredentials')
00145     def updateCredentials(self, request, response, login, new_password):
00146         """ Fulfill CredentialsUpdatePlugin requirements """
00147         # Need to at least remove user from cache
00148         pass
00149 
00150 
00151     security.declarePrivate('resetCredentials')
00152     def resetCredentials(self, request, response):
00153         """ Fulfill CredentialsResetPlugin requirements """
00154         # Remove user from cache?
00155         pass
00156 
00157 
00158     security.declarePrivate('getPropertiesForUser')
00159     def getPropertiesForUser(self, user, request=None):
00160         """ Fullfill PropertiesPlugin requirements """
00161         acl = self._getUserFolder()
00162 
00163         if acl is None:
00164             return {}
00165 
00166         user = acl.getUserById(user.getId())
00167 
00168         if user is None:
00169             return {}
00170 
00171         # XXX WAAA
00172         return copy.deepcopy(user.__dict__)
00173 
00174 
00175     security.declarePrivate('getRolesForPrincipal')
00176     def getRolesForPrincipal(self, user, request=None):
00177         """ Fullfill RolesPlugin requirements """
00178         acl = self._getUserFolder()
00179 
00180         if acl is None:
00181             return ()
00182 
00183         user = acl.getUserById(user.getId())
00184 
00185         if user is None:
00186             return ()
00187 
00188         return tuple(user.getRoles())
00189 
00190 
00191     security.declarePrivate('enumerateUsers')
00192     def enumerateUsers( self
00193                       , id=None
00194                       , login=None
00195                       , exact_match=0
00196                       , sort_by=None
00197                       , max_results=None
00198                       , **kw
00199                       ):
00200         """ Fulfill the EnumerationPlugin requirements """
00201         result = []
00202         acl = self._getUserFolder()
00203         plugin_id = self.getId()
00204         edit_url = '%s/%s/manage_userrecords' % (plugin_id, acl.getId())
00205 
00206         if acl is None:
00207             return ()
00208 
00209         if exact_match:
00210             if id:
00211                 user = acl.getUserById(id)
00212             elif login:
00213                 user = acl.getUser(login)
00214             else:
00215                 msg = 'Exact Match specified but no ID or Login given'
00216                 raise ValueError, msg
00217 
00218             if user is not None:
00219                 result.append( { 'id' : user.getId()
00220                                , 'login' : user.getUserName()
00221                                , 'pluginid' : plugin_id
00222                                , 'editurl' : '%s' % edit_url
00223                                } ) 
00224         else:
00225             l_results = []
00226             seen = []
00227             # XXX WAAAAA!!!!
00228             all_users = acl.getUsers()
00229 
00230             for user in all_users:
00231                 if id:
00232                     if user.getId().find(id) != -1:
00233                         result.append( { 'login' : user.getUserName()
00234                                        , 'id' : user.getId()
00235                                        , 'pluginid' : plugin_id
00236                                        } )
00237                 elif login:
00238                     if user.getUserName().find(login) != -1:
00239                         result.append( { 'login' : user.getUserName()
00240                                        , 'id' : user.getId()
00241                                        , 'pluginid' : plugin_id
00242                                        } )
00243 
00244             if sort_by is not None:
00245                 result.sort(lambda a, b: cmp( a.get(sort_by, '').lower()
00246                                             , b.get(sort_by, '').lower()
00247                                             ) )
00248 
00249             if max_results is not None:
00250                 try:
00251                     max_results = int(max_results)
00252                     result = result[:max_results+1]
00253                 except ValueError:
00254                     pass
00255 
00256         return tuple(result)
00257 
00258 classImplements( DelegatingMultiPlugin
00259                , IDelegatingMultiPlugin
00260                , IAuthenticationPlugin
00261                , IUserEnumerationPlugin
00262                , IRolesPlugin
00263                , ICredentialsUpdatePlugin
00264                , ICredentialsResetPlugin
00265                , IPropertiesPlugin
00266                )
00267 
00268 
00269 InitializeClass(DelegatingMultiPlugin)