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.inlineCallbacks
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 uid = yield self.master.db.users.identifierToUid( 133 identifier=user) 134 135 result = None 136 if op == 'remove': 137 if uid: 138 yield self.master.db.users.removeUser(uid) 139 result = user 140 else: 141 log.msg("Unable to find uid for identifier %s" % user) 142 elif op == 'get': 143 if uid: 144 result = yield self.master.db.users.getUser(uid) 145 else: 146 log.msg("Unable to find uid for identifier %s" % user) 147 148 results.append(result) 149 else: 150 for user in info: 151 # get identifier, guaranteed to be in user from checks 152 # done in C{scripts.runner} 153 ident = user.pop('identifier') 154 uid = yield self.master.db.users.identifierToUid( 155 identifier=ident) 156 157 # if only an identifier was in user, we're updating only 158 # the bb_username and bb_password. 159 if not user: 160 if uid: 161 result = yield self.master.db.users.updateUser( 162 uid=uid, 163 identifier=ident, 164 bb_username=bb_username, 165 bb_password=bb_password) 166 results.append(ident) 167 else: 168 log.msg("Unable to find uid for identifier %s" 169 % user) 170 else: 171 # when adding, we update the user after the first attr 172 once_through = False 173 for attr in user: 174 if op == 'update' or once_through: 175 if uid: 176 result = yield self.master.db.users.updateUser( 177 uid=uid, 178 identifier=ident, 179 bb_username=bb_username, 180 bb_password=bb_password, 181 attr_type=attr, 182 attr_data=user[attr]) 183 else: 184 log.msg("Unable to find uid for identifier %s" 185 % user) 186 elif op == 'add': 187 result = yield self.master.db.users.findUserByAttr( 188 identifier=ident, 189 attr_type=attr, 190 attr_data=user[attr]) 191 once_through = True 192 results.append(ident) 193 194 # result is None from updateUser calls 195 if result: 196 results.append(result) 197 uid = result 198 results = self.formatResults(op, results) 199 defer.returnValue(results)
200
201 -class CommandlineUserManager(UsersBase):
202 """ 203 Service that runs to set up and register CommandlineUserManagerPerspective 204 so `buildbot user` calls get to perspective_commandline. 205 """ 206
207 - def __init__(self, username=None, passwd=None, port=None):
208 UsersBase.__init__(self) 209 assert username and passwd, ("A username and password pair must be given " 210 "to connect and use `buildbot user`") 211 self.username = username 212 self.passwd = passwd 213 214 assert port, "A port must be specified for a PB connection" 215 self.port = port 216 self.registration = None
217
218 - def startService(self):
219 UsersBase.startService(self) 220 # set up factory and register with buildbot.pbmanager 221 def factory(mind, username): 222 return CommandlineUserManagerPerspective(self.master)
223 self.registration = self.master.pbmanager.register(self.port, 224 self.username, 225 self.passwd, 226 factory)
227
228 - def stopService(self):
229 d = defer.maybeDeferred(UsersBase.stopService, self) 230 def unreg(_): 231 if self.registration: 232 return self.registration.unregister()
233 d.addCallback(unreg) 234 return d 235