Back to index

plone3  3.1.7
GRUFTestCase.py
Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 ## GroupUserFolder
00003 ## Copyright (C)2006 Ingeniweb
00004 
00005 ## This program is free software; you can redistribute it and/or modify
00006 ## it under the terms of the GNU General Public License as published by
00007 ## the Free Software Foundation; either version 2 of the License, or
00008 ## (at your option) any later version.
00009 
00010 ## This program is distributed in the hope that it will be useful,
00011 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 ## GNU General Public License for more details.
00014 
00015 ## You should have received a copy of the GNU General Public License
00016 ## along with this program; see the file COPYING. If not, write to the
00017 ## Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 """
00019 
00020 """
00021 __version__ = "$Revision:  $"
00022 # $Source:  $
00023 # $Id: GRUFTestCase.py 30098 2006-09-08 12:35:01Z encolpe $
00024 __docformat__ = 'restructuredtext'
00025 
00026 import os, sys
00027 if __name__ == '__main__':
00028     execfile(os.path.join(sys.path[0], 'framework.py'))
00029 
00030 # Load fixture
00031 from Testing import ZopeTestCase
00032 
00033 # Permissions / security
00034 from AccessControl.Permissions import access_contents_information, view, add_documents_images_and_files, change_images_and_files, view_management_screens
00035 from AccessControl.SecurityManagement import newSecurityManager, noSecurityManager, getSecurityManager
00036 from AccessControl import Unauthorized
00037 from AccessControl.User import UnrestrictedUser
00038 from AccessControl import Permission
00039 import urllib
00040 
00041 
00042 
00043 # Set log options if Log module is available
00044 # This is done to set LOG_PROCESSORs to file logs instead of Zope logs
00045 try:
00046     import Log
00047 
00048     Log.LOG_LEVEL = Log.LOG_DEBUG
00049 
00050     Log.LOG_PROCESSOR = {
00051         Log.LOG_NONE: Log.LogFile,
00052         Log.LOG_CRITICAL: Log.LogFile,
00053         Log.LOG_ERROR: Log.LogFile,
00054         Log.LOG_WARNING: Log.LogFile,
00055         Log.LOG_NOTICE: Log.LogFile,
00056         Log.LOG_DEBUG: Log.LogFile,
00057         }
00058 
00059     from Log import *
00060     Log(LOG_NOTICE, "Starting %s at %d debug level" % (os.path.dirname(__file__), LOG_LEVEL, ))
00061 
00062 except:
00063     print "Log module not available"
00064     LOG_DEBUG = None
00065     LOG_NOTICE = None
00066     LOG_WARNING = None
00067     LOG_ERROR = None
00068     LOG_CRITICAL = None
00069     def Log(*args, **kw):
00070         pass
00071     raise
00072 
00073 
00074 
00075 class ManagementOpener(urllib.FancyURLopener):
00076     def prompt_user_passwd(self, host, realm): 
00077         return ('manager', 'secret')
00078         
00079 class UnauthorizedOpener(urllib.FancyURLopener):
00080     def prompt_user_passwd(self, host, realm): 
00081         raise Unauthorized, 'The URLopener was asked for authentication'
00082 
00083 
00084 class GRUFTestCase(ZopeTestCase.ZopeTestCase):
00085 
00086     def gruf_setup(self,):
00087         """
00088         gruf_setup(self,) => Basic gruf setup
00089         """
00090         # Replace default acl_user by a GRUF one
00091         self.folder.manage_delObjects(['acl_users'])
00092         self.folder.manage_addProduct['OFSP'].manage_addFolder('testFolder')
00093         self.gruf_folder = self.folder.testFolder
00094         self.gruf_folder.manage_addProduct['GroupUserFolder'].manage_addGroupUserFolder()
00095         self.gruf = self.gruf_folder.acl_users
00096 
00097 
00098     def gruf_sources_setup(self,):
00099         """
00100         gruf_sources_setup(self,) => this method installs the required sources inside GRUF.
00101         One can override this in a test case to install other sources and make another bunch of unit tests
00102         For example, for LDAPUserFolder, use manage_addProduct/LDAPUserFolder/addLDAPUserFolder
00103         """
00104         # Use this to replace the default user source
00105         self.gruf.replaceUserSource("Users", "manage_addProduct/OFSP/manage_addUserFolder")
00106 
00107         # Use this to replace the default group source
00108         self.gruf.replaceUserSource("Groups", "manage_addProduct/OFSP/manage_addUserFolder")
00109 
00110         # add a second (empty) user source
00111         self.gruf.addUserSource("manage_addProduct/OFSP/manage_addUserFolder")
00112 
00113     def security_context_setup(self,):
00114         """
00115         Build a complex security environment
00116 
00117         It creates:
00118           * 3 roles, r1, r2 and r3
00119           * 3 groups: g1, g2, g3
00120           * n users as follows (roles are between parenthesis)
00121 
00122                       !   g1    ! g2(r1)     ! g3(r2)     ! g4(r2,r3)  !  Resulting roles !
00123           ------------!---------!------------!------------!------------!------------------!
00124           u1          !         !            !            !            !   => (no role)   !
00125           u2          !   X     !            !            !            !   => (no role)   !
00126           u3          !   X     !      X     !            !            !   => r1          !
00127           u4          !   X     !      X     !      X     !            !   => r1,r2       !
00128           u5(r1)      !         !      X     !      X     !            !   => r1,r2       !
00129           u6(r1)      !         !            !      X     !            !   => r1,r2       !
00130           u7(r1)      !         !            !            !     X      !   => r1,r2,r3    !
00131           ---------------------------------------------------------------------------------
00132 
00133         It also creates a 'lr' folder in which g1 group and u3 and u6 are granted r3 role.
00134 
00135 
00136         And then, it creates nested groups as follow (-> = belongs to group...):
00137 
00138              u/g   !  belongs to... ! resulting roles                     !
00139          ----------!----------------!-------------------------------------!
00140           ng1      !   g1           ! (no role)                           !
00141           ng2      !   g2, g3       ! r1, r2                              !
00142           ng3      !   g2, ng2      ! r1, r2                              !
00143           ng4(r3)  !   g2, ng2      ! r1, r2, r3                          !
00144           ng5      !   g2, ng4      ! r1, r2, r3                          !
00145           ng6      !   ng5, ng6     ! r1, r2, r3 (no circ. ref)           !
00146           u8       !   ng1          ! (no role)                           !
00147           u9       !   g1, ng2      ! r1, r2                              !
00148           u10      !   ng2, ng3     ! r1, r2                              !
00149           u11(r3)  !   ng2, ng3     ! r1, r2, r3                          !
00150           u12      !   ng5, ng6     ! r1, r2, r3                          !
00151          -----------------------------------------------------------------!
00152 
00153          Plus we have the following local roles matrix (roles inside parenthesis are implicitly
00154          user-defined, roles inside brackets are implicitly lr-defined).
00155 
00156          folder
00157            |
00158            |-- acl_users (GRUF)
00159            |
00160            |                                          r1    r2    r3
00161            |                             /--
00162            |                             | group_g1               x
00163            |-- lr                        | u3        (x)          x
00164                |                         | u6        (x)   (x)    x
00165                |                         \--
00166                |
00167                |                         /--
00168                |                         | group_g1              [x]
00169                |-- sublr                 | u3        (x)    x    [x]
00170                |                         | u6        (x)    x*   [x]
00171                |                         \--
00172                |
00173                |                         /--
00174                |                         | group_g1              [x]
00175                |-- sublr2                | u3        (x)    x    [x]
00176                |   |                     | u6        (x)    x*   [x]
00177                |   |                     \--
00178                |   |
00179                |   |                     /--
00180                |   |                     | group_g1              [x]
00181                |   |-- subsublr2         | u3        (x)   [x]   [x]
00182                |                         | u6        (x)  [(x)]  [x]
00183                |                         \--
00184                |
00185          (now we block local roles under this branch)
00186                |
00187                |                         /--
00188                |                         | group_g1              
00189                |-- sublr3                | u3        (x)    x    
00190                    |                     | u6        (x)    x*   
00191                    |                     \--
00192                    |
00193                    |                     /--
00194                    |                     | group_g1              
00195                    |-- subsublr3         | u3        (x)   [x]   
00196                                          | u6        (x)  [(x)]  
00197                                          \--
00198                                          
00199         *: u6 will have r2 as a localrole AND a userdefined role.
00200         """
00201         # Create a few roles
00202         self.gruf.userFolderAddRole("r1")
00203         self.gruf.userFolderAddRole("r2")
00204         self.gruf.userFolderAddRole("r3")
00205 
00206         # Set View permission on those roles
00207         permissions = self.gruf_folder.ac_inherited_permissions(1)
00208         for ip in range(len(permissions)):
00209             name, value = permissions[ip][:2]
00210             if name == "View":
00211                 break
00212         p=Permission.Permission(name,value, self.gruf_folder)
00213         p.setRoles(("r1", "r2", "r3", ))
00214 
00215         # Setup users and groups
00216         self.security_context_setup_groups()
00217         self.security_context_setup_users()
00218         
00219         # Create a few folders to play with
00220         self.gruf_folder.manage_addProduct['OFSP'].manage_addFolder('lr')
00221         lr = self.gruf_folder.lr
00222         lr.manage_addProduct['OFSP'].manage_addFolder("sublr")
00223         sublr = self.gruf_folder.lr.sublr
00224         lr.manage_addProduct['OFSP'].manage_addFolder("sublr2")
00225         sublr2 = self.gruf_folder.lr.sublr2
00226         sublr2.manage_addProduct['OFSP'].manage_addFolder("subsublr2")
00227         subsublr2 = self.gruf_folder.lr.sublr2.subsublr2
00228         lr.manage_addProduct['OFSP'].manage_addFolder("sublr3")
00229         sublr3 = self.gruf_folder.lr.sublr3
00230         sublr3.manage_addProduct['OFSP'].manage_addFolder("subsublr3")
00231         subsublr3 = self.gruf_folder.lr.sublr3.subsublr3
00232         self.gruf._acquireLocalRoles(sublr3, 0)
00233         lr.manage_addLocalRoles("group_g1", ("r3", ))
00234         lr.manage_addLocalRoles("u3", ("r3", ))
00235         lr.manage_addLocalRoles("u6", ("r3", ))
00236         sublr.manage_addLocalRoles("u3", ("r2", ))
00237         sublr.manage_addLocalRoles("u6", ("r2", ))
00238         sublr2.manage_addLocalRoles("u3", ("r2", ))
00239         sublr2.manage_addLocalRoles("u6", ("r2", ))
00240         sublr3.manage_addLocalRoles("u3", ("r2", ))
00241         sublr3.manage_addLocalRoles("u6", ("r2", ))
00242         self.lr = lr
00243         self.sublr = sublr
00244         self.sublr2 = sublr2
00245         self.sublr3 = sublr3
00246         self.subsublr2 = subsublr2
00247         self.subsublr3 = subsublr3
00248 
00249 
00250     def security_context_setup_users(self,):
00251         # Create a manager and a few users
00252         self.gruf.userFolderAddUser('manager', 'secret', ('Manager',), (), (), )
00253         self.gruf.userFolderAddUser('u1', 'secret', (), (), (), )
00254         self.gruf.userFolderAddUser('u2', 'secret', (), (), ('g1', ), )
00255         self.gruf.userFolderAddUser('u3', 'secret', (), (), ('g1', 'g2'), )
00256         self.gruf.userFolderAddUser('u4', 'secret', (), (), ('g1', 'g2', 'g3'), )
00257         self.gruf.userFolderAddUser('u5', 'secret', ('r1', ), (), ('g2', 'g3'), )
00258         self.gruf.userFolderAddUser('u6', 'secret', ('r1', ), (), ('g3', ), )
00259         self.gruf.userFolderAddUser('u7', 'secret', ('r1', ), (), ('g4', ), )
00260 
00261         # Create nested-groups users
00262         self.gruf.userFolderAddUser('u8', 'secret', (), (), ('ng1', ), )        
00263         self.gruf.userFolderAddUser('u9', 'secret', (), (), ('g1', 'ng2', ), )
00264         self.gruf.userFolderAddUser('u10', 'secret', (), (), ('ng2', 'ng3', ), )        
00265         self.gruf.userFolderAddUser('u11', 'secret', ('r3', ), (), ('ng2', 'ng3', ), )        
00266 ##        self.gruf.userFolderAddUser('u12', 'secret', (), (), ('ng5', 'ng6', ), )        
00267 
00268     def security_context_setup_groups(self,):
00269         "create groups. We splitted to allow LDAP tests to override this"
00270         # Create a few groups
00271         self.gruf.userFolderAddGroup('g1', ())
00272         self.gruf.userFolderAddGroup('g2', ('r1', ))
00273         self.gruf.userFolderAddGroup('g3', ('r2', ))
00274         self.gruf.userFolderAddGroup('g4', ('r2', 'r3', ))
00275 
00276         # Create nested groups
00277         self.gruf.userFolderAddGroup('ng1', (), ('g1', ))
00278         self.gruf.userFolderAddGroup('ng2', (), ('g2', 'g3', ))
00279         self.gruf.userFolderAddGroup('ng3', (), ('g2', 'ng2', ))
00280         self.gruf.userFolderAddGroup('ng4', ('r3', ), ('g2', 'ng2', ))
00281         self.gruf.userFolderAddGroup('ng5', (), ('g2', 'ng4', ))
00282 ##        self.gruf.userFolderAddGroup('ng6', (), ('ng5', 'ng6', ))
00283 
00284         # Special case of nesting
00285         self.gruf.userFolderAddGroup('extranet', (), ())
00286         self.gruf.userFolderAddGroup('intranet', (), ('extranet', ))
00287         self.gruf.userFolderAddGroup('compta', (), ('intranet', 'extranet' ))
00288 
00289 
00290     def afterSetUp(self,):
00291         """
00292         afterSetUp(self) => This method is called to create Folder with a GRUF inside.
00293         """
00294         self.gruf_setup()
00295         self.gruf_sources_setup()
00296         self.security_context_setup()
00297 ##        # Need to commit so the ZServer threads see what we've done
00298 ##        get_transaction().commit()
00299 
00300 
00301 
00302     def beforeClose(self):
00303 ##        # Commit after cleanup
00304 ##        get_transaction().commit()
00305 
00306         # Remove users. This may be useful for non-ZODB user sources.
00307         self.delete_created_users()
00308 
00309     def delete_created_users(self,):
00310         self.gruf.userFolderDelUsers([
00311             "manager",
00312             "u1",
00313             "u2",
00314             "u3",
00315             "u4",
00316             "u5",
00317             "u6",
00318             "u7",
00319             "u8",
00320             "u9",
00321             "u10",
00322             "u11",
00323             "created_user",
00324             "test_prefix",
00325             "group_test_prefix",
00326             ])
00327         self.gruf.userFolderDelGroups([
00328             "g1",
00329             "g2",
00330             "g3",
00331             "g4",
00332             "ng1",
00333             "ng2",
00334             "ng3",
00335             "ng4",
00336             "ng5",
00337             "extranet",
00338             "intranet",
00339             "compta",
00340             ])
00341 
00342     def compareRoles(self, target, user, roles):
00343         """
00344         compareRoles(self, target, user, roles) => do not raise if user has exactly the specified roles.
00345         If target is None, test user roles (no local roles)
00346         """
00347         u = self.gruf.getUser(user)
00348         if not u:
00349             raise RuntimeError, "compareRoles: Invalid user: '%s'" % user
00350         if target is None:
00351             actual_roles = filter(lambda x: x not in ('Authenticated', 'Anonymous', ''), list(u.getRoles()))
00352         else:
00353             actual_roles = filter(lambda x: x not in ('Authenticated', 'Anonymous', ''), list(u.getRolesInContext(target)))
00354         actual_roles.sort()
00355         wished_roles = list(roles)
00356         wished_roles.sort()
00357         if actual_roles == wished_roles:
00358             return 1
00359         raise RuntimeError, "User %s: Whished roles: %s BUT current roles: %s" % (user, wished_roles, actual_roles)
00360 
00361 
00362     def compareGroups(self, user, groups):
00363         """
00364         compareGroups(self, user, groups) => do not raise if user has exactly the specified groups.
00365         """
00366         u = self.gruf.getUser(user)
00367         if not u:
00368             raise RuntimeError, "compareGroups: Invalid user: '%s'" % user
00369         actual_groups = list(u.getGroups())
00370         actual_groups.sort()
00371         wished_groups = map(lambda x: "group_%s" % x, list(groups))
00372         wished_groups.sort()
00373         if actual_groups == wished_groups:
00374             return 1
00375         raise RuntimeError, "User %s: Whished groups: %s BUT current groups: %s" % (user, wished_groups, actual_groups)
00376 
00377