[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),
+         )
+ 
+ 
+