comparison rhodecode/tests/functional/test_admin_users.py @ 4116:ffd45b185016 rhodecode-2.2.5-gpl

Imported some of the GPLv3'd changes from RhodeCode v2.2.5. This imports changes between changesets 21af6c4eab3d and 6177597791c2 in RhodeCode's original repository, including only changes to Python files and HTML. RhodeCode clearly licensed its changes to these files under GPLv3 in their /LICENSE file, which states the following: The Python code and integrated HTML are licensed under the GPLv3 license. (See: https://code.rhodecode.com/rhodecode/files/v2.2.5/LICENSE or http://web.archive.org/web/20140512193334/https://code.rhodecode.com/rhodecode/files/f3b123159901f15426d18e3dc395e8369f70ebe0/LICENSE for an online copy of that LICENSE file) Conservancy reviewed these changes and confirmed that they can be licensed as a whole to the Kallithea project under GPLv3-only. While some of the contents committed herein are clearly licensed GPLv3-or-later, on the whole we must assume the are GPLv3-only, since the statement above from RhodeCode indicates that they intend GPLv3-only as their license, per GPLv3ยง14 and other relevant sections of GPLv3.
author Bradley M. Kuhn <bkuhn@sfconservancy.org>
date Wed, 02 Jul 2014 19:03:13 -0400
parents d7488551578e
children da3c57422ee6
comparison
equal deleted inserted replaced
4115:8b7294a804a0 4116:ffd45b185016
1 # -*- coding: utf-8 -*-
2 # This program is free software: you can redistribute it and/or modify
3 # it under the terms of the GNU General Public License as published by
4 # the Free Software Foundation, either version 3 of the License, or
5 # (at your option) any later version.
6 #
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
11 #
12 # You should have received a copy of the GNU General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
1 from sqlalchemy.orm.exc import NoResultFound 15 from sqlalchemy.orm.exc import NoResultFound
2 16
3 from rhodecode.tests import * 17 from rhodecode.tests import *
4 from rhodecode.model.db import User, Permission 18 from rhodecode.tests.fixture import Fixture
19 from rhodecode.model.db import User, Permission, UserIpMap, UserApiKeys
5 from rhodecode.lib.auth import check_password 20 from rhodecode.lib.auth import check_password
6 from rhodecode.model.user import UserModel 21 from rhodecode.model.user import UserModel
7 from rhodecode.model import validators 22 from rhodecode.model import validators
8 from rhodecode.lib import helpers as h 23 from rhodecode.lib import helpers as h
9 from rhodecode.model.meta import Session 24 from rhodecode.model.meta import Session
10 25
26 fixture = Fixture()
27
11 28
12 class TestAdminUsersController(TestController): 29 class TestAdminUsersController(TestController):
30 test_user_1 = 'testme'
31
32 @classmethod
33 def teardown_class(cls):
34 if User.get_by_username(cls.test_user_1):
35 UserModel().delete(cls.test_user_1)
36 Session().commit()
13 37
14 def test_index(self): 38 def test_index(self):
15 self.log_user() 39 self.log_user()
16 response = self.app.get(url('users')) 40 response = self.app.get(url('users'))
17 # Test response... 41 # Test response...
18
19 def test_index_as_xml(self):
20 response = self.app.get(url('formatted_users', format='xml'))
21 42
22 def test_create(self): 43 def test_create(self):
23 self.log_user() 44 self.log_user()
24 username = 'newtestuser' 45 username = 'newtestuser'
25 password = 'test12' 46 password = 'test12'
27 name = 'name' 48 name = 'name'
28 lastname = 'lastname' 49 lastname = 'lastname'
29 email = 'mail@mail.com' 50 email = 'mail@mail.com'
30 51
31 response = self.app.post(url('users'), 52 response = self.app.post(url('users'),
32 {'username': username, 53 {'username': username,
33 'password': password, 54 'password': password,
34 'password_confirmation': password_confirmation, 55 'password_confirmation': password_confirmation,
35 'firstname': name, 56 'firstname': name,
36 'active': True, 57 'active': True,
37 'lastname': lastname, 58 'lastname': lastname,
38 'email': email}) 59 'extern_name': 'rhodecode',
60 'extern_type': 'rhodecode',
61 'email': email})
39 62
40 self.checkSessionFlash(response, '''Created user %s''' % (username)) 63 self.checkSessionFlash(response, '''Created user %s''' % (username))
41 64
42 new_user = Session().query(User).\ 65 new_user = Session().query(User).\
43 filter(User.username == username).one() 66 filter(User.username == username).one()
80 103
81 def test_new(self): 104 def test_new(self):
82 self.log_user() 105 self.log_user()
83 response = self.app.get(url('new_user')) 106 response = self.app.get(url('new_user'))
84 107
85 def test_new_as_xml(self): 108 @parameterized.expand(
86 response = self.app.get(url('formatted_new_user', format='xml')) 109 [('firstname', {'firstname': 'new_username'}),
87 110 ('lastname', {'lastname': 'new_username'}),
88 @parameterized.expand([('firstname', 'new_username'), 111 ('admin', {'admin': True}),
89 ('lastname', 'new_username'), 112 ('admin', {'admin': False}),
90 ('admin', True), 113 ('extern_type', {'extern_type': 'ldap'}),
91 ('admin', False), 114 ('extern_type', {'extern_type': None}),
92 ('ldap_dn', 'test'), 115 ('extern_name', {'extern_name': 'test'}),
93 ('ldap_dn', None), 116 ('extern_name', {'extern_name': None}),
94 ('active', False), 117 ('active', {'active': False}),
95 ('active', True), 118 ('active', {'active': True}),
96 ('email', 'some@email.com'), 119 ('email', {'email': 'some@email.com'}),
97 ]) 120 # ('new_password', {'new_password': 'foobar123',
98 def test_update(self, name, expected): 121 # 'password_confirmation': 'foobar123'})
99 self.log_user() 122 ])
100 uname = 'testme' 123 def test_update(self, name, attrs):
101 usr = UserModel().create_or_update(username=uname, password='qweqwe', 124 self.log_user()
102 email='testme@rhodecod.org') 125 usr = fixture.create_user(self.test_user_1, password='qweqwe',
126 email='testme@rhodecode.org',
127 extern_type='rhodecode',
128 extern_name=self.test_user_1,
129 skip_if_exists=True)
103 Session().commit() 130 Session().commit()
104 params = usr.get_api_data() 131 params = usr.get_api_data()
105 params.update({name: expected})
106 params.update({'password_confirmation': ''}) 132 params.update({'password_confirmation': ''})
107 params.update({'new_password': ''}) 133 params.update({'new_password': ''})
134 params.update(attrs)
108 if name == 'email': 135 if name == 'email':
109 params['emails'] = [expected] 136 params['emails'] = [attrs['email']]
110 if name == 'ldap_dn': 137 if name == 'extern_type':
111 #cannot update this via form 138 #cannot update this via form, expected value is original one
112 params['ldap_dn'] = None 139 params['extern_type'] = "rhodecode"
113 try: 140 if name == 'extern_name':
114 response = self.app.put(url('user', id=usr.user_id), params) 141 #cannot update this via form, expected value is original one
115 142 params['extern_name'] = self.test_user_1
116 self.checkSessionFlash(response, '''User updated successfully''') 143 # special case since this user is not
117 144 # logged in yet his data is not filled
118 updated_user = User.get_by_username(uname) 145 # so we use creation data
119 updated_params = updated_user.get_api_data() 146
120 updated_params.update({'password_confirmation': ''}) 147 response = self.app.put(url('user', id=usr.user_id), params)
121 updated_params.update({'new_password': ''}) 148 self.checkSessionFlash(response, 'User updated successfully')
122 149
123 self.assertEqual(params, updated_params) 150 updated_user = User.get_by_username(self.test_user_1)
124 151 updated_params = updated_user.get_api_data()
125 finally: 152 updated_params.update({'password_confirmation': ''})
126 UserModel().delete('testme') 153 updated_params.update({'new_password': ''})
127 154
128 def test_update_browser_fakeout(self): 155 self.assertEqual(params, updated_params)
129 response = self.app.post(url('user', id=1), params=dict(_method='put'))
130 156
131 def test_delete(self): 157 def test_delete(self):
132 self.log_user() 158 self.log_user()
133 username = 'newtestuserdeleteme' 159 username = 'newtestuserdeleteme'
134 password = 'test12' 160
135 name = 'name' 161 fixture.create_user(name=username)
136 lastname = 'lastname'
137 email = 'todeletemail@mail.com'
138
139 response = self.app.post(url('users'), {'username': username,
140 'password': password,
141 'password_confirmation': password,
142 'firstname': name,
143 'active': True,
144 'lastname': lastname,
145 'email': email})
146
147 response = response.follow()
148 162
149 new_user = Session().query(User)\ 163 new_user = Session().query(User)\
150 .filter(User.username == username).one() 164 .filter(User.username == username).one()
151 response = self.app.delete(url('user', id=new_user.user_id)) 165 response = self.app.delete(url('user', id=new_user.user_id))
152 166
153 self.checkSessionFlash(response, 'Successfully deleted user') 167 self.checkSessionFlash(response, 'Successfully deleted user')
154 168
155 def test_delete_browser_fakeout(self):
156 response = self.app.post(url('user', id=1),
157 params=dict(_method='delete'))
158
159 def test_show(self): 169 def test_show(self):
160 response = self.app.get(url('user', id=1)) 170 response = self.app.get(url('user', id=1))
161
162 def test_show_as_xml(self):
163 response = self.app.get(url('formatted_user', id=1, format='xml'))
164 171
165 def test_edit(self): 172 def test_edit(self):
166 self.log_user() 173 self.log_user()
167 user = User.get_by_username(TEST_USER_ADMIN_LOGIN) 174 user = User.get_by_username(TEST_USER_ADMIN_LOGIN)
168 response = self.app.get(url('edit_user', id=user.user_id)) 175 response = self.app.get(url('edit_user', id=user.user_id))
181 try: 188 try:
182 #User should have None permission on creation repository 189 #User should have None permission on creation repository
183 self.assertEqual(UserModel().has_perm(user, perm_none), False) 190 self.assertEqual(UserModel().has_perm(user, perm_none), False)
184 self.assertEqual(UserModel().has_perm(user, perm_create), False) 191 self.assertEqual(UserModel().has_perm(user, perm_create), False)
185 192
186 response = self.app.post(url('user_perm', id=uid), 193 response = self.app.post(url('edit_user_perms', id=uid),
187 params=dict(_method='put', 194 params=dict(_method='put',
188 create_repo_perm=True)) 195 create_repo_perm=True))
189 196
190 perm_none = Permission.get_by_key('hg.create.none') 197 perm_none = Permission.get_by_key('hg.create.none')
191 perm_create = Permission.get_by_key('hg.create.repository') 198 perm_create = Permission.get_by_key('hg.create.repository')
211 try: 218 try:
212 #User should have None permission on creation repository 219 #User should have None permission on creation repository
213 self.assertEqual(UserModel().has_perm(user, perm_none), False) 220 self.assertEqual(UserModel().has_perm(user, perm_none), False)
214 self.assertEqual(UserModel().has_perm(user, perm_create), False) 221 self.assertEqual(UserModel().has_perm(user, perm_create), False)
215 222
216 response = self.app.post(url('user_perm', id=uid), 223 response = self.app.post(url('edit_user_perms', id=uid),
217 params=dict(_method='put')) 224 params=dict(_method='put'))
218 225
219 perm_none = Permission.get_by_key('hg.create.none') 226 perm_none = Permission.get_by_key('hg.create.none')
220 perm_create = Permission.get_by_key('hg.create.repository') 227 perm_create = Permission.get_by_key('hg.create.repository')
221 228
240 try: 247 try:
241 #User should have None permission on creation repository 248 #User should have None permission on creation repository
242 self.assertEqual(UserModel().has_perm(user, perm_none), False) 249 self.assertEqual(UserModel().has_perm(user, perm_none), False)
243 self.assertEqual(UserModel().has_perm(user, perm_fork), False) 250 self.assertEqual(UserModel().has_perm(user, perm_fork), False)
244 251
245 response = self.app.post(url('user_perm', id=uid), 252 response = self.app.post(url('edit_user_perms', id=uid),
246 params=dict(_method='put', 253 params=dict(_method='put',
247 create_repo_perm=True)) 254 create_repo_perm=True))
248 255
249 perm_none = Permission.get_by_key('hg.create.none') 256 perm_none = Permission.get_by_key('hg.create.none')
250 perm_create = Permission.get_by_key('hg.create.repository') 257 perm_create = Permission.get_by_key('hg.create.repository')
270 try: 277 try:
271 #User should have None permission on creation repository 278 #User should have None permission on creation repository
272 self.assertEqual(UserModel().has_perm(user, perm_none), False) 279 self.assertEqual(UserModel().has_perm(user, perm_none), False)
273 self.assertEqual(UserModel().has_perm(user, perm_fork), False) 280 self.assertEqual(UserModel().has_perm(user, perm_fork), False)
274 281
275 response = self.app.post(url('user_perm', id=uid), 282 response = self.app.post(url('edit_user_perms', id=uid),
276 params=dict(_method='put')) 283 params=dict(_method='put'))
277 284
278 perm_none = Permission.get_by_key('hg.create.none') 285 perm_none = Permission.get_by_key('hg.create.none')
279 perm_create = Permission.get_by_key('hg.create.repository') 286 perm_create = Permission.get_by_key('hg.create.repository')
280 287
283 self.assertEqual(UserModel().has_perm(uid, perm_create), False) 290 self.assertEqual(UserModel().has_perm(uid, perm_create), False)
284 finally: 291 finally:
285 UserModel().delete(uid) 292 UserModel().delete(uid)
286 Session().commit() 293 Session().commit()
287 294
288 def test_edit_as_xml(self): 295 def test_ips(self):
289 response = self.app.get(url('formatted_edit_user', id=1, format='xml')) 296 self.log_user()
297 user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
298 response = self.app.get(url('edit_user_ips', id=user.user_id))
299 response.mustcontain('All IP addresses are allowed')
300
301 @parameterized.expand([
302 ('127/24', '127.0.0.1/24', '127.0.0.0 - 127.0.0.255', False),
303 ('10/32', '10.0.0.10/32', '10.0.0.10 - 10.0.0.10', False),
304 ('0/16', '0.0.0.0/16', '0.0.0.0 - 0.0.255.255', False),
305 ('0/8', '0.0.0.0/8', '0.0.0.0 - 0.255.255.255', False),
306 ('127_bad_mask', '127.0.0.1/99', '127.0.0.1 - 127.0.0.1', True),
307 ('127_bad_ip', 'foobar', 'foobar', True),
308 ])
309 def test_add_ip(self, test_name, ip, ip_range, failure):
310 self.log_user()
311 user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
312 user_id = user.user_id
313
314 response = self.app.put(url('edit_user_ips', id=user_id),
315 params=dict(new_ip=ip))
316
317 if failure:
318 self.checkSessionFlash(response, 'Please enter a valid IPv4 or IpV6 address')
319 response = self.app.get(url('edit_user_ips', id=user_id))
320 response.mustcontain(no=[ip])
321 response.mustcontain(no=[ip_range])
322
323 else:
324 response = self.app.get(url('edit_user_ips', id=user_id))
325 response.mustcontain(ip)
326 response.mustcontain(ip_range)
327
328 ## cleanup
329 for del_ip in UserIpMap.query().filter(UserIpMap.user_id == user_id).all():
330 Session().delete(del_ip)
331 Session().commit()
332
333 def test_delete_ip(self):
334 self.log_user()
335 user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
336 user_id = user.user_id
337 ip = '127.0.0.1/32'
338 ip_range = '127.0.0.1 - 127.0.0.1'
339 new_ip = UserModel().add_extra_ip(user_id, ip)
340 Session().commit()
341 new_ip_id = new_ip.ip_id
342
343 response = self.app.get(url('edit_user_ips', id=user_id))
344 response.mustcontain(ip)
345 response.mustcontain(ip_range)
346
347 self.app.post(url('edit_user_ips', id=user_id),
348 params=dict(_method='delete', del_ip_id=new_ip_id))
349
350 response = self.app.get(url('edit_user_ips', id=user_id))
351 response.mustcontain('All IP addresses are allowed')
352 response.mustcontain(no=[ip])
353 response.mustcontain(no=[ip_range])
354
355 def test_api_keys(self):
356 self.log_user()
357
358 user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
359 response = self.app.get(url('edit_user_api_keys', id=user.user_id))
360 response.mustcontain(user.api_key)
361 response.mustcontain('expires: never')
362
363 @parameterized.expand([
364 ('forever', -1),
365 ('5mins', 60*5),
366 ('30days', 60*60*24*30),
367 ])
368 def test_add_api_keys(self, desc, lifetime):
369 self.log_user()
370 user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
371 user_id = user.user_id
372
373 response = self.app.post(url('edit_user_api_keys', id=user_id),
374 {'_method': 'put', 'description': desc, 'lifetime': lifetime})
375 self.checkSessionFlash(response, 'Api key successfully created')
376 try:
377 response = response.follow()
378 user = User.get(user_id)
379 for api_key in user.api_keys:
380 response.mustcontain(api_key)
381 finally:
382 for api_key in UserApiKeys.query().filter(UserApiKeys.user_id == user_id).all():
383 Session().delete(api_key)
384 Session().commit()
385
386 def test_remove_api_key(self):
387 self.log_user()
388 user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
389 user_id = user.user_id
390
391 response = self.app.post(url('edit_user_api_keys', id=user_id),
392 {'_method': 'put', 'description': 'desc', 'lifetime': -1})
393 self.checkSessionFlash(response, 'Api key successfully created')
394 response = response.follow()
395
396 #now delete our key
397 keys = UserApiKeys.query().filter(UserApiKeys.user_id == user_id).all()
398 self.assertEqual(1, len(keys))
399
400 response = self.app.post(url('edit_user_api_keys', id=user_id),
401 {'_method': 'delete', 'del_api_key': keys[0].api_key})
402 self.checkSessionFlash(response, 'Api key successfully deleted')
403 keys = UserApiKeys.query().filter(UserApiKeys.user_id == user_id).all()
404 self.assertEqual(0, len(keys))
405
406 def test_reset_main_api_key(self):
407 self.log_user()
408 user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
409 user_id = user.user_id
410 api_key = user.api_key
411 response = self.app.get(url('edit_user_api_keys', id=user_id))
412 response.mustcontain(api_key)
413 response.mustcontain('expires: never')
414
415 response = self.app.post(url('edit_user_api_keys', id=user_id),
416 {'_method': 'delete', 'del_api_key_builtin': api_key})
417 self.checkSessionFlash(response, 'Api key successfully reset')
418 response = response.follow()
419 response.mustcontain(no=[api_key])