##// END OF EJS Templates
Removed redundant Exception catching
marcink -
r4075:92da990f default
parent child Browse files
Show More
@@ -1,869 +1,871 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.model.user
4 4 ~~~~~~~~~~~~~~~~~~~~
5 5
6 6 users model for RhodeCode
7 7
8 8 :created_on: Apr 9, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software: you can redistribute it and/or modify
14 14 # it under the terms of the GNU General Public License as published by
15 15 # the Free Software Foundation, either version 3 of the License, or
16 16 # (at your option) any later version.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26 26 import logging
27 27 import traceback
28 28 import itertools
29 29 import collections
30 30 from pylons import url
31 31 from pylons.i18n.translation import _
32 32
33 33 from sqlalchemy.exc import DatabaseError
34 34 from sqlalchemy.orm import joinedload
35 35
36 36 from rhodecode.lib.utils2 import safe_unicode, generate_api_key, get_current_rhodecode_user
37 37 from rhodecode.lib.caching_query import FromCache
38 38 from rhodecode.model import BaseModel
39 39 from rhodecode.model.db import User, Repository, Permission, \
40 40 UserToPerm, UserGroupRepoToPerm, UserGroupToPerm, UserGroupMember, \
41 41 Notification, RepoGroup, UserGroupRepoGroupToPerm, \
42 42 UserEmailMap, UserIpMap, UserGroupUserGroupToPerm, UserGroup
43 43 from rhodecode.lib.exceptions import DefaultUserException, \
44 44 UserOwnsReposException
45 45 from rhodecode.model.meta import Session
46 46
47 47
48 48 log = logging.getLogger(__name__)
49 49
50 50 PERM_WEIGHTS = Permission.PERM_WEIGHTS
51 51
52 52
53 53 class UserModel(BaseModel):
54 54 cls = User
55 55
56 56 def get(self, user_id, cache=False):
57 57 user = self.sa.query(User)
58 58 if cache:
59 59 user = user.options(FromCache("sql_cache_short",
60 60 "get_user_%s" % user_id))
61 61 return user.get(user_id)
62 62
63 63 def get_user(self, user):
64 64 return self._get_user(user)
65 65
66 66 def get_by_username(self, username, cache=False, case_insensitive=False):
67 67
68 68 if case_insensitive:
69 69 user = self.sa.query(User).filter(User.username.ilike(username))
70 70 else:
71 71 user = self.sa.query(User).filter(User.username == username)
72 72 if cache:
73 73 user = user.options(FromCache("sql_cache_short",
74 74 "get_user_%s" % username))
75 75 return user.scalar()
76 76
77 77 def get_by_email(self, email, cache=False, case_insensitive=False):
78 78 return User.get_by_email(email, case_insensitive, cache)
79 79
80 80 def get_by_api_key(self, api_key, cache=False):
81 81 return User.get_by_api_key(api_key, cache)
82 82
83 83 def create(self, form_data, cur_user=None):
84 84 if not cur_user:
85 85 cur_user = getattr(get_current_rhodecode_user(), 'username', None)
86 86
87 87 from rhodecode.lib.hooks import log_create_user, check_allowed_create_user
88 88 _fd = form_data
89 form_data = {
89 user_data = {
90 90 'username': _fd['username'], 'password': _fd['password'],
91 91 'email': _fd['email'], 'firstname': _fd['firstname'], 'lastname': _fd['lastname'],
92 92 'active': _fd['active'], 'admin': False
93 93 }
94 94 # raises UserCreationError if it's not allowed
95 check_allowed_create_user(form_data, cur_user)
95 check_allowed_create_user(user_data, cur_user)
96 96
97 97 from rhodecode.lib.auth import get_crypt_password
98 98 try:
99 99 new_user = User()
100 100 for k, v in form_data.items():
101 101 if k == 'password':
102 102 v = get_crypt_password(v)
103 103 if k == 'firstname':
104 104 k = 'name'
105 105 setattr(new_user, k, v)
106 106
107 107 new_user.api_key = generate_api_key(form_data['username'])
108 108 self.sa.add(new_user)
109 109
110 110 log_create_user(new_user.get_dict(), cur_user)
111 111 return new_user
112 112 except Exception:
113 113 log.error(traceback.format_exc())
114 114 raise
115 115
116 116 def create_or_update(self, username, password, email, firstname='',
117 117 lastname='', active=True, admin=False, ldap_dn=None,
118 118 cur_user=None):
119 119 """
120 120 Creates a new instance if not found, or updates current one
121 121
122 122 :param username:
123 123 :param password:
124 124 :param email:
125 125 :param active:
126 126 :param firstname:
127 127 :param lastname:
128 128 :param active:
129 129 :param admin:
130 130 :param ldap_dn:
131 131 :param cur_user:
132 132 """
133 133 if not cur_user:
134 134 cur_user = getattr(get_current_rhodecode_user(), 'username', None)
135 135
136 136 from rhodecode.lib.auth import get_crypt_password
137 137 from rhodecode.lib.hooks import log_create_user, check_allowed_create_user
138 form_data = {
138 user_data = {
139 139 'username': username, 'password': password,
140 140 'email': email, 'firstname': firstname, 'lastname': lastname,
141 141 'active': active, 'admin': admin
142 142 }
143 143 # raises UserCreationError if it's not allowed
144 check_allowed_create_user(form_data, cur_user)
144 check_allowed_create_user(user_data, cur_user)
145 145
146 146 log.debug('Checking for %s account in RhodeCode database' % username)
147 147 user = User.get_by_username(username, case_insensitive=True)
148 148 if user is None:
149 149 log.debug('creating new user %s' % username)
150 150 new_user = User()
151 151 edit = False
152 152 else:
153 153 log.debug('updating user %s' % username)
154 154 new_user = user
155 155 edit = True
156 156
157 157 try:
158 158 new_user.username = username
159 159 new_user.admin = admin
160 160 # set password only if creating an user or password is changed
161 161 if not edit or user.password != password:
162 162 new_user.password = get_crypt_password(password) if password else None
163 163 new_user.api_key = generate_api_key(username)
164 164 new_user.email = email
165 165 new_user.active = active
166 166 new_user.ldap_dn = safe_unicode(ldap_dn) if ldap_dn else None
167 167 new_user.name = firstname
168 168 new_user.lastname = lastname
169 169 self.sa.add(new_user)
170 170
171 171 if not edit:
172 172 log_create_user(new_user.get_dict(), cur_user)
173 173 return new_user
174 174 except (DatabaseError,):
175 175 log.error(traceback.format_exc())
176 176 raise
177 177
178 178 def create_for_container_auth(self, username, attrs, cur_user=None):
179 179 """
180 180 Creates the given user if it's not already in the database
181 181
182 182 :param username:
183 183 :param attrs:
184 184 :param cur_user:
185 185 """
186 186 if not cur_user:
187 187 cur_user = getattr(get_current_rhodecode_user(), 'username', None)
188 188 if self.get_by_username(username, case_insensitive=True) is None:
189 189 # autogenerate email for container account without one
190 190 generate_email = lambda usr: '%s@container_auth.account' % usr
191 191 firstname = attrs['name']
192 192 lastname = attrs['lastname']
193 193 active = attrs.get('active', True)
194 194 email = attrs['email'] or generate_email(username)
195 195
196 196 from rhodecode.lib.hooks import log_create_user, check_allowed_create_user
197 form_data = {
197 user_data = {
198 198 'username': username, 'password': None,
199 199 'email': email, 'firstname': firstname, 'lastname': lastname,
200 200 'active': attrs.get('active', True), 'admin': False
201 201 }
202 202 # raises UserCreationError if it's not allowed
203 check_allowed_create_user(form_data, cur_user)
203 check_allowed_create_user(user_data, cur_user)
204 204
205 205 try:
206 206 new_user = User()
207 207 new_user.username = username
208 208 new_user.password = None
209 209 new_user.api_key = generate_api_key(username)
210 210 new_user.email = email
211 211 new_user.active = active
212 212 new_user.name = firstname
213 213 new_user.lastname = lastname
214 214
215 215 self.sa.add(new_user)
216 216 log_create_user(new_user.get_dict(), cur_user)
217 217 return new_user
218 218 except (DatabaseError,):
219 219 log.error(traceback.format_exc())
220 220 self.sa.rollback()
221 221 raise
222 222 log.debug('User %s already exists. Skipping creation of account'
223 223 ' for container auth.', username)
224 224 return None
225 225
226 226 def create_ldap(self, username, password, user_dn, attrs, cur_user=None):
227 227 """
228 228 Checks if user is in database, if not creates this user marked
229 229 as ldap user
230 230
231 231 :param username:
232 232 :param password:
233 233 :param user_dn:
234 234 :param attrs:
235 235 :param cur_user:
236 236 """
237 237 if not cur_user:
238 238 cur_user = getattr(get_current_rhodecode_user(), 'username', None)
239 239 from rhodecode.lib.auth import get_crypt_password
240 240 log.debug('Checking for such ldap account in RhodeCode database')
241 241 if self.get_by_username(username, case_insensitive=True) is None:
242 242 # autogenerate email for container account without one
243 243 generate_email = lambda usr: '%s@ldap.account' % usr
244 244 password = get_crypt_password(password)
245 245 firstname = attrs['name']
246 246 lastname = attrs['lastname']
247 247 active = attrs.get('active', True)
248 248 email = attrs['email'] or generate_email(username)
249 249
250 250 from rhodecode.lib.hooks import log_create_user, check_allowed_create_user
251 form_data = {
251 user_data = {
252 252 'username': username, 'password': password,
253 253 'email': email, 'firstname': firstname, 'lastname': lastname,
254 254 'active': attrs.get('active', True), 'admin': False
255 255 }
256 256 # raises UserCreationError if it's not allowed
257 check_allowed_create_user(form_data, cur_user)
257 check_allowed_create_user(user_data, cur_user)
258 258
259 259 try:
260 260 new_user = User()
261 261 username = username.lower()
262 262 # add ldap account always lowercase
263 263 new_user.username = username
264 264 new_user.password = password
265 265 new_user.api_key = generate_api_key(username)
266 266 new_user.email = email
267 267 new_user.active = active
268 268 new_user.ldap_dn = safe_unicode(user_dn)
269 269 new_user.name = firstname
270 270 new_user.lastname = lastname
271 271 self.sa.add(new_user)
272 272
273 273 log_create_user(new_user.get_dict(), cur_user)
274 274 return new_user
275 275 except (DatabaseError,):
276 276 log.error(traceback.format_exc())
277 277 self.sa.rollback()
278 278 raise
279 279 log.debug('this %s user exists skipping creation of ldap account',
280 280 username)
281 281 return None
282 282
283 283 def create_registration(self, form_data):
284 284 from rhodecode.model.notification import NotificationModel
285 285
286 286 try:
287 287 form_data['admin'] = False
288 288 new_user = self.create(form_data)
289 289
290 290 self.sa.add(new_user)
291 291 self.sa.flush()
292 292
293 293 # notification to admins
294 294 subject = _('New user registration')
295 295 body = ('New user registration\n'
296 296 '---------------------\n'
297 297 '- Username: %s\n'
298 298 '- Full Name: %s\n'
299 299 '- Email: %s\n')
300 300 body = body % (new_user.username, new_user.full_name, new_user.email)
301 301 edit_url = url('edit_user', id=new_user.user_id, qualified=True)
302 302 kw = {'registered_user_url': edit_url}
303 303 NotificationModel().create(created_by=new_user, subject=subject,
304 304 body=body, recipients=None,
305 305 type_=Notification.TYPE_REGISTRATION,
306 306 email_kwargs=kw)
307 307
308 308 except Exception:
309 309 log.error(traceback.format_exc())
310 310 raise
311 311
312 312 def update(self, user_id, form_data, skip_attrs=[]):
313 313 from rhodecode.lib.auth import get_crypt_password
314 314 try:
315 315 user = self.get(user_id, cache=False)
316 316 if user.username == 'default':
317 317 raise DefaultUserException(
318 318 _("You can't Edit this user since it's"
319 319 " crucial for entire application"))
320 320
321 321 for k, v in form_data.items():
322 322 if k in skip_attrs:
323 323 continue
324 324 if k == 'new_password' and v:
325 325 user.password = get_crypt_password(v)
326 326 user.api_key = generate_api_key(user.username)
327 327 else:
328 328 if k == 'firstname':
329 329 k = 'name'
330 330 setattr(user, k, v)
331 331 self.sa.add(user)
332 332 except Exception:
333 333 log.error(traceback.format_exc())
334 334 raise
335 335
336 336 def update_user(self, user, **kwargs):
337 337 from rhodecode.lib.auth import get_crypt_password
338 338 try:
339 339 user = self._get_user(user)
340 340 if user.username == 'default':
341 341 raise DefaultUserException(
342 342 _("You can't Edit this user since it's"
343 343 " crucial for entire application")
344 344 )
345 345
346 346 for k, v in kwargs.items():
347 347 if k == 'password' and v:
348 348 v = get_crypt_password(v)
349 349 user.api_key = generate_api_key(user.username)
350 350
351 351 setattr(user, k, v)
352 352 self.sa.add(user)
353 353 return user
354 354 except Exception:
355 355 log.error(traceback.format_exc())
356 356 raise
357 357
358 358 def delete(self, user, cur_user=None):
359 359 if not cur_user:
360 360 cur_user = getattr(get_current_rhodecode_user(), 'username', None)
361 361 user = self._get_user(user)
362 362
363 363 try:
364 364 if user.username == 'default':
365 365 raise DefaultUserException(
366 366 _(u"You can't remove this user since it's"
367 367 " crucial for entire application")
368 368 )
369 369 if user.repositories:
370 370 repos = [x.repo_name for x in user.repositories]
371 371 raise UserOwnsReposException(
372 372 _(u'user "%s" still owns %s repositories and cannot be '
373 373 'removed. Switch owners or remove those repositories. %s')
374 374 % (user.username, len(repos), ', '.join(repos))
375 375 )
376 376 self.sa.delete(user)
377 377
378 378 from rhodecode.lib.hooks import log_delete_user
379 379 log_delete_user(user.get_dict(), cur_user)
380 380 except Exception:
381 381 log.error(traceback.format_exc())
382 382 raise
383 383
384 384 def reset_password_link(self, data):
385 385 from rhodecode.lib.celerylib import tasks, run_task
386 386 from rhodecode.model.notification import EmailNotificationModel
387 387 user_email = data['email']
388 388 try:
389 389 user = User.get_by_email(user_email)
390 390 if user:
391 391 log.debug('password reset user found %s' % user)
392 392 link = url('reset_password_confirmation', key=user.api_key,
393 393 qualified=True)
394 394 reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET
395 395 body = EmailNotificationModel().get_email_tmpl(reg_type,
396 396 **{'user': user.short_contact,
397 397 'reset_url': link})
398 398 log.debug('sending email')
399 399 run_task(tasks.send_email, user_email,
400 400 _("Password reset link"), body, body)
401 401 log.info('send new password mail to %s' % user_email)
402 402 else:
403 403 log.debug("password reset email %s not found" % user_email)
404 404 except Exception:
405 405 log.error(traceback.format_exc())
406 406 return False
407 407
408 408 return True
409 409
410 410 def reset_password(self, data):
411 411 from rhodecode.lib.celerylib import tasks, run_task
412 412 from rhodecode.lib import auth
413 413 user_email = data['email']
414 pre_db = True
414 415 try:
415 try:
416 user = User.get_by_email(user_email)
417 new_passwd = auth.PasswordGenerator().gen_password(8,
418 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
419 if user:
420 user.password = auth.get_crypt_password(new_passwd)
421 user.api_key = auth.generate_api_key(user.username)
422 Session().add(user)
423 Session().commit()
424 log.info('change password for %s' % user_email)
425 if new_passwd is None:
426 raise Exception('unable to generate new password')
427 except Exception:
428 log.error(traceback.format_exc())
429 Session().rollback()
416 user = User.get_by_email(user_email)
417 new_passwd = auth.PasswordGenerator().gen_password(8,
418 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
419 if user:
420 user.password = auth.get_crypt_password(new_passwd)
421 user.api_key = auth.generate_api_key(user.username)
422 Session().add(user)
423 Session().commit()
424 log.info('change password for %s' % user_email)
425 if new_passwd is None:
426 raise Exception('unable to generate new password')
430 427
428 pre_db = False
431 429 run_task(tasks.send_email, user_email,
432 430 _('Your new password'),
433 431 _('Your new RhodeCode password:%s') % (new_passwd,))
434 432 log.info('send new password mail to %s' % user_email)
435 433
436 434 except Exception:
437 435 log.error('Failed to update user password')
438 436 log.error(traceback.format_exc())
437 if pre_db:
438 # we rollback only if local db stuff fails. If it goes into
439 # run_task, we're pass rollback state this wouldn't work then
440 Session().rollback()
439 441
440 442 return True
441 443
442 444 def fill_data(self, auth_user, user_id=None, api_key=None):
443 445 """
444 446 Fetches auth_user by user_id,or api_key if present.
445 447 Fills auth_user attributes with those taken from database.
446 448 Additionally set's is_authenitated if lookup fails
447 449 present in database
448 450
449 451 :param auth_user: instance of user to set attributes
450 452 :param user_id: user id to fetch by
451 453 :param api_key: api key to fetch by
452 454 """
453 455 if user_id is None and api_key is None:
454 456 raise Exception('You need to pass user_id or api_key')
455 457
456 458 try:
457 459 if api_key:
458 460 dbuser = self.get_by_api_key(api_key)
459 461 else:
460 462 dbuser = self.get(user_id)
461 463
462 464 if dbuser is not None and dbuser.active:
463 465 log.debug('filling %s data' % dbuser)
464 466 for k, v in dbuser.get_dict().items():
465 467 setattr(auth_user, k, v)
466 468 else:
467 469 return False
468 470
469 471 except Exception:
470 472 log.error(traceback.format_exc())
471 473 auth_user.is_authenticated = False
472 474 return False
473 475
474 476 return True
475 477
476 478 def fill_perms(self, user, explicit=True, algo='higherwin'):
477 479 """
478 480 Fills user permission attribute with permissions taken from database
479 481 works for permissions given for repositories, and for permissions that
480 482 are granted to groups
481 483
482 484 :param user: user instance to fill his perms
483 485 :param explicit: In case there are permissions both for user and a group
484 486 that user is part of, explicit flag will defiine if user will
485 487 explicitly override permissions from group, if it's False it will
486 488 make decision based on the algo
487 489 :param algo: algorithm to decide what permission should be choose if
488 490 it's multiple defined, eg user in two different groups. It also
489 491 decides if explicit flag is turned off how to specify the permission
490 492 for case when user is in a group + have defined separate permission
491 493 """
492 494 RK = 'repositories'
493 495 GK = 'repositories_groups'
494 496 UK = 'user_groups'
495 497 GLOBAL = 'global'
496 498 user.permissions[RK] = {}
497 499 user.permissions[GK] = {}
498 500 user.permissions[UK] = {}
499 501 user.permissions[GLOBAL] = set()
500 502
501 503 def _choose_perm(new_perm, cur_perm):
502 504 new_perm_val = PERM_WEIGHTS[new_perm]
503 505 cur_perm_val = PERM_WEIGHTS[cur_perm]
504 506 if algo == 'higherwin':
505 507 if new_perm_val > cur_perm_val:
506 508 return new_perm
507 509 return cur_perm
508 510 elif algo == 'lowerwin':
509 511 if new_perm_val < cur_perm_val:
510 512 return new_perm
511 513 return cur_perm
512 514
513 515 #======================================================================
514 516 # fetch default permissions
515 517 #======================================================================
516 518 default_user = User.get_by_username('default', cache=True)
517 519 default_user_id = default_user.user_id
518 520
519 521 default_repo_perms = Permission.get_default_perms(default_user_id)
520 522 default_repo_groups_perms = Permission.get_default_group_perms(default_user_id)
521 523 default_user_group_perms = Permission.get_default_user_group_perms(default_user_id)
522 524
523 525 if user.is_admin:
524 526 #==================================================================
525 527 # admin user have all default rights for repositories
526 528 # and groups set to admin
527 529 #==================================================================
528 530 user.permissions[GLOBAL].add('hg.admin')
529 531
530 532 # repositories
531 533 for perm in default_repo_perms:
532 534 r_k = perm.UserRepoToPerm.repository.repo_name
533 535 p = 'repository.admin'
534 536 user.permissions[RK][r_k] = p
535 537
536 538 # repository groups
537 539 for perm in default_repo_groups_perms:
538 540 rg_k = perm.UserRepoGroupToPerm.group.group_name
539 541 p = 'group.admin'
540 542 user.permissions[GK][rg_k] = p
541 543
542 544 # user groups
543 545 for perm in default_user_group_perms:
544 546 u_k = perm.UserUserGroupToPerm.user_group.users_group_name
545 547 p = 'usergroup.admin'
546 548 user.permissions[UK][u_k] = p
547 549 return user
548 550
549 551 #==================================================================
550 552 # SET DEFAULTS GLOBAL, REPOS, REPOSITORY GROUPS
551 553 #==================================================================
552 554 uid = user.user_id
553 555
554 556 # default global permissions taken fron the default user
555 557 default_global_perms = self.sa.query(UserToPerm)\
556 558 .filter(UserToPerm.user_id == default_user_id)
557 559
558 560 for perm in default_global_perms:
559 561 user.permissions[GLOBAL].add(perm.permission.permission_name)
560 562
561 563 # defaults for repositories, taken from default user
562 564 for perm in default_repo_perms:
563 565 r_k = perm.UserRepoToPerm.repository.repo_name
564 566 if perm.Repository.private and not (perm.Repository.user_id == uid):
565 567 # disable defaults for private repos,
566 568 p = 'repository.none'
567 569 elif perm.Repository.user_id == uid:
568 570 # set admin if owner
569 571 p = 'repository.admin'
570 572 else:
571 573 p = perm.Permission.permission_name
572 574
573 575 user.permissions[RK][r_k] = p
574 576
575 577 # defaults for repository groups taken from default user permission
576 578 # on given group
577 579 for perm in default_repo_groups_perms:
578 580 rg_k = perm.UserRepoGroupToPerm.group.group_name
579 581 p = perm.Permission.permission_name
580 582 user.permissions[GK][rg_k] = p
581 583
582 584 # defaults for user groups taken from default user permission
583 585 # on given user group
584 586 for perm in default_user_group_perms:
585 587 u_k = perm.UserUserGroupToPerm.user_group.users_group_name
586 588 p = perm.Permission.permission_name
587 589 user.permissions[UK][u_k] = p
588 590
589 591 #======================================================================
590 592 # !! OVERRIDE GLOBALS !! with user permissions if any found
591 593 #======================================================================
592 594 # those can be configured from groups or users explicitly
593 595 _configurable = set([
594 596 'hg.fork.none', 'hg.fork.repository',
595 597 'hg.create.none', 'hg.create.repository',
596 598 'hg.usergroup.create.false', 'hg.usergroup.create.true'
597 599 ])
598 600
599 601 # USER GROUPS comes first
600 602 # user group global permissions
601 603 user_perms_from_users_groups = self.sa.query(UserGroupToPerm)\
602 604 .options(joinedload(UserGroupToPerm.permission))\
603 605 .join((UserGroupMember, UserGroupToPerm.users_group_id ==
604 606 UserGroupMember.users_group_id))\
605 607 .filter(UserGroupMember.user_id == uid)\
606 608 .order_by(UserGroupToPerm.users_group_id)\
607 609 .all()
608 610 #need to group here by groups since user can be in more than one group
609 611 _grouped = [[x, list(y)] for x, y in
610 612 itertools.groupby(user_perms_from_users_groups,
611 613 lambda x:x.users_group)]
612 614 for gr, perms in _grouped:
613 615 # since user can be in multiple groups iterate over them and
614 616 # select the lowest permissions first (more explicit)
615 617 ##TODO: do this^^
616 618 if not gr.inherit_default_permissions:
617 619 # NEED TO IGNORE all configurable permissions and
618 620 # replace them with explicitly set
619 621 user.permissions[GLOBAL] = user.permissions[GLOBAL]\
620 622 .difference(_configurable)
621 623 for perm in perms:
622 624 user.permissions[GLOBAL].add(perm.permission.permission_name)
623 625
624 626 # user specific global permissions
625 627 user_perms = self.sa.query(UserToPerm)\
626 628 .options(joinedload(UserToPerm.permission))\
627 629 .filter(UserToPerm.user_id == uid).all()
628 630
629 631 if not user.inherit_default_permissions:
630 632 # NEED TO IGNORE all configurable permissions and
631 633 # replace them with explicitly set
632 634 user.permissions[GLOBAL] = user.permissions[GLOBAL]\
633 635 .difference(_configurable)
634 636
635 637 for perm in user_perms:
636 638 user.permissions[GLOBAL].add(perm.permission.permission_name)
637 639 ## END GLOBAL PERMISSIONS
638 640
639 641 #======================================================================
640 642 # !! PERMISSIONS FOR REPOSITORIES !!
641 643 #======================================================================
642 644 #======================================================================
643 645 # check if user is part of user groups for this repository and
644 646 # fill in his permission from it. _choose_perm decides of which
645 647 # permission should be selected based on selected method
646 648 #======================================================================
647 649
648 650 # user group for repositories permissions
649 651 user_repo_perms_from_users_groups = \
650 652 self.sa.query(UserGroupRepoToPerm, Permission, Repository,)\
651 653 .join((Repository, UserGroupRepoToPerm.repository_id ==
652 654 Repository.repo_id))\
653 655 .join((Permission, UserGroupRepoToPerm.permission_id ==
654 656 Permission.permission_id))\
655 657 .join((UserGroupMember, UserGroupRepoToPerm.users_group_id ==
656 658 UserGroupMember.users_group_id))\
657 659 .filter(UserGroupMember.user_id == uid)\
658 660 .all()
659 661
660 662 multiple_counter = collections.defaultdict(int)
661 663 for perm in user_repo_perms_from_users_groups:
662 664 r_k = perm.UserGroupRepoToPerm.repository.repo_name
663 665 multiple_counter[r_k] += 1
664 666 p = perm.Permission.permission_name
665 667 cur_perm = user.permissions[RK][r_k]
666 668
667 669 if perm.Repository.user_id == uid:
668 670 # set admin if owner
669 671 p = 'repository.admin'
670 672 else:
671 673 if multiple_counter[r_k] > 1:
672 674 p = _choose_perm(p, cur_perm)
673 675 user.permissions[RK][r_k] = p
674 676
675 677 # user explicit permissions for repositories, overrides any specified
676 678 # by the group permission
677 679 user_repo_perms = Permission.get_default_perms(uid)
678 680 for perm in user_repo_perms:
679 681 r_k = perm.UserRepoToPerm.repository.repo_name
680 682 cur_perm = user.permissions[RK][r_k]
681 683 # set admin if owner
682 684 if perm.Repository.user_id == uid:
683 685 p = 'repository.admin'
684 686 else:
685 687 p = perm.Permission.permission_name
686 688 if not explicit:
687 689 p = _choose_perm(p, cur_perm)
688 690 user.permissions[RK][r_k] = p
689 691
690 692 #======================================================================
691 693 # !! PERMISSIONS FOR REPOSITORY GROUPS !!
692 694 #======================================================================
693 695 #======================================================================
694 696 # check if user is part of user groups for this repository groups and
695 697 # fill in his permission from it. _choose_perm decides of which
696 698 # permission should be selected based on selected method
697 699 #======================================================================
698 700 # user group for repo groups permissions
699 701 user_repo_group_perms_from_users_groups = \
700 702 self.sa.query(UserGroupRepoGroupToPerm, Permission, RepoGroup)\
701 703 .join((RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id))\
702 704 .join((Permission, UserGroupRepoGroupToPerm.permission_id
703 705 == Permission.permission_id))\
704 706 .join((UserGroupMember, UserGroupRepoGroupToPerm.users_group_id
705 707 == UserGroupMember.users_group_id))\
706 708 .filter(UserGroupMember.user_id == uid)\
707 709 .all()
708 710
709 711 multiple_counter = collections.defaultdict(int)
710 712 for perm in user_repo_group_perms_from_users_groups:
711 713 g_k = perm.UserGroupRepoGroupToPerm.group.group_name
712 714 multiple_counter[g_k] += 1
713 715 p = perm.Permission.permission_name
714 716 cur_perm = user.permissions[GK][g_k]
715 717 if multiple_counter[g_k] > 1:
716 718 p = _choose_perm(p, cur_perm)
717 719 user.permissions[GK][g_k] = p
718 720
719 721 # user explicit permissions for repository groups
720 722 user_repo_groups_perms = Permission.get_default_group_perms(uid)
721 723 for perm in user_repo_groups_perms:
722 724 rg_k = perm.UserRepoGroupToPerm.group.group_name
723 725 p = perm.Permission.permission_name
724 726 cur_perm = user.permissions[GK][rg_k]
725 727 if not explicit:
726 728 p = _choose_perm(p, cur_perm)
727 729 user.permissions[GK][rg_k] = p
728 730
729 731 #======================================================================
730 732 # !! PERMISSIONS FOR USER GROUPS !!
731 733 #======================================================================
732 734 # user group for user group permissions
733 735 user_group_user_groups_perms = \
734 736 self.sa.query(UserGroupUserGroupToPerm, Permission, UserGroup)\
735 737 .join((UserGroup, UserGroupUserGroupToPerm.target_user_group_id
736 738 == UserGroup.users_group_id))\
737 739 .join((Permission, UserGroupUserGroupToPerm.permission_id
738 740 == Permission.permission_id))\
739 741 .join((UserGroupMember, UserGroupUserGroupToPerm.user_group_id
740 742 == UserGroupMember.users_group_id))\
741 743 .filter(UserGroupMember.user_id == uid)\
742 744 .all()
743 745
744 746 multiple_counter = collections.defaultdict(int)
745 747 for perm in user_group_user_groups_perms:
746 748 g_k = perm.UserGroupUserGroupToPerm.target_user_group.users_group_name
747 749 multiple_counter[g_k] += 1
748 750 p = perm.Permission.permission_name
749 751 cur_perm = user.permissions[UK][g_k]
750 752 if multiple_counter[g_k] > 1:
751 753 p = _choose_perm(p, cur_perm)
752 754 user.permissions[UK][g_k] = p
753 755
754 756 #user explicit permission for user groups
755 757 user_user_groups_perms = Permission.get_default_user_group_perms(uid)
756 758 for perm in user_user_groups_perms:
757 759 u_k = perm.UserUserGroupToPerm.user_group.users_group_name
758 760 p = perm.Permission.permission_name
759 761 cur_perm = user.permissions[UK][u_k]
760 762 if not explicit:
761 763 p = _choose_perm(p, cur_perm)
762 764 user.permissions[UK][u_k] = p
763 765
764 766 return user
765 767
766 768 def has_perm(self, user, perm):
767 769 perm = self._get_perm(perm)
768 770 user = self._get_user(user)
769 771
770 772 return UserToPerm.query().filter(UserToPerm.user == user)\
771 773 .filter(UserToPerm.permission == perm).scalar() is not None
772 774
773 775 def grant_perm(self, user, perm):
774 776 """
775 777 Grant user global permissions
776 778
777 779 :param user:
778 780 :param perm:
779 781 """
780 782 user = self._get_user(user)
781 783 perm = self._get_perm(perm)
782 784 # if this permission is already granted skip it
783 785 _perm = UserToPerm.query()\
784 786 .filter(UserToPerm.user == user)\
785 787 .filter(UserToPerm.permission == perm)\
786 788 .scalar()
787 789 if _perm:
788 790 return
789 791 new = UserToPerm()
790 792 new.user = user
791 793 new.permission = perm
792 794 self.sa.add(new)
793 795
794 796 def revoke_perm(self, user, perm):
795 797 """
796 798 Revoke users global permissions
797 799
798 800 :param user:
799 801 :param perm:
800 802 """
801 803 user = self._get_user(user)
802 804 perm = self._get_perm(perm)
803 805
804 806 obj = UserToPerm.query()\
805 807 .filter(UserToPerm.user == user)\
806 808 .filter(UserToPerm.permission == perm)\
807 809 .scalar()
808 810 if obj:
809 811 self.sa.delete(obj)
810 812
811 813 def add_extra_email(self, user, email):
812 814 """
813 815 Adds email address to UserEmailMap
814 816
815 817 :param user:
816 818 :param email:
817 819 """
818 820 from rhodecode.model import forms
819 821 form = forms.UserExtraEmailForm()()
820 822 data = form.to_python(dict(email=email))
821 823 user = self._get_user(user)
822 824
823 825 obj = UserEmailMap()
824 826 obj.user = user
825 827 obj.email = data['email']
826 828 self.sa.add(obj)
827 829 return obj
828 830
829 831 def delete_extra_email(self, user, email_id):
830 832 """
831 833 Removes email address from UserEmailMap
832 834
833 835 :param user:
834 836 :param email_id:
835 837 """
836 838 user = self._get_user(user)
837 839 obj = UserEmailMap.query().get(email_id)
838 840 if obj:
839 841 self.sa.delete(obj)
840 842
841 843 def add_extra_ip(self, user, ip):
842 844 """
843 845 Adds ip address to UserIpMap
844 846
845 847 :param user:
846 848 :param ip:
847 849 """
848 850 from rhodecode.model import forms
849 851 form = forms.UserExtraIpForm()()
850 852 data = form.to_python(dict(ip=ip))
851 853 user = self._get_user(user)
852 854
853 855 obj = UserIpMap()
854 856 obj.user = user
855 857 obj.ip_addr = data['ip']
856 858 self.sa.add(obj)
857 859 return obj
858 860
859 861 def delete_extra_ip(self, user, ip_id):
860 862 """
861 863 Removes ip address from UserIpMap
862 864
863 865 :param user:
864 866 :param ip_id:
865 867 """
866 868 user = self._get_user(user)
867 869 obj = UserIpMap.query().get(ip_id)
868 870 if obj:
869 871 self.sa.delete(obj)
General Comments 0
You need to be logged in to leave comments. Login now