##// END OF EJS Templates
switch to defaultdict for counter implementation
marcink -
r3096:69b25f1b beta
parent child Browse files
Show More
@@ -1,707 +1,707 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 import functools
31 31 from pylons import url
32 32 from pylons.i18n.translation import _
33 33
34 34 from sqlalchemy.exc import DatabaseError
35 35 from sqlalchemy.orm import joinedload
36 36
37 37 from rhodecode.lib.utils2 import safe_unicode, generate_api_key
38 38 from rhodecode.lib.caching_query import FromCache
39 39 from rhodecode.model import BaseModel
40 40 from rhodecode.model.db import User, UserRepoToPerm, Repository, Permission, \
41 41 UserToPerm, UsersGroupRepoToPerm, UsersGroupToPerm, UsersGroupMember, \
42 42 Notification, RepoGroup, UserRepoGroupToPerm, UsersGroupRepoGroupToPerm, \
43 43 UserEmailMap
44 44 from rhodecode.lib.exceptions import DefaultUserException, \
45 45 UserOwnsReposException
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)\
72 72 .filter(User.username == username)
73 73 if cache:
74 74 user = user.options(FromCache("sql_cache_short",
75 75 "get_user_%s" % username))
76 76 return user.scalar()
77 77
78 78 def get_by_email(self, email, cache=False, case_insensitive=False):
79 79 return User.get_by_email(email, case_insensitive, cache)
80 80
81 81 def get_by_api_key(self, api_key, cache=False):
82 82 return User.get_by_api_key(api_key, cache)
83 83
84 84 def create(self, form_data):
85 85 from rhodecode.lib.auth import get_crypt_password
86 86 try:
87 87 new_user = User()
88 88 for k, v in form_data.items():
89 89 if k == 'password':
90 90 v = get_crypt_password(v)
91 91 if k == 'firstname':
92 92 k = 'name'
93 93 setattr(new_user, k, v)
94 94
95 95 new_user.api_key = generate_api_key(form_data['username'])
96 96 self.sa.add(new_user)
97 97 return new_user
98 98 except:
99 99 log.error(traceback.format_exc())
100 100 raise
101 101
102 102 def create_or_update(self, username, password, email, firstname='',
103 103 lastname='', active=True, admin=False, ldap_dn=None):
104 104 """
105 105 Creates a new instance if not found, or updates current one
106 106
107 107 :param username:
108 108 :param password:
109 109 :param email:
110 110 :param active:
111 111 :param firstname:
112 112 :param lastname:
113 113 :param active:
114 114 :param admin:
115 115 :param ldap_dn:
116 116 """
117 117
118 118 from rhodecode.lib.auth import get_crypt_password
119 119
120 120 log.debug('Checking for %s account in RhodeCode database' % username)
121 121 user = User.get_by_username(username, case_insensitive=True)
122 122 if user is None:
123 123 log.debug('creating new user %s' % username)
124 124 new_user = User()
125 125 edit = False
126 126 else:
127 127 log.debug('updating user %s' % username)
128 128 new_user = user
129 129 edit = True
130 130
131 131 try:
132 132 new_user.username = username
133 133 new_user.admin = admin
134 134 # set password only if creating an user or password is changed
135 135 if edit is False or user.password != password:
136 136 new_user.password = get_crypt_password(password)
137 137 new_user.api_key = generate_api_key(username)
138 138 new_user.email = email
139 139 new_user.active = active
140 140 new_user.ldap_dn = safe_unicode(ldap_dn) if ldap_dn else None
141 141 new_user.name = firstname
142 142 new_user.lastname = lastname
143 143 self.sa.add(new_user)
144 144 return new_user
145 145 except (DatabaseError,):
146 146 log.error(traceback.format_exc())
147 147 raise
148 148
149 149 def create_for_container_auth(self, username, attrs):
150 150 """
151 151 Creates the given user if it's not already in the database
152 152
153 153 :param username:
154 154 :param attrs:
155 155 """
156 156 if self.get_by_username(username, case_insensitive=True) is None:
157 157
158 158 # autogenerate email for container account without one
159 159 generate_email = lambda usr: '%s@container_auth.account' % usr
160 160
161 161 try:
162 162 new_user = User()
163 163 new_user.username = username
164 164 new_user.password = None
165 165 new_user.api_key = generate_api_key(username)
166 166 new_user.email = attrs['email']
167 167 new_user.active = attrs.get('active', True)
168 168 new_user.name = attrs['name'] or generate_email(username)
169 169 new_user.lastname = attrs['lastname']
170 170
171 171 self.sa.add(new_user)
172 172 return new_user
173 173 except (DatabaseError,):
174 174 log.error(traceback.format_exc())
175 175 self.sa.rollback()
176 176 raise
177 177 log.debug('User %s already exists. Skipping creation of account'
178 178 ' for container auth.', username)
179 179 return None
180 180
181 181 def create_ldap(self, username, password, user_dn, attrs):
182 182 """
183 183 Checks if user is in database, if not creates this user marked
184 184 as ldap user
185 185
186 186 :param username:
187 187 :param password:
188 188 :param user_dn:
189 189 :param attrs:
190 190 """
191 191 from rhodecode.lib.auth import get_crypt_password
192 192 log.debug('Checking for such ldap account in RhodeCode database')
193 193 if self.get_by_username(username, case_insensitive=True) is None:
194 194
195 195 # autogenerate email for ldap account without one
196 196 generate_email = lambda usr: '%s@ldap.account' % usr
197 197
198 198 try:
199 199 new_user = User()
200 200 username = username.lower()
201 201 # add ldap account always lowercase
202 202 new_user.username = username
203 203 new_user.password = get_crypt_password(password)
204 204 new_user.api_key = generate_api_key(username)
205 205 new_user.email = attrs['email'] or generate_email(username)
206 206 new_user.active = attrs.get('active', True)
207 207 new_user.ldap_dn = safe_unicode(user_dn)
208 208 new_user.name = attrs['name']
209 209 new_user.lastname = attrs['lastname']
210 210
211 211 self.sa.add(new_user)
212 212 return new_user
213 213 except (DatabaseError,):
214 214 log.error(traceback.format_exc())
215 215 self.sa.rollback()
216 216 raise
217 217 log.debug('this %s user exists skipping creation of ldap account',
218 218 username)
219 219 return None
220 220
221 221 def create_registration(self, form_data):
222 222 from rhodecode.model.notification import NotificationModel
223 223
224 224 try:
225 225 form_data['admin'] = False
226 226 new_user = self.create(form_data)
227 227
228 228 self.sa.add(new_user)
229 229 self.sa.flush()
230 230
231 231 # notification to admins
232 232 subject = _('new user registration')
233 233 body = ('New user registration\n'
234 234 '---------------------\n'
235 235 '- Username: %s\n'
236 236 '- Full Name: %s\n'
237 237 '- Email: %s\n')
238 238 body = body % (new_user.username, new_user.full_name,
239 239 new_user.email)
240 240 edit_url = url('edit_user', id=new_user.user_id, qualified=True)
241 241 kw = {'registered_user_url': edit_url}
242 242 NotificationModel().create(created_by=new_user, subject=subject,
243 243 body=body, recipients=None,
244 244 type_=Notification.TYPE_REGISTRATION,
245 245 email_kwargs=kw)
246 246
247 247 except:
248 248 log.error(traceback.format_exc())
249 249 raise
250 250
251 251 def update(self, user_id, form_data, skip_attrs=[]):
252 252 from rhodecode.lib.auth import get_crypt_password
253 253 try:
254 254 user = self.get(user_id, cache=False)
255 255 if user.username == 'default':
256 256 raise DefaultUserException(
257 257 _("You can't Edit this user since it's"
258 258 " crucial for entire application"))
259 259
260 260 for k, v in form_data.items():
261 261 if k in skip_attrs:
262 262 continue
263 263 if k == 'new_password' and v:
264 264 user.password = get_crypt_password(v)
265 265 user.api_key = generate_api_key(user.username)
266 266 else:
267 267 if k == 'firstname':
268 268 k = 'name'
269 269 setattr(user, k, v)
270 270 self.sa.add(user)
271 271 except:
272 272 log.error(traceback.format_exc())
273 273 raise
274 274
275 275 def update_user(self, user, **kwargs):
276 276 from rhodecode.lib.auth import get_crypt_password
277 277 try:
278 278 user = self._get_user(user)
279 279 if user.username == 'default':
280 280 raise DefaultUserException(
281 281 _("You can't Edit this user since it's"
282 282 " crucial for entire application")
283 283 )
284 284
285 285 for k, v in kwargs.items():
286 286 if k == 'password' and v:
287 287 v = get_crypt_password(v)
288 288 user.api_key = generate_api_key(user.username)
289 289
290 290 setattr(user, k, v)
291 291 self.sa.add(user)
292 292 return user
293 293 except:
294 294 log.error(traceback.format_exc())
295 295 raise
296 296
297 297 def update_my_account(self, user_id, form_data):
298 298 from rhodecode.lib.auth import get_crypt_password
299 299 try:
300 300 user = self.get(user_id, cache=False)
301 301 if user.username == 'default':
302 302 raise DefaultUserException(
303 303 _("You can't Edit this user since it's"
304 304 " crucial for entire application")
305 305 )
306 306 for k, v in form_data.items():
307 307 if k == 'new_password' and v:
308 308 user.password = get_crypt_password(v)
309 309 user.api_key = generate_api_key(user.username)
310 310 else:
311 311 if k == 'firstname':
312 312 k = 'name'
313 313 if k not in ['admin', 'active']:
314 314 setattr(user, k, v)
315 315
316 316 self.sa.add(user)
317 317 except:
318 318 log.error(traceback.format_exc())
319 319 raise
320 320
321 321 def delete(self, user):
322 322 user = self._get_user(user)
323 323
324 324 try:
325 325 if user.username == 'default':
326 326 raise DefaultUserException(
327 327 _(u"You can't remove this user since it's"
328 328 " crucial for entire application")
329 329 )
330 330 if user.repositories:
331 331 repos = [x.repo_name for x in user.repositories]
332 332 raise UserOwnsReposException(
333 333 _(u'user "%s" still owns %s repositories and cannot be '
334 334 'removed. Switch owners or remove those repositories. %s')
335 335 % (user.username, len(repos), ', '.join(repos))
336 336 )
337 337 self.sa.delete(user)
338 338 except:
339 339 log.error(traceback.format_exc())
340 340 raise
341 341
342 342 def reset_password_link(self, data):
343 343 from rhodecode.lib.celerylib import tasks, run_task
344 344 run_task(tasks.send_password_link, data['email'])
345 345
346 346 def reset_password(self, data):
347 347 from rhodecode.lib.celerylib import tasks, run_task
348 348 run_task(tasks.reset_user_password, data['email'])
349 349
350 350 def fill_data(self, auth_user, user_id=None, api_key=None):
351 351 """
352 352 Fetches auth_user by user_id,or api_key if present.
353 353 Fills auth_user attributes with those taken from database.
354 354 Additionally set's is_authenitated if lookup fails
355 355 present in database
356 356
357 357 :param auth_user: instance of user to set attributes
358 358 :param user_id: user id to fetch by
359 359 :param api_key: api key to fetch by
360 360 """
361 361 if user_id is None and api_key is None:
362 362 raise Exception('You need to pass user_id or api_key')
363 363
364 364 try:
365 365 if api_key:
366 366 dbuser = self.get_by_api_key(api_key)
367 367 else:
368 368 dbuser = self.get(user_id)
369 369
370 370 if dbuser is not None and dbuser.active:
371 371 log.debug('filling %s data' % dbuser)
372 372 for k, v in dbuser.get_dict().items():
373 373 setattr(auth_user, k, v)
374 374 else:
375 375 return False
376 376
377 377 except:
378 378 log.error(traceback.format_exc())
379 379 auth_user.is_authenticated = False
380 380 return False
381 381
382 382 return True
383 383
384 384 def fill_perms(self, user, explicit=True, algo='higherwin'):
385 385 """
386 386 Fills user permission attribute with permissions taken from database
387 387 works for permissions given for repositories, and for permissions that
388 388 are granted to groups
389 389
390 390 :param user: user instance to fill his perms
391 391 :param explicit: In case there are permissions both for user and a group
392 392 that user is part of, explicit flag will defiine if user will
393 393 explicitly override permissions from group, if it's False it will
394 394 make decision based on the algo
395 395 :param algo: algorithm to decide what permission should be choose if
396 396 it's multiple defined, eg user in two different groups. It also
397 397 decides if explicit flag is turned off how to specify the permission
398 398 for case when user is in a group + have defined separate permission
399 399 """
400 400 RK = 'repositories'
401 401 GK = 'repositories_groups'
402 402 GLOBAL = 'global'
403 403 user.permissions[RK] = {}
404 404 user.permissions[GK] = {}
405 405 user.permissions[GLOBAL] = set()
406 406
407 407 def _choose_perm(new_perm, cur_perm):
408 408 new_perm_val = PERM_WEIGHTS[new_perm]
409 409 cur_perm_val = PERM_WEIGHTS[cur_perm]
410 410 if algo == 'higherwin':
411 411 if new_perm_val > cur_perm_val:
412 412 return new_perm
413 413 return cur_perm
414 414 elif algo == 'lowerwin':
415 415 if new_perm_val < cur_perm_val:
416 416 return new_perm
417 417 return cur_perm
418 418
419 419 #======================================================================
420 420 # fetch default permissions
421 421 #======================================================================
422 422 default_user = User.get_by_username('default', cache=True)
423 423 default_user_id = default_user.user_id
424 424
425 425 default_repo_perms = Permission.get_default_perms(default_user_id)
426 426 default_repo_groups_perms = Permission.get_default_group_perms(default_user_id)
427 427
428 428 if user.is_admin:
429 429 #==================================================================
430 430 # admin user have all default rights for repositories
431 431 # and groups set to admin
432 432 #==================================================================
433 433 user.permissions[GLOBAL].add('hg.admin')
434 434
435 435 # repositories
436 436 for perm in default_repo_perms:
437 437 r_k = perm.UserRepoToPerm.repository.repo_name
438 438 p = 'repository.admin'
439 439 user.permissions[RK][r_k] = p
440 440
441 441 # repositories groups
442 442 for perm in default_repo_groups_perms:
443 443 rg_k = perm.UserRepoGroupToPerm.group.group_name
444 444 p = 'group.admin'
445 445 user.permissions[GK][rg_k] = p
446 446 return user
447 447
448 448 #==================================================================
449 449 # SET DEFAULTS GLOBAL, REPOS, REPOS GROUPS
450 450 #==================================================================
451 451 uid = user.user_id
452 452
453 453 # default global permissions taken fron the default user
454 454 default_global_perms = self.sa.query(UserToPerm)\
455 455 .filter(UserToPerm.user_id == default_user_id)
456 456
457 457 for perm in default_global_perms:
458 458 user.permissions[GLOBAL].add(perm.permission.permission_name)
459 459
460 460 # defaults for repositories, taken from default user
461 461 for perm in default_repo_perms:
462 462 r_k = perm.UserRepoToPerm.repository.repo_name
463 463 if perm.Repository.private and not (perm.Repository.user_id == uid):
464 464 # disable defaults for private repos,
465 465 p = 'repository.none'
466 466 elif perm.Repository.user_id == uid:
467 467 # set admin if owner
468 468 p = 'repository.admin'
469 469 else:
470 470 p = perm.Permission.permission_name
471 471
472 472 user.permissions[RK][r_k] = p
473 473
474 474 # defaults for repositories groups taken from default user permission
475 475 # on given group
476 476 for perm in default_repo_groups_perms:
477 477 rg_k = perm.UserRepoGroupToPerm.group.group_name
478 478 p = perm.Permission.permission_name
479 479 user.permissions[GK][rg_k] = p
480 480
481 481 #======================================================================
482 482 # !! OVERRIDE GLOBALS !! with user permissions if any found
483 483 #======================================================================
484 484 # those can be configured from groups or users explicitly
485 485 _configurable = set(['hg.fork.none', 'hg.fork.repository',
486 486 'hg.create.none', 'hg.create.repository'])
487 487
488 488 # USER GROUPS comes first
489 489 # users group global permissions
490 490 user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\
491 491 .options(joinedload(UsersGroupToPerm.permission))\
492 492 .join((UsersGroupMember, UsersGroupToPerm.users_group_id ==
493 493 UsersGroupMember.users_group_id))\
494 494 .filter(UsersGroupMember.user_id == uid)\
495 495 .order_by(UsersGroupToPerm.users_group_id)\
496 496 .all()
497 497 #need to group here by groups since user can be in more than one group
498 498 _grouped = [[x, list(y)] for x, y in
499 499 itertools.groupby(user_perms_from_users_groups,
500 500 lambda x:x.users_group)]
501 501 for gr, perms in _grouped:
502 502 # since user can be in multiple groups iterate over them and
503 503 # select the lowest permissions first (more explicit)
504 504 ##TODO: do this^^
505 505 if not gr.inherit_default_permissions:
506 506 # NEED TO IGNORE all configurable permissions and
507 507 # replace them with explicitly set
508 508 user.permissions[GLOBAL] = user.permissions[GLOBAL]\
509 509 .difference(_configurable)
510 510 for perm in perms:
511 511 user.permissions[GLOBAL].add(perm.permission.permission_name)
512 512
513 513 # user specific global permissions
514 514 user_perms = self.sa.query(UserToPerm)\
515 515 .options(joinedload(UserToPerm.permission))\
516 516 .filter(UserToPerm.user_id == uid).all()
517 517
518 518 if not user.inherit_default_permissions:
519 519 # NEED TO IGNORE all configurable permissions and
520 520 # replace them with explicitly set
521 521 user.permissions[GLOBAL] = user.permissions[GLOBAL]\
522 522 .difference(_configurable)
523 523
524 524 for perm in user_perms:
525 525 user.permissions[GLOBAL].add(perm.permission.permission_name)
526 526
527 527 #======================================================================
528 528 # !! PERMISSIONS FOR REPOSITORIES !!
529 529 #======================================================================
530 530 #======================================================================
531 531 # check if user is part of user groups for this repository and
532 532 # fill in his permission from it. _choose_perm decides of which
533 533 # permission should be selected based on selected method
534 534 #======================================================================
535 535
536 536 # users group for repositories permissions
537 537 user_repo_perms_from_users_groups = \
538 538 self.sa.query(UsersGroupRepoToPerm, Permission, Repository,)\
539 539 .join((Repository, UsersGroupRepoToPerm.repository_id ==
540 540 Repository.repo_id))\
541 541 .join((Permission, UsersGroupRepoToPerm.permission_id ==
542 542 Permission.permission_id))\
543 543 .join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id ==
544 544 UsersGroupMember.users_group_id))\
545 545 .filter(UsersGroupMember.user_id == uid)\
546 546 .all()
547 547
548 multiple_counter = collections.Counter()
548 multiple_counter = collections.defaultdict(int)
549 549 for perm in user_repo_perms_from_users_groups:
550 550 r_k = perm.UsersGroupRepoToPerm.repository.repo_name
551 551 multiple_counter[r_k] += 1
552 552 p = perm.Permission.permission_name
553 553 cur_perm = user.permissions[RK][r_k]
554 554
555 555 if perm.Repository.user_id == uid:
556 556 # set admin if owner
557 557 p = 'repository.admin'
558 558 else:
559 559 if multiple_counter[r_k] > 1:
560 560 p = _choose_perm(p, cur_perm)
561 561 user.permissions[RK][r_k] = p
562 562
563 563 # user explicit permissions for repositories, overrides any specified
564 564 # by the group permission
565 565 user_repo_perms = \
566 566 self.sa.query(UserRepoToPerm, Permission, Repository)\
567 567 .join((Repository, UserRepoToPerm.repository_id ==
568 568 Repository.repo_id))\
569 569 .join((Permission, UserRepoToPerm.permission_id ==
570 570 Permission.permission_id))\
571 571 .filter(UserRepoToPerm.user_id == uid)\
572 572 .all()
573 573
574 574 for perm in user_repo_perms:
575 575 r_k = perm.UserRepoToPerm.repository.repo_name
576 576 cur_perm = user.permissions[RK][r_k]
577 577 # set admin if owner
578 578 if perm.Repository.user_id == uid:
579 579 p = 'repository.admin'
580 580 else:
581 581 p = perm.Permission.permission_name
582 582 if not explicit:
583 583 p = _choose_perm(p, cur_perm)
584 584 user.permissions[RK][r_k] = p
585 585
586 586 #======================================================================
587 587 # !! PERMISSIONS FOR REPOSITORIES GROUPS !!
588 588 #======================================================================
589 589 #======================================================================
590 590 # check if user is part of user groups for this repository groups and
591 591 # fill in his permission from it. _choose_perm decides of which
592 592 # permission should be selected based on selected method
593 593 #======================================================================
594 594 # users group for repo groups permissions
595 595 user_repo_group_perms_from_users_groups = \
596 596 self.sa.query(UsersGroupRepoGroupToPerm, Permission, RepoGroup)\
597 597 .join((RepoGroup, UsersGroupRepoGroupToPerm.group_id == RepoGroup.group_id))\
598 598 .join((Permission, UsersGroupRepoGroupToPerm.permission_id
599 599 == Permission.permission_id))\
600 600 .join((UsersGroupMember, UsersGroupRepoGroupToPerm.users_group_id
601 601 == UsersGroupMember.users_group_id))\
602 602 .filter(UsersGroupMember.user_id == uid)\
603 603 .all()
604 604
605 multiple_counter = collections.Counter()
605 multiple_counter = collections.defaultdict(int)
606 606 for perm in user_repo_group_perms_from_users_groups:
607 607 g_k = perm.UsersGroupRepoGroupToPerm.group.group_name
608 608 multiple_counter[g_k] += 1
609 609 p = perm.Permission.permission_name
610 610 cur_perm = user.permissions[GK][g_k]
611 611 if multiple_counter[g_k] > 1:
612 612 p = _choose_perm(p, cur_perm)
613 613 user.permissions[GK][g_k] = p
614 614
615 615 # user explicit permissions for repository groups
616 616 user_repo_groups_perms = \
617 617 self.sa.query(UserRepoGroupToPerm, Permission, RepoGroup)\
618 618 .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\
619 619 .join((Permission, UserRepoGroupToPerm.permission_id
620 620 == Permission.permission_id))\
621 621 .filter(UserRepoGroupToPerm.user_id == uid)\
622 622 .all()
623 623
624 624 for perm in user_repo_groups_perms:
625 625 rg_k = perm.UserRepoGroupToPerm.group.group_name
626 626 p = perm.Permission.permission_name
627 627 cur_perm = user.permissions[GK][rg_k]
628 628 if not explicit:
629 629 p = _choose_perm(p, cur_perm)
630 630 user.permissions[GK][rg_k] = p
631 631
632 632 return user
633 633
634 634 def has_perm(self, user, perm):
635 635 perm = self._get_perm(perm)
636 636 user = self._get_user(user)
637 637
638 638 return UserToPerm.query().filter(UserToPerm.user == user)\
639 639 .filter(UserToPerm.permission == perm).scalar() is not None
640 640
641 641 def grant_perm(self, user, perm):
642 642 """
643 643 Grant user global permissions
644 644
645 645 :param user:
646 646 :param perm:
647 647 """
648 648 user = self._get_user(user)
649 649 perm = self._get_perm(perm)
650 650 # if this permission is already granted skip it
651 651 _perm = UserToPerm.query()\
652 652 .filter(UserToPerm.user == user)\
653 653 .filter(UserToPerm.permission == perm)\
654 654 .scalar()
655 655 if _perm:
656 656 return
657 657 new = UserToPerm()
658 658 new.user = user
659 659 new.permission = perm
660 660 self.sa.add(new)
661 661
662 662 def revoke_perm(self, user, perm):
663 663 """
664 664 Revoke users global permissions
665 665
666 666 :param user:
667 667 :param perm:
668 668 """
669 669 user = self._get_user(user)
670 670 perm = self._get_perm(perm)
671 671
672 672 obj = UserToPerm.query()\
673 673 .filter(UserToPerm.user == user)\
674 674 .filter(UserToPerm.permission == perm)\
675 675 .scalar()
676 676 if obj:
677 677 self.sa.delete(obj)
678 678
679 679 def add_extra_email(self, user, email):
680 680 """
681 681 Adds email address to UserEmailMap
682 682
683 683 :param user:
684 684 :param email:
685 685 """
686 686 from rhodecode.model import forms
687 687 form = forms.UserExtraEmailForm()()
688 688 data = form.to_python(dict(email=email))
689 689 user = self._get_user(user)
690 690
691 691 obj = UserEmailMap()
692 692 obj.user = user
693 693 obj.email = data['email']
694 694 self.sa.add(obj)
695 695 return obj
696 696
697 697 def delete_extra_email(self, user, email_id):
698 698 """
699 699 Removes email address from UserEmailMap
700 700
701 701 :param user:
702 702 :param email_id:
703 703 """
704 704 user = self._get_user(user)
705 705 obj = UserEmailMap.query().get(email_id)
706 706 if obj:
707 707 self.sa.delete(obj)
General Comments 0
You need to be logged in to leave comments. Login now