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