[Zope-PTK] ALPHA patch for LoginManager 0.8.5 support
Dan L. Pierson
dan@sol.control.com
Tue, 23 May 2000 15:29:54 -0400 (EDT)
This doesn't add any functionality, but it does appear to work.
Please bang on it. I'll be out for about 1 1/2 weeks starting
Thursday evening so very early bug reports are more likely to get
prompt attention (does this count as a half-Guido? :-)).
Index: PersistentUserSource.py
===================================================================
RCS file: /cvs-repository/ZopePTK/PTKDemo/PersistentUserSource.py,v
retrieving revision 1.4
diff -c -r1.4 PersistentUserSource.py
*** PersistentUserSource.py 2000/03/03 17:33:06 1.4
--- PersistentUserSource.py 2000/05/23 20:18:48
***************
*** 1,8 ****
"""
This module impliments a mickey-mouse UserSource which contains persistent
! LoginUsers and a Member mix-in class which provides some hacks to fake the
! property sheet interface.
PersistentUserSource and the Member mix-in are meant to attempt to nail
down the external interface. This should not be taken as an example of a
proper UserSource or LoginUser!!!
--- 1,12 ----
"""
This module impliments a mickey-mouse UserSource which contains persistent
! LoginUsers and a Member mix-in class.
+ This version works with LoginManager 0.8.5 and ZPatterns 0.3.0. It
+ may work with later ones. The external interfaces are now mostly
+ defined by LoginManager but the addUser and changeUser stuff is still
+ local to the PTK and may well be changed.
+
PersistentUserSource and the Member mix-in are meant to attempt to nail
down the external interface. This should not be taken as an example of a
proper UserSource or LoginUser!!!
***************
*** 11,63 ****
from Products.LoginManager.UserSources import BasicUserSource
from OFS.Folder import Folder
- from Products.LoginManager.LoginManager import registerUserSource
from Globals import HTMLFile
from Persistence import PersistentMapping
! class PersistentUserSource(BasicUserSource, Folder):
"""
! A PersistenUserSource is a UserSource who's LoginUsers are
contained as persistent Zope objects.
"""
meta_type = "Persistent User Source"
-
- manage_options = tuple(
- [Folder.manage_options[0],
- {'label':'Role Mappings', 'action':'manage_mappingsForm'},
- {'label':'Class', 'action':'manage_classForm'}]
- + list(Folder.manage_options[1:])
- )
! def __init__(self, id):
! PersistentUserSource.inheritedAttribute('__init__')(self, id)
self.__users = PersistentMapping()
self.__roles = PersistentMapping()
self.__domains = PersistentMapping()
self.__ = PersistentMapping()
!
! def getUser(self, id):
"""Fetch a named user"""
user = (self.__users.has_key(id) and self.__users[id]) or None
! if user: user._setRack(self)
! return user.__of__(self)
def rolesForUser(self,user):
"""Fetch this user's roles"""
! id = user.getUserName()
! return (self.__roles.has_key(id) and self.__roles[id]) or []
def domainsForUser(self,user):
"""Fetch this user's domains"""
! id = user.getUserName()
! return (self.__domains.has_key(id) and self.__domains[id]) or []
def authenticateUser(self,user,password,request):
"""Authenticate this user"""
id = user.getUserName()
return self.__.has_key(id) and password == self.__[id]
def changeUser(self, user, password, roles, domains):
"""Change the user 'user'."""
userid = user.getUserName()
--- 15,120 ----
from Products.LoginManager.UserSources import BasicUserSource
from OFS.Folder import Folder
from Globals import HTMLFile
from Persistence import PersistentMapping
+ from ComputedAttribute import ComputedAttribute
+ import Products
+ import types
! class PersistentUserSource(BasicUserSource):
"""
! A PersistentUserSource is a UserSource who's LoginUsers are
contained as persistent Zope objects.
"""
meta_type = "Persistent User Source"
! def __init__(self, id, title=''):
! BasicUserSource.__init__.im_func(self, id, title)
self.__users = PersistentMapping()
self.__roles = PersistentMapping()
self.__domains = PersistentMapping()
self.__ = PersistentMapping()
!
! def retrieveItem(self, id):
"""Fetch a named user"""
user = (self.__users.has_key(id) and self.__users[id]) or None
! if user:
! user = user.__of__(self)
! return user
def rolesForUser(self,user):
"""Fetch this user's roles"""
! try:
! id = user.getUserName()
! data = self.__roles[id]
! if type(data) == types.StringType:
! data = split(data)
! else:
! data = list(data)
! if len(data) > 0 and type(data[0]) != types.StringType:
! if hasattr(data[0], 'role'):
! data = map(lambda x: x.role, data)
! elif hasattr(data[0], 'r'):
! data = map(lambda x: x.r, data)
! except:
! data = ['Anonymous']
! # XXX log exception or something
!
! if 'Anonymous' not in data:
! data.insert(0, 'Anonymous')
+ data = self._map_roles(data)
+ return data
+
def domainsForUser(self,user):
"""Fetch this user's domains"""
! try:
! id = user.getUserName()
! data = self.__domains[id]
! if type(data) == types.StringType:
! data = split(data)
! else:
! data = list(data)
! if len(data) > 0 and type(data[0]) != types.StringType:
! if hasattr(data[0], 'domain'):
! data = map(lambda x: x.domain, data)
! elif hasattr(data[0], 'd'):
! data = map(lambda x: x.d, data)
! except:
! data = []
! # XXX log exception or something
!
! return data
def authenticateUser(self,user,password,request):
"""Authenticate this user"""
id = user.getUserName()
return self.__.has_key(id) and password == self.__[id]
+ def getUsers(self):
+ """Return a list of the user objects."""
+ return self.__users.values()
+
+ def getUserNames(self):
+ """Return a list of the user names."""
+ names = []
+ for user in self.__users.values():
+ names.append(user.getUserName())
+ return names
+
+ #def getUserInfo(self, username):
+ # """Bad juju! Remove this after debugging!"""
+ # try:
+ # return [username, self.__[username], self.__roles[username],
+ # self.__domains[username]]
+ # except:
+ # return [username, 'Error getting info']
+
+ def _getPassword(self, username):
+ # Needed for PortalObjectBase.mail_password
+ return self.__[username]
+
def changeUser(self, user, password, roles, domains):
"""Change the user 'user'."""
userid = user.getUserName()
***************
*** 68,74 ****
# I might get burned with this name, but it's very temporary
def addUser(self, userid, password, roles, domains):
! user = self._User(userid)
self.__users[userid] = user
self.__roles[userid] = roles
self.__domains[userid] = domains
--- 125,131 ----
# I might get burned with this name, but it's very temporary
def addUser(self, userid, password, roles, domains):
! user = self.newItem(userid)
self.__users[userid] = user
self.__roles[userid] = roles
self.__domains[userid] = domains
***************
*** 79,86 ****
for ps in self.PropertySheets():
ps.manage_changeProperties(REQUEST)
def getHomeUrl(self):
! return self.getPortal().Members[self.getUserName()].absolute_url()
def toolbox_actions(self):
"""Implements the Toolbox Action Provider interface"""
--- 136,152 ----
for ps in self.PropertySheets():
ps.manage_changeProperties(REQUEST)
+ def getHomeFolder(self):
+ """Returns the user's home folder object."""
+ return self.getPortal().Members[self.getUserName()]
+
def getHomeUrl(self):
! """Returns the URL to this user's Member folder."""
! return self.getHomeFolder().absolute_url()
!
! def get_toolbox_actions(self, klass=None):
! """Hmmm, fake this for now."""
! return self.toolbox_actions()
def toolbox_actions(self):
"""Implements the Toolbox Action Provider interface"""
***************
*** 91,109 ****
'category': 'user'},
]
! def PropertySheets(self):
! """Return all my propery sheets in a list"""
! return self.propertysheets
!
! def PropertySheet(self, sheet):
! """Return the sheet named by 'sheet'"""
! return getattr(self.propertysheets, sheet)
def changeUser(self, password, roles, domains):
"""
Change me!
! These items (pw, roles, doains) will be moved to a designated
propertysheet in the final implementation. This method will
probably hang around after that as a shortcut.
"""
--- 157,171 ----
'category': 'user'},
]
! def _getPassword(self):
! # Needed for PortalObjectBase.mailPassword
! return self._v_rack._getPassword(self.id)
def changeUser(self, password, roles, domains):
"""
Change me!
! These items (pw, roles, domains) will be moved to a designated
propertysheet in the final implementation. This method will
probably hang around after that as a shortcut.
"""
***************
*** 114,132 ****
def manage_addPersistentUserSource(self, id, title='', REQUEST=None):
"""Add a PUS"""
! ob = PersistentUserSource(id)
! ob.id = id
! ob.title = title
! self._setObject(id, ob)
! if REQUEST is not None:
! return self.manage_UserSourcesForm(
! self, REQUEST, update_menu=1,
! message='Added Persistent User Source.')
!
! registerUserSource(
! 'Persistent User Source',
! addform = ('manage_addPersistentUserSourceForm',
! manage_addPersistentUserSourceForm),
! addmethod = ('manage_addPersistentUserSource',
! manage_addPersistentUserSource)
! )
--- 176,182 ----
def manage_addPersistentUserSource(self, id, title='', REQUEST=None):
"""Add a PUS"""
! ob = PersistentUserSource(id, title)
! return self.Destination()._installPlugIn(ob,
! 'Added Persistent User Source',
! REQUEST)
Index: Portal.py
===================================================================
RCS file: /cvs-repository/ZopePTK/PTKDemo/Portal.py,v
retrieving revision 1.17
diff -c -r1.17 Portal.py
*** Portal.py 2000/04/06 20:27:57 1.17
--- Portal.py 2000/05/23 20:18:48
***************
*** 37,42 ****
--- 37,54 ----
('Owner',)),
)
+ _using_LoginManager = 0
+
+ def _getPUS(self):
+ if self._using_LoginManager:
+ # Get the PersistentUserSource object that stores our users
+ for us in self.acl_users.UserSourcesGroup.objectValues():
+ if us.meta_type == 'Persistent User Source':
+ # The following works around a PlugIn bug
+ return us.__of__(self.acl_users)
+ else:
+ return self.acl_users
+
def install(self, REQUEST=None):
"""Set up initial components -- called by ZClass constructor"""
***************
*** 57,72 ****
acl_users = self.MembersClass()
self.this()._setObject('acl_users', acl_users)
elif db == 'LoginManager':
! from Products.LoginManager.LoginManager import LoginManager
self.MembersClass = LoginManager
! acl_users = self.MembersClass()
! self.this()._setObject('acl_users', acl_users)
! self.acl_users.manage_addPersistentUserSource('PUS')
! self.acl_users.PUS.manage_class('DemoPortal/LoginMember')
else:
self.MembersClass = self.SQLMemberFolder
acl_users = self.MembersClass(db)
self.this()._setObject('acl_users', acl_users)
# I'm not sure why this is done via this() but this is what
# addMemberFolder does, so I do as well.
self.this().__allow_groups__=self.acl_users
--- 69,90 ----
acl_users = self.MembersClass()
self.this()._setObject('acl_users', acl_users)
elif db == 'LoginManager':
! self._using_LoginManager = 1
! from Products.LoginManager.LoginManager import \
! LoginManager, manage_addLoginManager
! from PersistentUserSource import PersistentUserSource
self.MembersClass = LoginManager
! manage_addLoginManager(self,
! 'Persistent User Source',
! ['Basic Cookie Login', 'Basic Auth Login'],
! 0, 0, 0)
! # self.acl_users was magically created by the above call
! self._getPUS().manage_setStorage('DemoPortal/LoginMember')
else:
self.MembersClass = self.SQLMemberFolder
acl_users = self.MembersClass(db)
self.this()._setObject('acl_users', acl_users)
+
# I'm not sure why this is done via this() but this is what
# addMemberFolder does, so I do as well.
self.this().__allow_groups__=self.acl_users
***************
*** 78,105 ****
catalog = self.SiteIndex
catalog.initialize()
! ## # Create roles
! ## self._addRole('Member')
! ## self._addRole('Reviewer')
! ## self._addRole('Contributor')
!
! ## # Give permissions out
! ## self.manage_role('Owner', [
! ## 'View management screens',
! ## 'Add portal content',
! ## 'Add Folders',
! ## 'Delete objects',
! ## 'FTP access',
! ## 'Manage properties',
! ## 'Undo changes',
! ## 'Request review'
! ## ])
! ## self.manage_role('Reviewer', [
! ## 'Review portal content',
! ## ])
! ## self.manage_role('Contributor', [
! ## 'Contribute portal content',
! ## ])
def portal_reconfig(self, REQUEST):
"Accept changes from portal_config"
--- 96,126 ----
catalog = self.SiteIndex
catalog.initialize()
! # Create roles
! self._addRole('Member')
! self._addRole('Reviewer')
! self._addRole('Contributor')
!
! # Give permissions out
! self.manage_role('Owner', [
! 'View management screens',
! 'Add portal content',
! 'Add Folders',
! 'Delete objects',
! 'FTP access',
! 'Manage properties',
! 'Undo changes',
! 'Request review'
! ])
! self.manage_role('Reviewer', [
! 'Review portal content',
! ])
! self.manage_role('Contributor', [
! 'Contribute portal content',
! ])
! self.manage_role('Member', [
! 'Reply to item',
! ])
def portal_reconfig(self, REQUEST):
"Accept changes from portal_config"
***************
*** 137,145 ****
"""
# Consider changing this to check for a permission rather than a role
if REQUEST.AUTHENTICATED_USER.has_role('Manager'):
! return self.acl_users.getUserNames()
names = []
! for user in self.acl_users.getUsers():
if user.listed:
names.append(user.getUserName())
return names
--- 158,166 ----
"""
# Consider changing this to check for a permission rather than a role
if REQUEST.AUTHENTICATED_USER.has_role('Manager'):
! return self._getPUS().getUserNames()
names = []
! for user in self._getPUS().getUsers():
if user.listed:
names.append(user.getUserName())
return names
***************
*** 152,158 ****
if self.acl_users.meta_type == 'Login Manager':
# The acl_users folder is a LoginManager. Search for a UserSource
# with the needed support.
! for source in self.acl_users.userSourcesList:
if hasattr(source, 'addUser'):
source.__of__(self).addUser(name, password, roles, domains)
return
--- 173,179 ----
if self.acl_users.meta_type == 'Login Manager':
# The acl_users folder is a LoginManager. Search for a UserSource
# with the needed support.
! for source in self.acl_users.UserSourcesGroup.objectValues():
if hasattr(source, 'addUser'):
source.__of__(self).addUser(name, password, roles, domains)
return
***************
*** 241,251 ****
self.acl_users.getUser(username).setMemberProperties(REQUEST)
# Create manager's home folder
! manage_addPortalFolder(self.Members, username)
! f=getattr(self.Members, username)
!
! # Create manager's default page
! # f.manage_addDTMLMethod('index_html', title=username, file=self.memberdefault_html)
# Copy the interface
self.refresh_interface(interface)
--- 262,268 ----
self.acl_users.getUser(username).setMemberProperties(REQUEST)
# Create manager's home folder
! self.register_hook(REQUEST)
# Copy the interface
self.refresh_interface(interface)
Index: __init__.py
===================================================================
RCS file: /cvs-repository/ZopePTK/PTKDemo/__init__.py,v
retrieving revision 1.2
diff -c -r1.2 __init__.py
*** __init__.py 2000/02/28 22:00:54 1.2
--- __init__.py 2000/05/23 20:18:48
***************
*** 17,19 ****
--- 17,30 ----
'Demo SQL Member Folder Base')
context.registerBaseClass(PersistentUserSource.MemberMixin,
'PTK Member Mix-in')
+
+ # PlugIns
+ context.registerPlugInClass(
+ PersistentUserSource.PersistentUserSource,
+ permission = 'Add Persistent User Source',
+ constructors = (PersistentUserSource.manage_addPersistentUserSourceForm,
+ PersistentUserSource.manage_addPersistentUserSource),
+ )
+
+
+