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 as published by 
  8  # 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   
 44  @monkeypatch('Products.CMFCore.DirectoryView.DirectoryInformation') 
45 -def prepareContents(self, registry, register_subdirs=0):
46 # Creates objects for each file. 47 data = {} 48 objects = [] 49 types = self._readTypesFile() 50 for entry in _filtered_listdir(self._filepath, ignore=self.ignore): 51 if not self._isAllowableFilename(entry): 52 continue 53 entry_filepath = path.join(self._filepath, entry) 54 if path.isdir(entry_filepath): 55 # Add a subdirectory only if it was previously registered, 56 # unless register_subdirs is set. 57 entry_reg_key = '/'.join((self._reg_key, entry)) 58 info = registry.getDirectoryInfo(entry_reg_key) 59 if info is None and register_subdirs: 60 # Register unknown subdirs 61 registry.registerDirectoryByKey(entry_filepath, 62 entry_reg_key) 63 info = registry.getDirectoryInfo(entry_reg_key) 64 if info is not None: 65 # Folders on the file system have no extension or 66 # meta_type, as a crutch to enable customizing what gets 67 # created to represent a filesystem folder in a 68 # DirectoryView we use a fake type "FOLDER". That way 69 # other implementations can register for that type and 70 # circumvent the hardcoded assumption that all filesystem 71 # directories will turn into DirectoryViews. 72 mt = types.get(entry) or 'FOLDER' 73 t = registry.getTypeByMetaType(mt) 74 if t is None: 75 t = DirectoryView 76 metadata = FSMetadata(entry_filepath) 77 metadata.read() 78 ob = t( entry 79 , entry_reg_key 80 , properties=metadata.getProperties() 81 ) 82 ob_id = ob.getId() 83 data[ob_id] = ob 84 objects.append({'id': ob_id, 'meta_type': ob.meta_type}) 85 else: 86 pos = entry.rfind('.') 87 if pos >= 0: 88 name = entry[:pos] 89 ext = path.normcase(entry[pos + 1:]) 90 else: 91 name = entry 92 ext = '' 93 if not name or name == 'REQUEST': 94 # Not an allowable id. 95 continue 96 mo = bad_id(name) 97 if mo is not None and mo != -1: # Both re and regex formats 98 # Not an allowable id. 99 continue 100 t = None 101 mt = types.get(entry, None) 102 if mt is None: 103 mt = types.get(name, None) 104 if mt is not None: 105 t = registry.getTypeByMetaType(mt) 106 if t is None: 107 t = registry.getTypeByExtension(ext) 108 109 if t is not None: 110 metadata = FSMetadata(entry_filepath) 111 metadata.read() 112 try: 113 ob = t(name, entry_filepath, fullname=entry, 114 properties=metadata.getProperties()) 115 except: 116 import sys 117 import traceback 118 typ, val, tb = sys.exc_info() 119 try: 120 logger.exception("prepareContents") 121 122 exc_lines = traceback.format_exception( typ, 123 val, 124 tb ) 125 ob = BadFile( name, 126 entry_filepath, 127 exc_str='\r\n'.join(exc_lines), 128 fullname=entry ) 129 finally: 130 tb = None # Avoid leaking frame! 131 132 # FS-based security 133 permissions = metadata.getSecurity() 134 if permissions is not None: 135 for name in permissions.keys(): 136 acquire, roles = permissions[name] 137 try: 138 ob.manage_permission(name,roles,acquire) 139 except ValueError: 140 logger.exception("Error setting permissions") 141 ########################################################################### 142 # This is the monkeypatch. These lines don't exist in CMFCore. This allows 143 # unauthenticated users to access filesystem-based resources like page 144 # templates and static UI elements. 145 ########################################################################### 146 else: 147 ob.manage_permission('View',('Authenticated',),1) 148 ########################################################################### 149 # End monkeypatch 150 ########################################################################### 151 152 # only DTML Methods and Python Scripts can have proxy roles 153 if hasattr(ob, '_proxy_roles'): 154 try: 155 ob._proxy_roles = tuple(metadata.getProxyRoles()) 156 except: 157 logger.exception("Error setting proxy role") 158 159 ob_id = ob.getId() 160 data[ob_id] = ob 161 objects.append({'id': ob_id, 'meta_type': ob.meta_type}) 162 163 return data, tuple(objects)
164