comparison rhodecode/lib/auth.py @ 1628:de71a4bde097 beta

Some code cleanups and fixes
author Marcin Kuzminski <marcin@python-works.com>
date Mon, 31 Oct 2011 21:42:41 +0200
parents cbc2b1913cdf
children 25d8e4836bc2
comparison
equal deleted inserted replaced
1627:c622e3a85499 1628:de71a4bde097
123 123
124 124
125 def check_password(password, hashed): 125 def check_password(password, hashed):
126 return RhodeCodeCrypto.hash_check(password, hashed) 126 return RhodeCodeCrypto.hash_check(password, hashed)
127 127
128 128 def generate_api_key(str_, salt=None):
129 def generate_api_key(username, salt=None): 129 """
130 Generates API KEY from given string
131
132 :param str_:
133 :param salt:
134 """
135
130 if salt is None: 136 if salt is None:
131 salt = _RandomNameSequence().next() 137 salt = _RandomNameSequence().next()
132 138
133 return hashlib.sha1(username + salt).hexdigest() 139 return hashlib.sha1(str_ + salt).hexdigest()
134 140
135 141
136 def authfunc(environ, username, password): 142 def authfunc(environ, username, password):
137 """Dummy authentication function used in Mercurial/Git/ and access control, 143 """
144 Dummy authentication function used in Mercurial/Git/ and access control,
138 145
139 :param environ: needed only for using in Basic auth 146 :param environ: needed only for using in Basic auth
140 """ 147 """
141 return authenticate(username, password) 148 return authenticate(username, password)
142 149
143 150
144 def authenticate(username, password): 151 def authenticate(username, password):
145 """Authentication function used for access control, 152 """
153 Authentication function used for access control,
146 firstly checks for db authentication then if ldap is enabled for ldap 154 firstly checks for db authentication then if ldap is enabled for ldap
147 authentication, also creates ldap user if not in database 155 authentication, also creates ldap user if not in database
148 156
149 :param username: username 157 :param username: username
150 :param password: password 158 :param password: password
226 def login_container_auth(username): 234 def login_container_auth(username):
227 user = User.get_by_username(username) 235 user = User.get_by_username(username)
228 if user is None: 236 if user is None:
229 user_model = UserModel() 237 user_model = UserModel()
230 user_attrs = { 238 user_attrs = {
231 'name': username, 239 'name': username,
232 'lastname': None, 240 'lastname': None,
233 'email': None, 241 'email': None,
234 } 242 }
235 if not user_model.create_for_container_auth(username, user_attrs): 243 user = user_model.create_for_container_auth(username, user_attrs)
244 if not user:
236 return None 245 return None
237 user = User.get_by_username(username)
238 log.info('User %s was created by container authentication', username) 246 log.info('User %s was created by container authentication', username)
239 247
240 if not user.active: 248 if not user.active:
241 return None 249 return None
242 250
243 user.update_lastlogin() 251 user.update_lastlogin()
244 log.debug('User %s is now logged in by container authentication', user.username) 252 log.debug('User %s is now logged in by container authentication',
253 user.username)
245 return user 254 return user
246 255
247 def get_container_username(environ, cfg=config): 256 def get_container_username(environ, cfg):
248 from paste.httpheaders import REMOTE_USER 257 from paste.httpheaders import REMOTE_USER
249 from paste.deploy.converters import asbool 258 from paste.deploy.converters import asbool
250 259
260 proxy_pass_enabled = asbool(cfg.get('proxypass_auth_enabled', False))
251 username = REMOTE_USER(environ) 261 username = REMOTE_USER(environ)
252 262
253 if not username and asbool(cfg.get('proxypass_auth_enabled', False)): 263 if not username and proxy_pass_enabled:
254 username = environ.get('HTTP_X_FORWARDED_USER') 264 username = environ.get('HTTP_X_FORWARDED_USER')
255 265
256 if username: 266 if username and proxy_pass_enabled:
257 #Removing realm and domain from username 267 # Removing realm and domain from username
258 username = username.partition('@')[0] 268 username = username.partition('@')[0]
259 username = username.rpartition('\\')[2] 269 username = username.rpartition('\\')[2]
260 log.debug('Received username %s from container', username) 270 log.debug('Received username %s from container', username)
261 271
262 return username 272 return username
274 def __init__(self, user_id=None, api_key=None, username=None): 284 def __init__(self, user_id=None, api_key=None, username=None):
275 285
276 self.user_id = user_id 286 self.user_id = user_id
277 self.api_key = None 287 self.api_key = None
278 self.username = username 288 self.username = username
279 289
280 self.name = '' 290 self.name = ''
281 self.lastname = '' 291 self.lastname = ''
282 self.email = '' 292 self.email = ''
283 self.is_authenticated = False 293 self.is_authenticated = False
284 self.admin = False 294 self.admin = False
288 298
289 def propagate_data(self): 299 def propagate_data(self):
290 user_model = UserModel() 300 user_model = UserModel()
291 self.anonymous_user = User.get_by_username('default') 301 self.anonymous_user = User.get_by_username('default')
292 is_user_loaded = False 302 is_user_loaded = False
303
304 # try go get user by api key
293 if self._api_key and self._api_key != self.anonymous_user.api_key: 305 if self._api_key and self._api_key != self.anonymous_user.api_key:
294 #try go get user by api key
295 log.debug('Auth User lookup by API KEY %s', self._api_key) 306 log.debug('Auth User lookup by API KEY %s', self._api_key)
296 is_user_loaded = user_model.fill_data(self, api_key=self._api_key) 307 is_user_loaded = user_model.fill_data(self, api_key=self._api_key)
297 elif self.user_id is not None \ 308 # lookup by userid
298 and self.user_id != self.anonymous_user.user_id: 309 elif (self.user_id is not None and
310 self.user_id != self.anonymous_user.user_id):
299 log.debug('Auth User lookup by USER ID %s', self.user_id) 311 log.debug('Auth User lookup by USER ID %s', self.user_id)
300 is_user_loaded = user_model.fill_data(self, user_id=self.user_id) 312 is_user_loaded = user_model.fill_data(self, user_id=self.user_id)
313 # lookup by username
301 elif self.username: 314 elif self.username:
302 log.debug('Auth User lookup by USER NAME %s', self.username) 315 log.debug('Auth User lookup by USER NAME %s', self.username)
303 dbuser = login_container_auth(self.username) 316 dbuser = login_container_auth(self.username)
304 if dbuser is not None: 317 if dbuser is not None:
305 for k, v in dbuser.get_dict().items(): 318 for k, v in dbuser.get_dict().items():
306 setattr(self, k, v) 319 setattr(self, k, v)
307 self.set_authenticated() 320 self.set_authenticated()
308 is_user_loaded = True 321 is_user_loaded = True
309 322
310 if not is_user_loaded: 323 if not is_user_loaded:
324 # if we cannot authenticate user try anonymous
311 if self.anonymous_user.active is True: 325 if self.anonymous_user.active is True:
312 user_model.fill_data(self, 326 user_model.fill_data(self,user_id=self.anonymous_user.user_id)
313 user_id=self.anonymous_user.user_id) 327 # then we set this user is logged in
314 #then we set this user is logged in
315 self.is_authenticated = True 328 self.is_authenticated = True
316 else: 329 else:
317 self.user_id = None 330 self.user_id = None
318 self.username = None 331 self.username = None
319 self.is_authenticated = False 332 self.is_authenticated = False
335 def __repr__(self): 348 def __repr__(self):
336 return "<AuthUser('id:%s:%s|%s')>" % (self.user_id, self.username, 349 return "<AuthUser('id:%s:%s|%s')>" % (self.user_id, self.username,
337 self.is_authenticated) 350 self.is_authenticated)
338 351
339 def set_authenticated(self, authenticated=True): 352 def set_authenticated(self, authenticated=True):
340
341 if self.user_id != self.anonymous_user.user_id: 353 if self.user_id != self.anonymous_user.user_id:
342 self.is_authenticated = authenticated 354 self.is_authenticated = authenticated
343 355
344 356
345 def set_available_permissions(config): 357 def set_available_permissions(config):
346 """This function will propagate pylons globals with all available defined 358 """
359 This function will propagate pylons globals with all available defined
347 permission given in db. We don't want to check each time from db for new 360 permission given in db. We don't want to check each time from db for new
348 permissions since adding a new permission also requires application restart 361 permissions since adding a new permission also requires application restart
349 ie. to decorate new views with the newly created permission 362 ie. to decorate new views with the newly created permission
350 363
351 :param config: current pylons config instance 364 :param config: current pylons config instance
472 'view this page'), 485 'view this page'),
473 category='warning') 486 category='warning')
474 return redirect(url('login_home', came_from=p)) 487 return redirect(url('login_home', came_from=p))
475 488
476 else: 489 else:
477 #redirect with forbidden ret code 490 # redirect with forbidden ret code
478 return abort(403) 491 return abort(403)
479 492
480 def check_permissions(self): 493 def check_permissions(self):
481 """Dummy function for overriding""" 494 """Dummy function for overriding"""
482 raise Exception('You have to write this function in child class') 495 raise Exception('You have to write this function in child class')
659 if self.required_perms.intersection(self.user_perms): 672 if self.required_perms.intersection(self.user_perms):
660 log.debug('permission granted') 673 log.debug('permission granted')
661 return True 674 return True
662 log.debug('permission denied') 675 log.debug('permission denied')
663 return False 676 return False
677