##// END OF EJS Templates
fixed security issue when saving ldap user saved plaintext password
marcink -
r750:73c99f45 beta
parent child Browse files
Show More
@@ -1,219 +1,220 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # Model for users
3 # Model for users
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
8 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
9 # of the License or (at your opinion) any later version of the license.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
19 # MA 02110-1301, USA.
20 """
20 """
21 Created on April 9, 2010
21 Created on April 9, 2010
22 Model for users
22 Model for users
23 :author: marcink
23 :author: marcink
24 """
24 """
25
25
26 from pylons.i18n.translation import _
26 from pylons.i18n.translation import _
27 from rhodecode.model.caching_query import FromCache
27 from rhodecode.model.caching_query import FromCache
28 from rhodecode.model.db import User
28 from rhodecode.model.db import User
29 from rhodecode.model.meta import Session
29 from rhodecode.model.meta import Session
30 from rhodecode.lib.exceptions import *
30 from rhodecode.lib.exceptions import *
31
31 import logging
32 import logging
32 import traceback
33 import traceback
33
34
34 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
35
36
36
37
37
38
38 class UserModel(object):
39 class UserModel(object):
39
40
40 def __init__(self):
41 def __init__(self):
41 self.sa = Session()
42 self.sa = Session()
42
43
43 def get(self, user_id, cache=False):
44 def get(self, user_id, cache=False):
44 user = self.sa.query(User)
45 user = self.sa.query(User)
45 if cache:
46 if cache:
46 user = user.options(FromCache("sql_cache_short",
47 user = user.options(FromCache("sql_cache_short",
47 "get_user_%s" % user_id))
48 "get_user_%s" % user_id))
48 return user.get(user_id)
49 return user.get(user_id)
49
50
50
51
51 def get_by_username(self, username, cache=False, case_insensitive=False):
52 def get_by_username(self, username, cache=False, case_insensitive=False):
52
53
53 if case_insensitive:
54 if case_insensitive:
54 user = self.sa.query(User).filter(User.username.ilike(username))
55 user = self.sa.query(User).filter(User.username.ilike(username))
55 else:
56 else:
56 user = self.sa.query(User)\
57 user = self.sa.query(User)\
57 .filter(User.username == username)
58 .filter(User.username == username)
58 if cache:
59 if cache:
59 user = user.options(FromCache("sql_cache_short",
60 user = user.options(FromCache("sql_cache_short",
60 "get_user_%s" % username))
61 "get_user_%s" % username))
61 return user.scalar()
62 return user.scalar()
62
63
63 def create(self, form_data):
64 def create(self, form_data):
64 try:
65 try:
65 new_user = User()
66 new_user = User()
66 for k, v in form_data.items():
67 for k, v in form_data.items():
67 setattr(new_user, k, v)
68 setattr(new_user, k, v)
68
69
69 self.sa.add(new_user)
70 self.sa.add(new_user)
70 self.sa.commit()
71 self.sa.commit()
71 except:
72 except:
72 log.error(traceback.format_exc())
73 log.error(traceback.format_exc())
73 self.sa.rollback()
74 self.sa.rollback()
74 raise
75 raise
75
76
76 def create_ldap(self, username, password):
77 def create_ldap(self, username, password):
77 """
78 """
78 Checks if user is in database, if not creates this user marked
79 Checks if user is in database, if not creates this user marked
79 as ldap user
80 as ldap user
80 :param username:
81 :param username:
81 :param password:
82 :param password:
82 """
83 """
83
84 from rhodecode.lib.auth import get_crypt_password
84 if self.get_by_username(username) is None:
85 if self.get_by_username(username) is None:
85 try:
86 try:
86 new_user = User()
87 new_user = User()
87 new_user.username = username
88 new_user.username = username
88 new_user.password = password
89 new_user.password = get_crypt_password(password)
89 new_user.email = '%s@ldap.server' % username
90 new_user.email = '%s@ldap.server' % username
90 new_user.active = True
91 new_user.active = True
91 new_user.is_ldap = True
92 new_user.is_ldap = True
92 new_user.name = '%s@ldap' % username
93 new_user.name = '%s@ldap' % username
93 new_user.lastname = ''
94 new_user.lastname = ''
94
95
95
96
96 self.sa.add(new_user)
97 self.sa.add(new_user)
97 self.sa.commit()
98 self.sa.commit()
98 return True
99 return True
99 except:
100 except:
100 log.error(traceback.format_exc())
101 log.error(traceback.format_exc())
101 self.sa.rollback()
102 self.sa.rollback()
102 raise
103 raise
103
104
104 return False
105 return False
105
106
106 def create_registration(self, form_data):
107 def create_registration(self, form_data):
107 from rhodecode.lib.celerylib import tasks, run_task
108 from rhodecode.lib.celerylib import tasks, run_task
108 try:
109 try:
109 new_user = User()
110 new_user = User()
110 for k, v in form_data.items():
111 for k, v in form_data.items():
111 if k != 'admin':
112 if k != 'admin':
112 setattr(new_user, k, v)
113 setattr(new_user, k, v)
113
114
114 self.sa.add(new_user)
115 self.sa.add(new_user)
115 self.sa.commit()
116 self.sa.commit()
116 body = ('New user registration\n'
117 body = ('New user registration\n'
117 'username: %s\n'
118 'username: %s\n'
118 'email: %s\n')
119 'email: %s\n')
119 body = body % (form_data['username'], form_data['email'])
120 body = body % (form_data['username'], form_data['email'])
120
121
121 run_task(tasks.send_email, None,
122 run_task(tasks.send_email, None,
122 _('[RhodeCode] New User registration'),
123 _('[RhodeCode] New User registration'),
123 body)
124 body)
124 except:
125 except:
125 log.error(traceback.format_exc())
126 log.error(traceback.format_exc())
126 self.sa.rollback()
127 self.sa.rollback()
127 raise
128 raise
128
129
129 def update(self, user_id, form_data):
130 def update(self, user_id, form_data):
130 try:
131 try:
131 new_user = self.get(user_id, cache=False)
132 new_user = self.get(user_id, cache=False)
132 if new_user.username == 'default':
133 if new_user.username == 'default':
133 raise DefaultUserException(
134 raise DefaultUserException(
134 _("You can't Edit this user since it's"
135 _("You can't Edit this user since it's"
135 " crucial for entire application"))
136 " crucial for entire application"))
136
137
137 for k, v in form_data.items():
138 for k, v in form_data.items():
138 if k == 'new_password' and v != '':
139 if k == 'new_password' and v != '':
139 new_user.password = v
140 new_user.password = v
140 else:
141 else:
141 setattr(new_user, k, v)
142 setattr(new_user, k, v)
142
143
143 self.sa.add(new_user)
144 self.sa.add(new_user)
144 self.sa.commit()
145 self.sa.commit()
145 except:
146 except:
146 log.error(traceback.format_exc())
147 log.error(traceback.format_exc())
147 self.sa.rollback()
148 self.sa.rollback()
148 raise
149 raise
149
150
150 def update_my_account(self, user_id, form_data):
151 def update_my_account(self, user_id, form_data):
151 try:
152 try:
152 new_user = self.get(user_id, cache=False)
153 new_user = self.get(user_id, cache=False)
153 if new_user.username == 'default':
154 if new_user.username == 'default':
154 raise DefaultUserException(
155 raise DefaultUserException(
155 _("You can't Edit this user since it's"
156 _("You can't Edit this user since it's"
156 " crucial for entire application"))
157 " crucial for entire application"))
157 for k, v in form_data.items():
158 for k, v in form_data.items():
158 if k == 'new_password' and v != '':
159 if k == 'new_password' and v != '':
159 new_user.password = v
160 new_user.password = v
160 else:
161 else:
161 if k not in ['admin', 'active']:
162 if k not in ['admin', 'active']:
162 setattr(new_user, k, v)
163 setattr(new_user, k, v)
163
164
164 self.sa.add(new_user)
165 self.sa.add(new_user)
165 self.sa.commit()
166 self.sa.commit()
166 except:
167 except:
167 log.error(traceback.format_exc())
168 log.error(traceback.format_exc())
168 self.sa.rollback()
169 self.sa.rollback()
169 raise
170 raise
170
171
171 def delete(self, user_id):
172 def delete(self, user_id):
172 try:
173 try:
173 user = self.get(user_id, cache=False)
174 user = self.get(user_id, cache=False)
174 if user.username == 'default':
175 if user.username == 'default':
175 raise DefaultUserException(
176 raise DefaultUserException(
176 _("You can't remove this user since it's"
177 _("You can't remove this user since it's"
177 " crucial for entire application"))
178 " crucial for entire application"))
178 if user.repositories:
179 if user.repositories:
179 raise UserOwnsReposException(_('This user still owns %s '
180 raise UserOwnsReposException(_('This user still owns %s '
180 'repositories and cannot be '
181 'repositories and cannot be '
181 'removed. Switch owners or '
182 'removed. Switch owners or '
182 'remove those repositories') \
183 'remove those repositories') \
183 % user.repositories)
184 % user.repositories)
184 self.sa.delete(user)
185 self.sa.delete(user)
185 self.sa.commit()
186 self.sa.commit()
186 except:
187 except:
187 log.error(traceback.format_exc())
188 log.error(traceback.format_exc())
188 self.sa.rollback()
189 self.sa.rollback()
189 raise
190 raise
190
191
191 def reset_password(self, data):
192 def reset_password(self, data):
192 from rhodecode.lib.celerylib import tasks, run_task
193 from rhodecode.lib.celerylib import tasks, run_task
193 run_task(tasks.reset_user_password, data['email'])
194 run_task(tasks.reset_user_password, data['email'])
194
195
195
196
196 def fill_data(self, user):
197 def fill_data(self, user):
197 """
198 """
198 Fills user data with those from database and log out user if not
199 Fills user data with those from database and log out user if not
199 present in database
200 present in database
200 :param user:
201 :param user:
201 """
202 """
202
203
203 if not hasattr(user, 'user_id') or user.user_id is None:
204 if not hasattr(user, 'user_id') or user.user_id is None:
204 raise Exception('passed in user has to have the user_id attribute')
205 raise Exception('passed in user has to have the user_id attribute')
205
206
206
207
207 log.debug('filling auth user data')
208 log.debug('filling auth user data')
208 try:
209 try:
209 dbuser = self.get(user.user_id)
210 dbuser = self.get(user.user_id)
210 user.username = dbuser.username
211 user.username = dbuser.username
211 user.is_admin = dbuser.admin
212 user.is_admin = dbuser.admin
212 user.name = dbuser.name
213 user.name = dbuser.name
213 user.lastname = dbuser.lastname
214 user.lastname = dbuser.lastname
214 user.email = dbuser.email
215 user.email = dbuser.email
215 except:
216 except:
216 log.error(traceback.format_exc())
217 log.error(traceback.format_exc())
217 user.is_authenticated = False
218 user.is_authenticated = False
218
219
219 return user
220 return user
General Comments 0
You need to be logged in to leave comments. Login now