##// END OF EJS Templates
Improved message about deleting user who owns repositories
marcink -
r2153:fa637dc3 beta
parent child Browse files
Show More
@@ -1,588 +1,589 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.user
3 rhodecode.model.user
4 ~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~
5
5
6 users model for RhodeCode
6 users model for RhodeCode
7
7
8 :created_on: Apr 9, 2010
8 :created_on: Apr 9, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28
28
29 from pylons import url
29 from pylons import url
30 from pylons.i18n.translation import _
30 from pylons.i18n.translation import _
31
31
32 from rhodecode.lib.utils2 import safe_unicode, generate_api_key
32 from rhodecode.lib.utils2 import safe_unicode, generate_api_key
33 from rhodecode.lib.caching_query import FromCache
33 from rhodecode.lib.caching_query import FromCache
34
34
35 from rhodecode.model import BaseModel
35 from rhodecode.model import BaseModel
36 from rhodecode.model.db import User, UserRepoToPerm, Repository, Permission, \
36 from rhodecode.model.db import User, UserRepoToPerm, Repository, Permission, \
37 UserToPerm, UsersGroupRepoToPerm, UsersGroupToPerm, UsersGroupMember, \
37 UserToPerm, UsersGroupRepoToPerm, UsersGroupToPerm, UsersGroupMember, \
38 Notification, RepoGroup, UserRepoGroupToPerm, UsersGroup,\
38 Notification, RepoGroup, UserRepoGroupToPerm, UsersGroup,\
39 UsersGroupRepoGroupToPerm
39 UsersGroupRepoGroupToPerm
40 from rhodecode.lib.exceptions import DefaultUserException, \
40 from rhodecode.lib.exceptions import DefaultUserException, \
41 UserOwnsReposException
41 UserOwnsReposException
42
42
43 from sqlalchemy.exc import DatabaseError
43 from sqlalchemy.exc import DatabaseError
44
44
45 from sqlalchemy.orm import joinedload
45 from sqlalchemy.orm import joinedload
46
46
47 log = logging.getLogger(__name__)
47 log = logging.getLogger(__name__)
48
48
49
49
50 PERM_WEIGHTS = {
50 PERM_WEIGHTS = {
51 'repository.none': 0,
51 'repository.none': 0,
52 'repository.read': 1,
52 'repository.read': 1,
53 'repository.write': 3,
53 'repository.write': 3,
54 'repository.admin': 4,
54 'repository.admin': 4,
55 'group.none': 0,
55 'group.none': 0,
56 'group.read': 1,
56 'group.read': 1,
57 'group.write': 3,
57 'group.write': 3,
58 'group.admin': 4,
58 'group.admin': 4,
59 }
59 }
60
60
61
61
62 class UserModel(BaseModel):
62 class UserModel(BaseModel):
63
63
64 def __get_user(self, user):
64 def __get_user(self, user):
65 return self._get_instance(User, user, callback=User.get_by_username)
65 return self._get_instance(User, user, callback=User.get_by_username)
66
66
67 def __get_perm(self, permission):
67 def __get_perm(self, permission):
68 return self._get_instance(Permission, permission,
68 return self._get_instance(Permission, permission,
69 callback=Permission.get_by_key)
69 callback=Permission.get_by_key)
70
70
71 def get(self, user_id, cache=False):
71 def get(self, user_id, cache=False):
72 user = self.sa.query(User)
72 user = self.sa.query(User)
73 if cache:
73 if cache:
74 user = user.options(FromCache("sql_cache_short",
74 user = user.options(FromCache("sql_cache_short",
75 "get_user_%s" % user_id))
75 "get_user_%s" % user_id))
76 return user.get(user_id)
76 return user.get(user_id)
77
77
78 def get_user(self, user):
78 def get_user(self, user):
79 return self.__get_user(user)
79 return self.__get_user(user)
80
80
81 def get_by_username(self, username, cache=False, case_insensitive=False):
81 def get_by_username(self, username, cache=False, case_insensitive=False):
82
82
83 if case_insensitive:
83 if case_insensitive:
84 user = self.sa.query(User).filter(User.username.ilike(username))
84 user = self.sa.query(User).filter(User.username.ilike(username))
85 else:
85 else:
86 user = self.sa.query(User)\
86 user = self.sa.query(User)\
87 .filter(User.username == username)
87 .filter(User.username == username)
88 if cache:
88 if cache:
89 user = user.options(FromCache("sql_cache_short",
89 user = user.options(FromCache("sql_cache_short",
90 "get_user_%s" % username))
90 "get_user_%s" % username))
91 return user.scalar()
91 return user.scalar()
92
92
93 def get_by_api_key(self, api_key, cache=False):
93 def get_by_api_key(self, api_key, cache=False):
94 return User.get_by_api_key(api_key, cache)
94 return User.get_by_api_key(api_key, cache)
95
95
96 def create(self, form_data):
96 def create(self, form_data):
97 try:
97 try:
98 new_user = User()
98 new_user = User()
99 for k, v in form_data.items():
99 for k, v in form_data.items():
100 setattr(new_user, k, v)
100 setattr(new_user, k, v)
101
101
102 new_user.api_key = generate_api_key(form_data['username'])
102 new_user.api_key = generate_api_key(form_data['username'])
103 self.sa.add(new_user)
103 self.sa.add(new_user)
104 return new_user
104 return new_user
105 except:
105 except:
106 log.error(traceback.format_exc())
106 log.error(traceback.format_exc())
107 raise
107 raise
108
108
109 def create_or_update(self, username, password, email, name, lastname,
109 def create_or_update(self, username, password, email, name, lastname,
110 active=True, admin=False, ldap_dn=None):
110 active=True, admin=False, ldap_dn=None):
111 """
111 """
112 Creates a new instance if not found, or updates current one
112 Creates a new instance if not found, or updates current one
113
113
114 :param username:
114 :param username:
115 :param password:
115 :param password:
116 :param email:
116 :param email:
117 :param active:
117 :param active:
118 :param name:
118 :param name:
119 :param lastname:
119 :param lastname:
120 :param active:
120 :param active:
121 :param admin:
121 :param admin:
122 :param ldap_dn:
122 :param ldap_dn:
123 """
123 """
124
124
125 from rhodecode.lib.auth import get_crypt_password
125 from rhodecode.lib.auth import get_crypt_password
126
126
127 log.debug('Checking for %s account in RhodeCode database' % username)
127 log.debug('Checking for %s account in RhodeCode database' % username)
128 user = User.get_by_username(username, case_insensitive=True)
128 user = User.get_by_username(username, case_insensitive=True)
129 if user is None:
129 if user is None:
130 log.debug('creating new user %s' % username)
130 log.debug('creating new user %s' % username)
131 new_user = User()
131 new_user = User()
132 else:
132 else:
133 log.debug('updating user %s' % username)
133 log.debug('updating user %s' % username)
134 new_user = user
134 new_user = user
135
135
136 try:
136 try:
137 new_user.username = username
137 new_user.username = username
138 new_user.admin = admin
138 new_user.admin = admin
139 new_user.password = get_crypt_password(password)
139 new_user.password = get_crypt_password(password)
140 new_user.api_key = generate_api_key(username)
140 new_user.api_key = generate_api_key(username)
141 new_user.email = email
141 new_user.email = email
142 new_user.active = active
142 new_user.active = active
143 new_user.ldap_dn = safe_unicode(ldap_dn) if ldap_dn else None
143 new_user.ldap_dn = safe_unicode(ldap_dn) if ldap_dn else None
144 new_user.name = name
144 new_user.name = name
145 new_user.lastname = lastname
145 new_user.lastname = lastname
146 self.sa.add(new_user)
146 self.sa.add(new_user)
147 return new_user
147 return new_user
148 except (DatabaseError,):
148 except (DatabaseError,):
149 log.error(traceback.format_exc())
149 log.error(traceback.format_exc())
150 raise
150 raise
151
151
152 def create_for_container_auth(self, username, attrs):
152 def create_for_container_auth(self, username, attrs):
153 """
153 """
154 Creates the given user if it's not already in the database
154 Creates the given user if it's not already in the database
155
155
156 :param username:
156 :param username:
157 :param attrs:
157 :param attrs:
158 """
158 """
159 if self.get_by_username(username, case_insensitive=True) is None:
159 if self.get_by_username(username, case_insensitive=True) is None:
160
160
161 # autogenerate email for container account without one
161 # autogenerate email for container account without one
162 generate_email = lambda usr: '%s@container_auth.account' % usr
162 generate_email = lambda usr: '%s@container_auth.account' % usr
163
163
164 try:
164 try:
165 new_user = User()
165 new_user = User()
166 new_user.username = username
166 new_user.username = username
167 new_user.password = None
167 new_user.password = None
168 new_user.api_key = generate_api_key(username)
168 new_user.api_key = generate_api_key(username)
169 new_user.email = attrs['email']
169 new_user.email = attrs['email']
170 new_user.active = attrs.get('active', True)
170 new_user.active = attrs.get('active', True)
171 new_user.name = attrs['name'] or generate_email(username)
171 new_user.name = attrs['name'] or generate_email(username)
172 new_user.lastname = attrs['lastname']
172 new_user.lastname = attrs['lastname']
173
173
174 self.sa.add(new_user)
174 self.sa.add(new_user)
175 return new_user
175 return new_user
176 except (DatabaseError,):
176 except (DatabaseError,):
177 log.error(traceback.format_exc())
177 log.error(traceback.format_exc())
178 self.sa.rollback()
178 self.sa.rollback()
179 raise
179 raise
180 log.debug('User %s already exists. Skipping creation of account'
180 log.debug('User %s already exists. Skipping creation of account'
181 ' for container auth.', username)
181 ' for container auth.', username)
182 return None
182 return None
183
183
184 def create_ldap(self, username, password, user_dn, attrs):
184 def create_ldap(self, username, password, user_dn, attrs):
185 """
185 """
186 Checks if user is in database, if not creates this user marked
186 Checks if user is in database, if not creates this user marked
187 as ldap user
187 as ldap user
188
188
189 :param username:
189 :param username:
190 :param password:
190 :param password:
191 :param user_dn:
191 :param user_dn:
192 :param attrs:
192 :param attrs:
193 """
193 """
194 from rhodecode.lib.auth import get_crypt_password
194 from rhodecode.lib.auth import get_crypt_password
195 log.debug('Checking for such ldap account in RhodeCode database')
195 log.debug('Checking for such ldap account in RhodeCode database')
196 if self.get_by_username(username, case_insensitive=True) is None:
196 if self.get_by_username(username, case_insensitive=True) is None:
197
197
198 # autogenerate email for ldap account without one
198 # autogenerate email for ldap account without one
199 generate_email = lambda usr: '%s@ldap.account' % usr
199 generate_email = lambda usr: '%s@ldap.account' % usr
200
200
201 try:
201 try:
202 new_user = User()
202 new_user = User()
203 username = username.lower()
203 username = username.lower()
204 # add ldap account always lowercase
204 # add ldap account always lowercase
205 new_user.username = username
205 new_user.username = username
206 new_user.password = get_crypt_password(password)
206 new_user.password = get_crypt_password(password)
207 new_user.api_key = generate_api_key(username)
207 new_user.api_key = generate_api_key(username)
208 new_user.email = attrs['email'] or generate_email(username)
208 new_user.email = attrs['email'] or generate_email(username)
209 new_user.active = attrs.get('active', True)
209 new_user.active = attrs.get('active', True)
210 new_user.ldap_dn = safe_unicode(user_dn)
210 new_user.ldap_dn = safe_unicode(user_dn)
211 new_user.name = attrs['name']
211 new_user.name = attrs['name']
212 new_user.lastname = attrs['lastname']
212 new_user.lastname = attrs['lastname']
213
213
214 self.sa.add(new_user)
214 self.sa.add(new_user)
215 return new_user
215 return new_user
216 except (DatabaseError,):
216 except (DatabaseError,):
217 log.error(traceback.format_exc())
217 log.error(traceback.format_exc())
218 self.sa.rollback()
218 self.sa.rollback()
219 raise
219 raise
220 log.debug('this %s user exists skipping creation of ldap account',
220 log.debug('this %s user exists skipping creation of ldap account',
221 username)
221 username)
222 return None
222 return None
223
223
224 def create_registration(self, form_data):
224 def create_registration(self, form_data):
225 from rhodecode.model.notification import NotificationModel
225 from rhodecode.model.notification import NotificationModel
226
226
227 try:
227 try:
228 new_user = User()
228 new_user = User()
229 for k, v in form_data.items():
229 for k, v in form_data.items():
230 if k != 'admin':
230 if k != 'admin':
231 setattr(new_user, k, v)
231 setattr(new_user, k, v)
232
232
233 self.sa.add(new_user)
233 self.sa.add(new_user)
234 self.sa.flush()
234 self.sa.flush()
235
235
236 # notification to admins
236 # notification to admins
237 subject = _('new user registration')
237 subject = _('new user registration')
238 body = ('New user registration\n'
238 body = ('New user registration\n'
239 '---------------------\n'
239 '---------------------\n'
240 '- Username: %s\n'
240 '- Username: %s\n'
241 '- Full Name: %s\n'
241 '- Full Name: %s\n'
242 '- Email: %s\n')
242 '- Email: %s\n')
243 body = body % (new_user.username, new_user.full_name,
243 body = body % (new_user.username, new_user.full_name,
244 new_user.email)
244 new_user.email)
245 edit_url = url('edit_user', id=new_user.user_id, qualified=True)
245 edit_url = url('edit_user', id=new_user.user_id, qualified=True)
246 kw = {'registered_user_url': edit_url}
246 kw = {'registered_user_url': edit_url}
247 NotificationModel().create(created_by=new_user, subject=subject,
247 NotificationModel().create(created_by=new_user, subject=subject,
248 body=body, recipients=None,
248 body=body, recipients=None,
249 type_=Notification.TYPE_REGISTRATION,
249 type_=Notification.TYPE_REGISTRATION,
250 email_kwargs=kw)
250 email_kwargs=kw)
251
251
252 except:
252 except:
253 log.error(traceback.format_exc())
253 log.error(traceback.format_exc())
254 raise
254 raise
255
255
256 def update(self, user_id, form_data):
256 def update(self, user_id, form_data):
257 try:
257 try:
258 user = self.get(user_id, cache=False)
258 user = self.get(user_id, cache=False)
259 if user.username == 'default':
259 if user.username == 'default':
260 raise DefaultUserException(
260 raise DefaultUserException(
261 _("You can't Edit this user since it's"
261 _("You can't Edit this user since it's"
262 " crucial for entire application"))
262 " crucial for entire application"))
263
263
264 for k, v in form_data.items():
264 for k, v in form_data.items():
265 if k == 'new_password' and v != '':
265 if k == 'new_password' and v != '':
266 user.password = v
266 user.password = v
267 user.api_key = generate_api_key(user.username)
267 user.api_key = generate_api_key(user.username)
268 else:
268 else:
269 setattr(user, k, v)
269 setattr(user, k, v)
270
270
271 self.sa.add(user)
271 self.sa.add(user)
272 except:
272 except:
273 log.error(traceback.format_exc())
273 log.error(traceback.format_exc())
274 raise
274 raise
275
275
276 def update_my_account(self, user_id, form_data):
276 def update_my_account(self, user_id, form_data):
277 try:
277 try:
278 user = self.get(user_id, cache=False)
278 user = self.get(user_id, cache=False)
279 if user.username == 'default':
279 if user.username == 'default':
280 raise DefaultUserException(
280 raise DefaultUserException(
281 _("You can't Edit this user since it's"
281 _("You can't Edit this user since it's"
282 " crucial for entire application"))
282 " crucial for entire application"))
283 for k, v in form_data.items():
283 for k, v in form_data.items():
284 if k == 'new_password' and v != '':
284 if k == 'new_password' and v != '':
285 user.password = v
285 user.password = v
286 user.api_key = generate_api_key(user.username)
286 user.api_key = generate_api_key(user.username)
287 else:
287 else:
288 if k not in ['admin', 'active']:
288 if k not in ['admin', 'active']:
289 setattr(user, k, v)
289 setattr(user, k, v)
290
290
291 self.sa.add(user)
291 self.sa.add(user)
292 except:
292 except:
293 log.error(traceback.format_exc())
293 log.error(traceback.format_exc())
294 raise
294 raise
295
295
296 def delete(self, user):
296 def delete(self, user):
297 user = self.__get_user(user)
297 user = self.__get_user(user)
298
298
299 try:
299 try:
300 if user.username == 'default':
300 if user.username == 'default':
301 raise DefaultUserException(
301 raise DefaultUserException(
302 _("You can't remove this user since it's"
302 _(u"You can't remove this user since it's"
303 " crucial for entire application")
303 " crucial for entire application")
304 )
304 )
305 if user.repositories:
305 if user.repositories:
306 repos = [x.repo_name for x in user.repositories]
306 raise UserOwnsReposException(
307 raise UserOwnsReposException(
307 _('user "%s" still owns %s repositories and cannot be '
308 _(u'user "%s" still owns %s repositories and cannot be '
308 'removed. Switch owners or remove those repositories')
309 'removed. Switch owners or remove those repositories. %s')
309 % (user.username, user.repositories)
310 % (user.username, len(repos), ', '.join(repos))
310 )
311 )
311 self.sa.delete(user)
312 self.sa.delete(user)
312 except:
313 except:
313 log.error(traceback.format_exc())
314 log.error(traceback.format_exc())
314 raise
315 raise
315
316
316 def reset_password_link(self, data):
317 def reset_password_link(self, data):
317 from rhodecode.lib.celerylib import tasks, run_task
318 from rhodecode.lib.celerylib import tasks, run_task
318 run_task(tasks.send_password_link, data['email'])
319 run_task(tasks.send_password_link, data['email'])
319
320
320 def reset_password(self, data):
321 def reset_password(self, data):
321 from rhodecode.lib.celerylib import tasks, run_task
322 from rhodecode.lib.celerylib import tasks, run_task
322 run_task(tasks.reset_user_password, data['email'])
323 run_task(tasks.reset_user_password, data['email'])
323
324
324 def fill_data(self, auth_user, user_id=None, api_key=None):
325 def fill_data(self, auth_user, user_id=None, api_key=None):
325 """
326 """
326 Fetches auth_user by user_id,or api_key if present.
327 Fetches auth_user by user_id,or api_key if present.
327 Fills auth_user attributes with those taken from database.
328 Fills auth_user attributes with those taken from database.
328 Additionally set's is_authenitated if lookup fails
329 Additionally set's is_authenitated if lookup fails
329 present in database
330 present in database
330
331
331 :param auth_user: instance of user to set attributes
332 :param auth_user: instance of user to set attributes
332 :param user_id: user id to fetch by
333 :param user_id: user id to fetch by
333 :param api_key: api key to fetch by
334 :param api_key: api key to fetch by
334 """
335 """
335 if user_id is None and api_key is None:
336 if user_id is None and api_key is None:
336 raise Exception('You need to pass user_id or api_key')
337 raise Exception('You need to pass user_id or api_key')
337
338
338 try:
339 try:
339 if api_key:
340 if api_key:
340 dbuser = self.get_by_api_key(api_key)
341 dbuser = self.get_by_api_key(api_key)
341 else:
342 else:
342 dbuser = self.get(user_id)
343 dbuser = self.get(user_id)
343
344
344 if dbuser is not None and dbuser.active:
345 if dbuser is not None and dbuser.active:
345 log.debug('filling %s data' % dbuser)
346 log.debug('filling %s data' % dbuser)
346 for k, v in dbuser.get_dict().items():
347 for k, v in dbuser.get_dict().items():
347 setattr(auth_user, k, v)
348 setattr(auth_user, k, v)
348 else:
349 else:
349 return False
350 return False
350
351
351 except:
352 except:
352 log.error(traceback.format_exc())
353 log.error(traceback.format_exc())
353 auth_user.is_authenticated = False
354 auth_user.is_authenticated = False
354 return False
355 return False
355
356
356 return True
357 return True
357
358
358 def fill_perms(self, user):
359 def fill_perms(self, user):
359 """
360 """
360 Fills user permission attribute with permissions taken from database
361 Fills user permission attribute with permissions taken from database
361 works for permissions given for repositories, and for permissions that
362 works for permissions given for repositories, and for permissions that
362 are granted to groups
363 are granted to groups
363
364
364 :param user: user instance to fill his perms
365 :param user: user instance to fill his perms
365 """
366 """
366 RK = 'repositories'
367 RK = 'repositories'
367 GK = 'repositories_groups'
368 GK = 'repositories_groups'
368 GLOBAL = 'global'
369 GLOBAL = 'global'
369 user.permissions[RK] = {}
370 user.permissions[RK] = {}
370 user.permissions[GK] = {}
371 user.permissions[GK] = {}
371 user.permissions[GLOBAL] = set()
372 user.permissions[GLOBAL] = set()
372
373
373 #======================================================================
374 #======================================================================
374 # fetch default permissions
375 # fetch default permissions
375 #======================================================================
376 #======================================================================
376 default_user = User.get_by_username('default', cache=True)
377 default_user = User.get_by_username('default', cache=True)
377 default_user_id = default_user.user_id
378 default_user_id = default_user.user_id
378
379
379 default_repo_perms = Permission.get_default_perms(default_user_id)
380 default_repo_perms = Permission.get_default_perms(default_user_id)
380 default_repo_groups_perms = Permission.get_default_group_perms(default_user_id)
381 default_repo_groups_perms = Permission.get_default_group_perms(default_user_id)
381
382
382 if user.is_admin:
383 if user.is_admin:
383 #==================================================================
384 #==================================================================
384 # admin user have all default rights for repositories
385 # admin user have all default rights for repositories
385 # and groups set to admin
386 # and groups set to admin
386 #==================================================================
387 #==================================================================
387 user.permissions[GLOBAL].add('hg.admin')
388 user.permissions[GLOBAL].add('hg.admin')
388
389
389 # repositories
390 # repositories
390 for perm in default_repo_perms:
391 for perm in default_repo_perms:
391 r_k = perm.UserRepoToPerm.repository.repo_name
392 r_k = perm.UserRepoToPerm.repository.repo_name
392 p = 'repository.admin'
393 p = 'repository.admin'
393 user.permissions[RK][r_k] = p
394 user.permissions[RK][r_k] = p
394
395
395 # repositories groups
396 # repositories groups
396 for perm in default_repo_groups_perms:
397 for perm in default_repo_groups_perms:
397 rg_k = perm.UserRepoGroupToPerm.group.group_name
398 rg_k = perm.UserRepoGroupToPerm.group.group_name
398 p = 'group.admin'
399 p = 'group.admin'
399 user.permissions[GK][rg_k] = p
400 user.permissions[GK][rg_k] = p
400
401
401 else:
402 else:
402 #==================================================================
403 #==================================================================
403 # set default permissions first for repositories and groups
404 # set default permissions first for repositories and groups
404 #==================================================================
405 #==================================================================
405 uid = user.user_id
406 uid = user.user_id
406
407
407 # default global permissions
408 # default global permissions
408 default_global_perms = self.sa.query(UserToPerm)\
409 default_global_perms = self.sa.query(UserToPerm)\
409 .filter(UserToPerm.user_id == default_user_id)
410 .filter(UserToPerm.user_id == default_user_id)
410
411
411 for perm in default_global_perms:
412 for perm in default_global_perms:
412 user.permissions[GLOBAL].add(perm.permission.permission_name)
413 user.permissions[GLOBAL].add(perm.permission.permission_name)
413
414
414 # defaults for repositories, taken from default user
415 # defaults for repositories, taken from default user
415 for perm in default_repo_perms:
416 for perm in default_repo_perms:
416 r_k = perm.UserRepoToPerm.repository.repo_name
417 r_k = perm.UserRepoToPerm.repository.repo_name
417 if perm.Repository.private and not (perm.Repository.user_id == uid):
418 if perm.Repository.private and not (perm.Repository.user_id == uid):
418 # disable defaults for private repos,
419 # disable defaults for private repos,
419 p = 'repository.none'
420 p = 'repository.none'
420 elif perm.Repository.user_id == uid:
421 elif perm.Repository.user_id == uid:
421 # set admin if owner
422 # set admin if owner
422 p = 'repository.admin'
423 p = 'repository.admin'
423 else:
424 else:
424 p = perm.Permission.permission_name
425 p = perm.Permission.permission_name
425
426
426 user.permissions[RK][r_k] = p
427 user.permissions[RK][r_k] = p
427
428
428 # defaults for repositories groups taken from default user permission
429 # defaults for repositories groups taken from default user permission
429 # on given group
430 # on given group
430 for perm in default_repo_groups_perms:
431 for perm in default_repo_groups_perms:
431 rg_k = perm.UserRepoGroupToPerm.group.group_name
432 rg_k = perm.UserRepoGroupToPerm.group.group_name
432 p = perm.Permission.permission_name
433 p = perm.Permission.permission_name
433 user.permissions[GK][rg_k] = p
434 user.permissions[GK][rg_k] = p
434
435
435 #==================================================================
436 #==================================================================
436 # overwrite defaults with user permissions if any found
437 # overwrite defaults with user permissions if any found
437 #==================================================================
438 #==================================================================
438
439
439 # user global permissions
440 # user global permissions
440 user_perms = self.sa.query(UserToPerm)\
441 user_perms = self.sa.query(UserToPerm)\
441 .options(joinedload(UserToPerm.permission))\
442 .options(joinedload(UserToPerm.permission))\
442 .filter(UserToPerm.user_id == uid).all()
443 .filter(UserToPerm.user_id == uid).all()
443
444
444 for perm in user_perms:
445 for perm in user_perms:
445 user.permissions[GLOBAL].add(perm.permission.permission_name)
446 user.permissions[GLOBAL].add(perm.permission.permission_name)
446
447
447 # user explicit permissions for repositories
448 # user explicit permissions for repositories
448 user_repo_perms = \
449 user_repo_perms = \
449 self.sa.query(UserRepoToPerm, Permission, Repository)\
450 self.sa.query(UserRepoToPerm, Permission, Repository)\
450 .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\
451 .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\
451 .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\
452 .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\
452 .filter(UserRepoToPerm.user_id == uid)\
453 .filter(UserRepoToPerm.user_id == uid)\
453 .all()
454 .all()
454
455
455 for perm in user_repo_perms:
456 for perm in user_repo_perms:
456 # set admin if owner
457 # set admin if owner
457 r_k = perm.UserRepoToPerm.repository.repo_name
458 r_k = perm.UserRepoToPerm.repository.repo_name
458 if perm.Repository.user_id == uid:
459 if perm.Repository.user_id == uid:
459 p = 'repository.admin'
460 p = 'repository.admin'
460 else:
461 else:
461 p = perm.Permission.permission_name
462 p = perm.Permission.permission_name
462 user.permissions[RK][r_k] = p
463 user.permissions[RK][r_k] = p
463
464
464 #==================================================================
465 #==================================================================
465 # check if user is part of user groups for this repository and
466 # check if user is part of user groups for this repository and
466 # fill in (or replace with higher) permissions
467 # fill in (or replace with higher) permissions
467 #==================================================================
468 #==================================================================
468
469
469 # users group global
470 # users group global
470 user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\
471 user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\
471 .options(joinedload(UsersGroupToPerm.permission))\
472 .options(joinedload(UsersGroupToPerm.permission))\
472 .join((UsersGroupMember, UsersGroupToPerm.users_group_id ==
473 .join((UsersGroupMember, UsersGroupToPerm.users_group_id ==
473 UsersGroupMember.users_group_id))\
474 UsersGroupMember.users_group_id))\
474 .filter(UsersGroupMember.user_id == uid).all()
475 .filter(UsersGroupMember.user_id == uid).all()
475
476
476 for perm in user_perms_from_users_groups:
477 for perm in user_perms_from_users_groups:
477 user.permissions[GLOBAL].add(perm.permission.permission_name)
478 user.permissions[GLOBAL].add(perm.permission.permission_name)
478
479
479 # users group for repositories permissions
480 # users group for repositories permissions
480 user_repo_perms_from_users_groups = \
481 user_repo_perms_from_users_groups = \
481 self.sa.query(UsersGroupRepoToPerm, Permission, Repository,)\
482 self.sa.query(UsersGroupRepoToPerm, Permission, Repository,)\
482 .join((Repository, UsersGroupRepoToPerm.repository_id == Repository.repo_id))\
483 .join((Repository, UsersGroupRepoToPerm.repository_id == Repository.repo_id))\
483 .join((Permission, UsersGroupRepoToPerm.permission_id == Permission.permission_id))\
484 .join((Permission, UsersGroupRepoToPerm.permission_id == Permission.permission_id))\
484 .join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id == UsersGroupMember.users_group_id))\
485 .join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id == UsersGroupMember.users_group_id))\
485 .filter(UsersGroupMember.user_id == uid)\
486 .filter(UsersGroupMember.user_id == uid)\
486 .all()
487 .all()
487
488
488 for perm in user_repo_perms_from_users_groups:
489 for perm in user_repo_perms_from_users_groups:
489 r_k = perm.UsersGroupRepoToPerm.repository.repo_name
490 r_k = perm.UsersGroupRepoToPerm.repository.repo_name
490 p = perm.Permission.permission_name
491 p = perm.Permission.permission_name
491 cur_perm = user.permissions[RK][r_k]
492 cur_perm = user.permissions[RK][r_k]
492 # overwrite permission only if it's greater than permission
493 # overwrite permission only if it's greater than permission
493 # given from other sources
494 # given from other sources
494 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
495 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
495 user.permissions[RK][r_k] = p
496 user.permissions[RK][r_k] = p
496
497
497 #==================================================================
498 #==================================================================
498 # get access for this user for repos group and override defaults
499 # get access for this user for repos group and override defaults
499 #==================================================================
500 #==================================================================
500
501
501 # user explicit permissions for repository
502 # user explicit permissions for repository
502 user_repo_groups_perms = \
503 user_repo_groups_perms = \
503 self.sa.query(UserRepoGroupToPerm, Permission, RepoGroup)\
504 self.sa.query(UserRepoGroupToPerm, Permission, RepoGroup)\
504 .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\
505 .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\
505 .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\
506 .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\
506 .filter(UserRepoGroupToPerm.user_id == uid)\
507 .filter(UserRepoGroupToPerm.user_id == uid)\
507 .all()
508 .all()
508
509
509 for perm in user_repo_groups_perms:
510 for perm in user_repo_groups_perms:
510 rg_k = perm.UserRepoGroupToPerm.group.group_name
511 rg_k = perm.UserRepoGroupToPerm.group.group_name
511 p = perm.Permission.permission_name
512 p = perm.Permission.permission_name
512 cur_perm = user.permissions[GK][rg_k]
513 cur_perm = user.permissions[GK][rg_k]
513 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
514 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
514 user.permissions[GK][rg_k] = p
515 user.permissions[GK][rg_k] = p
515
516
516 #==================================================================
517 #==================================================================
517 # check if user is part of user groups for this repo group and
518 # check if user is part of user groups for this repo group and
518 # fill in (or replace with higher) permissions
519 # fill in (or replace with higher) permissions
519 #==================================================================
520 #==================================================================
520
521
521 # users group for repositories permissions
522 # users group for repositories permissions
522 user_repo_group_perms_from_users_groups = \
523 user_repo_group_perms_from_users_groups = \
523 self.sa.query(UsersGroupRepoGroupToPerm, Permission, RepoGroup)\
524 self.sa.query(UsersGroupRepoGroupToPerm, Permission, RepoGroup)\
524 .join((RepoGroup, UsersGroupRepoGroupToPerm.group_id == RepoGroup.group_id))\
525 .join((RepoGroup, UsersGroupRepoGroupToPerm.group_id == RepoGroup.group_id))\
525 .join((Permission, UsersGroupRepoGroupToPerm.permission_id == Permission.permission_id))\
526 .join((Permission, UsersGroupRepoGroupToPerm.permission_id == Permission.permission_id))\
526 .join((UsersGroupMember, UsersGroupRepoGroupToPerm.users_group_id == UsersGroupMember.users_group_id))\
527 .join((UsersGroupMember, UsersGroupRepoGroupToPerm.users_group_id == UsersGroupMember.users_group_id))\
527 .filter(UsersGroupMember.user_id == uid)\
528 .filter(UsersGroupMember.user_id == uid)\
528 .all()
529 .all()
529
530
530 for perm in user_repo_group_perms_from_users_groups:
531 for perm in user_repo_group_perms_from_users_groups:
531 g_k = perm.UsersGroupRepoGroupToPerm.group.group_name
532 g_k = perm.UsersGroupRepoGroupToPerm.group.group_name
532 print perm, g_k
533 print perm, g_k
533 p = perm.Permission.permission_name
534 p = perm.Permission.permission_name
534 cur_perm = user.permissions[GK][g_k]
535 cur_perm = user.permissions[GK][g_k]
535 # overwrite permission only if it's greater than permission
536 # overwrite permission only if it's greater than permission
536 # given from other sources
537 # given from other sources
537 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
538 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
538 user.permissions[GK][g_k] = p
539 user.permissions[GK][g_k] = p
539
540
540 return user
541 return user
541
542
542 def has_perm(self, user, perm):
543 def has_perm(self, user, perm):
543 if not isinstance(perm, Permission):
544 if not isinstance(perm, Permission):
544 raise Exception('perm needs to be an instance of Permission class '
545 raise Exception('perm needs to be an instance of Permission class '
545 'got %s instead' % type(perm))
546 'got %s instead' % type(perm))
546
547
547 user = self.__get_user(user)
548 user = self.__get_user(user)
548
549
549 return UserToPerm.query().filter(UserToPerm.user == user)\
550 return UserToPerm.query().filter(UserToPerm.user == user)\
550 .filter(UserToPerm.permission == perm).scalar() is not None
551 .filter(UserToPerm.permission == perm).scalar() is not None
551
552
552 def grant_perm(self, user, perm):
553 def grant_perm(self, user, perm):
553 """
554 """
554 Grant user global permissions
555 Grant user global permissions
555
556
556 :param user:
557 :param user:
557 :param perm:
558 :param perm:
558 """
559 """
559 user = self.__get_user(user)
560 user = self.__get_user(user)
560 perm = self.__get_perm(perm)
561 perm = self.__get_perm(perm)
561 # if this permission is already granted skip it
562 # if this permission is already granted skip it
562 _perm = UserToPerm.query()\
563 _perm = UserToPerm.query()\
563 .filter(UserToPerm.user == user)\
564 .filter(UserToPerm.user == user)\
564 .filter(UserToPerm.permission == perm)\
565 .filter(UserToPerm.permission == perm)\
565 .scalar()
566 .scalar()
566 if _perm:
567 if _perm:
567 return
568 return
568 new = UserToPerm()
569 new = UserToPerm()
569 new.user = user
570 new.user = user
570 new.permission = perm
571 new.permission = perm
571 self.sa.add(new)
572 self.sa.add(new)
572
573
573 def revoke_perm(self, user, perm):
574 def revoke_perm(self, user, perm):
574 """
575 """
575 Revoke users global permissions
576 Revoke users global permissions
576
577
577 :param user:
578 :param user:
578 :param perm:
579 :param perm:
579 """
580 """
580 user = self.__get_user(user)
581 user = self.__get_user(user)
581 perm = self.__get_perm(perm)
582 perm = self.__get_perm(perm)
582
583
583 obj = UserToPerm.query()\
584 obj = UserToPerm.query()\
584 .filter(UserToPerm.user == user)\
585 .filter(UserToPerm.user == user)\
585 .filter(UserToPerm.permission == perm)\
586 .filter(UserToPerm.permission == perm)\
586 .scalar()
587 .scalar()
587 if obj:
588 if obj:
588 self.sa.delete(obj)
589 self.sa.delete(obj)
General Comments 0
You need to be logged in to leave comments. Login now