Package Products :: Package ZenUtils :: Package patches :: Module dirviewmonkey
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenUtils.patches.dirviewmonkey

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2007, all rights reserved. 
  4  #  
  5  # This content is made available according to terms specified in 
  6  # License.zenoss under the directory where your Zenoss product is installed. 
  7  #  
  8  ############################################################################## 
  9   
 10   
 11  """ 
 12  This module patches CMFCore DirectoryViews to allow unauthenticated users 
 13  access to filesystem-based resources. This is necessary for ZenDeviceACL to 
 14  function. 
 15  """ 
 16   
 17  ####################################################### 
 18  # DirectoryView imports 
 19  ####################################################### 
 20  import logging 
 21  from os import path 
 22  from OFS.ObjectManager import bad_id 
 23   
 24  from Products.CMFCore.FSMetadata import FSMetadata 
 25  from Products.CMFCore.FSObject import BadFile 
 26   
 27  logger = logging.getLogger('CMFCore.DirectoryView') 
 28   
 29  ####################################################### 
 30  # Imports from DirectoryView itself 
 31  ####################################################### 
 32  from Products.CMFCore.DirectoryView import _filtered_listdir 
 33  from Products.CMFCore.DirectoryView import DirectoryView 
 34   
 35  ####################################################### 
 36  # The only import we need 
 37  ####################################################### 
 38  from Products.ZenUtils.Utils import monkeypatch 
39 40 @monkeypatch(FSMetadata) 41 -def read(self):
42 """ Find the files to read, either the old security and 43 properties type or the new metadata type """ 44 filename = self._filename + '.metadata' 45 if path.exists(filename): 46 # found the new type, lets use that 47 self._readMetadata() 48 else: 49 ########################################################################### 50 # This is a monkeypatch. CMFCore 2.0 returns {} where 1.x returned 51 # None; we rely on None. {} is (maybe) ambiguous. 52 ########################################################################### 53 self._properties = None 54 self._security = None
55 ###########################################################################
56 # End monkeypatch 57 ########################################################################### 58 59 60 @monkeypatch('Products.CMFCore.DirectoryView.DirectoryInformation') 61 -def prepareContents(self, registry, register_subdirs=0):
62 # Creates objects for each file. 63 data = {} 64 objects = [] 65 types = self._readTypesFile() 66 for entry in _filtered_listdir(self._filepath, ignore=self.ignore): 67 if not self._isAllowableFilename(entry): 68 continue 69 entry_filepath = path.join(self._filepath, entry) 70 if path.isdir(entry_filepath): 71 # Add a subdirectory only if it was previously registered, 72 # unless register_subdirs is set. 73 entry_reg_key = '/'.join((self._reg_key, entry)) 74 info = registry.getDirectoryInfo(entry_reg_key) 75 if info is None and register_subdirs: 76 # Register unknown subdirs 77 registry.registerDirectoryByKey(entry_filepath, 78 entry_reg_key) 79 info = registry.getDirectoryInfo(entry_reg_key) 80 if info is not None: 81 # Folders on the file system have no extension or 82 # meta_type, as a crutch to enable customizing what gets 83 # created to represent a filesystem folder in a 84 # DirectoryView we use a fake type "FOLDER". That way 85 # other implementations can register for that type and 86 # circumvent the hardcoded assumption that all filesystem 87 # directories will turn into DirectoryViews. 88 mt = types.get(entry) or 'FOLDER' 89 t = registry.getTypeByMetaType(mt) 90 if t is None: 91 t = DirectoryView 92 metadata = FSMetadata(entry_filepath) 93 metadata.read() 94 ob = t( entry 95 , entry_reg_key 96 , properties=metadata.getProperties() 97 ) 98 ob_id = ob.getId() 99 data[ob_id] = ob 100 objects.append({'id': ob_id, 'meta_type': ob.meta_type}) 101 else: 102 pos = entry.rfind('.') 103 if pos >= 0: 104 name = entry[:pos] 105 ext = path.normcase(entry[pos + 1:]) 106 else: 107 name = entry 108 ext = '' 109 if not name or name == 'REQUEST': 110 # Not an allowable id. 111 continue 112 mo = bad_id(name) 113 if mo is not None and mo != -1: # Both re and regex formats 114 # Not an allowable id. 115 continue 116 t = None 117 mt = types.get(entry, None) 118 if mt is None: 119 mt = types.get(name, None) 120 if mt is not None: 121 t = registry.getTypeByMetaType(mt) 122 if t is None: 123 t = registry.getTypeByExtension(ext) 124 125 if t is not None: 126 metadata = FSMetadata(entry_filepath) 127 metadata.read() 128 try: 129 ob = t(name, entry_filepath, fullname=entry, 130 properties=metadata.getProperties()) 131 except: 132 import sys 133 import traceback 134 typ, val, tb = sys.exc_info() 135 try: 136 logger.exception("prepareContents") 137 138 exc_lines = traceback.format_exception( typ, 139 val, 140 tb ) 141 ob = BadFile( name, 142 entry_filepath, 143 exc_str='\r\n'.join(exc_lines), 144 fullname=entry ) 145 finally: 146 tb = None # Avoid leaking frame! 147 148 # FS-based security 149 permissions = metadata.getSecurity() 150 if permissions is not None: 151 for name in permissions.keys(): 152 acquire, roles = permissions[name] 153 try: 154 ob.manage_permission(name,roles,acquire) 155 except ValueError: 156 logger.exception("Error setting permissions") 157 ########################################################################### 158 # This is the monkeypatch. These lines don't exist in CMFCore. This allows 159 # unauthenticated users to access filesystem-based resources like page 160 # templates and static UI elements. 161 ########################################################################### 162 else: 163 ob.manage_permission('View',('Authenticated',),1) 164 ########################################################################### 165 # End monkeypatch 166 ########################################################################### 167 168 # only DTML Methods and Python Scripts can have proxy roles 169 if hasattr(ob, '_proxy_roles'): 170 try: 171 ob._proxy_roles = tuple(metadata.getProxyRoles()) 172 except: 173 logger.exception("Error setting proxy role") 174 175 ob_id = ob.getId() 176 data[ob_id] = ob 177 objects.append({'id': ob_id, 'meta_type': ob.meta_type}) 178 179 return data, tuple(objects)
180