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 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  """ 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 getLoginButton(self):
    175          return """<input type="submit" name="submitbutton"
    176                  class="submitbutton" value=""/>"""
    177
    178 -    def getExtraLoginFormContents(self):
    179          """
    180          On first run, log us in as admin automatically.
    181
    182          This is done via a proxy form with hidden fields, so that the browser
    183          doesn't ask to save the password (which will be changed on the next
    184          screen).
    185          """
    186          if not self.dmd._rq:
    187              return """
    188              <form id="_proxy_form">
    189              <input type="hidden" name="__ac_name"/>
    190              <input type="hidden" name="__ac_password"/>
    191              <input type="hidden" name="came_from" value="/zport/dmd/quickstart"/>
    192              </form>
    193              <script>
    194              var origform=document.forms[0];
    195              var newform = document.getElementById('_proxy_form');
    196              newform.__ac_name.value = 'admin';
    197              newform.__ac_password.value = 'zenoss';
    198              newform.action = origform.action;
    199              newform.method = origform.method;
    200              newform.submit()
    201              </script>
    202              """
    203
    204
    205  Globals.InitializeClass(ZentinelPortal)
    206
    207
    208 -class PortalGenerator:
    209
    210      klass = ZentinelPortal
    211
    212 -    def setupTools(self, p):
    213          """Set up initial tools"""
    214          addCMFCoreTool = p.manage_addProduct['CMFCore'].manage_addTool
    215          addCMFCoreTool('CMF Skins Tool', None)
    216
    217
    218 -    def setupMailHost(self, p):
    219          p.manage_addProduct['MailHost'].manage_addMailHost(
    220              'MailHost', smtp_host='localhost')
    221
    222
    223 -    def setupUserFolder(self, p):
    224          #p.manage_addProduct['OFSP'].manage_addUserFolder()
    225          Security.createPASFolder(p)
    226          Security.setupPASFolder(p)
    227
    228
    229 -    def setupCookieAuth(self, p):
    230          # XXX PAS is handling this now, right?
    231          #p.manage_addProduct['CMFCore'].manage_addCC(
    232          #    id='cookie_authentication')
    233          pass
    234
    235
    236 -    def setupRoles(self, p):
    237          # Set up the suggested roles.
    238          p.__ac_roles__ += (ZEN_USER_ROLE, ZEN_MANAGER_ROLE,)
    239
    240
    241 -    def setupPermissions(self, p):
    242          # Set up some suggested role to permission mappings.
    243          mp = p.manage_permission
    244          mp(ZEN_CHANGE_SETTINGS,[ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    245          mp(ZEN_CHANGE_DEVICE, [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    246          mp(ZEN_CHANGE_DEVICE_PRODSTATE,
    247              [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    248          mp(ZEN_MANAGE_DMD, [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    249          mp(ZEN_DELETE, [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    250          mp(ZEN_DELETE_DEVICE, [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    251          mp(ZEN_ADD, [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    252          mp(ZEN_VIEW, [ZEN_USER_ROLE, ZEN_MANAGER_ROLE,
    253                          MANAGER_ROLE, OWNER_ROLE])
    254          mp(ZEN_COMMON, ["Authenticated", ZEN_USER_ROLE, ZEN_MANAGER_ROLE,
    255                          MANAGER_ROLE, OWNER_ROLE], 1)
    256
    257          # Events
    258          mp(ZEN_MANAGE_EVENTMANAGER,
    259              [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    260          mp(ZEN_MANAGE_EVENTS,
    261              [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    262          mp(ZEN_SEND_EVENTS,
    263              [ZEN_MANAGER_ROLE, OWNER_ROLE, MANAGER_ROLE,], 1)
    264
    265          mp(ZEN_CHANGE_ALERTING_RULES,
    266              [ZEN_MANAGER_ROLE, MANAGER_ROLE, OWNER_ROLE], 1)
    267          mp(ZEN_CHANGE_ADMIN_OBJECTS, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    268          mp(ZEN_CHANGE_EVENT_VIEWS, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    269          mp(ZEN_ADMIN_DEVICE, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    270          mp(ZEN_MANAGE_DEVICE, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    271          mp(ZEN_ZPROPERTIES_EDIT, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    272          mp(ZEN_ZPROPERTIES_VIEW,
    273              [ZEN_MANAGER_ROLE, MANAGER_ROLE, ZEN_USER_ROLE], 1)
    274          mp(ZEN_EDIT_LOCAL_TEMPLATES, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    275          mp(ZEN_RUN_COMMANDS, [ZEN_USER_ROLE, ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    276          mp(ZEN_DEFINE_COMMANDS_EDIT, [MANAGER_ROLE], 1)
    277          mp(ZEN_DEFINE_COMMANDS_VIEW,
    278              [ZEN_MANAGER_ROLE, MANAGER_ROLE, ZEN_USER_ROLE], 1)
    279          mp(ZEN_MAINTENANCE_WINDOW_EDIT, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    280          mp(ZEN_MAINTENANCE_WINDOW_VIEW,
    281              [ZEN_MANAGER_ROLE, MANAGER_ROLE, ZEN_USER_ROLE], 1)
    282          mp(ZEN_ADMINISTRATORS_EDIT, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    283          mp(ZEN_ADMINISTRATORS_VIEW,
    284              [ZEN_MANAGER_ROLE, MANAGER_ROLE, ZEN_USER_ROLE], 1)
    285          #mp(ZEN_EDIT_USER, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    286          #mp(ZEN_EDIT_USERGROUP, [ZEN_MANAGER_ROLE, MANAGER_ROLE], 1)
    287
    288 -    def setupDefaultSkins(self, p):
    289          from Products.CMFCore.DirectoryView import addDirectoryViews
    290          ps = getToolByName(p, 'portal_skins')
    291          addDirectoryViews(ps, 'skins', globals())
    292          ps.manage_addProduct['OFSP'].manage_addFolder(id='custom')
    293          ps.addSkinSelection('Basic', "custom, zenmodel", make_default=1)
    294          p.setupCurrentSkin()
    295
    296
    297 -    def setupSessionManager(self, p):
    298          """build a session manager and brower id manager for zport"""
    299          constructBrowserIdManager(p, cookiepath="/zport")
    300          constructSessionDataManager(p, "session_data_manager",
    301                      title="Session Data Manager",
    302                      path='/temp_folder/session_data')
    303
    304
    305 -    def setup(self, p, create_userfolder):
    306          if create_userfolder:
    307              self.setupUserFolder(p)
    308          #self.setupCookieAuth(p)
    309          self.setupTools(p)
    310          self.setupMailHost(p)
    311          self.setupRoles(p)
    312          self.setupPermissions(p)
    313          self.setupDefaultSkins(p)
    314          self.setupSessionManager(p)
    315
    316
    317 -    def create(self, parent, id, create_userfolder):
    318          id = str(id)
    319          portal = self.klass(id=id)
    320          parent._setObject(id, portal)
    321          # Return the fully wrapped object.
    322          p = parent.this()._getOb(id)
    323          self.setup(p, create_userfolder)
    324          return p
    325
    326
    327 -    def setupDefaultProperties(self, p, title, description,
    328                                 email_from_address, email_from_name,
    329                                 validate_email,
    330                                 ):
    331          p._setProperty('email_from_address', email_from_address, 'string')
    332          p._setProperty('email_from_name', email_from_name, 'string')
    333          p._setProperty('validate_email', validate_email and 1 or 0, 'boolean')
    334          p.title = title
    335          p.description = description
    336
    337
    338  manage_addZentinelPortal = Globals.HTMLFile('dtml/addPortal', globals())
    339  manage_addZentinelPortal.__name__ = 'addPortal'
    340
    341 -def manage_addZentinelPortal(obj, id="zport", title='Zentinel Portal',
    342                           description='',
    343                           create_userfolder=True,
    344                           email_from_address='postmaster@localhost',
    345                           email_from_name='Portal Administrator',
    346                           validate_email=0, RESPONSE=None):
    347      '''
    348      Adds a portal instance.
    349      '''
    350      gen = PortalGenerator()
    351      from string import strip
    352      id = strip(id)
    353      p = gen.create(obj, id, create_userfolder)
    354      gen.setupDefaultProperties(p, title, description,
    355                                 email_from_address, email_from_name,
    356                                 validate_email)
    357      if RESPONSE is not None:
    358          RESPONSE.redirect(obj.absolute_url()+'/manage_main')
    359