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

# Source Code for Module Products.ZenModel.UserSettings

       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  import types
      15  from DateTime import DateTime
      16  from random import choice
      17  from email.MIMEText import MIMEText
      18  import socket
      19  import logging
      20  log = logging.getLogger("zen.UserSettings")
      21
      22  from Globals import DTMLFile
      23  from Globals import InitializeClass
      24  from AccessControl import ClassSecurityInfo
      25  from AccessControl import getSecurityManager
      26  from Acquisition import aq_base
      27  from Products.PluggableAuthService import interfaces
      28  from Products.PluggableAuthService.PluggableAuthService \
      29      import _SWALLOWABLE_PLUGIN_EXCEPTIONS
      30  from zExceptions import Unauthorized
      31
      32  from Products.ZenEvents.ActionRule import ActionRule
      33  from Products.ZenEvents.CustomEventView import CustomEventView
      34  from Products.ZenRelations.RelSchema import *
      35  from Products.ZenUtils import Time
      36  from Products.ZenUtils.Utils import unused, prepId
      37  from Products.ZenUtils import DotNetCommunication
      38  from Products.ZenWidgets import messaging
      39
      40  from ZenossSecurity import *
      41  from ZenModelRM import ZenModelRM
      42  from Products.ZenUtils import Utils
      43
      44
      45 -class LocalAndLDAPUserEntries(Exception): pass
      46
      47  UserSettingsId = "ZenUsers"
      48
      49 -def manage_addUserSettingsManager(context, REQUEST=None):
      50      """Create user settings manager."""
      51      ufm = UserSettingsManager(UserSettingsId)
      52      context._setObject(ufm.getId(), ufm)
      53      if REQUEST is not None:
      54          REQUEST['RESPONSE'].redirect(context.absolute_url() + '/manage_main')
      55
      56
      57 -def rolefilter(r): return r not in ("Anonymous", "Authenticated", "Owner")
      58
      59
      60 -class UserSettingsManager(ZenModelRM):
      61      """Manage zenoss user folders.
      62      """
      63      security = ClassSecurityInfo()
      64
      65      meta_type = "UserSettingsManager"
      66
      67      #zPrimaryBasePath = ("", "zport")
      68
      69      sub_meta_types = ("UserSettings",)
      70
      71      factory_type_information = (
      72          {
      73              'id'             : 'UserSettingsManager',
      74              'meta_type'      : 'UserSettingsManager',
      75              'description'    : """Base class for all devices""",
      76              'icon'           : 'UserSettingsManager.gif',
      77              'product'        : 'ZenModel',
      78              'factory'        : 'manage_addUserSettingsManager',
      79              'immediate_view' : 'manageUserFolder',
      80              'actions'        :
      81           (
      82                  { 'id'            : 'settings'
      83                  , 'name'          : 'Settings'
      84                  , 'action'        : '../editSettings'
      85                  , 'permissions'   : ( ZEN_MANAGE_DMD, )
      86                  },
      87                  { 'id'            : 'manage'
      88                  , 'name'          : 'Commands'
      89                  , 'action'        : '../dataRootManage'
      90                  , 'permissions'   : (ZEN_MANAGE_DMD,)
      91                  },
      92                  { 'id'            : 'users'
      93                  , 'name'          : 'Users'
      94                  , 'action'        : 'manageUserFolder'
      95                  , 'permissions'   : ( ZEN_MANAGE_DMD, )
      96                  },
      97                  { 'id'            : 'packs'
      98                  , 'name'          : 'ZenPacks'
      99                  , 'action'        : '../ZenPackManager/viewZenPacks'
     100                  , 'permissions'   : ( ZEN_MANAGE_DMD, )
     101                  },
     102                  { 'id'            : 'jobs'
     103                  , 'name'          : 'Jobs'
     104                  , 'action'        : '../joblist'
     105                  , 'permissions'   : ( "Manage DMD", )
     106                  },
     107                  #{ 'id'            : 'menus'
     108                  #, 'name'          : 'Menus'
     109                  #, 'action'        : '../editMenus'
     110                  #, 'permissions'   : ( ZEN_MANAGE_DMD, )
     111                  #},
     112                  { 'id'            : 'portlets'
     113                  , 'name'          : 'Portlets'
     114                  , 'action'        : '../editPortletPerms'
     115                  , 'permissions'   : ( ZEN_MANAGE_DMD, )
     116                  },
     117                  { 'id'            : 'daemons'
     118                  , 'name'          : 'Daemons'
     119                  , 'action'        : '../../About/zenossInfo'
     120                  , 'permissions'   : ( ZEN_MANAGE_DMD, )
     121                  },
     122                  { 'id'            : 'versions'
     123                  , 'name'          : 'Versions'
     124                  , 'action'        : '../../About/zenossVersions'
     125                  , 'permissions'   : ( ZEN_MANAGE_DMD, )
     126                  },
     127                  { 'id'            : 'backups'
     128                  , 'name'          : 'Backups'
     129                  , 'action'        : '../backupInfo'
     130                  , 'permissions'   : ( ZEN_MANAGE_DMD, )
     131                  },
     132             )
     133           },
     134          )
     135
     136
     137 -    def getAllUserSettings(self):
     138          """Return list user settings objects.
     139          """
     140          # This code used to filter out the admin user.
     141          # See ticket #1615 for why it no longer does.
     142          users = self.objectValues(spec="UserSettings")
     143          users.sort(lambda a,b:cmp(a.id, b.id))
     144          return users
     145
     146 -    def getAllGroupSettings(self):
     147          """Return list user settings objects.
     148          """
     149          groups = self.objectValues(spec="GroupSettings")
     150          groups.sort(lambda a,b:cmp(a.id, b.id))
     151          return groups
     152
     153 -    def getAllUserSettingsNames(self, filtNames=()):
     154          """Return list of all zenoss usernames.
     155          """
     156          filt = lambda x: x not in filtNames
     157          return [ u.id for u in self.getAllUserSettings() if filt(u.id) ]
     158
     159 -    def getAllGroupSettingsNames(self, filtNames=()):
     160          """Return list of all zenoss usernames.
     161          """
     162          filt = lambda x: x not in filtNames
     163          return [ g.id for g in self.getAllGroupSettings() if filt(g.id) ]
     164
     165 -    def getUsers(self):
     166          """Return list of Users wrapped in their settings folder.
     167          """
     168          users = []
     169          for uset in self.objectValues(spec="UserSettings"):
     170              user = self.acl_users.getUser(uset.id)
     171              if user: users.append(user.__of__(uset))
     172          return users
     173
     174
     175 -    def getUser(self, userid=None):
     176          """Return a user object.  If userid is not passed return current user.
     177          """
     178          if userid is None:
     179              user = getSecurityManager().getUser()
     180          else:
     181              user = self.acl_users.getUser(userid)
     182          if user: return user.__of__(self.acl_users)
     183
     184
     185 -    def getAllActionRules(self):
     186          for u in self.getAllUserSettings() + self.getAllGroupSettings():
     187              for ar in u.getActionRules():
     188                  yield ar
     189
     190 -    def getUserSettings(self, userid=None):
     191          """Return a user folder.  If userid is not passed return current user.
     192          """
     193          user=None
     194          if userid is None:
     195              user = getSecurityManager().getUser()
     196              userid = user.getId()
     197          if not userid: raise Unauthorized
     198          folder = self._getOb(userid,None)
     199          if not folder and userid:
     200              ufolder = UserSettings(userid)
     201              self._setObject(ufolder.getId(), ufolder)
     202              folder = self._getOb(userid)
     203              if not user:
     204                  user = self.getUser(userid)
     205              if user:
     206                  # Load default values from our auth backend
     207                  psheets = user.listPropertysheets()
     208                  psheets.reverse() # Because first sheet should have priority
     209                  for ps in map(lambda ps: user.getPropertysheet(ps), psheets):
     210                      props = {}
     211                      for id in ps.propertyIds():
     212                          props[id] = ps.getProperty(id)
     213                      ufolder.updatePropsFromDict(props)
     214                  folder.changeOwnership(user)
     215                  folder.manage_setLocalRoles(userid, ("Owner",))
     216          return folder
     217
     218
     219 -    def getGroupSettings(self, groupid):
     220          groupid = prepId(groupid)
     221          if not self._getOb(groupid, False):
     222              gfolder = GroupSettings(groupid)
     223              self._setObject(gfolder.getId(), gfolder)
     224          return self._getOb(groupid)
     225
     226
     227 -    def setDashboardState(self, userid=None, REQUEST=None):
     228          """ Store a user's portlets and layout. If userid is not passed
     229              set the state for the current user.
     230          """
     231          user = self.getUserSettings(userid)
     232          posted = Utils.extractPostContent(REQUEST)
     233          if posted:
     234              user.dashboardState = posted
     235          return True
     236
     237 -    def getUserSettingsUrl(self, userid=None):
     238          """Return the url to the current user's folder.
     239          """
     240          uf = self.getUserSettings(userid)
     241          if uf: return uf.getPrimaryUrlPath()
     242          return ""
     243
     244
     245      security.declareProtected(ZEN_MANAGE_DMD, 'manage_addUser')
     246 -    def manage_addUser(self, userid, password=None,roles=("ZenUser",),
     247                      REQUEST=None,**kw):
     248          """
     249          Add a Zenoss user to the system and set the user's default properties.
     250
     251          @parameter userid: username to add
     252          @parameter password: password for the username
     253          @parameter roles: tuple of role names
     254          @parameter REQUEST: Zope object containing details about this request
     255          """
     256          if not userid: return
     257
     258          userid= userid.strip()
     259
     260          illegal_usernames= [ 'user', ]
     261
     262          user_name= userid.lower()
     263          if user_name in illegal_usernames:
     264              if REQUEST:
     265                  messaging.IMessageSender(self).sendToBrowser(
     266                      'Error',
     267                      'The username "%s" is reserved.' % userid,
     268                      priority=messaging.WARNING
     269                  )
     270                  return self.callZenScreen(REQUEST)
     271              else:
     272                  return None
     273
     274          if password is None:
     275              password = self.generatePassword()
     276
     277          self.acl_users._doAddUser(userid,password,roles,"")
     278          self.acl_users.ZCacheable_invalidate()
     279          user = self.acl_users.getUser(userid)
     280          ufolder = self.getUserSettings(userid)
     281          if REQUEST: kw = REQUEST.form
     282          ufolder.updatePropsFromDict(kw)
     283
     284          if REQUEST:
     285              messaging.IMessageSender(self).sendToBrowser(
     286                  'User Added',
     287                  'User "%s" has been created.' % userid
     288              )
     289              return self.callZenScreen(REQUEST)
     290          else:
     291              return user
     292
     293
     294 -    def generatePassword(self):
     295          """ Generate a valid password.
     296          """
     297          # we don't use these to avoid typos: OQ0Il1
     298          chars = 'ABCDEFGHJKLMNPRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789'
     299          return ''.join( [ choice(chars) for i in range(6) ] )
     300
     301
     302 -    def authenticateCredentials(self, login, password):
     303          """
     304          Authenticates a given set of credentials against all configured
     305          authentication plugins. Returns True for successful authentication and
     306          False otherwise.
     307          """
     308          if login == 'admin':
     309              acl_users = self.getPhysicalRoot().acl_users
     310          else:
     311              acl_users = self.acl_users
     312
     313          try:
     314              authenticators = acl_users.plugins.listPlugins(
     315                  interfaces.plugins.IAuthenticationPlugin)
     316          except _SWALLOWABLE_PLUGIN_EXCEPTIONS:
     317              authenticators = ()
     318
     319          for authenticator_id, auth in authenticators:
     320              try:
     321                  uid_and_info = auth.authenticateCredentials(
     322                      {'login':login, 'password':password})
     323
     324                  if uid_and_info is None:
     325                      continue
     326
     327                  user_id, info = uid_and_info
     328              except _SWALLOWABLE_PLUGIN_EXCEPTIONS:
     329                  continue
     330
     331              return user_id is not None
     332
     333
     334      security.declareProtected(ZEN_MANAGE_DMD, 'manage_changeUser')
     335 -    def manage_changeUser(self, userid, password=None, sndpassword=None,
     336                            roles=None, domains=None, REQUEST=None, **kw):
     337          """Change a zenoss users settings.
     338          """
     339          user = self.acl_users.getUser(userid)
     340          if not user:
     341              if REQUEST:
     342                  messaging.IMessageSender(self).sendToBrowser(
     343                      'Error',
     344                      'User "%s" was not found.' % userid,
     345                      priority=messaging.WARNING
     346                  )
     347                  return self.callZenScreen(REQUEST)
     348              else:
     349                  return
     350          if password and password != sndpassword:
     351              if REQUEST:
     352                  messaging.IMessageSender(self).sendToBrowser(
     353                      'Error',
     354                      "Passwords didn't match. No change.",
     355                      priority=messaging.WARNING
     356                  )
     357                  return self.callZenScreen(REQUEST)
     358              else:
     359                  raise ValueError("passwords don't match")
     360          if password is None: password = user._getPassword()
     361          if roles is None: roles = user.roles
     362          if domains is None: domains = user.domains
     363          self.acl_users._doChangeUser(userid,password,roles,domains)
     364          self.acl_users.ZCacheable_invalidate()
     365          ufolder = self.getUserSettings(userid)
     366          ufolder.updatePropsFromDict(kw)
     367          if REQUEST:
     368              messaging.IMessageSender(self).sendToBrowser(
     369                  'Settings Saved',
     370                  Time.SaveMessage()
     371              )
     372              return self.callZenScreen(REQUEST)
     373          else:
     374              return user
     375
     376
     377      security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteUsers')
     378 -    def manage_deleteUsers(self, userids=(), REQUEST=None):
     379          """Delete a list of zenoss users from the system.
     380          """
     381          # get a list of plugins that can add manage users and then call the
     382          # appropriate methods
     383          #
     384          # XXX this needs to be reviewed when new plugins are added, such as the
     385          # LDAP plugin
     386          if 'admin' in userids:
     387              messaging.IMessageSender(self).sendToBrowser(
     388                  'Error',
     389                  "Cannot delete admin user. No users were deleted.",
     390                  messaging.WARNING
     391              )
     392              return self.callZenScreen(REQUEST)
     393
     394          ifaces = [interfaces.plugins.IUserAdderPlugin]
     395          getPlugins = self.acl_users.plugins.listPlugins
     396          plugins = [ getPlugins(x)[0][1] for x in ifaces ]
     397          for userid in userids:
     398              try:
     399                  for plugin in plugins:
     400                      plugin.removeUser(userid)
     401                  self.acl_users.ZCacheable_invalidate()
     402              except KeyError:
     403                  # this means that there's no user in the acl_users, but that
     404                  # Zenoss still sees the user; we want to pass on this exception
     405                  # so that Zenoss can clean up
     406                  pass
     407              if getattr(aq_base(self), userid, False):
     408                  us = self._getOb(userid)
     409                  for ar in us.adminRoles():
     410                      ar.userSetting.removeRelation()
     411                      mobj = ar.managedObject().primaryAq()
     412                      mobj.adminRoles._delObject(ar.id)
     413                  self._delObject(userid)
     414
     415          if REQUEST:
     416              messaging.IMessageSender(self).sendToBrowser(
     417                  'Users Deleted',
     418                  "Users were deleted: %s." % (', '.join(userids))
     419              )
     420              return self.callZenScreen(REQUEST)
     421
     422
     423      security.declareProtected(ZEN_MANAGE_DMD, 'manage_addGroup')
     424 -    def manage_addGroup(self, groupid, REQUEST=None):
     425          """Add a zenoss group to the system and set its default properties.
     426          """
     427          if not groupid: return
     428          groupid = prepId(groupid)
     429          try:
     430              self.acl_users.groupManager.addGroup(groupid)
     431              self.acl_users.ZCacheable_invalidate()
     432          except KeyError: pass
     433          self.getGroupSettings(groupid)
     434          if REQUEST:
     435              messaging.IMessageSender(self).sendToBrowser(
     436                  'Group Added',
     437                  'Group "%s" has been created.' % groupid
     438              )
     439              return self.callZenScreen(REQUEST)
     440
     441
     442      security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteGroups')
     443 -    def manage_deleteGroups(self, groupids=(), REQUEST=None):
     444          """ Delete a zenoss group from the system
     445          """
     446          gm = self.acl_users.groupManager
     447          if type(groupids) in types.StringTypes:
     448              groupids = [groupids]
     449          for groupid in groupids:
     450              if self._getOb(groupid): self._delObject(groupid)
     451              try:
     452                  gm.removeGroup(groupid)
     453                  self.acl_users.ZCacheable_invalidate()
     454              except KeyError: pass
     455          if REQUEST:
     456              messaging.IMessageSender(self).sendToBrowser(
     457                  'Groups Deleted',
     458                  "Groups were deleted: %s." % (', '.join(groupids))
     459              )
     460              return self.callZenScreen(REQUEST)
     461
     462
     463      security.declareProtected(ZEN_MANAGE_DMD, 'manage_addUsersToGroups')
     464 -    def manage_addUsersToGroups(self, userids=(), groupids=(), REQUEST=None):
     465          """ Add users to a group
     466          """
     467          if type(userids) in types.StringTypes:
     468              userids = [userids]
     469          if type(groupids) in types.StringTypes:
     470              groupids = [groupids]
     471          for groupid in groupids:
     472              self._getOb(groupid).manage_addUsersToGroup(userids)
     473          if REQUEST:
     474              if len(groupids) == 0:
     475                  messaging.IMessageSender(self).sendToBrowser(
     476                      'Error',
     477                      'No groups were selected.',
     478                      priority=messaging.WARNING
     479                  )
     480              else:
     481                  messaging.IMessageSender(self).sendToBrowser(
     482                      'Groups Modified',
     483                      'Users %s were added to group %s.' % (
     484                          ', '.join(userids), ', '.join(groupids))
     485                  )
     486              return self.callZenScreen(REQUEST)
     487
     488
     489      security.declareProtected(ZEN_MANAGE_DMD, 'manage_emailTestAdmin')
     490 -    def manage_emailTestAdmin(self, userid, REQUEST=None):
     491          ''' Do email test for given user
     492          '''
     493          userSettings = self.getUserSettings(userid)
     494          msg = userSettings.manage_emailTest()
     495          if msg:
     496              messaging.IMessageSender(self).sendToBrowser('Email Test', msg)
     497          if REQUEST:
     498              return self.callZenScreen(REQUEST)
     499
     500
     501      security.declareProtected(ZEN_MANAGE_DMD, 'manage_pagerTestAdmin')
     502 -    def manage_pagerTestAdmin(self, userid, REQUEST=None):
     503          ''' Do pager test for given user
     504          '''
     505          userSettings = self.getUserSettings(userid)
     506          msg = userSettings.manage_pagerTest()
     507          if msg:
     508              messaging.IMessageSender(self).sendToBrowser('Pager Test', msg)
     509          if REQUEST:
     510              return self.callZenScreen(REQUEST)
     511
     512
     513 -    def cleanUserFolders(self):
     514          """Delete orphaned user folders.
     515          """
     516          userfolders = self._getOb(UserSettingsId)
     517          userids = self.acl_users.getUserNames()
     518          for fid in userfolders.objectIds():
     519              if fid not in userids:
     520                  userfolders._delObject(fid)
     521          self.acl_users.ZCacheable_invalidate()
     522
     523
     524 -    def getAllRoles(self):
     525          """Get list of all roles without Anonymous and Authenticated.
     526          """
     527          return filter(rolefilter, self.valid_roles())
     528
     529
     530 -    def exportXmlHook(self,ofile, ignorerels):
     531          map(lambda x: x.exportXml(ofile, ignorerels), self.getAllUserSettings())
     532
     533
     534
     535 -def manage_addUserSettings(context, id, title = None, REQUEST = None):
     536      """make a device class"""
     537      dc = UserSettings(id, title)
     538      context._setObject(id, dc)
     539      if REQUEST:
     540          REQUEST['RESPONSE'].redirect(context.absolute_url() + '/manage_main')
     541
     542
     543  addUserSettings = DTMLFile('dtml/addUserSettings',globals())
     544
     545
     546 -class UserSettings(ZenModelRM):
     547      """zenoss user folder has users preferences.
     548      """
     549
     550      meta_type = "UserSettings"
     551
     552      sub_meta_types = ("ActionRule",)
     553
     554      email = ""
     555      pager = ""
     556      defaultPageSize = 40
     557      defaultEventPageSize = 30
     558      defaultAdminRole = "ZenUser"
     559      defaultAdminLevel = 1
     560      oncallStart = 0
     561      oncallEnd = 0
     562      escalationMinutes = 0
     563      dashboardState = ''
     564      netMapStartObject = ''
     565      eventConsoleRefresh = True
     566      zenossNetUser = ''
     567      zenossNetPassword = ''
     568
     569      _properties = ZenModelRM._properties + (
     570          {'id':'email', 'type':'string', 'mode':'w'},
     571          {'id':'pager', 'type':'string', 'mode':'w'},
     572          {'id':'defaultPageSize', 'type':'int', 'mode':'w'},
     573          {'id':'defaultEventPageSize', 'type':'int', 'mode':'w'},
     574          {'id':'defaultAdminRole', 'type':'string', 'mode':'w'},
     575          {'id':'defaultAdminLevel', 'type':'int', 'mode':'w'},
     576          {'id':'oncallStart', 'type':'int', 'mode':'w'},
     577          {'id':'oncallEnd', 'type':'int', 'mode':'w'},
     578          {'id':'escalationMinutes', 'type':'int', 'mode':'w'},
     579          {'id':'dashboardState', 'type':'string', 'mode':'w'},
     580          {'id':'netMapStartObject', 'type':'string', 'mode':'w'},
     581          {'id':'eventConsoleRefresh', 'type':'boolean', 'mode':'w'},
     582          {'id':'zenossNetUser', 'type':'string', 'mode':'w'},
     583          {'id':'zenossNetPassword', 'type':'string', 'mode':'w'},
     584      )
     585
     586
     587      _relations =  (
     588          ("adminRoles", ToMany(ToOne, "Products.ZenModel.AdministrativeRole",
     589                                "userSetting")),
     590          ("messages", ToManyCont(ToOne,
     591              "Products.ZenWidgets.PersistentMessage.PersistentMessage",
     592              "messageQueue")),
     593      )
     594
     595     # Screen action bindings (and tab definitions)
     596      factory_type_information = (
     597          {
     598              'immediate_view' : 'editUserSettings',
     599              'actions'        :
     600              (
     601                  {'name'         : 'Edit',
     602                  'action'        : 'editUserSettings',
     603                  'permissions'   : (ZEN_CHANGE_SETTINGS,),
     604                  },
     605                  {'name'         : 'Administered Objects',
     606                  'action'        : 'administeredDevices',
     607                  'permissions'   : (ZEN_CHANGE_ADMIN_OBJECTS,)
     608                  },
     609                  {'name'         : 'Event Views',
     610                  'action'        : 'editEventViews',
     611                  # ideally make this its own permission
     612                  'permissions'   : (ZEN_CHANGE_SETTINGS,),
     613                  },
     614                  {'name'         : 'Alerting Rules',
     615                  'action'        : 'editActionRules',
     616                  'permissions'   : (ZEN_CHANGE_ALERTING_RULES,),
     617                  },
     618              )
     619           },
     620          )
     621
     622      security = ClassSecurityInfo()
     623
     624      security.declareProtected('View', 'zentinelTabs')
     625 -    def zentinelTabs(self, templateName, REQUEST=None):
     626          """Return a list of hashs that define the screen tabs for this object.
     627          [{'name':'Name','action':'template','selected':False},...]
     628          """
     629          tabs = super(UserSettings, self).zentinelTabs(templateName, REQUEST)
     630          # if we don't have any global roles take away edit tab
     631          if self.hasNoGlobalRoles():
     632              return tabs[:-1]
     633          return tabs
     634
     635 -    def hasNoGlobalRoles(self):
     636          """This user doesn't have global roles. Used to limit access
     637          """
     638          return self.id != 'admin' and len(self.getUserRoles()) == 0
     639
     640 -    def getUserRoles(self):
     641          """Get current roles for this user.
     642          """
     643          user = self.getUser(self.id)
     644          if user:
     645              # This call will create GroupSettings objects for any externally-
     646              # sourced groups.
     647              self.getAllAdminRoles()
     648              return filter(rolefilter, user.getRoles())
     649          return []
     650
     651
     652 -    def getUserGroupSettingsNames(self):
     653          """Return group settings objects for user
     654          """
     655          user = self.getUser(self.id)
     656          if user:
     657              return self.acl_users._getGroupsForPrincipal(user)
     658          return ()
     659
     660
     661      security.declareProtected(ZEN_CHANGE_SETTINGS, 'updatePropsFromDict')
     662 -    def updatePropsFromDict(self, propdict):
     663          props = self.propertyIds()
     664          for k, v in propdict.items():
     665              if k in props: setattr(self,k,v)
     666
     667
     668 -    def iseditable(self):
     669          """Can the current user edit this settings object.
     670          """
     671          currentUser = getSecurityManager().getUser()
     672
     673          # Managers can edit any users' settings.
     674          if currentUser.has_role("Manager"):
     675              return True
     676
     677          # thisUser can be None if the plugin that created it is inactive.
     678          thisUser = self.acl_users.getUser(self.id)
     679          if thisUser is None:
     680              return False
     681
     682          # ZenManagers can edit any users' settings except for Managers.
     683          if currentUser.has_role("ZenManager") \
     684              and not thisUser.has_role("Manager"):
     685              return True
     686
     687          # Users can edit their own settings.
     688          if thisUser.getUserName() == currentUser.getUserName():
     689              return True
     690
     691          return False
     692
     693
     694      security.declareProtected(ZEN_CHANGE_SETTINGS, 'manage_resetPassword')
     695 -    def manage_resetPassword(self):
     696          """
     697          Reset a password.
     698          """
     699          email = self.email.strip()
     700          if not email:
     701              messaging.IMessageSender(self).sendToBrowser(
     702                  'Password Reset Failed',
     703                  'Cannot send password reset email; user has no'+
     704                  ' email address.',
     705                  priority=messaging.WARNING
     706              )
     707              return self.callZenScreen(self.REQUEST)
     708
     709          newpw = self.generatePassword()
     710          body = """
     711          Your Zenoss password has been reset at %s's request.
     712
     713          Your new password is: %s
     714          """ % (self.getUser().getId(), newpw)
     715          msg = MIMEText(body)
     716          msg['Subject'] = 'Zenoss Password Reset Request'
     717          msg['From'] = self.dmd.getEmailFrom()
     718          msg['To'] = email
     719          msg['Date'] = DateTime().rfc822()
     720          result, errorMsg = Utils.sendEmail(msg, self.dmd.smtpHost,
     721                              self.dmd.smtpPort,
     722                              self.dmd.smtpUseTLS, self.dmd.smtpUser,
     723                              self.dmd.smtpPass)
     724          if result:
     725              userManager = self.acl_users.userManager
     726              try:
     727                  userManager.updateUserPassword(self.id, newpw)
     728              except KeyError:
     729                  self.getPhysicalRoot().acl_users.userManager.updateUserPassword(
     730                                  self.id, newpw)
     731              messaging.IMessageSender(self).sendToBrowser(
     732                  'Password reset',
     733                  'An email with a new password has been sent.'
     734              )
     735              loggedInUser = self.REQUEST['AUTHENTICATED_USER']
     736              # we only want to log out the user if it's *their* password
     737              # they've changed, not, for example, if the admin user is
     738              # changing another user's password
     739              if loggedInUser.getUserName() == self.id:
     740                  self.acl_users.logout(self.REQUEST)
     741          else:
     742              messaging.IMessageSender(self).sendToBrowser(
     743                  'Password reset failed',
     744                  'Unable to send password reset email: %s' % errorMsg,
     745                  priority=messaging.WARNING
     746              )
     747          return self.callZenScreen(self.REQUEST)
     748
     749
     750      security.declareProtected(ZEN_CHANGE_SETTINGS, 'manage_editUserSettings')
     751 -    def manage_editUserSettings(self, oldpassword=None, password=None,
     752                                  sndpassword=None, roles=None, groups=None,
     753                                  domains=None, REQUEST=None, **kw):
     754          """Update user settings.
     755          """
     756          # get the user object; return if no user
     757          user = self.acl_users.getUser(self.id)
     758          if not user:
     759              user = self.getPhysicalRoot().acl_users.getUser(self.id)
     760          if not user:
     761              if REQUEST:
     762                  messaging.IMessageSender(self).sendToBrowser(
     763                      'Error',
     764                      'User %s not found.' % self.id,
     765                      priority=messaging.WARNING
     766                  )
     767                  return self.callZenScreen(REQUEST)
     768              else:
     769                  return
     770
     771          # Verify existing password
     772          curuser = self.getUser().getId()
     773          if not oldpassword or not self.ZenUsers.authenticateCredentials(
     774              curuser, oldpassword):
     775              if REQUEST:
     776                  messaging.IMessageSender(self).sendToBrowser(
     777                      'Error',
     778                      'Confirmation password is empty or invalid. Please'+
     779                      ' confirm your password for security reasons.',
     780                      priority=messaging.WARNING
     781                  )
     782                  return self.callZenScreen(REQUEST)
     783              else:
     784                  raise ValueError("Current password is incorrect.")
     785
     786          # update role info
     787          roleManager = self.acl_users.roleManager
     788          origRoles = filter(rolefilter, user.getRoles())
     789
     790          if not self.has_role('Manager') and roles and 'Manager' in roles:
     791              if REQUEST:
     792                  messaging.IMessageSender(self).sendToBrowser(
     793                      'Error',
     794                      'Only Managers can make more Managers.',
     795                      priority=messaging.WARNING
     796                  )
     797                  return self.callZenScreen(REQUEST)
     798              else:
     799                  return
     800
     801          if not self.has_role('Manager') and origRoles and \
     802              'Manager' in origRoles:
     803
     804              if REQUEST:
     805                  messaging.IMessageSender(self).sendToBrowser(
     806                      'Error',
     807                      'Only Managers can modify other Managers.',
     808                      priority=messaging.WARNING
     809                  )
     810                  return self.callZenScreen(REQUEST)
     811              else:
     812                  return
     813
     814          # if there's a change, then we need to update
     815          if roles != origRoles and self.isManager():
     816              from sets import Set as set
     817              # get roles to remove and then remove them
     818              removeRoles = list(set(origRoles).difference(set(roles)))
     819              for role in removeRoles:
     820                  try:
     821                      roleManager.removeRoleFromPrincipal(role, self.id)
     822                  except KeyError:
     823                      # User doesn't actually have that role; ignore
     824                      pass
     825              # get roles to add and then add them
     826              addRoles = list(set(roles).difference(set(origRoles)))
     827              for role in addRoles:
     828                  roleManager.assignRoleToPrincipal(role, self.id)
     829
     830          # update group info
     831          groupManager = self.acl_users.groupManager
     832          origGroups = groupManager.getGroupsForPrincipal(user)
     833          # if there's a change, then we need to update
     834          if groups != origGroups and self.isManager():
     835              # can we use the built-in set?
     836              try:
     837                  set()
     838              except NameError:
     839                  from sets import Set as set
     840              # get groups to remove and then remove them
     841              removeGroups = set(origGroups).difference(set(groups))
     842              for groupid in removeGroups:
     843                  groupManager.removePrincipalFromGroup(user.getId(), groupid)
     844              # get groups to add and then add them
     845              addGroups = set(groups).difference(set(origGroups))
     846              for groupid in addGroups:
     847                  try:
     848                      groupManager.addPrincipalToGroup(user.getId(), groupid)
     849                  except KeyError:
     850                      # This can occur if the group came from an external source.
     851                      pass
     852
     853          # we're not managing domains right now
     854          if domains:
     855              msg = 'Zenoss does not currently manage domains for users.'
     856              raise NotImplementedError(msg)
     857
     858          # update Zenoss user folder settings
     859          if REQUEST:
     860              kw = REQUEST.form
     861          self.manage_changeProperties(**kw)
     862
     863          # update password info
     864          if self.id=='admin':
     865              userManager = self.getPhysicalRoot().acl_users.userManager
     866          else:
     867              userManager = self.acl_users.userManager
     868          if password:
     869              if password.find(':') >= 0:
     870                  if REQUEST:
     871                      messaging.IMessageSender(self).sendToBrowser(
     872                          'Error',
     873                          'Passwords cannot contain a ":". Password not updated.',
     874                          priority=messaging.WARNING
     875                      )
     876                      return self.callZenScreen(REQUEST)
     877                  else:
     878                      raise ValueError("Passwords cannot contain a ':' ")
     879              elif password != sndpassword:
     880                  if REQUEST:
     881                      messaging.IMessageSender(self).sendToBrowser(
     882                          'Error',
     883                          'Passwords did not match. Password not updated.',
     884                          priority=messaging.WARNING
     885                      )
     886                      return self.callZenScreen(REQUEST)
     887                  else:
     888                      raise ValueError("Passwords don't match")
     889              else:
     890                  try: userManager.updateUserPassword(self.id, password)
     891                  except KeyError:
     892                      self.getPhysicalRoot().acl_users.userManager.updateUserPassword(
     893                                      self.id, password)
     894                  if REQUEST:
     895                      loggedInUser = REQUEST['AUTHENTICATED_USER']
     896                      # we only want to log out the user if it's *their* passowrd
     897                      # they've changed, not, for example, if the admin user is
     898                      # changing another user's password
     899                      if loggedInUser.getUserName() == self.id:
     900                          self.acl_users.logout(REQUEST)
     901
     902          self.acl_users.ZCacheable_invalidate()
     903
     904          # finish up
     905          if REQUEST:
     906              messaging.IMessageSender(self).sendToBrowser(
     907                  'Settings Saved',
     908                  Time.SaveMessage()
     909              )
     910              return self.callZenScreen(REQUEST)
     911          else:
     912              return user
     913
     914      security.declareProtected(ZEN_CHANGE_ALERTING_RULES, 'manage_addActionRule')
     915 -    def manage_addActionRule(self, id=None, REQUEST=None):
     916          """Add an action rule to this object.
     917          """
     918          if id:
     919              ar = ActionRule(id)
     920              self._setObject(id, ar)
     921              ar = self._getOb(id)
     922              user = getSecurityManager().getUser()
     923              userid = user.getId()
     924              if userid != self.id:
     925                  userid = self.id
     926                  user = self.getUser(userid)
     927                  ar.changeOwnership(user)
     928                  ar.manage_setLocalRoles(userid, ("Owner",))
     929          if REQUEST:
     930              return self.callZenScreen(REQUEST)
     931
     932 -    def getActionRules(self):
     933          return self.objectValues(spec=ActionRule.meta_type)
     934
     935      security.declareProtected(ZEN_CHANGE_EVENT_VIEWS,
     936          'manage_addCustomEventView')
     937 -    def manage_addCustomEventView(self, id=None, REQUEST=None):
     938          """Add an action rule to this object.
     939          """
     940          if id:
     941              ar = CustomEventView(id)
     942              self._setObject(id, ar)
     943              ar = self._getOb(id)
     944              user = getSecurityManager().getUser()
     945              userid = user.getId()
     946              if userid != self.id:
     947                  userid = self.id
     948                  user = self.getUser(userid)
     949                  ar.changeOwnership(user)
     950                  ar.manage_setLocalRoles(userid, ("Owner",))
     951          if REQUEST:
     952              return self.callZenScreen(REQUEST)
     953
     954
     955      security.declareProtected(ZEN_CHANGE_ADMIN_OBJECTS,
     956          'manage_addAdministrativeRole')
     957 -    def manage_addAdministrativeRole(self, name=None, type='device',
     958                                      role=None, REQUEST=None):
     959          "Add a Admin Role to this device"
     960          unused(role)
     961          mobj = None
     962          if not name:
     963              name = REQUEST.deviceName
     964          if type == 'device':
     965              mobj =self.getDmdRoot("Devices").findDevice(name)
     966          else:
     967              try:
     968                  root = type.capitalize()+'s'
     969                  if type == "deviceClass":
     970                      mobj = self.getDmdRoot("Devices").getOrganizer(name)
     971                  else:
     972                      mobj = self.getDmdRoot(root).getOrganizer(name)
     973              except KeyError: pass
     974          if not mobj:
     975              if REQUEST:
     976                  messaging.IMessageSender(self).sendToBrowser(
     977                      'Error',
     978                      "%s %s not found"%(type.capitalize(),name),
     979                      priority=messaging.WARNING
     980                  )
     981                  return self.callZenScreen(REQUEST)
     982              else: return
     983          roleNames = [ r.id for r in mobj.adminRoles() ]
     984          if self.id in roleNames:
     985              if REQUEST:
     986                  messaging.IMessageSender(self).sendToBrowser(
     987                      'Error',
     988                      (("Administrative Role for %s %s "
     989                       "for user %s already exists.") % (type, name, self.id)),
     990                      priority=messaging.WARNING
     991                  )
     992                  return self.callZenScreen(REQUEST)
     993              else: return
     994          mobj.manage_addAdministrativeRole(self.id)
     995          if REQUEST:
     996              messaging.IMessageSender(self).sendToBrowser(
     997                  'Role Added',
     998                  ("Administrative Role for %s %s for user %s added" %
     999                      (type, name, self.id))
    1000              )
    1001              return self.callZenScreen(REQUEST)
    1002
    1003
    1004      security.declareProtected(ZEN_CHANGE_ADMIN_OBJECTS,
    1005          'manage_editAdministrativeRoles')
    1006 -    def manage_editAdministrativeRoles(self, ids=(), role=(),
    1007                                          level=(), REQUEST=None):
    1008          """Edit list of admin roles.
    1009          """
    1010          if type(ids) in types.StringTypes:
    1011              ids = [ids]
    1012              level = [level]
    1013              role = [role]
    1014          else:
    1015              ids = list(ids)
    1016          for ar in self.adminRoles():
    1017              mobj = ar.managedObject()
    1018              try: i = ids.index(mobj.managedObjectName())
    1019              except ValueError: continue
    1020              mobj = mobj.primaryAq()
    1021              mobj.manage_editAdministrativeRoles(self.id, role[i], level[i])
    1022          if REQUEST:
    1023              if ids:
    1024                  messaging.IMessageSender(self).sendToBrowser(
    1025                      'Roles Updated',
    1026                      "Administrative roles were updated."
    1027                  )
    1028              return self.callZenScreen(REQUEST)
    1029
    1030
    1031      security.declareProtected(ZEN_CHANGE_ADMIN_OBJECTS,
    1032          'manage_deleteAdministrativeRole')
    1033 -    def manage_deleteAdministrativeRole(self, delids=(), REQUEST=None):
    1034          "Delete a admin role to this device"
    1035          if type(delids) in types.StringTypes:
    1036              delids = [delids]
    1037          for ar in self.adminRoles():
    1038              mobj = ar.managedObject()
    1039              if mobj.managedObjectName() not in delids: continue
    1040              mobj = mobj.primaryAq()
    1041              mobj.manage_deleteAdministrativeRole(self.id)
    1042          if REQUEST:
    1043              if delids:
    1044                  messaging.IMessageSender(self).sendToBrowser(
    1045                      'Roles Deleted',
    1046                      "Administrative roles were deleted."
    1047                  )
    1048              return self.callZenScreen(REQUEST)
    1049
    1050
    1051      security.declareProtected(ZEN_CHANGE_SETTINGS, 'getAllAdminRoles')
    1052 -    def getAllAdminRoles(self):
    1053          """Return all admin roles for this user and its groups
    1054          """
    1055          ars = self.adminRoles()
    1056          for group in self.getUser().getGroups():
    1057              gs = self.getGroupSettings(group)
    1058              ars.extend(gs.adminRoles())
    1059          return ars
    1060
    1061
    1062      security.declareProtected(ZEN_CHANGE_SETTINGS, 'manage_emailTest')
    1063 -    def manage_emailTest(self, REQUEST=None):
    1064          ''' Send a test email to the given userid.
    1065          '''
    1066          destSettings = self.getUserSettings(self.getId())
    1067          destAddresses = destSettings.getEmailAddresses()
    1068          msg = None
    1069          if destAddresses:
    1070              fqdn = socket.getfqdn()
    1071              thisUser = self.getUser()
    1072              srcId = thisUser.getId()
    1073              self.getUserSettings(srcId)
    1074              srcAddress = self.dmd.getEmailFrom()
    1075              # Read body from file probably
    1076              body = ('This is a test message sent by %s' % srcId +
    1077                      ' from the Zenoss installation on %s.' % fqdn)
    1078              emsg = MIMEText(body)
    1079              emsg['Subject'] = 'Zenoss Email Test'
    1080              emsg['From'] = srcAddress
    1081              emsg['To'] = ', '.join(destAddresses)
    1082              emsg['Date'] = DateTime().rfc822()
    1083              result, errorMsg = Utils.sendEmail(emsg, self.dmd.smtpHost,
    1084                                  self.dmd.smtpPort,
    1085                                  self.dmd.smtpUseTLS, self.dmd.smtpUser,
    1086                                  self.dmd.smtpPass)
    1087              if result:
    1088                  msg = 'Test email sent to %s' % ', '.join(destAddresses)
    1089              else:
    1090                  msg = 'Test failed: %s' % errorMsg
    1091          else:
    1092              msg = 'Test email not sent, user has no email address.'
    1093          if REQUEST:
    1094              messaging.IMessageSender(self).sendToBrowser(
    1095                  'Email Test',
    1096                  msg.replace("'", "\\'")
    1097              )
    1098              return self.callZenScreen(REQUEST)
    1099          else:
    1100              return msg
    1101
    1102
    1103      security.declareProtected(ZEN_CHANGE_SETTINGS, 'manage_pagerTest')
    1104 -    def manage_pagerTest(self, REQUEST=None):
    1105          ''' Send a test page
    1106          '''
    1107          destSettings = self.getUserSettings(self.getId())
    1108          destPagers = [ x.strip() for x in
    1109              (destSettings.getPagerAddresses() or []) ]
    1110          msg = None
    1111          fqdn = socket.getfqdn()
    1112          srcId = self.getUser().getId()
    1113          testMsg = ('Test sent by %s' % srcId +
    1114                  ' from the Zenoss installation on %s.' % fqdn)
    1115          for destPager in destPagers:
    1116              result, errorMsg = Utils.sendPage(destPager, testMsg,
    1117                                      self.dmd.pageCommand)
    1118              if result:
    1119                  msg = 'Test page sent to %s' % ', '.join(destPagers)
    1120              else:
    1121                  msg = 'Test failed: %s' % errorMsg
    1122                  break
    1123          if not destPagers:
    1124              msg = 'Test page not sent, user has no pager number.'
    1125          if REQUEST:
    1126              messaging.IMessageSender(self).sendToBrowser(
    1127                  'Pager Test', msg)
    1128              return self.callZenScreen(REQUEST)
    1129          else:
    1130              return msg
    1131
    1132 -    def exportXmlHook(self, ofile, ignorerels):
    1133          """patch to export all user configuration
    1134          """
    1135          for o in self.objectValues():
    1136              if hasattr(aq_base(o), 'exportXml'):
    1137                  o.exportXml(ofile, ignorerels)
    1138
    1139 -    def getPagerAddresses(self):
    1140          if self.pager.strip():
    1141              return [self.pager.strip()]
    1142          return []
    1143
    1144 -    def getEmailAddresses(self):
    1145          if self.email.strip():
    1146              return [self.email]
    1147          return []
    1148
    1149 -    def getDotNetSession(self):
    1150          """
    1151          Use the Zenoss.net credentials associated with this user to log in to a
    1152          Zenoss.net session.
    1153          """
    1154          session = DotNetCommunication.getDotNetSession(
    1155                                          self.zenossNetUser,
    1156                                          self.zenossNetPassword)
    1157          return session
    1158
    1159 -class GroupSettings(UserSettings):
    1160
    1161      meta_type = 'GroupSettings'
    1162
    1163      factory_type_information = (
    1164          {
    1165              'immediate_view' : 'editGroupSettings',
    1166              'actions'        :
    1167              (
    1168                  {'name'         : 'Edit',
    1169                  'action'        : 'editGroupSettings',
    1170                  'permissions'   : (ZEN_CHANGE_SETTINGS,),
    1171                  },
    1172                  {'name'         : 'Administered Objects',
    1173                  'action'        : 'administeredDevices',
    1174                  'permissions'   : (ZEN_CHANGE_ADMIN_OBJECTS,)
    1175                  },
    1176                  {'name'         : 'Event Views',
    1177                  'action'        : 'editEventViews',
    1178                  # ideally make this its own permission
    1179                  'permissions'   : (ZEN_CHANGE_SETTINGS,),
    1180                  },
    1181                  {'name'         : 'Alerting Rules',
    1182                  'action'        : 'editActionRules',
    1183                  'permissions'   : (ZEN_CHANGE_ALERTING_RULES,),
    1184                  },
    1185              )
    1186           },
    1187          )
    1188
    1189      security = ClassSecurityInfo()
    1190
    1191 -    def _getG(self):
    1192          return self.zport.acl_users.groupManager
    1193
    1194
    1195 -    def hasNoGlobalRoles(self):
    1196          """This is a group we never have roles. This is set to false so that
    1197          fuctionality that would normally be taken away for a restricted user is
    1198          left in.
    1199          """
    1200          return False
    1201
    1202
    1203      security.declareProtected(ZEN_MANAGE_DMD, 'manage_addUsersToGroup')
    1204 -    def manage_addUsersToGroup( self, userids, REQUEST=None ):
    1205          """ Add user to this group
    1206          """
    1207          if type(userids) in types.StringTypes:
    1208              userids = [userids]
    1209          for userid in userids:
    1210              self._getG().addPrincipalToGroup( userid, self.id )
    1211          if REQUEST:
    1212              messaging.IMessageSender(self).sendToBrowser(
    1213                  'Users Added',
    1214                  'Added %s to Group %s' % (','.join(userids), self.id)
    1215              )
    1216              return self.callZenScreen(REQUEST)
    1217
    1218      security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteUserFromGroup')
    1219 -    def manage_deleteUserFromGroup( self, userid ):
    1220          self._getG().removePrincipalFromGroup( userid, self.id )
    1221
    1222      security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteUsersFromGroup')
    1223 -    def manage_deleteUsersFromGroup(self, userids=(), REQUEST=None ):
    1224          """ Delete users from this group
    1225          """
    1226          for userid in userids:
    1227              self.manage_deleteUserFromGroup(userid)
    1228          if REQUEST:
    1229              messaging.IMessageSender(self).sendToBrowser(
    1230                  'Users Removed',
    1231                  'Deleted users from Group %s' % self.id
    1232              )
    1233              return self.callZenScreen(REQUEST)
    1234
    1235 -    def getMemberUserSettings(self):
    1236          return [ self.getUserSettings(u[0])
    1237           for u in self._getG().listAssignedPrincipals(self.id) ]
    1238
    1239 -    def getMemberUserIds(self):
    1240          """
    1241          Returns a list of user ids that are members of this group.
    1242          """
    1243          # We must using reverse mapping of all users to their groups rather
    1244          # than going directly to the group's assigned principals because
    1245          # some group backends don't support listAssignedPrincipals.
    1246          return [ u.id for u in self.ZenUsers.getAllUserSettings()
    1247              if self.id in u.getUserGroupSettingsNames() ]
    1248
    1249 -    def printUsers(self):
    1250          try:
    1251              userIds = self.getMemberUserIds()
    1252          except LocalAndLDAPUserEntries, ex:
    1253              return str(ex)
    1254
    1255          return ", ".join(userIds)
    1256
    1257 -    def getEmailAddresses(self):
    1258          try:
    1259              userIds = self.getMemberUserIds()
    1260          except LocalAndLDAPUserEntries, ex:
    1261              return []
    1262
    1263          result = []
    1264          for username in userIds:
    1265              result.extend(self.getUserSettings(username).getEmailAddresses())
    1266          return result
    1267
    1268 -    def getPagerAddresses(self):
    1269          try:
    1270              userIds = self.getMemberUserIds()
    1271          except LocalAndLDAPUserEntries, ex:
    1272              return []
    1273
    1274          result = []
    1275          for username in userIds:
    1276              result.extend(self.getUserSettings(username).getPagerAddresses())
    1277          return result
    1278
    1279
    1280  InitializeClass(UserSettingsManager)
    1281  InitializeClass(UserSettings)
    1282