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