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