Show More
@@ -22,14 +22,19 b' import pytest' | |||
|
22 | 22 | |
|
23 | 23 | from rhodecode.model.meta import Session |
|
24 | 24 | from rhodecode.model.user import UserModel |
|
25 | from rhodecode.model.auth_token import AuthTokenModel | |
|
25 | 26 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN |
|
26 | 27 | |
|
27 | 28 | |
|
28 | 29 | @pytest.fixture(scope="class") |
|
29 | 30 | def testuser_api(request, pylonsapp): |
|
30 | 31 | cls = request.cls |
|
32 | ||
|
33 | # ADMIN USER | |
|
31 | 34 | cls.usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) |
|
32 | 35 | cls.apikey = cls.usr.api_key |
|
36 | ||
|
37 | # REGULAR USER | |
|
33 | 38 | cls.test_user = UserModel().create_or_update( |
|
34 | 39 | username='test-api', |
|
35 | 40 | password='test', |
@@ -37,6 +42,11 b' def testuser_api(request, pylonsapp):' | |||
|
37 | 42 | firstname='first', |
|
38 | 43 | lastname='last' |
|
39 | 44 | ) |
|
45 | # create TOKEN for user, if he doesn't have one | |
|
46 | if not cls.test_user.api_key: | |
|
47 | AuthTokenModel().create( | |
|
48 | user=cls.test_user, description='TEST_USER_TOKEN') | |
|
49 | ||
|
40 | 50 | Session().commit() |
|
41 | 51 | cls.TEST_USER_LOGIN = cls.test_user.username |
|
42 | 52 | cls.apikey_regular = cls.test_user.api_key |
@@ -29,6 +29,7 b' from rhodecode.api.tests.utils import (' | |||
|
29 | 29 | |
|
30 | 30 | @pytest.mark.usefixtures("testuser_api", "app") |
|
31 | 31 | class TestClosePullRequest(object): |
|
32 | ||
|
32 | 33 | @pytest.mark.backends("git", "hg") |
|
33 | 34 | def test_api_close_pull_request(self, pr_util): |
|
34 | 35 | pull_request = pr_util.create_pull_request() |
@@ -53,11 +53,10 b' class TestApiDeleteRepo(object):' | |||
|
53 | 53 | } |
|
54 | 54 | assert_ok(id_, expected, given=response.body) |
|
55 | 55 | |
|
56 | def test_api_delete_repo_by_non_admin_no_permission( | |
|
57 | self, backend, user_regular): | |
|
56 | def test_api_delete_repo_by_non_admin_no_permission(self, backend): | |
|
58 | 57 | repo = backend.create_repo() |
|
59 | 58 | id_, params = build_data( |
|
60 |
|
|
|
59 | self.apikey_regular, 'delete_repo', repoid=repo.repo_name, ) | |
|
61 | 60 | response = api_call(self.app, params) |
|
62 | 61 | expected = 'repository `%s` does not exist' % (repo.repo_name) |
|
63 | 62 | assert_error(id_, expected, given=response.body) |
@@ -62,7 +62,6 b' def get_user(request, apiuser, userid=Op' | |||
|
62 | 62 | "result": { |
|
63 | 63 | "active": true, |
|
64 | 64 | "admin": false, |
|
65 | "api_key": "api-key", | |
|
66 | 65 | "api_keys": [ list of keys ], |
|
67 | 66 | "email": "user@example.com", |
|
68 | 67 | "emails": [ |
@@ -292,13 +292,13 b' class DbManage(object):' | |||
|
292 | 292 | TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL |
|
293 | 293 | |
|
294 | 294 | self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS, |
|
295 | TEST_USER_ADMIN_EMAIL, True) | |
|
295 | TEST_USER_ADMIN_EMAIL, True, api_key=True) | |
|
296 | 296 | |
|
297 | 297 | self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, |
|
298 | TEST_USER_REGULAR_EMAIL, False) | |
|
298 | TEST_USER_REGULAR_EMAIL, False, api_key=True) | |
|
299 | 299 | |
|
300 | 300 | self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS, |
|
301 | TEST_USER_REGULAR2_EMAIL, False) | |
|
301 | TEST_USER_REGULAR2_EMAIL, False, api_key=True) | |
|
302 | 302 | |
|
303 | 303 | def create_ui_settings(self, repo_store_path): |
|
304 | 304 | """ |
@@ -561,7 +561,9 b' class DbManage(object):' | |||
|
561 | 561 | |
|
562 | 562 | if api_key: |
|
563 | 563 | log.info('setting a provided api key for the user %s', username) |
|
564 | user.api_key = api_key | |
|
564 | from rhodecode.model.auth_token import AuthTokenModel | |
|
565 | AuthTokenModel().create( | |
|
566 | user=user, description='BUILTIN TOKEN') | |
|
565 | 567 | |
|
566 | 568 | def create_default_user(self): |
|
567 | 569 | log.info('creating default user') |
@@ -257,6 +257,11 b' class ExtensionCallback(object):' | |||
|
257 | 257 | log.debug('Calling extension callback for %s', self._hook_name) |
|
258 | 258 | |
|
259 | 259 | kwargs_to_pass = dict((key, kwargs[key]) for key in self._kwargs_keys) |
|
260 | # backward compat for removed api_key for old hooks. THis was it works | |
|
261 | # with older rcextensions that require api_key present | |
|
262 | if self._hook_name in ['CREATE_USER_HOOK', 'DELETE_USER_HOOK']: | |
|
263 | kwargs_to_pass['api_key'] = '_DEPRECATED_' | |
|
264 | ||
|
260 | 265 | callback = self._get_callback() |
|
261 | 266 | if callback: |
|
262 | 267 | return callback(**kwargs_to_pass) |
@@ -356,7 +361,7 b' log_create_user = ExtensionCallback(' | |||
|
356 | 361 | 'username', 'full_name_or_username', 'full_contact', 'user_id', |
|
357 | 362 | 'name', 'firstname', 'short_contact', 'admin', 'lastname', |
|
358 | 363 | 'ip_addresses', 'extern_type', 'extern_name', |
|
359 |
'email |
|
|
364 | 'email', 'api_keys', 'last_login', | |
|
360 | 365 | 'full_name', 'active', 'password', 'emails', |
|
361 | 366 | 'inherit_default_permissions', 'created_by', 'created_on')) |
|
362 | 367 | |
@@ -367,7 +372,7 b' log_delete_user = ExtensionCallback(' | |||
|
367 | 372 | 'username', 'full_name_or_username', 'full_contact', 'user_id', |
|
368 | 373 | 'name', 'firstname', 'short_contact', 'admin', 'lastname', |
|
369 | 374 | 'ip_addresses', |
|
370 |
'email', ' |
|
|
375 | 'email', 'last_login', | |
|
371 | 376 | 'full_name', 'active', 'password', 'emails', |
|
372 | 377 | 'inherit_default_permissions', 'deleted_by')) |
|
373 | 378 |
@@ -572,6 +572,9 b' class User(Base, BaseModel):' | |||
|
572 | 572 | .filter(or_(UserApiKeys.expires == -1, |
|
573 | 573 | UserApiKeys.expires >= time.time()))\ |
|
574 | 574 | .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL).first() |
|
575 | if user_auth_token: | |
|
576 | user_auth_token = user_auth_token.api_key | |
|
577 | ||
|
575 | 578 | return user_auth_token |
|
576 | 579 | |
|
577 | 580 | @api_key.setter |
@@ -962,6 +965,9 b' class UserApiKeys(Base, BaseModel):' | |||
|
962 | 965 | |
|
963 | 966 | user = relationship('User', lazy='joined') |
|
964 | 967 | |
|
968 | def __unicode__(self): | |
|
969 | return u"<%s('%s')>" % (self.__class__.__name__, self.role) | |
|
970 | ||
|
965 | 971 | @classmethod |
|
966 | 972 | def _get_role_name(cls, role): |
|
967 | 973 | return { |
@@ -37,6 +37,7 b' from rhodecode.model.user import UserMod' | |||
|
37 | 37 | from rhodecode.model.repo_group import RepoGroupModel |
|
38 | 38 | from rhodecode.model.user_group import UserGroupModel |
|
39 | 39 | from rhodecode.model.gist import GistModel |
|
40 | from rhodecode.model.auth_token import AuthTokenModel | |
|
40 | 41 | |
|
41 | 42 | dn = os.path.dirname |
|
42 | 43 | FIXTURES = os.path.join(dn(dn(os.path.abspath(__file__))), 'tests', 'fixtures') |
@@ -260,6 +261,11 b' class Fixture(object):' | |||
|
260 | 261 | return user |
|
261 | 262 | form_data = self._get_user_create_params(name, **kwargs) |
|
262 | 263 | user = UserModel().create(form_data) |
|
264 | ||
|
265 | # create token for user | |
|
266 | AuthTokenModel().create( | |
|
267 | user=user, description='TEST_USER_TOKEN') | |
|
268 | ||
|
263 | 269 | Session().commit() |
|
264 | 270 | user = User.get_by_username(user.username) |
|
265 | 271 | return user |
@@ -258,39 +258,38 b' class TestMyAccountController(TestContro' | |||
|
258 | 258 | usr = self.log_user('test_regular2', 'test12') |
|
259 | 259 | user = User.get(usr['user_id']) |
|
260 | 260 | response = self.app.get(url('my_account_auth_tokens')) |
|
261 | response.mustcontain(user.api_key) | |
|
262 |
response.mustcontain( |
|
|
261 | for token in user.auth_tokens: | |
|
262 | response.mustcontain(token) | |
|
263 | response.mustcontain('never') | |
|
263 | 264 | |
|
264 | 265 | @pytest.mark.parametrize("desc, lifetime", [ |
|
265 | 266 | ('forever', -1), |
|
266 | 267 | ('5mins', 60*5), |
|
267 | 268 | ('30days', 60*60*24*30), |
|
268 | 269 | ]) |
|
269 | def test_my_account_add_auth_tokens(self, desc, lifetime): | |
|
270 | usr = self.log_user('test_regular2', 'test12') | |
|
271 |
user = |
|
|
270 | def test_my_account_add_auth_tokens(self, desc, lifetime, user_util): | |
|
271 | user = user_util.create_user(password='qweqwe') | |
|
272 | user_id = user.user_id | |
|
273 | self.log_user(user.username, 'qweqwe') | |
|
274 | ||
|
272 | 275 | response = self.app.post(url('my_account_auth_tokens'), |
|
273 | 276 | {'description': desc, 'lifetime': lifetime, |
|
274 | 277 | 'csrf_token': self.csrf_token}) |
|
275 | 278 | assert_session_flash(response, 'Auth token successfully created') |
|
276 | try: | |
|
277 |
|
|
|
278 |
|
|
|
279 |
|
|
|
280 |
|
|
|
281 | finally: | |
|
282 | for auth_token in UserApiKeys.query().all(): | |
|
283 | Session().delete(auth_token) | |
|
284 | Session().commit() | |
|
279 | ||
|
280 | response = response.follow() | |
|
281 | user = User.get(user_id) | |
|
282 | for auth_token in user.auth_tokens: | |
|
283 | response.mustcontain(auth_token) | |
|
285 | 284 | |
|
286 | 285 | def test_my_account_remove_auth_token(self, user_util): |
|
287 |
user = user_util.create_user(password= |
|
|
286 | user = user_util.create_user(password='qweqwe') | |
|
288 | 287 | user_id = user.user_id |
|
289 |
self.log_user(user.username, |
|
|
288 | self.log_user(user.username, 'qweqwe') | |
|
290 | 289 | |
|
291 | 290 | user = User.get(user_id) |
|
292 | 291 | keys = user.extra_auth_tokens |
|
293 |
assert |
|
|
292 | assert 2 == len(keys) | |
|
294 | 293 | |
|
295 | 294 | response = self.app.post(url('my_account_auth_tokens'), |
|
296 | 295 | {'description': 'desc', 'lifetime': -1, |
@@ -300,7 +299,7 b' class TestMyAccountController(TestContro' | |||
|
300 | 299 | |
|
301 | 300 | user = User.get(user_id) |
|
302 | 301 | keys = user.extra_auth_tokens |
|
303 |
assert |
|
|
302 | assert 3 == len(keys) | |
|
304 | 303 | |
|
305 | 304 | response = self.app.post( |
|
306 | 305 | url('my_account_auth_tokens'), |
@@ -310,7 +309,7 b' class TestMyAccountController(TestContro' | |||
|
310 | 309 | |
|
311 | 310 | user = User.get(user_id) |
|
312 | 311 | keys = user.extra_auth_tokens |
|
313 |
assert |
|
|
312 | assert 2 == len(keys) | |
|
314 | 313 | |
|
315 | 314 | def test_valid_change_password(self, user_util): |
|
316 | 315 | new_password = 'my_new_valid_password' |
@@ -327,7 +326,7 b' class TestMyAccountController(TestContro' | |||
|
327 | 326 | response = self.app.post(url('my_account_password'), form_data).follow() |
|
328 | 327 | assert 'Successfully updated password' in response |
|
329 | 328 | |
|
330 |
|
|
|
329 | # check_password depends on user being in session | |
|
331 | 330 | Session().add(user) |
|
332 | 331 | try: |
|
333 | 332 | assert check_password(new_password, user.password) |
@@ -573,17 +573,18 b' class TestAdminUsersController(TestContr' | |||
|
573 | 573 | user = User.get_by_username(TEST_USER_REGULAR_LOGIN) |
|
574 | 574 | response = self.app.get( |
|
575 | 575 | url('edit_user_auth_tokens', user_id=user.user_id)) |
|
576 | response.mustcontain(user.api_key) | |
|
577 |
response.mustcontain( |
|
|
576 | for token in user.auth_tokens: | |
|
577 | response.mustcontain(token) | |
|
578 | response.mustcontain('never') | |
|
578 | 579 | |
|
579 | 580 | @pytest.mark.parametrize("desc, lifetime", [ |
|
580 | 581 | ('forever', -1), |
|
581 | 582 | ('5mins', 60*5), |
|
582 | 583 | ('30days', 60*60*24*30), |
|
583 | 584 | ]) |
|
584 | def test_add_auth_token(self, desc, lifetime): | |
|
585 | def test_add_auth_token(self, desc, lifetime, user_util): | |
|
585 | 586 | self.log_user() |
|
586 | user = User.get_by_username(TEST_USER_REGULAR_LOGIN) | |
|
587 | user = user_util.create_user() | |
|
587 | 588 | user_id = user.user_id |
|
588 | 589 | |
|
589 | 590 | response = self.app.post( |
@@ -591,20 +592,15 b' class TestAdminUsersController(TestContr' | |||
|
591 | 592 | {'_method': 'put', 'description': desc, 'lifetime': lifetime, |
|
592 | 593 | 'csrf_token': self.csrf_token}) |
|
593 | 594 | assert_session_flash(response, 'Auth token successfully created') |
|
594 | try: | |
|
595 | response = response.follow() | |
|
596 | user = User.get(user_id) | |
|
597 | for auth_token in user.auth_tokens: | |
|
598 | response.mustcontain(auth_token) | |
|
599 | finally: | |
|
600 | for api_key in UserApiKeys.query().filter( | |
|
601 | UserApiKeys.user_id == user_id).all(): | |
|
602 | Session().delete(api_key) | |
|
603 | Session().commit() | |
|
604 | 595 | |
|
605 | def test_remove_auth_token(self): | |
|
596 | response = response.follow() | |
|
597 | user = User.get(user_id) | |
|
598 | for auth_token in user.auth_tokens: | |
|
599 | response.mustcontain(auth_token) | |
|
600 | ||
|
601 | def test_remove_auth_token(self, user_util): | |
|
606 | 602 | self.log_user() |
|
607 | user = User.get_by_username(TEST_USER_REGULAR_LOGIN) | |
|
603 | user = user_util.create_user() | |
|
608 | 604 | user_id = user.user_id |
|
609 | 605 | |
|
610 | 606 | response = self.app.post( |
@@ -616,7 +612,7 b' class TestAdminUsersController(TestContr' | |||
|
616 | 612 | |
|
617 | 613 | # now delete our key |
|
618 | 614 | keys = UserApiKeys.query().filter(UserApiKeys.user_id == user_id).all() |
|
619 |
assert |
|
|
615 | assert 3 == len(keys) | |
|
620 | 616 | |
|
621 | 617 | response = self.app.post( |
|
622 | 618 | url('edit_user_auth_tokens', user_id=user_id), |
@@ -624,4 +620,4 b' class TestAdminUsersController(TestContr' | |||
|
624 | 620 | 'csrf_token': self.csrf_token}) |
|
625 | 621 | assert_session_flash(response, 'Auth token successfully deleted') |
|
626 | 622 | keys = UserApiKeys.query().filter(UserApiKeys.user_id == user_id).all() |
|
627 |
assert |
|
|
623 | assert 2 == len(keys) |
@@ -366,7 +366,7 b' class TestLoginController(object):' | |||
|
366 | 366 | assert ret.email == email |
|
367 | 367 | assert ret.name == name |
|
368 | 368 | assert ret.lastname == lastname |
|
369 |
assert ret.a |
|
|
369 | assert ret.auth_tokens is not None | |
|
370 | 370 | assert not ret.admin |
|
371 | 371 | |
|
372 | 372 | def test_forgot_password_wrong_mail(self): |
@@ -463,6 +463,7 b' class TestLoginController(object):' | |||
|
463 | 463 | |
|
464 | 464 | if test_name == 'proper_auth_token': |
|
465 | 465 | auth_token = user_admin.api_key |
|
466 | assert auth_token | |
|
466 | 467 | |
|
467 | 468 | with fixture.anon_access(False): |
|
468 | 469 | self.app.get(url(controller='changeset', |
@@ -71,16 +71,22 b' def test_create_admin_and_prompt_sets_th' | |||
|
71 | 71 | assert create_user.call_args[1]['api_key'] == 'testkey' |
|
72 | 72 | |
|
73 | 73 | |
|
74 | def test_create_user_sets_the_api_key(db_manage): | |
|
74 | @pytest.mark.parametrize('add_keys', [True, False]) | |
|
75 | def test_create_user_sets_the_api_key(db_manage, add_keys): | |
|
76 | username = 'test_add_keys_{}'.format(add_keys) | |
|
75 | 77 | db_manage.create_user( |
|
76 |
|
|
|
77 |
api_key= |
|
|
78 | username, 'testpassword', 'test@example.com', | |
|
79 | api_key=add_keys) | |
|
78 | 80 | |
|
79 |
user = db.User.get_by_username( |
|
|
80 | assert user.api_key == 'testkey' | |
|
81 | user = db.User.get_by_username(username) | |
|
82 | if add_keys: | |
|
83 | assert 2 == len(user.auth_tokens) | |
|
84 | else: | |
|
85 | # only feed token | |
|
86 | assert 1 == len(user.auth_tokens) | |
|
81 | 87 | |
|
82 | 88 | |
|
83 | 89 | def test_create_user_without_api_key(db_manage): |
|
84 | 90 | db_manage.create_user('test', 'testpassword', 'test@example.com') |
|
85 | 91 | user = db.User.get_by_username('test') |
|
86 | assert user.api_key | |
|
92 | assert user.api_key is None |
@@ -109,15 +109,12 b' def test_get_api_data_replaces_secret_da' | |||
|
109 | 109 | api_key_length = 40 |
|
110 | 110 | expected_replacement = '*' * api_key_length |
|
111 | 111 | |
|
112 | assert api_data['api_key'] == expected_replacement | |
|
113 | 112 | for key in api_data['api_keys']: |
|
114 | 113 | assert key == expected_replacement |
|
115 | 114 | |
|
116 | 115 | |
|
117 | 116 | def test_get_api_data_includes_secret_data_if_activated(test_user): |
|
118 | 117 | api_data = test_user.get_api_data(include_secrets=True) |
|
119 | ||
|
120 | assert api_data['api_key'] == test_user.api_key | |
|
121 | 118 | assert api_data['api_keys'] == test_user.auth_tokens |
|
122 | 119 | |
|
123 | 120 |
General Comments 0
You need to be logged in to leave comments.
Login now