Back to index

plone3  3.1.7
user.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # PlonePAS - Adapt PluggableAuthService for use in Plone
00004 # Copyright (C) 2005 Enfold Systems, Kapil Thangavelu, et al
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 """
00016 ZODB based user manager with introspection and management interfaces.
00017 
00018 """
00019 
00020 from AccessControl import ClassSecurityInfo, AuthEncoding
00021 from Globals import InitializeClass, DTMLFile
00022 
00023 from zope.interface import implementedBy
00024 
00025 from Products.PlonePAS.interfaces.plugins import IUserManagement, IUserIntrospection
00026 from Products.PlonePAS.interfaces.capabilities import IDeleteCapability, IPasswordSetCapability
00027 
00028 from Products.PluggableAuthService.utils import createViewName
00029 from Products.PluggableAuthService.utils import classImplements
00030 from Products.PluggableAuthService.plugins.ZODBUserManager import ZODBUserManager as BasePlugin
00031 
00032 manage_addUserManagerForm = DTMLFile('../zmi/UserManagerForm',
00033                                           globals())
00034 
00035 def manage_addUserManager(dispatcher, id, title=None, REQUEST=None):
00036     """ Add a UserManager to a Pluggable Auth Service. """
00037 
00038     pum = UserManager(id, title)
00039     dispatcher._setObject(pum.getId(), pum)
00040 
00041     if REQUEST is not None:
00042         REQUEST['RESPONSE'].redirect(
00043             '%s/manage_workspace'
00044             '?manage_tabs_message='
00045             'UserManager+added.'
00046             % dispatcher.absolute_url())
00047 
00048 class UserManager(BasePlugin):
00049     """PAS plugin for managing users. (adds write API)
00050     """
00051 
00052     meta_type = 'User Manager'
00053     security = ClassSecurityInfo()
00054 
00055     def addUser(self, user_id, login_name, password):
00056         """Original ZODBUserManager.addUser, modified to check if
00057         incoming password is already encypted.
00058 
00059         This support clean migration from default user source.
00060         Should go into PAS.
00061         """
00062         if self._user_passwords.get(user_id) is not None:
00063             raise KeyError, 'Duplicate user ID: %s' % user_id
00064 
00065         if self._login_to_userid.get(login_name) is not None:
00066             raise KeyError, 'Duplicate login name: %s' % login_name
00067 
00068         if not AuthEncoding.is_encrypted(password):
00069             password = AuthEncoding.pw_encrypt(password)
00070         self._user_passwords[ user_id ] = password
00071         self._login_to_userid[ login_name ] = user_id
00072         self._userid_to_login[ user_id ] = login_name
00073 
00074         # enumerateUsers return value has changed
00075         view_name = createViewName('enumerateUsers')
00076         self.ZCacheable_invalidate(view_name=view_name)
00077 
00078     ## User Management interface
00079 
00080     security.declarePrivate('doDeleteUser')
00081     def doDeleteUser(self, userid):
00082         """Given a user id, delete that user
00083         """
00084         return self.removeUser(userid)
00085 
00086     security.declarePrivate('doChangeUser')
00087     def doChangeUser(self, principal_id, password):
00088         """Change a user's password
00089         """
00090         if self._user_passwords.get(principal_id) is None:
00091             raise RuntimeError, "User does not exist: %s" % principal_id
00092         self._user_passwords[principal_id] = AuthEncoding.pw_encrypt(password)
00093 
00094     # implement interfaces IDeleteCapability, IPasswordSetCapability
00095 
00096     security.declarePublic('allowDeletePrincipal')
00097     def allowDeletePrincipal(self, principal_id):
00098         """True iff this plugin can delete a certain user/group.
00099         This is true if this plugin manages the user.
00100         """
00101         if self._user_passwords.get(principal_id) is not None:
00102             return 1
00103         return 0
00104 
00105     security.declarePublic('allowPasswordSet')
00106     def allowPasswordSet(self, principal_id):
00107         """True iff this plugin can set the password a certain user.
00108         This is true if this plugin manages the user.
00109         """
00110         return self.allowDeletePrincipal(principal_id)
00111 
00112     ## User Introspection interface
00113 
00114     def getUserIds(self):
00115         """
00116         Return a list of user ids
00117         """
00118         return self.listUserIds()
00119 
00120     def getUserNames(self):
00121         """
00122         Return a list of usernames
00123         """
00124         return [x['login_name'] for x in self.listUserInfo()]
00125 
00126     def getUsers(self):
00127         """
00128         Return a list of users
00129         """
00130         uf = self.acl_users
00131         return [uf.getUserById(x) for x in self.getUserIds()]
00132 
00133 classImplements(UserManager,
00134                 IUserManagement, IUserIntrospection,
00135                 IDeleteCapability, IPasswordSetCapability,
00136                 *implementedBy(BasePlugin))
00137 
00138 InitializeClass(UserManager)