##// END OF EJS Templates
removed extra query for default user
marcink -
r1270:49872ed3 beta
parent child Browse files
Show More
@@ -1,383 +1,383 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) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 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.i18n.translation import _
29 from pylons.i18n.translation import _
30
30
31 from rhodecode.model import BaseModel
31 from rhodecode.model import BaseModel
32 from rhodecode.model.caching_query import FromCache
32 from rhodecode.model.caching_query import FromCache
33 from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \
33 from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \
34 UserToPerm, UsersGroupRepoToPerm, UsersGroupToPerm, UsersGroupMember
34 UserToPerm, UsersGroupRepoToPerm, UsersGroupToPerm, UsersGroupMember
35 from rhodecode.lib.exceptions import DefaultUserException, \
35 from rhodecode.lib.exceptions import DefaultUserException, \
36 UserOwnsReposException
36 UserOwnsReposException
37
37
38 from sqlalchemy.exc import DatabaseError
38 from sqlalchemy.exc import DatabaseError
39 from rhodecode.lib import generate_api_key
39 from rhodecode.lib import generate_api_key
40 from sqlalchemy.orm import joinedload
40 from sqlalchemy.orm import joinedload
41
41
42 log = logging.getLogger(__name__)
42 log = logging.getLogger(__name__)
43
43
44 PERM_WEIGHTS = {'repository.none': 0,
44 PERM_WEIGHTS = {'repository.none': 0,
45 'repository.read': 1,
45 'repository.read': 1,
46 'repository.write': 3,
46 'repository.write': 3,
47 'repository.admin': 3}
47 'repository.admin': 3}
48
48
49
49
50 class UserModel(BaseModel):
50 class UserModel(BaseModel):
51
51
52 def get(self, user_id, cache=False):
52 def get(self, user_id, cache=False):
53 user = self.sa.query(User)
53 user = self.sa.query(User)
54 if cache:
54 if cache:
55 user = user.options(FromCache("sql_cache_short",
55 user = user.options(FromCache("sql_cache_short",
56 "get_user_%s" % user_id))
56 "get_user_%s" % user_id))
57 return user.get(user_id)
57 return user.get(user_id)
58
58
59 def get_by_username(self, username, cache=False, case_insensitive=False):
59 def get_by_username(self, username, cache=False, case_insensitive=False):
60
60
61 if case_insensitive:
61 if case_insensitive:
62 user = self.sa.query(User).filter(User.username.ilike(username))
62 user = self.sa.query(User).filter(User.username.ilike(username))
63 else:
63 else:
64 user = self.sa.query(User)\
64 user = self.sa.query(User)\
65 .filter(User.username == username)
65 .filter(User.username == username)
66 if cache:
66 if cache:
67 user = user.options(FromCache("sql_cache_short",
67 user = user.options(FromCache("sql_cache_short",
68 "get_user_%s" % username))
68 "get_user_%s" % username))
69 return user.scalar()
69 return user.scalar()
70
70
71 def get_by_api_key(self, api_key, cache=False):
71 def get_by_api_key(self, api_key, cache=False):
72
72
73 user = self.sa.query(User)\
73 user = self.sa.query(User)\
74 .filter(User.api_key == api_key)
74 .filter(User.api_key == api_key)
75 if cache:
75 if cache:
76 user = user.options(FromCache("sql_cache_short",
76 user = user.options(FromCache("sql_cache_short",
77 "get_user_%s" % api_key))
77 "get_user_%s" % api_key))
78 return user.scalar()
78 return user.scalar()
79
79
80 def create(self, form_data):
80 def create(self, form_data):
81 try:
81 try:
82 new_user = User()
82 new_user = User()
83 for k, v in form_data.items():
83 for k, v in form_data.items():
84 setattr(new_user, k, v)
84 setattr(new_user, k, v)
85
85
86 new_user.api_key = generate_api_key(form_data['username'])
86 new_user.api_key = generate_api_key(form_data['username'])
87 self.sa.add(new_user)
87 self.sa.add(new_user)
88 self.sa.commit()
88 self.sa.commit()
89 except:
89 except:
90 log.error(traceback.format_exc())
90 log.error(traceback.format_exc())
91 self.sa.rollback()
91 self.sa.rollback()
92 raise
92 raise
93
93
94 def create_ldap(self, username, password, user_dn, attrs):
94 def create_ldap(self, username, password, user_dn, attrs):
95 """
95 """
96 Checks if user is in database, if not creates this user marked
96 Checks if user is in database, if not creates this user marked
97 as ldap user
97 as ldap user
98 :param username:
98 :param username:
99 :param password:
99 :param password:
100 :param user_dn:
100 :param user_dn:
101 :param attrs:
101 :param attrs:
102 """
102 """
103 from rhodecode.lib.auth import get_crypt_password
103 from rhodecode.lib.auth import get_crypt_password
104 log.debug('Checking for such ldap account in RhodeCode database')
104 log.debug('Checking for such ldap account in RhodeCode database')
105 if self.get_by_username(username, case_insensitive=True) is None:
105 if self.get_by_username(username, case_insensitive=True) is None:
106 try:
106 try:
107 new_user = User()
107 new_user = User()
108 # add ldap account always lowercase
108 # add ldap account always lowercase
109 new_user.username = username.lower()
109 new_user.username = username.lower()
110 new_user.password = get_crypt_password(password)
110 new_user.password = get_crypt_password(password)
111 new_user.api_key = generate_api_key(username)
111 new_user.api_key = generate_api_key(username)
112 new_user.email = attrs['email']
112 new_user.email = attrs['email']
113 new_user.active = True
113 new_user.active = True
114 new_user.ldap_dn = user_dn
114 new_user.ldap_dn = user_dn
115 new_user.name = attrs['name']
115 new_user.name = attrs['name']
116 new_user.lastname = attrs['lastname']
116 new_user.lastname = attrs['lastname']
117
117
118 self.sa.add(new_user)
118 self.sa.add(new_user)
119 self.sa.commit()
119 self.sa.commit()
120 return True
120 return True
121 except (DatabaseError,):
121 except (DatabaseError,):
122 log.error(traceback.format_exc())
122 log.error(traceback.format_exc())
123 self.sa.rollback()
123 self.sa.rollback()
124 raise
124 raise
125 log.debug('this %s user exists skipping creation of ldap account',
125 log.debug('this %s user exists skipping creation of ldap account',
126 username)
126 username)
127 return False
127 return False
128
128
129 def create_registration(self, form_data):
129 def create_registration(self, form_data):
130 from rhodecode.lib.celerylib import tasks, run_task
130 from rhodecode.lib.celerylib import tasks, run_task
131 try:
131 try:
132 new_user = User()
132 new_user = User()
133 for k, v in form_data.items():
133 for k, v in form_data.items():
134 if k != 'admin':
134 if k != 'admin':
135 setattr(new_user, k, v)
135 setattr(new_user, k, v)
136
136
137 self.sa.add(new_user)
137 self.sa.add(new_user)
138 self.sa.commit()
138 self.sa.commit()
139 body = ('New user registration\n'
139 body = ('New user registration\n'
140 'username: %s\n'
140 'username: %s\n'
141 'email: %s\n')
141 'email: %s\n')
142 body = body % (form_data['username'], form_data['email'])
142 body = body % (form_data['username'], form_data['email'])
143
143
144 run_task(tasks.send_email, None,
144 run_task(tasks.send_email, None,
145 _('[RhodeCode] New User registration'),
145 _('[RhodeCode] New User registration'),
146 body)
146 body)
147 except:
147 except:
148 log.error(traceback.format_exc())
148 log.error(traceback.format_exc())
149 self.sa.rollback()
149 self.sa.rollback()
150 raise
150 raise
151
151
152 def update(self, user_id, form_data):
152 def update(self, user_id, form_data):
153 try:
153 try:
154 user = self.get(user_id, cache=False)
154 user = self.get(user_id, cache=False)
155 if user.username == 'default':
155 if user.username == 'default':
156 raise DefaultUserException(
156 raise DefaultUserException(
157 _("You can't Edit this user since it's"
157 _("You can't Edit this user since it's"
158 " crucial for entire application"))
158 " crucial for entire application"))
159
159
160 for k, v in form_data.items():
160 for k, v in form_data.items():
161 if k == 'new_password' and v != '':
161 if k == 'new_password' and v != '':
162 user.password = v
162 user.password = v
163 user.api_key = generate_api_key(user.username)
163 user.api_key = generate_api_key(user.username)
164 else:
164 else:
165 setattr(user, k, v)
165 setattr(user, k, v)
166
166
167 self.sa.add(user)
167 self.sa.add(user)
168 self.sa.commit()
168 self.sa.commit()
169 except:
169 except:
170 log.error(traceback.format_exc())
170 log.error(traceback.format_exc())
171 self.sa.rollback()
171 self.sa.rollback()
172 raise
172 raise
173
173
174 def update_my_account(self, user_id, form_data):
174 def update_my_account(self, user_id, form_data):
175 try:
175 try:
176 user = self.get(user_id, cache=False)
176 user = self.get(user_id, cache=False)
177 if user.username == 'default':
177 if user.username == 'default':
178 raise DefaultUserException(
178 raise DefaultUserException(
179 _("You can't Edit this user since it's"
179 _("You can't Edit this user since it's"
180 " crucial for entire application"))
180 " crucial for entire application"))
181 for k, v in form_data.items():
181 for k, v in form_data.items():
182 if k == 'new_password' and v != '':
182 if k == 'new_password' and v != '':
183 user.password = v
183 user.password = v
184 user.api_key = generate_api_key(user.username)
184 user.api_key = generate_api_key(user.username)
185 else:
185 else:
186 if k not in ['admin', 'active']:
186 if k not in ['admin', 'active']:
187 setattr(user, k, v)
187 setattr(user, k, v)
188
188
189 self.sa.add(user)
189 self.sa.add(user)
190 self.sa.commit()
190 self.sa.commit()
191 except:
191 except:
192 log.error(traceback.format_exc())
192 log.error(traceback.format_exc())
193 self.sa.rollback()
193 self.sa.rollback()
194 raise
194 raise
195
195
196 def delete(self, user_id):
196 def delete(self, user_id):
197 try:
197 try:
198 user = self.get(user_id, cache=False)
198 user = self.get(user_id, cache=False)
199 if user.username == 'default':
199 if user.username == 'default':
200 raise DefaultUserException(
200 raise DefaultUserException(
201 _("You can't remove this user since it's"
201 _("You can't remove this user since it's"
202 " crucial for entire application"))
202 " crucial for entire application"))
203 if user.repositories:
203 if user.repositories:
204 raise UserOwnsReposException(_('This user still owns %s '
204 raise UserOwnsReposException(_('This user still owns %s '
205 'repositories and cannot be '
205 'repositories and cannot be '
206 'removed. Switch owners or '
206 'removed. Switch owners or '
207 'remove those repositories') \
207 'remove those repositories') \
208 % user.repositories)
208 % user.repositories)
209 self.sa.delete(user)
209 self.sa.delete(user)
210 self.sa.commit()
210 self.sa.commit()
211 except:
211 except:
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
215
216 def reset_password(self, data):
216 def reset_password(self, data):
217 from rhodecode.lib.celerylib import tasks, run_task
217 from rhodecode.lib.celerylib import tasks, run_task
218 run_task(tasks.reset_user_password, data['email'])
218 run_task(tasks.reset_user_password, data['email'])
219
219
220 def fill_data(self, auth_user, user_id=None, api_key=None):
220 def fill_data(self, auth_user, user_id=None, api_key=None):
221 """
221 """
222 Fetches auth_user by user_id,or api_key if present.
222 Fetches auth_user by user_id,or api_key if present.
223 Fills auth_user attributes with those taken from database.
223 Fills auth_user attributes with those taken from database.
224 Additionally set's is_authenitated if lookup fails
224 Additionally set's is_authenitated if lookup fails
225 present in database
225 present in database
226
226
227 :param auth_user: instance of user to set attributes
227 :param auth_user: instance of user to set attributes
228 :param user_id: user id to fetch by
228 :param user_id: user id to fetch by
229 :param api_key: api key to fetch by
229 :param api_key: api key to fetch by
230 """
230 """
231 if user_id is None and api_key is None:
231 if user_id is None and api_key is None:
232 raise Exception('You need to pass user_id or api_key')
232 raise Exception('You need to pass user_id or api_key')
233
233
234 try:
234 try:
235 if api_key:
235 if api_key:
236 dbuser = self.get_by_api_key(api_key)
236 dbuser = self.get_by_api_key(api_key)
237 else:
237 else:
238 dbuser = self.get(user_id)
238 dbuser = self.get(user_id)
239
239
240 if dbuser is not None:
240 if dbuser is not None:
241 log.debug('filling %s data', dbuser)
241 log.debug('filling %s data', dbuser)
242 for k, v in dbuser.get_dict().items():
242 for k, v in dbuser.get_dict().items():
243 setattr(auth_user, k, v)
243 setattr(auth_user, k, v)
244
244
245 except:
245 except:
246 log.error(traceback.format_exc())
246 log.error(traceback.format_exc())
247 auth_user.is_authenticated = False
247 auth_user.is_authenticated = False
248
248
249 return auth_user
249 return auth_user
250
250
251 def fill_perms(self, user):
251 def fill_perms(self, user):
252 """
252 """
253 Fills user permission attribute with permissions taken from database
253 Fills user permission attribute with permissions taken from database
254 works for permissions given for repositories, and for permissions that
254 works for permissions given for repositories, and for permissions that
255 are granted to groups
255 are granted to groups
256
256
257 :param user: user instance to fill his perms
257 :param user: user instance to fill his perms
258 """
258 """
259
259
260 user.permissions['repositories'] = {}
260 user.permissions['repositories'] = {}
261 user.permissions['global'] = set()
261 user.permissions['global'] = set()
262
262
263 #======================================================================
263 #======================================================================
264 # fetch default permissions
264 # fetch default permissions
265 #======================================================================
265 #======================================================================
266 default_user = self.get_by_username('default', cache=True)
266 default_user = self.get_by_username('default', cache=True)
267
267
268 default_perms = self.sa.query(RepoToPerm, Repository, Permission)\
268 default_perms = self.sa.query(RepoToPerm, Repository, Permission)\
269 .join((Repository, RepoToPerm.repository_id ==
269 .join((Repository, RepoToPerm.repository_id ==
270 Repository.repo_id))\
270 Repository.repo_id))\
271 .join((Permission, RepoToPerm.permission_id ==
271 .join((Permission, RepoToPerm.permission_id ==
272 Permission.permission_id))\
272 Permission.permission_id))\
273 .filter(RepoToPerm.user == default_user).all()
273 .filter(RepoToPerm.user == default_user).all()
274
274
275 if user.is_admin:
275 if user.is_admin:
276 #==================================================================
276 #==================================================================
277 # #admin have all default rights set to admin
277 # #admin have all default rights set to admin
278 #==================================================================
278 #==================================================================
279 user.permissions['global'].add('hg.admin')
279 user.permissions['global'].add('hg.admin')
280
280
281 for perm in default_perms:
281 for perm in default_perms:
282 p = 'repository.admin'
282 p = 'repository.admin'
283 user.permissions['repositories'][perm.RepoToPerm.
283 user.permissions['repositories'][perm.RepoToPerm.
284 repository.repo_name] = p
284 repository.repo_name] = p
285
285
286 else:
286 else:
287 #==================================================================
287 #==================================================================
288 # set default permissions
288 # set default permissions
289 #==================================================================
289 #==================================================================
290 uid = user.user_id
290 uid = user.user_id
291
291
292 #default global
292 #default global
293 default_global_perms = self.sa.query(UserToPerm)\
293 default_global_perms = self.sa.query(UserToPerm)\
294 .filter(UserToPerm.user == User.by_username('default'))
294 .filter(UserToPerm.user == default_user)
295
295
296 for perm in default_global_perms:
296 for perm in default_global_perms:
297 user.permissions['global'].add(perm.permission.permission_name)
297 user.permissions['global'].add(perm.permission.permission_name)
298
298
299 #default for repositories
299 #default for repositories
300 for perm in default_perms:
300 for perm in default_perms:
301 if perm.Repository.private and not (perm.Repository.user_id ==
301 if perm.Repository.private and not (perm.Repository.user_id ==
302 uid):
302 uid):
303 #diself.sable defaults for private repos,
303 #diself.sable defaults for private repos,
304 p = 'repository.none'
304 p = 'repository.none'
305 elif perm.Repository.user_id == uid:
305 elif perm.Repository.user_id == uid:
306 #set admin if owner
306 #set admin if owner
307 p = 'repository.admin'
307 p = 'repository.admin'
308 else:
308 else:
309 p = perm.Permission.permission_name
309 p = perm.Permission.permission_name
310
310
311 user.permissions['repositories'][perm.RepoToPerm.
311 user.permissions['repositories'][perm.RepoToPerm.
312 repository.repo_name] = p
312 repository.repo_name] = p
313
313
314 #==================================================================
314 #==================================================================
315 # overwrite default with user permissions if any
315 # overwrite default with user permissions if any
316 #==================================================================
316 #==================================================================
317
317
318 #user global
318 #user global
319 user_perms = self.sa.query(UserToPerm)\
319 user_perms = self.sa.query(UserToPerm)\
320 .options(joinedload(UserToPerm.permission))\
320 .options(joinedload(UserToPerm.permission))\
321 .filter(UserToPerm.user_id == uid).all()
321 .filter(UserToPerm.user_id == uid).all()
322
322
323 for perm in user_perms:
323 for perm in user_perms:
324 user.permissions['global'].add(perm.permission.
324 user.permissions['global'].add(perm.permission.
325 permission_name)
325 permission_name)
326
326
327 #user repositories
327 #user repositories
328 user_repo_perms = self.sa.query(RepoToPerm, Permission,
328 user_repo_perms = self.sa.query(RepoToPerm, Permission,
329 Repository)\
329 Repository)\
330 .join((Repository, RepoToPerm.repository_id ==
330 .join((Repository, RepoToPerm.repository_id ==
331 Repository.repo_id))\
331 Repository.repo_id))\
332 .join((Permission, RepoToPerm.permission_id ==
332 .join((Permission, RepoToPerm.permission_id ==
333 Permission.permission_id))\
333 Permission.permission_id))\
334 .filter(RepoToPerm.user_id == uid).all()
334 .filter(RepoToPerm.user_id == uid).all()
335
335
336 for perm in user_repo_perms:
336 for perm in user_repo_perms:
337 # set admin if owner
337 # set admin if owner
338 if perm.Repository.user_id == uid:
338 if perm.Repository.user_id == uid:
339 p = 'repository.admin'
339 p = 'repository.admin'
340 else:
340 else:
341 p = perm.Permission.permission_name
341 p = perm.Permission.permission_name
342 user.permissions['repositories'][perm.RepoToPerm.
342 user.permissions['repositories'][perm.RepoToPerm.
343 repository.repo_name] = p
343 repository.repo_name] = p
344
344
345 #==================================================================
345 #==================================================================
346 # check if user is part of groups for this repository and fill in
346 # check if user is part of groups for this repository and fill in
347 # (or replace with higher) permissions
347 # (or replace with higher) permissions
348 #==================================================================
348 #==================================================================
349
349
350 #users group global
350 #users group global
351 user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\
351 user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\
352 .options(joinedload(UsersGroupToPerm.permission))\
352 .options(joinedload(UsersGroupToPerm.permission))\
353 .join((UsersGroupMember, UsersGroupToPerm.users_group_id ==
353 .join((UsersGroupMember, UsersGroupToPerm.users_group_id ==
354 UsersGroupMember.users_group_id))\
354 UsersGroupMember.users_group_id))\
355 .filter(UsersGroupMember.user_id == uid).all()
355 .filter(UsersGroupMember.user_id == uid).all()
356
356
357 for perm in user_perms_from_users_groups:
357 for perm in user_perms_from_users_groups:
358 user.permissions['global'].add(perm.permission.permission_name)
358 user.permissions['global'].add(perm.permission.permission_name)
359
359
360 #users group repositories
360 #users group repositories
361 user_repo_perms_from_users_groups = self.sa.query(
361 user_repo_perms_from_users_groups = self.sa.query(
362 UsersGroupRepoToPerm,
362 UsersGroupRepoToPerm,
363 Permission, Repository,)\
363 Permission, Repository,)\
364 .join((Repository, UsersGroupRepoToPerm.repository_id ==
364 .join((Repository, UsersGroupRepoToPerm.repository_id ==
365 Repository.repo_id))\
365 Repository.repo_id))\
366 .join((Permission, UsersGroupRepoToPerm.permission_id ==
366 .join((Permission, UsersGroupRepoToPerm.permission_id ==
367 Permission.permission_id))\
367 Permission.permission_id))\
368 .join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id ==
368 .join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id ==
369 UsersGroupMember.users_group_id))\
369 UsersGroupMember.users_group_id))\
370 .filter(UsersGroupMember.user_id == uid).all()
370 .filter(UsersGroupMember.user_id == uid).all()
371
371
372 for perm in user_repo_perms_from_users_groups:
372 for perm in user_repo_perms_from_users_groups:
373 p = perm.Permission.permission_name
373 p = perm.Permission.permission_name
374 cur_perm = user.permissions['repositories'][perm.
374 cur_perm = user.permissions['repositories'][perm.
375 UsersGroupRepoToPerm.
375 UsersGroupRepoToPerm.
376 repository.repo_name]
376 repository.repo_name]
377 #overwrite permission only if it's greater than permission
377 #overwrite permission only if it's greater than permission
378 # given from other sources
378 # given from other sources
379 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
379 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
380 user.permissions['repositories'][perm.UsersGroupRepoToPerm.
380 user.permissions['repositories'][perm.UsersGroupRepoToPerm.
381 repository.repo_name] = p
381 repository.repo_name] = p
382
382
383 return user
383 return user
General Comments 0
You need to be logged in to leave comments. Login now