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

Source Code for Module Products.ZenUtils.patches.dirviewmonkey

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