Package Products :: Package ZenModel :: Module ZentinelPortal |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenModel.ZentinelPortal

      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  """ Portal class
     14
     15  $Id: ZentinelPortal.py,v 1.17 2004/04/08 15:35:25 edahl Exp $
     16  """
     17
     18  import urllib, urlparse
     19  import re
     20
     21  import Globals
     22
     23  from zExceptions import Redirect
     24  from AccessControl import getSecurityManager, ClassSecurityInfo
     25
     26  from Products.Sessions.BrowserIdManager import constructBrowserIdManager
     27  from Products.Sessions.SessionDataManager import constructSessionDataManager
     28
     29  from Products.CMFCore.PortalObject import PortalObjectBase
     30  from Products.CMFCore.utils import getToolByName
     31
     32  from Products.ZenUtils import Security, Time
     33  from Products.ZenUtils.Utils import prepId
     34  from Products.ZenUI3.browser.interfaces import IErrorMessage
     35
     36  from ZenossSecurity import *
     37
     38  from Products.AdvancedQuery import MatchGlob, Eq, Or
     39
     40 -class ZentinelPortal ( PortalObjectBase ):
     41      """
     42      The *only* function this class should have is to help in the setup
     43      of a new ZentinelPortal. It should not assist in the functionality at all.
     44      """
     45      meta_type = 'ZentinelPortal'
     46
     47      _properties = (
     48          {'id':'title', 'type':'string'},
     49          {'id':'description', 'type':'text'},
     50          )
     51      title = ''
     52      description = ''
     53
     54      security = ClassSecurityInfo()
     55
     56 -    def __init__( self, id, title='' ):
     57          PortalObjectBase.__init__( self, id, title )
     58
     59 -    def server_time(self):
     60          return Time.isoDateTime()
     61
     62 -    def _additionalQuery(self):
     63          return None
     64
     65      security.declareProtected(ZEN_COMMON, 'searchDevices')
     66 -    def searchDevices(self, queryString='', REQUEST=None):
     67          """Returns the concatenation of a device name, ip and mac
     68          search on the list of devices.
     69          """
     70          zcatalog = self.dmd.Devices.deviceSearch
     71          glob = queryString.rstrip('*') + '*'
     72          idGlob = MatchGlob('id', glob)
     73          titleGlob = MatchGlob('titleOrId', glob)
     74          idOrTitleQuery = Or(idGlob,titleGlob)
     75          query = Or(idOrTitleQuery, Eq('getDeviceIp', queryString))
     76          additionalQuery = self._additionalQuery()
     77          if additionalQuery:
     78              query = And( query, additionalQuery )
     79          brains = zcatalog.evalAdvancedQuery(query)
     80          if REQUEST and len(brains) == 1:
     81              raise Redirect(urllib.quote(brains[0].getPrimaryId))
     82          if additionalQuery:
     83              idGlob = And( idGlob, additionalQuery )
     84          brains += self.dmd.Networks.ipSearch.evalAdvancedQuery(idGlob)
     85          return [ b.getObject() for b in brains ]
     86
     87      security.declareProtected(ZEN_COMMON, 'searchComponents')
     88 -    def searchComponents(self, device='', component='', REQUEST=None):
     89          """
     90          Redirect to the component of a device. Hopefully.
     91          """
     92          catalog = self.dmd.Devices.componentSearch
     93          brains = []
     94          if device and component:
     95              brains = catalog(getParentDeviceName=device)
     96          matchingBrains = []
     97          if brains:
     98              component = prepId(component)
     99              for brain in brains:
    100                  if brain.getPath().split('/')[-1]==component:
    101                      if REQUEST:
    102                          raise Redirect(urllib.quote(
    103                              brain.getPath()+'/viewEvents'))
    104                      else:
    105                          matchingBrains.append(brain)
    106              if REQUEST and len(matchingBrains) == 0:
    107                  return self.searchDevices(device, REQUEST)
    108          return [b.getObject() for b in matchingBrains]
    109
    110      security.declareProtected(ZEN_COMMON, 'dotNetProxy')
    111 -    def dotNetProxy(self, path='', params={}, REQUEST=None):
    112          """
    113          Logs in to Zenoss.net using the user's credentials and retrieves data,
    114          thereby putting it in the current domain
    115          """
    116          session = self.dmd.ZenUsers.getUserSettings().getDotNetSession()
    117          response = session.open(path.lstrip('/'))
    118          if response:
    119              data = response.read()
    120              headers = response.headers.dict
    121              url = response.geturl()
    122              response.close()
    123          else:
    124              return response
    125          localbase = 'http://localhost:8080/zport/dotNetProxy?path='
    126          allrefs = re.compile(r"""(href *= *["']|src *= *["'])(.*?)(["'])""")
    127          proxyrefs = re.compile(
    128              r"""((<a[^<>]*?|location\.)href *= *["'])(.*?)(['"])""")
    129
    130          def mod_rewrite(matchobj):
    131              start, path, end = matchobj.groups()
    132              if not path.startswith('javascript'):
    133                  path = urlparse.urljoin(url, path)
    134              return start + path + end
    135
    136          def make_proxied(matchobj):
    137              start, trash, path, end = matchobj.groups()
    138              path = path.replace(session.base_url, localbase)
    139              return start + path + end
    140
    141          data = re.sub(allrefs, mod_rewrite, data)
    142          data = re.sub(proxyrefs, make_proxied, data)
    143          for header in headers:
    144              REQUEST.RESPONSE.setHeader(header, headers[header])
    145          return data
    146
    147 -    def isManager(self, obj=None):
    148          """
    149          Return true if user is authenticated and has Manager role.
    150          """
    151          user = self.dmd.ZenUsers.getUser()
    152          if user:
    153              return user.has_role((MANAGER_ROLE, ZEN_MANAGER_ROLE), obj)
    154
    155
    156 -    def has_role(self, role, obj=None):
    157          """Check to see of a user has a role.
    158          """
    159          if obj is None: obj = self
    160          user = getSecurityManager().getUser()
    161          if user: return user.has_role(role, obj)
    162
    163
    164 -    def has_permission(self, perm, obj=None):
    165          """Check to see of a user has a permission.
    166          """
    167          if obj is None: obj = self
    168          user = getSecurityManager().getUser()
    169          if user: return user.has_permission(perm, obj)
    170
    171 -    def getZenossVersionShort(self):
    172          return self.About.getZenossVersionShort()
    173
    174 -    def getExtraLoginFormContents(self):
    175          """
    176          On first run, log us in as admin automatically.
    177
    178          This is done via a proxy form with hidden fields, so that the browser
    179          doesn't ask to save the password (which will be changed on the next
    180          screen).
    181          """
    182          if not self.dmd._rq:
    183              return """
    184              <form id="_proxy_form">
    185              <input type="hidden" name="__ac_name"/>
    186              <input type="hidden" name="__ac_password"/>
    187              <input type="hidden" name="came_from" value="/zport/dmd/quickstart"/>
    188              </form>
    189              <script>
    190              var origform=document.forms[0];
    191              var newform = document.getElementById('_proxy_form');
    192              newform.__ac_name.value = 'admin';
    193              newform.__ac_password.value = 'zenoss';
    194              newform.action = origform.action;
    195              newform.method = origform.method;
    196              newform.submit()
    197              </script>
    198              """
    199
    200
    201  Globals.InitializeClass(ZentinelPortal)
    202
    203
    204 -class PortalGenerator:
    205
    206      klass = ZentinelPortal
    207
    208 -    def setupTools(self, p):
    209          """Set up initial tools"""
    210          addCMFCoreTool = p.manage_addProduct['CMFCore'].manage_addTool
    211          addCMFCoreTool('CMF Skins Tool', None)
    212
    213
    214 -    def setupMailHost(self, p):
    215          p.manage_addProduct['MailHost'].manage_addMailHost(
    216              'MailHost', smtp_host='localhost')
    217
    218
    219 -    def setupUserFolder(self, p):
    220          #p.manage_addProduct['OFSP'].manage_addUserFolder()
    221          Security.createPASFolder(p)
    222          Security.setupPASFolder(p)
    223
    224
    225 -    def setupCookieAuth(self, p):
    226          # XXX PAS is handling this now, right?
    227          #p.manage_addProduct['CMFCore'].manage_addCC(
    228          #    id='cookie_authentication')
    229          pass
    230
    231
    232 -    def setupRoles(self, p):
    233          # Set up the suggested roles.
    234          p.__ac_roles__ += (ZEN_USER_ROLE, ZEN_MANAGER_ROLE,)
    235
    236
    237 -    def setupPermissions(self, p):
    238          # Set up some suggested role to permission mappings.
    239          mp = p.manage_permission
    240          mp(ZEN_CHANGE_SETTINGS,[ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    241          mp(ZEN_CHANGE_DEVICE, [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    242          mp(ZEN_CHANGE_DEVICE_PRODSTATE,
    243              [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    244          mp(ZEN_MANAGE_DMD, [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    245          mp(ZEN_DELETE, [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    246          mp(ZEN_DELETE_DEVICE, [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    247          mp(ZEN_ADD, [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    248          mp(ZEN_VIEW, [ZEN_USER_ROLE, ZEN_MANAGER_ROLE,
    249                          MANAGER_ROLE, OWNER_ROLE])
    250          mp(ZEN_COMMON, ["Authenticated", ZEN_USER_ROLE, ZEN_MANAGER_ROLE,
    251                          MANAGER_ROLE, OWNER_ROLE], 1)
    252
    253          # Events
    254          mp(ZEN_MANAGE_EVENTMANAGER,
    255              [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    256          mp(ZEN_MANAGE_EVENTS,
    257              [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    258          mp(ZEN_SEND_EVENTS,
    259              [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    260
    261          mp(ZEN_CHANGE_ALERTING_RULES,
    262              [ZEN_MANAGER_ROLE, MANAGER_ROLE, OWNER_ROLE], 1)
    263          mp(ZEN_CHANGE_ADMIN_OBJECTS, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    264          mp(ZEN_CHANGE_EVENT_VIEWS, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    265          mp(ZEN_ADMIN_DEVICE, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    266          mp(ZEN_MANAGE_DEVICE, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    267          mp(ZEN_ZPROPERTIES_EDIT, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    268          mp(ZEN_ZPROPERTIES_VIEW,
    269              [ZEN_MANAGER_ROLE, MANAGER_ROLE, ZEN_USER_ROLE], 1)
    270          mp(ZEN_EDIT_LOCAL_TEMPLATES, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    271          mp(ZEN_RUN_COMMANDS, [ZEN_USER_ROLE, ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    272          mp(ZEN_DEFINE_COMMANDS_EDIT, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    273          mp(ZEN_DEFINE_COMMANDS_VIEW,
    274              [ZEN_MANAGER_ROLE, MANAGER_ROLE, ZEN_USER_ROLE], 1)
    275          mp(ZEN_MAINTENANCE_WINDOW_EDIT, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    276          mp(ZEN_MAINTENANCE_WINDOW_VIEW,
    277              [ZEN_MANAGER_ROLE, MANAGER_ROLE, ZEN_USER_ROLE], 1)
    278          mp(ZEN_ADMINISTRATORS_EDIT, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    279          mp(ZEN_ADMINISTRATORS_VIEW,
    280              [ZEN_MANAGER_ROLE, MANAGER_ROLE, ZEN_USER_ROLE], 1)
    281          #mp(ZEN_EDIT_USER, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    282          #mp(ZEN_EDIT_USERGROUP, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    283
    284 -    def setupDefaultSkins(self, p):
    285          from Products.CMFCore.DirectoryView import addDirectoryViews
    286          ps = getToolByName(p, 'portal_skins')
    287          addDirectoryViews(ps, 'skins', globals())
    288          ps.manage_addProduct['OFSP'].manage_addFolder(id='custom')
    289          ps.addSkinSelection('Basic', "custom, zenmodel", make_default=1)
    290          p.setupCurrentSkin()
    291
    292
    293 -    def setupSessionManager(self, p):
    294          """build a session manager and brower id manager for zport"""
    295          constructBrowserIdManager(p, cookiepath="/zport")
    296          constructSessionDataManager(p, "session_data_manager",
    297                      title="Session Data Manager",
    298                      path='/temp_folder/session_data')
    299
    300
    301 -    def setup(self, p, create_userfolder):
    302          if create_userfolder:
    303              self.setupUserFolder(p)
    304          #self.setupCookieAuth(p)
    305          self.setupTools(p)
    306          self.setupMailHost(p)
    307          self.setupRoles(p)
    308          self.setupPermissions(p)
    309          self.setupDefaultSkins(p)
    310          self.setupSessionManager(p)
    311
    312
    313 -    def create(self, parent, id, create_userfolder):
    314          id = str(id)
    315          portal = self.klass(id=id)
    316          parent._setObject(id, portal)
    317          # Return the fully wrapped object.
    318          p = parent.this()._getOb(id)
    319          self.setup(p, create_userfolder)
    320          return p
    321
    322
    323 -    def setupDefaultProperties(self, p, title, description,
    324                                 email_from_address, email_from_name,
    325                                 validate_email,
    326                                 ):
    327          p._setProperty('email_from_address', email_from_address, 'string')
    328          p._setProperty('email_from_name', email_from_name, 'string')
    329          p._setProperty('validate_email', validate_email and 1 or 0, 'boolean')
    330          p.title = title
    331          p.description = description
    332
    333
    334  manage_addZentinelPortal = Globals.HTMLFile('dtml/addPortal', globals())
    335  manage_addZentinelPortal.__name__ = 'addPortal'
    336
    337 -def manage_addZentinelPortal(obj, id="zport", title='Zentinel Portal',
    338                           description='',
    339                           create_userfolder=True,
    340                           email_from_address='postmaster@localhost',
    341                           email_from_name='Portal Administrator',
    342                           validate_email=0, RESPONSE=None):
    343      '''
    344      Adds a portal instance.
    345      '''
    346      gen = PortalGenerator()
    347      from string import strip
    348      id = strip(id)
    349      p = gen.create(obj, id, create_userfolder)
    350      gen.setupDefaultProperties(p, title, description,
    351                                 email_from_address, email_from_name,
    352                                 validate_email)
    353      if RESPONSE is not None:
    354          RESPONSE.redirect(obj.absolute_url()+'/manage_main')
    355