Package buildbot :: Package process :: Package users :: Module manual
[frames] | no frames]

Source Code for Module buildbot.process.users.manual

  1  # This file is part of Buildbot.  Buildbot is free software: you can 
  2  # redistribute it and/or modify it under the terms of the GNU General Public 
  3  # License as published by the Free Software Foundation, version 2. 
  4  # 
  5  # This program is distributed in the hope that it will be useful, but WITHOUT 
  6  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  8  # details. 
  9  # 
 10  # You should have received a copy of the GNU General Public License along with 
 11  # this program; if not, write to the Free Software Foundation, Inc., 51 
 12  # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 13  # 
 14  # Copyright Buildbot Team Members 
 15   
 16  # this class is known to contain cruft and will be looked at later, so 
 17  # no current implementation utilizes it aside from scripts.runner. 
 18   
 19  from twisted.python import log 
 20  from twisted.internet import defer 
 21  from twisted.application import service 
 22  from buildbot import pbutil 
23 24 -class UsersBase(service.MultiService):
25 """ 26 Base class for services that manage users manually. This takes care 27 of the service.MultiService work needed by all the services that 28 subclass it. 29 """ 30
31 - def __init__(self):
32 service.MultiService.__init__(self) 33 self.master = None
34
35 - def startService(self):
36 service.MultiService.startService(self)
37
38 - def stopService(self):
39 return service.MultiService.stopService(self)
40
41 -class CommandlineUserManagerPerspective(pbutil.NewCredPerspective):
42 """ 43 Perspective registered in buildbot.pbmanager and contains the real 44 workings of `buildbot user` by working with the database when 45 perspective_commandline is called. 46 """ 47
48 - def __init__(self, master):
49 self.master = master
50
51 - def formatResults(self, op, results):
52 """ 53 This formats the results of the database operations for printing 54 back to the caller 55 56 @param op: operation to perform (add, remove, update, get) 57 @type op: string 58 59 @param results: results from db queries in perspective_commandline 60 @type results: list 61 62 @returns: string containing formatted results 63 """ 64 formatted_results = "" 65 66 if op == 'add': 67 # list, alternating ident, uid 68 formatted_results += "user(s) added:\n" 69 for user in results: 70 if isinstance(user, basestring): 71 formatted_results += "identifier: %s\n" % user 72 else: 73 formatted_results += "uid: %d\n\n" % user 74 elif op == 'remove': 75 # list of dictionaries 76 formatted_results += "user(s) removed:\n" 77 for user in results: 78 if user: 79 formatted_results += "identifier: %s\n" % (user) 80 elif op == 'update': 81 # list, alternating ident, None 82 formatted_results += "user(s) updated:\n" 83 for user in results: 84 if user: 85 formatted_results += "identifier: %s\n" % (user) 86 elif op == 'get': 87 # list of dictionaries 88 formatted_results += "user(s) found:\n" 89 for user in results: 90 if user: 91 for key in user: 92 if key != 'bb_password': 93 formatted_results += "%s: %s\n" % (key, user[key]) 94 formatted_results += "\n" 95 else: 96 formatted_results += "no match found\n" 97 return formatted_results
98 99 @defer.deferredGenerator
100 - def perspective_commandline(self, op, bb_username, bb_password, ids, info):
101 """ 102 This performs the requested operations from the `buildbot user` 103 call by calling the proper buildbot.db.users methods based on 104 the operation. It yields a deferred instance with the results 105 from the database methods. 106 107 @param op: operation to perform (add, remove, update, get) 108 @type op: string 109 110 @param bb_username: username portion of auth credentials 111 @type bb_username: string 112 113 @param bb_password: hashed password portion of auth credentials 114 @type bb_password: hashed string 115 116 @param ids: user identifiers used to find existing users 117 @type ids: list of strings or None 118 119 @param info: type/value pairs for each user that will be added 120 or updated in the database 121 @type info: list of dictionaries or None 122 123 @returns: results from db.users methods via deferred 124 """ 125 log.msg("perspective_commandline called") 126 results = [] 127 128 if ids: 129 for user in ids: 130 # get identifier, guaranteed to be in user from checks 131 # done in C{scripts.runner} 132 d = self.master.db.users.identifierToUid(identifier=user) 133 wfd = defer.waitForDeferred(d) 134 yield wfd 135 uid = wfd.getResult() 136 137 result = None 138 if op == 'remove': 139 if uid: 140 d = self.master.db.users.removeUser(uid) 141 wfd = defer.waitForDeferred(d) 142 yield wfd 143 wfd.getResult() 144 result = user 145 else: 146 log.msg("Unable to find uid for identifier %s" % user) 147 elif op == 'get': 148 if uid: 149 d = self.master.db.users.getUser(uid) 150 wfd = defer.waitForDeferred(d) 151 yield wfd 152 result = wfd.getResult() 153 else: 154 log.msg("Unable to find uid for identifier %s" % user) 155 156 results.append(result) 157 else: 158 for user in info: 159 # get identifier, guaranteed to be in user from checks 160 # done in C{scripts.runner} 161 ident = user.pop('identifier') 162 d = self.master.db.users.identifierToUid(identifier=ident) 163 wfd = defer.waitForDeferred(d) 164 yield wfd 165 uid = wfd.getResult() 166 167 # if only an identifier was in user, we're updating only 168 # the bb_username and bb_password. 169 if not user: 170 if uid: 171 d = self.master.db.users.updateUser( 172 uid=uid, 173 identifier=ident, 174 bb_username=bb_username, 175 bb_password=bb_password) 176 wfd = defer.waitForDeferred(d) 177 yield wfd 178 results.append(ident) 179 result = wfd.getResult() 180 else: 181 log.msg("Unable to find uid for identifier %s" 182 % user) 183 else: 184 # when adding, we update the user after the first attr 185 once_through = False 186 for attr in user: 187 if op == 'update' or once_through: 188 if uid: 189 d = self.master.db.users.updateUser( 190 uid=uid, 191 identifier=ident, 192 bb_username=bb_username, 193 bb_password=bb_password, 194 attr_type=attr, 195 attr_data=user[attr]) 196 else: 197 log.msg("Unable to find uid for identifier %s" 198 % user) 199 elif op == 'add': 200 d = self.master.db.users.findUserByAttr( 201 identifier=ident, 202 attr_type=attr, 203 attr_data=user[attr]) 204 once_through = True 205 wfd = defer.waitForDeferred(d) 206 yield wfd 207 results.append(ident) 208 result = wfd.getResult() 209 210 # result is None from updateUser calls 211 if result: 212 results.append(result) 213 uid = result 214 results = self.formatResults(op, results) 215 yield results
216
217 -class CommandlineUserManager(UsersBase):
218 """ 219 Service that runs to set up and register CommandlineUserManagerPerspective 220 so `buildbot user` calls get to perspective_commandline. 221 """ 222
223 - def __init__(self, username=None, passwd=None, port=None):
224 UsersBase.__init__(self) 225 assert username and passwd, ("A username and password pair must be given " 226 "to connect and use `buildbot user`") 227 self.username = username 228 self.passwd = passwd 229 230 assert port, "A port must be specified for a PB connection" 231 self.port = port 232 self.registration = None
233
234 - def startService(self):
235 UsersBase.startService(self) 236 # set up factory and register with buildbot.pbmanager 237 def factory(mind, username): 238 return CommandlineUserManagerPerspective(self.master)
239 self.registration = self.master.pbmanager.register(self.port, 240 self.username, 241 self.passwd, 242 factory)
243
244 - def stopService(self):
245 d = defer.maybeDeferred(UsersBase.stopService, self) 246 def unreg(_): 247 if self.registration: 248 return self.registration.unregister()
249 d.addCallback(unreg) 250 return d 251