Show More
@@ -40,7 +40,7 b' BACKENDS = {' | |||||
40 | CELERY_ENABLED = False |
|
40 | CELERY_ENABLED = False | |
41 | CELERY_EAGER = False |
|
41 | CELERY_EAGER = False | |
42 |
|
42 | |||
43 |
# link to config for py |
|
43 | # link to config for pyramid | |
44 | CONFIG = {} |
|
44 | CONFIG = {} | |
45 |
|
45 | |||
46 | # Populated with the settings dictionary from application init in |
|
46 | # Populated with the settings dictionary from application init in |
@@ -911,7 +911,8 b' def update_repo(' | |||||
911 | repo_enable_downloads=enable_downloads |
|
911 | repo_enable_downloads=enable_downloads | |
912 | if not isinstance(enable_downloads, Optional) else repo.enable_downloads) |
|
912 | if not isinstance(enable_downloads, Optional) else repo.enable_downloads) | |
913 |
|
913 | |||
914 |
ref_choices, _labels = ScmModel().get_repo_landing_revs( |
|
914 | ref_choices, _labels = ScmModel().get_repo_landing_revs( | |
|
915 | request.translate, repo=repo) | |||
915 |
|
916 | |||
916 | old_values = repo.get_api_data() |
|
917 | old_values = repo.get_api_data() | |
917 | schema = repo_schema.RepoSchema().bind( |
|
918 | schema = repo_schema.RepoSchema().bind( |
@@ -32,7 +32,7 b' def assert_auth_settings_updated(respons' | |||||
32 |
|
32 | |||
33 |
|
33 | |||
34 | @pytest.mark.usefixtures("autologin_user", "app") |
|
34 | @pytest.mark.usefixtures("autologin_user", "app") | |
35 |
class TestAuthSettings |
|
35 | class TestAuthSettingsView(object): | |
36 |
|
36 | |||
37 | def _enable_plugins(self, plugins_list, csrf_token, override=None, |
|
37 | def _enable_plugins(self, plugins_list, csrf_token, override=None, | |
38 | verify_response=False): |
|
38 | verify_response=False): |
@@ -385,7 +385,7 b' class TestAdminUsersView(TestController)' | |||||
385 | 'csrf_token': self.csrf_token, |
|
385 | 'csrf_token': self.csrf_token, | |
386 | }) |
|
386 | }) | |
387 |
|
387 | |||
388 | msg = '???' |
|
388 | msg = u'Username "%(username)s" is forbidden' | |
389 | msg = h.html_escape(msg % {'username': 'new_user'}) |
|
389 | msg = h.html_escape(msg % {'username': 'new_user'}) | |
390 | response.mustcontain('<span class="error-message">%s</span>' % msg) |
|
390 | response.mustcontain('<span class="error-message">%s</span>' % msg) | |
391 | response.mustcontain( |
|
391 | response.mustcontain( |
@@ -53,8 +53,6 b' log = logging.getLogger(__name__)' | |||||
53 | class AdminPermissionsView(BaseAppView, DataGridAppView): |
|
53 | class AdminPermissionsView(BaseAppView, DataGridAppView): | |
54 | def load_default_context(self): |
|
54 | def load_default_context(self): | |
55 | c = self._get_local_tmpl_context() |
|
55 | c = self._get_local_tmpl_context() | |
56 |
|
||||
57 |
|
||||
58 | PermissionModel().set_global_permission_choices( |
|
56 | PermissionModel().set_global_permission_choices( | |
59 | c, gettext_translator=self.request.translate) |
|
57 | c, gettext_translator=self.request.translate) | |
60 | return c |
|
58 | return c |
@@ -58,7 +58,7 b' class AdminReposView(BaseAppView, DataGr' | |||||
58 | c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) |
|
58 | c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) | |
59 | c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups) |
|
59 | c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups) | |
60 | c.landing_revs_choices, c.landing_revs = \ |
|
60 | c.landing_revs_choices, c.landing_revs = \ | |
61 | ScmModel().get_repo_landing_revs() |
|
61 | ScmModel().get_repo_landing_revs(self.request.translate) | |
62 | c.personal_repo_group = self._rhodecode_user.personal_repo_group |
|
62 | c.personal_repo_group = self._rhodecode_user.personal_repo_group | |
63 |
|
63 | |||
64 | @LoginRequired() |
|
64 | @LoginRequired() |
@@ -660,7 +660,7 b' class AdminSettingsView(BaseAppView):' | |||||
660 | c.active = 'search' |
|
660 | c.active = 'search' | |
661 |
|
661 | |||
662 | searcher = searcher_from_config(self.request.registry.settings) |
|
662 | searcher = searcher_from_config(self.request.registry.settings) | |
663 | c.statistics = searcher.statistics() |
|
663 | c.statistics = searcher.statistics(self.request.translate) | |
664 |
|
664 | |||
665 | return self._get_template_context(c) |
|
665 | return self._get_template_context(c) | |
666 |
|
666 |
@@ -259,7 +259,6 b' class UsersView(UserAppView):' | |||||
259 | PermissionModel().set_global_permission_choices( |
|
259 | PermissionModel().set_global_permission_choices( | |
260 | c, gettext_translator=req.translate) |
|
260 | c, gettext_translator=req.translate) | |
261 |
|
261 | |||
262 |
|
||||
263 | return c |
|
262 | return c | |
264 |
|
263 | |||
265 | @LoginRequired() |
|
264 | @LoginRequired() |
@@ -88,32 +88,31 b' class TestLoginController(object):' | |||||
88 | def test_login_admin_ok(self): |
|
88 | def test_login_admin_ok(self): | |
89 | response = self.app.post(route_path('login'), |
|
89 | response = self.app.post(route_path('login'), | |
90 | {'username': 'test_admin', |
|
90 | {'username': 'test_admin', | |
91 | 'password': 'test12'}) |
|
91 | 'password': 'test12'}, status=302) | |
92 | assert response.status == '302 Found' |
|
92 | response = response.follow() | |
93 | session = response.get_session_from_response() |
|
93 | session = response.get_session_from_response() | |
94 | username = session['rhodecode_user'].get('username') |
|
94 | username = session['rhodecode_user'].get('username') | |
95 | assert username == 'test_admin' |
|
95 | assert username == 'test_admin' | |
96 | response = response.follow() |
|
|||
97 | response.mustcontain('/%s' % HG_REPO) |
|
96 | response.mustcontain('/%s' % HG_REPO) | |
98 |
|
97 | |||
99 | def test_login_regular_ok(self): |
|
98 | def test_login_regular_ok(self): | |
100 | response = self.app.post(route_path('login'), |
|
99 | response = self.app.post(route_path('login'), | |
101 | {'username': 'test_regular', |
|
100 | {'username': 'test_regular', | |
102 | 'password': 'test12'}) |
|
101 | 'password': 'test12'}, status=302) | |
103 |
|
102 | |||
104 | assert response.status == '302 Found' |
|
103 | response = response.follow() | |
105 | session = response.get_session_from_response() |
|
104 | session = response.get_session_from_response() | |
106 | username = session['rhodecode_user'].get('username') |
|
105 | username = session['rhodecode_user'].get('username') | |
107 | assert username == 'test_regular' |
|
106 | assert username == 'test_regular' | |
108 | response = response.follow() |
|
107 | ||
109 | response.mustcontain('/%s' % HG_REPO) |
|
108 | response.mustcontain('/%s' % HG_REPO) | |
110 |
|
109 | |||
111 | def test_login_ok_came_from(self): |
|
110 | def test_login_ok_came_from(self): | |
112 | test_came_from = '/_admin/users?branch=stable' |
|
111 | test_came_from = '/_admin/users?branch=stable' | |
113 | _url = '{}?came_from={}'.format(route_path('login'), test_came_from) |
|
112 | _url = '{}?came_from={}'.format(route_path('login'), test_came_from) | |
114 | response = self.app.post( |
|
113 | response = self.app.post( | |
115 | _url, {'username': 'test_admin', 'password': 'test12'}) |
|
114 | _url, {'username': 'test_admin', 'password': 'test12'}, status=302) | |
116 | assert response.status == '302 Found' |
|
115 | ||
117 | assert 'branch=stable' in response.location |
|
116 | assert 'branch=stable' in response.location | |
118 | response = response.follow() |
|
117 | response = response.follow() | |
119 |
|
118 | |||
@@ -124,8 +123,8 b' class TestLoginController(object):' | |||||
124 | with fixture.anon_access(False): |
|
123 | with fixture.anon_access(False): | |
125 | kwargs = {'branch': 'stable'} |
|
124 | kwargs = {'branch': 'stable'} | |
126 | response = self.app.get( |
|
125 | response = self.app.get( | |
127 |
h.route_path('repo_summary', repo_name=HG_REPO, _query=kwargs) |
|
126 | h.route_path('repo_summary', repo_name=HG_REPO, _query=kwargs), | |
128 |
|
|
127 | status=302) | |
129 |
|
128 | |||
130 | response_query = urlparse.parse_qsl(response.location) |
|
129 | response_query = urlparse.parse_qsl(response.location) | |
131 | assert 'branch=stable' in response_query[0][1] |
|
130 | assert 'branch=stable' in response_query[0][1] | |
@@ -200,13 +199,12 b' class TestLoginController(object):' | |||||
200 | self.destroy_users.add(temp_user) |
|
199 | self.destroy_users.add(temp_user) | |
201 | response = self.app.post(route_path('login'), |
|
200 | response = self.app.post(route_path('login'), | |
202 | {'username': temp_user, |
|
201 | {'username': temp_user, | |
203 | 'password': 'test123'}) |
|
202 | 'password': 'test123'}, status=302) | |
204 |
|
203 | |||
205 | assert response.status == '302 Found' |
|
204 | response = response.follow() | |
206 | session = response.get_session_from_response() |
|
205 | session = response.get_session_from_response() | |
207 | username = session['rhodecode_user'].get('username') |
|
206 | username = session['rhodecode_user'].get('username') | |
208 | assert username == temp_user |
|
207 | assert username == temp_user | |
209 | response = response.follow() |
|
|||
210 | response.mustcontain('/%s' % HG_REPO) |
|
208 | response.mustcontain('/%s' % HG_REPO) | |
211 |
|
209 | |||
212 | # new password should be bcrypted, after log-in and transfer |
|
210 | # new password should be bcrypted, after log-in and transfer | |
@@ -233,7 +231,7 b' class TestLoginController(object):' | |||||
233 | ) |
|
231 | ) | |
234 |
|
232 | |||
235 | assertr = response.assert_response() |
|
233 | assertr = response.assert_response() | |
236 | msg = '???' |
|
234 | msg = 'Username "%(username)s" already exists' | |
237 | msg = msg % {'username': uname} |
|
235 | msg = msg % {'username': uname} | |
238 | assertr.element_contains('#username+.error-message', msg) |
|
236 | assertr.element_contains('#username+.error-message', msg) | |
239 |
|
237 | |||
@@ -251,7 +249,7 b' class TestLoginController(object):' | |||||
251 | ) |
|
249 | ) | |
252 |
|
250 | |||
253 | assertr = response.assert_response() |
|
251 | assertr = response.assert_response() | |
254 | msg = '???' |
|
252 | msg = u'This e-mail address is already taken' | |
255 | assertr.element_contains('#email+.error-message', msg) |
|
253 | assertr.element_contains('#email+.error-message', msg) | |
256 |
|
254 | |||
257 | def test_register_err_same_email_case_sensitive(self): |
|
255 | def test_register_err_same_email_case_sensitive(self): | |
@@ -267,7 +265,7 b' class TestLoginController(object):' | |||||
267 | } |
|
265 | } | |
268 | ) |
|
266 | ) | |
269 | assertr = response.assert_response() |
|
267 | assertr = response.assert_response() | |
270 | msg = '???' |
|
268 | msg = u'This e-mail address is already taken' | |
271 | assertr.element_contains('#email+.error-message', msg) |
|
269 | assertr.element_contains('#email+.error-message', msg) | |
272 |
|
270 | |||
273 | def test_register_err_wrong_data(self): |
|
271 | def test_register_err_wrong_data(self): | |
@@ -321,7 +319,7 b' class TestLoginController(object):' | |||||
321 | ) |
|
319 | ) | |
322 |
|
320 | |||
323 | assertr = response.assert_response() |
|
321 | assertr = response.assert_response() | |
324 | msg = '???' |
|
322 | msg = u'Username "%(username)s" already exists' | |
325 | msg = msg % {'username': usr} |
|
323 | msg = msg % {'username': usr} | |
326 | assertr.element_contains('#username+.error-message', msg) |
|
324 | assertr.element_contains('#username+.error-message', msg) | |
327 |
|
325 | |||
@@ -338,7 +336,7 b' class TestLoginController(object):' | |||||
338 | } |
|
336 | } | |
339 | ) |
|
337 | ) | |
340 |
|
338 | |||
341 | msg = '???' |
|
339 | msg = u'Invalid characters (non-ascii) in password' | |
342 | response.mustcontain(msg) |
|
340 | response.mustcontain(msg) | |
343 |
|
341 | |||
344 | def test_register_password_mismatch(self): |
|
342 | def test_register_password_mismatch(self): | |
@@ -353,7 +351,7 b' class TestLoginController(object):' | |||||
353 | 'lastname': 'test' |
|
351 | 'lastname': 'test' | |
354 | } |
|
352 | } | |
355 | ) |
|
353 | ) | |
356 | msg = '???' |
|
354 | msg = u'Passwords do not match' | |
357 | response.mustcontain(msg) |
|
355 | response.mustcontain(msg) | |
358 |
|
356 | |||
359 | def test_register_ok(self): |
|
357 | def test_register_ok(self): | |
@@ -363,6 +361,11 b' class TestLoginController(object):' | |||||
363 | name = 'testname' |
|
361 | name = 'testname' | |
364 | lastname = 'testlastname' |
|
362 | lastname = 'testlastname' | |
365 |
|
363 | |||
|
364 | # this initializes a session | |||
|
365 | response = self.app.get(route_path('register')) | |||
|
366 | response.mustcontain('Create an Account') | |||
|
367 | ||||
|
368 | ||||
366 | response = self.app.post( |
|
369 | response = self.app.post( | |
367 | route_path('register'), |
|
370 | route_path('register'), | |
368 | { |
|
371 | { | |
@@ -373,9 +376,10 b' class TestLoginController(object):' | |||||
373 | 'firstname': name, |
|
376 | 'firstname': name, | |
374 | 'lastname': lastname, |
|
377 | 'lastname': lastname, | |
375 | 'admin': True |
|
378 | 'admin': True | |
376 | } |
|
379 | }, | |
377 | ) # This should be overriden |
|
380 | status=302 | |
378 | assert response.status == '302 Found' |
|
381 | ) # This should be overridden | |
|
382 | ||||
379 | assert_session_flash( |
|
383 | assert_session_flash( | |
380 | response, 'You have successfully registered with RhodeCode') |
|
384 | response, 'You have successfully registered with RhodeCode') | |
381 |
|
385 | |||
@@ -391,6 +395,9 b' class TestLoginController(object):' | |||||
391 |
|
395 | |||
392 | def test_forgot_password_wrong_mail(self): |
|
396 | def test_forgot_password_wrong_mail(self): | |
393 | bad_email = 'marcin@wrongmail.org' |
|
397 | bad_email = 'marcin@wrongmail.org' | |
|
398 | # this initializes a session | |||
|
399 | self.app.get(route_path('reset_password')) | |||
|
400 | ||||
394 | response = self.app.post( |
|
401 | response = self.app.post( | |
395 | route_path('reset_password'), {'email': bad_email, } |
|
402 | route_path('reset_password'), {'email': bad_email, } | |
396 | ) |
|
403 | ) | |
@@ -398,8 +405,8 b' class TestLoginController(object):' | |||||
398 | 'If such email exists, a password reset link was sent to it.') |
|
405 | 'If such email exists, a password reset link was sent to it.') | |
399 |
|
406 | |||
400 | def test_forgot_password(self, user_util): |
|
407 | def test_forgot_password(self, user_util): | |
401 | response = self.app.get(route_path('reset_password')) |
|
408 | # this initializes a session | |
402 | assert response.status == '200 OK' |
|
409 | self.app.get(route_path('reset_password')) | |
403 |
|
410 | |||
404 | user = user_util.create_user() |
|
411 | user = user_util.create_user() | |
405 | user_id = user.user_id |
|
412 | user_id = user.user_id | |
@@ -412,8 +419,7 b' class TestLoginController(object):' | |||||
412 |
|
419 | |||
413 | # BAD KEY |
|
420 | # BAD KEY | |
414 | confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), 'badkey') |
|
421 | confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), 'badkey') | |
415 | response = self.app.get(confirm_url) |
|
422 | response = self.app.get(confirm_url, status=302) | |
416 | assert response.status == '302 Found' |
|
|||
417 | assert response.location.endswith(route_path('reset_password')) |
|
423 | assert response.location.endswith(route_path('reset_password')) | |
418 | assert_session_flash(response, 'Given reset token is invalid') |
|
424 | assert_session_flash(response, 'Given reset token is invalid') | |
419 |
|
425 |
@@ -58,7 +58,7 b' class TestRegisterCaptcha(object):' | |||||
58 | ('privkey', '', CaptchaData(True, 'privkey', '')), |
|
58 | ('privkey', '', CaptchaData(True, 'privkey', '')), | |
59 | ('privkey', 'pubkey', CaptchaData(True, 'privkey', 'pubkey')), |
|
59 | ('privkey', 'pubkey', CaptchaData(True, 'privkey', 'pubkey')), | |
60 | ]) |
|
60 | ]) | |
61 |
def test_get_captcha_data(self, private_key, public_key, expected, |
|
61 | def test_get_captcha_data(self, private_key, public_key, expected, | |
62 | request_stub, user_util): |
|
62 | request_stub, user_util): | |
63 | request_stub.user = user_util.create_user().AuthUser() |
|
63 | request_stub.user = user_util.create_user().AuthUser() | |
64 | request_stub.matched_route = AttributeDict({'name': 'login'}) |
|
64 | request_stub.matched_route = AttributeDict({'name': 'login'}) |
@@ -32,7 +32,7 b' from recaptcha.client.captcha import sub' | |||||
32 |
|
32 | |||
33 | from rhodecode.apps._base import BaseAppView |
|
33 | from rhodecode.apps._base import BaseAppView | |
34 | from rhodecode.authentication.base import authenticate, HTTP_TYPE |
|
34 | from rhodecode.authentication.base import authenticate, HTTP_TYPE | |
35 | from rhodecode.events import UserRegistered |
|
35 | from rhodecode.events import UserRegistered, trigger | |
36 | from rhodecode.lib import helpers as h |
|
36 | from rhodecode.lib import helpers as h | |
37 | from rhodecode.lib import audit_logger |
|
37 | from rhodecode.lib import audit_logger | |
38 | from rhodecode.lib.auth import ( |
|
38 | from rhodecode.lib.auth import ( | |
@@ -147,7 +147,7 b' class LoginView(BaseAppView):' | |||||
147 | raise HTTPFound(c.came_from, headers=headers) |
|
147 | raise HTTPFound(c.came_from, headers=headers) | |
148 | except UserCreationError as e: |
|
148 | except UserCreationError as e: | |
149 | log.error(e) |
|
149 | log.error(e) | |
150 |
|
|
150 | h.flash(e, category='error') | |
151 |
|
151 | |||
152 | return self._get_template_context(c) |
|
152 | return self._get_template_context(c) | |
153 |
|
153 | |||
@@ -201,7 +201,7 b' class LoginView(BaseAppView):' | |||||
201 | # the fly can throw this exception signaling that there's issue |
|
201 | # the fly can throw this exception signaling that there's issue | |
202 | # with user creation, explanation should be provided in |
|
202 | # with user creation, explanation should be provided in | |
203 | # Exception itself |
|
203 | # Exception itself | |
204 |
|
|
204 | h.flash(e, category='error') | |
205 | return self._get_template_context(c) |
|
205 | return self._get_template_context(c) | |
206 |
|
206 | |||
207 | @CSRFRequired() |
|
207 | @CSRFRequired() | |
@@ -250,6 +250,7 b' class LoginView(BaseAppView):' | |||||
250 | route_name='register', request_method='POST', |
|
250 | route_name='register', request_method='POST', | |
251 | renderer='rhodecode:templates/register.mako') |
|
251 | renderer='rhodecode:templates/register.mako') | |
252 | def register_post(self): |
|
252 | def register_post(self): | |
|
253 | self.load_default_context() | |||
253 | captcha = self._get_captcha_data() |
|
254 | captcha = self._get_captcha_data() | |
254 | auto_active = 'hg.register.auto_activate' in User.get_default_user()\ |
|
255 | auto_active = 'hg.register.auto_activate' in User.get_default_user()\ | |
255 | .AuthUser().permissions['global'] |
|
256 | .AuthUser().permissions['global'] | |
@@ -275,10 +276,10 b' class LoginView(BaseAppView):' | |||||
275 |
|
276 | |||
276 | new_user = UserModel().create_registration(form_result) |
|
277 | new_user = UserModel().create_registration(form_result) | |
277 | event = UserRegistered(user=new_user, session=self.session) |
|
278 | event = UserRegistered(user=new_user, session=self.session) | |
278 |
|
|
279 | trigger(event) | |
279 |
|
|
280 | h.flash( | |
280 | _('You have successfully registered with RhodeCode'), |
|
281 | _('You have successfully registered with RhodeCode'), | |
281 |
|
|
282 | category='success') | |
282 | Session().commit() |
|
283 | Session().commit() | |
283 |
|
284 | |||
284 | redirect_ro = self.request.route_path('login') |
|
285 | redirect_ro = self.request.route_path('login') | |
@@ -295,16 +296,17 b' class LoginView(BaseAppView):' | |||||
295 | # the fly can throw this exception signaling that there's issue |
|
296 | # the fly can throw this exception signaling that there's issue | |
296 | # with user creation, explanation should be provided in |
|
297 | # with user creation, explanation should be provided in | |
297 | # Exception itself |
|
298 | # Exception itself | |
298 |
|
|
299 | h.flash(e, category='error') | |
299 | return self.register() |
|
300 | return self.register() | |
300 |
|
301 | |||
301 | @view_config( |
|
302 | @view_config( | |
302 | route_name='reset_password', request_method=('GET', 'POST'), |
|
303 | route_name='reset_password', request_method=('GET', 'POST'), | |
303 | renderer='rhodecode:templates/password_reset.mako') |
|
304 | renderer='rhodecode:templates/password_reset.mako') | |
304 | def password_reset(self): |
|
305 | def password_reset(self): | |
|
306 | c = self.load_default_context() | |||
305 | captcha = self._get_captcha_data() |
|
307 | captcha = self._get_captcha_data() | |
306 |
|
308 | |||
307 |
|
|
309 | template_context = { | |
308 | 'captcha_active': captcha.active, |
|
310 | 'captcha_active': captcha.active, | |
309 | 'captcha_public_key': captcha.public_key, |
|
311 | 'captcha_public_key': captcha.public_key, | |
310 | 'defaults': {}, |
|
312 | 'defaults': {}, | |
@@ -319,8 +321,8 b' class LoginView(BaseAppView):' | |||||
319 | if h.HasPermissionAny('hg.password_reset.disabled')(): |
|
321 | if h.HasPermissionAny('hg.password_reset.disabled')(): | |
320 | _email = self.request.POST.get('email', '') |
|
322 | _email = self.request.POST.get('email', '') | |
321 | log.error('Failed attempt to reset password for `%s`.', _email) |
|
323 | log.error('Failed attempt to reset password for `%s`.', _email) | |
322 |
|
|
324 | h.flash(_('Password reset has been disabled.'), | |
323 |
|
|
325 | category='error') | |
324 | return HTTPFound(self.request.route_path('reset_password')) |
|
326 | return HTTPFound(self.request.route_path('reset_password')) | |
325 |
|
327 | |||
326 | password_reset_form = PasswordResetForm(self.request.translate)() |
|
328 | password_reset_form = PasswordResetForm(self.request.translate)() | |
@@ -361,7 +363,7 b' class LoginView(BaseAppView):' | |||||
361 | UserModel().reset_password_link( |
|
363 | UserModel().reset_password_link( | |
362 | form_result, password_reset_url) |
|
364 | form_result, password_reset_url) | |
363 | # Display success message and redirect. |
|
365 | # Display success message and redirect. | |
364 |
|
|
366 | h.flash(msg, category='success') | |
365 |
|
367 | |||
366 | action_data = {'email': user_email, |
|
368 | action_data = {'email': user_email, | |
367 | 'user_agent': self.request.user_agent} |
|
369 | 'user_agent': self.request.user_agent} | |
@@ -371,30 +373,30 b' class LoginView(BaseAppView):' | |||||
371 | return HTTPFound(self.request.route_path('reset_password')) |
|
373 | return HTTPFound(self.request.route_path('reset_password')) | |
372 |
|
374 | |||
373 | except formencode.Invalid as errors: |
|
375 | except formencode.Invalid as errors: | |
374 |
|
|
376 | template_context.update({ | |
375 | 'defaults': errors.value, |
|
377 | 'defaults': errors.value, | |
376 | 'errors': errors.error_dict, |
|
378 | 'errors': errors.error_dict, | |
377 | }) |
|
379 | }) | |
378 | if not self.request.POST.get('email'): |
|
380 | if not self.request.POST.get('email'): | |
379 | # case of empty email, we want to report that |
|
381 | # case of empty email, we want to report that | |
380 | return render_ctx |
|
382 | return self._get_template_context(c, **template_context) | |
381 |
|
383 | |||
382 | if 'recaptcha_field' in errors.error_dict: |
|
384 | if 'recaptcha_field' in errors.error_dict: | |
383 | # case of failed captcha |
|
385 | # case of failed captcha | |
384 | return render_ctx |
|
386 | return self._get_template_context(c, **template_context) | |
385 |
|
387 | |||
386 | log.debug('faking response on invalid password reset') |
|
388 | log.debug('faking response on invalid password reset') | |
387 | # make this take 2s, to prevent brute forcing. |
|
389 | # make this take 2s, to prevent brute forcing. | |
388 | time.sleep(2) |
|
390 | time.sleep(2) | |
389 |
|
|
391 | h.flash(msg, category='success') | |
390 | return HTTPFound(self.request.route_path('reset_password')) |
|
392 | return HTTPFound(self.request.route_path('reset_password')) | |
391 |
|
393 | |||
392 | return render_ctx |
|
394 | return self._get_template_context(c, **template_context) | |
393 |
|
395 | |||
394 | @view_config(route_name='reset_password_confirmation', |
|
396 | @view_config(route_name='reset_password_confirmation', | |
395 | request_method='GET') |
|
397 | request_method='GET') | |
396 | def password_reset_confirmation(self): |
|
398 | def password_reset_confirmation(self): | |
397 |
|
399 | self.load_default_context() | ||
398 | if self.request.GET and self.request.GET.get('key'): |
|
400 | if self.request.GET and self.request.GET.get('key'): | |
399 | # make this take 2s, to prevent brute forcing. |
|
401 | # make this take 2s, to prevent brute forcing. | |
400 | time.sleep(2) |
|
402 | time.sleep(2) | |
@@ -407,18 +409,18 b' class LoginView(BaseAppView):' | |||||
407 | log.debug('Got token with role:%s expected is %s', |
|
409 | log.debug('Got token with role:%s expected is %s', | |
408 | getattr(token, 'role', 'EMPTY_TOKEN'), |
|
410 | getattr(token, 'role', 'EMPTY_TOKEN'), | |
409 | UserApiKeys.ROLE_PASSWORD_RESET) |
|
411 | UserApiKeys.ROLE_PASSWORD_RESET) | |
410 |
|
|
412 | h.flash( | |
411 |
_('Given reset token is invalid'), |
|
413 | _('Given reset token is invalid'), category='error') | |
412 | return HTTPFound(self.request.route_path('reset_password')) |
|
414 | return HTTPFound(self.request.route_path('reset_password')) | |
413 |
|
415 | |||
414 | try: |
|
416 | try: | |
415 | owner = token.user |
|
417 | owner = token.user | |
416 | data = {'email': owner.email, 'token': token.api_key} |
|
418 | data = {'email': owner.email, 'token': token.api_key} | |
417 | UserModel().reset_password(data) |
|
419 | UserModel().reset_password(data) | |
418 |
|
|
420 | h.flash( | |
419 | _('Your password reset was successful, ' |
|
421 | _('Your password reset was successful, ' | |
420 | 'a new password has been sent to your email'), |
|
422 | 'a new password has been sent to your email'), | |
421 |
|
|
423 | category='success') | |
422 | except Exception as e: |
|
424 | except Exception as e: | |
423 | log.error(e) |
|
425 | log.error(e) | |
424 | return HTTPFound(self.request.route_path('reset_password')) |
|
426 | return HTTPFound(self.request.route_path('reset_password')) |
@@ -198,6 +198,6 b' class TestMyAccountEdit(TestController):' | |||||
198 | params=params) |
|
198 | params=params) | |
199 |
|
199 | |||
200 | response.mustcontain('An email address must contain a single @') |
|
200 | response.mustcontain('An email address must contain a single @') | |
201 | msg = '???' |
|
201 | msg = u'Username "%(username)s" already exists' | |
202 | msg = h.html_escape(msg % {'username': 'test_admin'}) |
|
202 | msg = h.html_escape(msg % {'username': 'test_admin'}) | |
203 | response.mustcontain(u"%s" % msg) |
|
203 | response.mustcontain(u"%s" % msg) |
@@ -572,6 +572,7 b' class MyAccountView(BaseAppView, DataGri' | |||||
572 | route_name='my_account_pullrequests_data', |
|
572 | route_name='my_account_pullrequests_data', | |
573 | request_method='GET', renderer='json_ext') |
|
573 | request_method='GET', renderer='json_ext') | |
574 | def my_account_pullrequests_data(self): |
|
574 | def my_account_pullrequests_data(self): | |
|
575 | self.load_default_context() | |||
575 | req_get = self.request.GET |
|
576 | req_get = self.request.GET | |
576 | closed = str2bool(req_get.get('closed')) |
|
577 | closed = str2bool(req_get.get('closed')) | |
577 |
|
578 |
@@ -48,6 +48,7 b' def route_path(name, params=None, **kwar' | |||||
48 | import urllib |
|
48 | import urllib | |
49 |
|
49 | |||
50 | base_url = { |
|
50 | base_url = { | |
|
51 | 'repo_summary': '/{repo_name}', | |||
51 | 'repo_archivefile': '/{repo_name}/archive/{fname}', |
|
52 | 'repo_archivefile': '/{repo_name}/archive/{fname}', | |
52 | 'repo_files_diff': '/{repo_name}/diff/{f_path}', |
|
53 | 'repo_files_diff': '/{repo_name}/diff/{f_path}', | |
53 | 'repo_files_diff_2way_redirect': '/{repo_name}/diff-2way/{f_path}', |
|
54 | 'repo_files_diff_2way_redirect': '/{repo_name}/diff-2way/{f_path}', | |
@@ -999,8 +1000,11 b' class TestFilesViewOtherCases(object):' | |||||
999 | .format(repo_file_add_url)) |
|
1000 | .format(repo_file_add_url)) | |
1000 |
|
1001 | |||
1001 | def test_access_empty_repo_redirect_to_summary_with_alert_no_write_perms( |
|
1002 | def test_access_empty_repo_redirect_to_summary_with_alert_no_write_perms( | |
1002 |
self, backend_stub, |
|
1003 | self, backend_stub, autologin_regular_user): | |
1003 | repo = backend_stub.create_repo() |
|
1004 | repo = backend_stub.create_repo() | |
|
1005 | # init session for anon user | |||
|
1006 | route_path('repo_summary', repo_name=repo.repo_name) | |||
|
1007 | ||||
1004 | repo_file_add_url = route_path( |
|
1008 | repo_file_add_url = route_path( | |
1005 | 'repo_files_add_file', |
|
1009 | 'repo_files_add_file', | |
1006 | repo_name=repo.repo_name, |
|
1010 | repo_name=repo.repo_name, |
@@ -53,11 +53,11 b' class RepoForksView(RepoAppView, DataGri' | |||||
53 | perm_set=['group.write', 'group.admin']) |
|
53 | perm_set=['group.write', 'group.admin']) | |
54 | c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) |
|
54 | c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) | |
55 | c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups) |
|
55 | c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups) | |
56 |
choices, c.landing_revs = ScmModel().get_repo_landing_revs( |
|
56 | choices, c.landing_revs = ScmModel().get_repo_landing_revs( | |
|
57 | self.request.translate) | |||
57 | c.landing_revs_choices = choices |
|
58 | c.landing_revs_choices = choices | |
58 | c.personal_repo_group = c.rhodecode_user.personal_repo_group |
|
59 | c.personal_repo_group = c.rhodecode_user.personal_repo_group | |
59 |
|
60 | |||
60 |
|
||||
61 | return c |
|
61 | return c | |
62 |
|
62 | |||
63 | @LoginRequired() |
|
63 | @LoginRequired() | |
@@ -78,6 +78,7 b' class RepoForksView(RepoAppView, DataGri' | |||||
78 | renderer='json_ext', xhr=True) |
|
78 | renderer='json_ext', xhr=True) | |
79 | def repo_forks_data(self): |
|
79 | def repo_forks_data(self): | |
80 | _ = self.request.translate |
|
80 | _ = self.request.translate | |
|
81 | self.load_default_context() | |||
81 | column_map = { |
|
82 | column_map = { | |
82 | 'fork_name': 'repo_name', |
|
83 | 'fork_name': 'repo_name', | |
83 | 'fork_date': 'created_on', |
|
84 | 'fork_date': 'created_on', |
@@ -173,6 +173,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
173 | route_name='pullrequest_show_all_data', request_method='GET', |
|
173 | route_name='pullrequest_show_all_data', request_method='GET', | |
174 | renderer='json_ext', xhr=True) |
|
174 | renderer='json_ext', xhr=True) | |
175 | def pull_request_list_data(self): |
|
175 | def pull_request_list_data(self): | |
|
176 | self.load_default_context() | |||
176 |
|
177 | |||
177 | # additional filters |
|
178 | # additional filters | |
178 | req_get = self.request.GET |
|
179 | req_get = self.request.GET | |
@@ -675,6 +676,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
675 | route_name='pullrequest_repo_refs', request_method='GET', |
|
676 | route_name='pullrequest_repo_refs', request_method='GET', | |
676 | renderer='json_ext', xhr=True) |
|
677 | renderer='json_ext', xhr=True) | |
677 | def pull_request_repo_refs(self): |
|
678 | def pull_request_repo_refs(self): | |
|
679 | self.load_default_context() | |||
678 | target_repo_name = self.request.matchdict['target_repo_name'] |
|
680 | target_repo_name = self.request.matchdict['target_repo_name'] | |
679 | repo = Repository.get_by_repo_name(target_repo_name) |
|
681 | repo = Repository.get_by_repo_name(target_repo_name) | |
680 | if not repo: |
|
682 | if not repo: | |
@@ -745,6 +747,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
745 | def pull_request_create(self): |
|
747 | def pull_request_create(self): | |
746 | _ = self.request.translate |
|
748 | _ = self.request.translate | |
747 | self.assure_not_empty_repo() |
|
749 | self.assure_not_empty_repo() | |
|
750 | self.load_default_context() | |||
748 |
|
751 | |||
749 | controls = peppercorn.parse(self.request.POST.items()) |
|
752 | controls = peppercorn.parse(self.request.POST.items()) | |
750 |
|
753 | |||
@@ -878,6 +881,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
878 | pull_request = PullRequest.get_or_404( |
|
881 | pull_request = PullRequest.get_or_404( | |
879 | self.request.matchdict['pull_request_id']) |
|
882 | self.request.matchdict['pull_request_id']) | |
880 |
|
883 | |||
|
884 | self.load_default_context() | |||
881 | # only owner or admin can update it |
|
885 | # only owner or admin can update it | |
882 | allowed_to_update = PullRequestModel().check_user_update( |
|
886 | allowed_to_update = PullRequestModel().check_user_update( | |
883 | pull_request, self._rhodecode_user) |
|
887 | pull_request, self._rhodecode_user) | |
@@ -976,6 +980,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
976 | pull_request = PullRequest.get_or_404( |
|
980 | pull_request = PullRequest.get_or_404( | |
977 | self.request.matchdict['pull_request_id']) |
|
981 | self.request.matchdict['pull_request_id']) | |
978 |
|
982 | |||
|
983 | self.load_default_context() | |||
979 | check = MergeCheck.validate(pull_request, self._rhodecode_db_user, |
|
984 | check = MergeCheck.validate(pull_request, self._rhodecode_db_user, | |
980 | translator=self.request.translate) |
|
985 | translator=self.request.translate) | |
981 | merge_possible = not check.failed |
|
986 | merge_possible = not check.failed | |
@@ -1048,6 +1053,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1048 |
|
1053 | |||
1049 | pull_request = PullRequest.get_or_404( |
|
1054 | pull_request = PullRequest.get_or_404( | |
1050 | self.request.matchdict['pull_request_id']) |
|
1055 | self.request.matchdict['pull_request_id']) | |
|
1056 | self.load_default_context() | |||
1051 |
|
1057 | |||
1052 | pr_closed = pull_request.is_closed() |
|
1058 | pr_closed = pull_request.is_closed() | |
1053 | allowed_to_delete = PullRequestModel().check_user_delete( |
|
1059 | allowed_to_delete = PullRequestModel().check_user_delete( |
@@ -62,10 +62,11 b' class RepoSettingsView(RepoAppView):' | |||||
62 | # we might be in missing requirement state, so we load things |
|
62 | # we might be in missing requirement state, so we load things | |
63 | # without touching scm_instance() |
|
63 | # without touching scm_instance() | |
64 | c.landing_revs_choices, c.landing_revs = \ |
|
64 | c.landing_revs_choices, c.landing_revs = \ | |
65 | ScmModel().get_repo_landing_revs() |
|
65 | ScmModel().get_repo_landing_revs(self.request.translate) | |
66 | else: |
|
66 | else: | |
67 | c.landing_revs_choices, c.landing_revs = \ |
|
67 | c.landing_revs_choices, c.landing_revs = \ | |
68 |
ScmModel().get_repo_landing_revs( |
|
68 | ScmModel().get_repo_landing_revs( | |
|
69 | self.request.translate, self.db_repo) | |||
69 |
|
70 | |||
70 | c.personal_repo_group = c.auth_user.personal_repo_group |
|
71 | c.personal_repo_group = c.auth_user.personal_repo_group | |
71 | c.repo_fields = RepositoryField.query()\ |
|
72 | c.repo_fields = RepositoryField.query()\ |
@@ -428,7 +428,7 b' class UserGroupsView(UserGroupAppView):' | |||||
428 |
|
428 | |||
429 | try: |
|
429 | try: | |
430 | # first stage that verifies the checkbox |
|
430 | # first stage that verifies the checkbox | |
431 | _form = UserIndividualPermissionsForm() |
|
431 | _form = UserIndividualPermissionsForm(self.request.translate) | |
432 | form_result = _form.to_python(dict(self.request.POST)) |
|
432 | form_result = _form.to_python(dict(self.request.POST)) | |
433 | inherit_perms = form_result['inherit_default_permissions'] |
|
433 | inherit_perms = form_result['inherit_default_permissions'] | |
434 | user_group.inherit_default_permissions = inherit_perms |
|
434 | user_group.inherit_default_permissions = inherit_perms |
@@ -74,9 +74,6 b' def load_pyramid_environment(global_conf' | |||||
74 | # Initialize the database connection. |
|
74 | # Initialize the database connection. | |
75 | utils.initialize_database(settings_merged) |
|
75 | utils.initialize_database(settings_merged) | |
76 |
|
76 | |||
77 | # TODO(marcink): base_path handling ? |
|
|||
78 | # repos_path = list(db_cfg.items('paths'))[0][1] |
|
|||
79 |
|
||||
80 | load_rcextensions(root_path=settings_merged['here']) |
|
77 | load_rcextensions(root_path=settings_merged['here']) | |
81 |
|
78 | |||
82 | # Limit backends to `vcs.backends` from configuration |
|
79 | # Limit backends to `vcs.backends` from configuration |
@@ -29,7 +29,6 b' import socket' | |||||
29 |
|
29 | |||
30 | import markupsafe |
|
30 | import markupsafe | |
31 | import ipaddress |
|
31 | import ipaddress | |
32 | import pyramid.threadlocal |
|
|||
33 |
|
32 | |||
34 | from paste.auth.basic import AuthBasicAuthenticator |
|
33 | from paste.auth.basic import AuthBasicAuthenticator | |
35 | from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden, get_exception |
|
34 | from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden, get_exception | |
@@ -41,15 +40,11 b' from rhodecode.lib import auth, utils2' | |||||
41 | from rhodecode.lib import helpers as h |
|
40 | from rhodecode.lib import helpers as h | |
42 | from rhodecode.lib.auth import AuthUser, CookieStoreWrapper |
|
41 | from rhodecode.lib.auth import AuthUser, CookieStoreWrapper | |
43 | from rhodecode.lib.exceptions import UserCreationError |
|
42 | from rhodecode.lib.exceptions import UserCreationError | |
44 | from rhodecode.lib.utils import ( |
|
43 | from rhodecode.lib.utils import (password_changed, get_enabled_hook_classes) | |
45 | get_repo_slug, set_rhodecode_config, password_changed, |
|
|||
46 | get_enabled_hook_classes) |
|
|||
47 | from rhodecode.lib.utils2 import ( |
|
44 | from rhodecode.lib.utils2 import ( | |
48 | str2bool, safe_unicode, AttributeDict, safe_int, md5, aslist, safe_str) |
|
45 | str2bool, safe_unicode, AttributeDict, safe_int, md5, aslist, safe_str) | |
49 | from rhodecode.model import meta |
|
|||
50 | from rhodecode.model.db import Repository, User, ChangesetComment |
|
46 | from rhodecode.model.db import Repository, User, ChangesetComment | |
51 | from rhodecode.model.notification import NotificationModel |
|
47 | from rhodecode.model.notification import NotificationModel | |
52 | from rhodecode.model.scm import ScmModel |
|
|||
53 | from rhodecode.model.settings import VcsSettingsModel, SettingsModel |
|
48 | from rhodecode.model.settings import VcsSettingsModel, SettingsModel | |
54 |
|
49 | |||
55 | log = logging.getLogger(__name__) |
|
50 | log = logging.getLogger(__name__) | |
@@ -440,6 +435,8 b' def get_auth_user(request):' | |||||
440 | # AuthUser |
|
435 | # AuthUser | |
441 | auth_user = AuthUser(ip_addr=ip_addr) |
|
436 | auth_user = AuthUser(ip_addr=ip_addr) | |
442 |
|
437 | |||
|
438 | # in case someone changes a password for user it triggers session | |||
|
439 | # flush and forces a re-login | |||
443 | if password_changed(auth_user, session): |
|
440 | if password_changed(auth_user, session): | |
444 | session.invalidate() |
|
441 | session.invalidate() | |
445 | cookie_store = CookieStoreWrapper(session.get('rhodecode_user')) |
|
442 | cookie_store = CookieStoreWrapper(session.get('rhodecode_user')) |
@@ -23,19 +23,15 b'' | |||||
23 | Set of diffing helpers, previously part of vcs |
|
23 | Set of diffing helpers, previously part of vcs | |
24 | """ |
|
24 | """ | |
25 |
|
25 | |||
|
26 | import re | |||
26 | import collections |
|
27 | import collections | |
27 | import re |
|
|||
28 | import difflib |
|
28 | import difflib | |
29 | import logging |
|
29 | import logging | |
30 |
|
30 | |||
31 | from itertools import tee, imap |
|
31 | from itertools import tee, imap | |
32 |
|
32 | |||
33 | from rhodecode.translation import temp_translation_factory as _ |
|
|||
34 |
|
||||
35 | from rhodecode.lib.vcs.exceptions import VCSError |
|
33 | from rhodecode.lib.vcs.exceptions import VCSError | |
36 | from rhodecode.lib.vcs.nodes import FileNode, SubModuleNode |
|
34 | from rhodecode.lib.vcs.nodes import FileNode, SubModuleNode | |
37 | from rhodecode.lib.vcs.backends.base import EmptyCommit |
|
|||
38 | from rhodecode.lib.helpers import escape |
|
|||
39 | from rhodecode.lib.utils2 import safe_unicode |
|
35 | from rhodecode.lib.utils2 import safe_unicode | |
40 |
|
36 | |||
41 | log = logging.getLogger(__name__) |
|
37 | log = logging.getLogger(__name__) | |
@@ -51,69 +47,6 b' class OPS(object):' | |||||
51 | DEL = 'D' |
|
47 | DEL = 'D' | |
52 |
|
48 | |||
53 |
|
49 | |||
54 | def wrap_to_table(str_): |
|
|||
55 | return '''<table class="code-difftable"> |
|
|||
56 | <tr class="line no-comment"> |
|
|||
57 | <td class="add-comment-line tooltip" title="%s"><span class="add-comment-content"></span></td> |
|
|||
58 | <td></td> |
|
|||
59 | <td class="lineno new"></td> |
|
|||
60 | <td class="code no-comment"><pre>%s</pre></td> |
|
|||
61 | </tr> |
|
|||
62 | </table>''' % (_('Click to comment'), str_) |
|
|||
63 |
|
||||
64 |
|
||||
65 | def wrapped_diff(filenode_old, filenode_new, diff_limit=None, file_limit=None, |
|
|||
66 | show_full_diff=False, ignore_whitespace=True, line_context=3, |
|
|||
67 | enable_comments=False): |
|
|||
68 | """ |
|
|||
69 | returns a wrapped diff into a table, checks for cut_off_limit for file and |
|
|||
70 | whole diff and presents proper message |
|
|||
71 | """ |
|
|||
72 |
|
||||
73 | if filenode_old is None: |
|
|||
74 | filenode_old = FileNode(filenode_new.path, '', EmptyCommit()) |
|
|||
75 |
|
||||
76 | if filenode_old.is_binary or filenode_new.is_binary: |
|
|||
77 | diff = wrap_to_table(_('Binary file')) |
|
|||
78 | stats = None |
|
|||
79 | size = 0 |
|
|||
80 | data = None |
|
|||
81 |
|
||||
82 | elif diff_limit != -1 and (diff_limit is None or |
|
|||
83 | (filenode_old.size < diff_limit and filenode_new.size < diff_limit)): |
|
|||
84 |
|
||||
85 | f_gitdiff = get_gitdiff(filenode_old, filenode_new, |
|
|||
86 | ignore_whitespace=ignore_whitespace, |
|
|||
87 | context=line_context) |
|
|||
88 | diff_processor = DiffProcessor( |
|
|||
89 | f_gitdiff, format='gitdiff', diff_limit=diff_limit, |
|
|||
90 | file_limit=file_limit, show_full_diff=show_full_diff) |
|
|||
91 | _parsed = diff_processor.prepare() |
|
|||
92 |
|
||||
93 | diff = diff_processor.as_html(enable_comments=enable_comments) |
|
|||
94 | stats = _parsed[0]['stats'] if _parsed else None |
|
|||
95 | size = len(diff or '') |
|
|||
96 | data = _parsed[0] if _parsed else None |
|
|||
97 | else: |
|
|||
98 | diff = wrap_to_table(_('Changeset was too big and was cut off, use ' |
|
|||
99 | 'diff menu to display this diff')) |
|
|||
100 | stats = None |
|
|||
101 | size = 0 |
|
|||
102 | data = None |
|
|||
103 | if not diff: |
|
|||
104 | submodules = filter(lambda o: isinstance(o, SubModuleNode), |
|
|||
105 | [filenode_new, filenode_old]) |
|
|||
106 | if submodules: |
|
|||
107 | diff = wrap_to_table(escape('Submodule %r' % submodules[0])) |
|
|||
108 | else: |
|
|||
109 | diff = wrap_to_table(_('No changes detected')) |
|
|||
110 |
|
||||
111 | cs1 = filenode_old.commit.raw_id |
|
|||
112 | cs2 = filenode_new.commit.raw_id |
|
|||
113 |
|
||||
114 | return size, cs1, cs2, diff, stats, data |
|
|||
115 |
|
||||
116 |
|
||||
117 | def get_gitdiff(filenode_old, filenode_new, ignore_whitespace=True, context=3): |
|
50 | def get_gitdiff(filenode_old, filenode_new, ignore_whitespace=True, context=3): | |
118 | """ |
|
51 | """ | |
119 | Returns git style diff between given ``filenode_old`` and ``filenode_new``. |
|
52 | Returns git style diff between given ``filenode_old`` and ``filenode_new``. | |
@@ -916,6 +849,10 b' class DiffProcessor(object):' | |||||
916 | """ |
|
849 | """ | |
917 | Return given diff as html table with customized css classes |
|
850 | Return given diff as html table with customized css classes | |
918 | """ |
|
851 | """ | |
|
852 | # TODO(marcink): not sure how to pass in translator | |||
|
853 | # here in an efficient way, leave the _ for proper gettext extraction | |||
|
854 | _ = lambda s: s | |||
|
855 | ||||
919 | def _link_to_if(condition, label, url): |
|
856 | def _link_to_if(condition, label, url): | |
920 | """ |
|
857 | """ | |
921 | Generates a link if condition is meet or just the label if not. |
|
858 | Generates a link if condition is meet or just the label if not. |
@@ -51,7 +51,7 b' def _obj_dump(obj):' | |||||
51 | return str(obj) |
|
51 | return str(obj) | |
52 | elif isinstance(obj, complex): |
|
52 | elif isinstance(obj, complex): | |
53 | return [obj.real, obj.imag] |
|
53 | return [obj.real, obj.imag] | |
54 | elif rhodecode and isinstance(obj, rhodecode.translation.LazyString): |
|
54 | elif rhodecode and isinstance(obj, rhodecode.translation._LazyString): | |
55 | return obj.eval() |
|
55 | return obj.eval() | |
56 | else: |
|
56 | else: | |
57 | raise TypeError(repr(obj) + " is not JSON serializable") |
|
57 | raise TypeError(repr(obj) + " is not JSON serializable") |
@@ -1929,12 +1929,12 b' def secure_form(form_url, method="POST",' | |||||
1929 | """ |
|
1929 | """ | |
1930 | from webhelpers.pylonslib.secure_form import insecure_form |
|
1930 | from webhelpers.pylonslib.secure_form import insecure_form | |
1931 |
|
1931 | |||
1932 | session = None |
|
|||
1933 |
|
||||
1934 | # TODO(marcink): after pyramid migration require request variable ALWAYS |
|
|||
1935 | if 'request' in attrs: |
|
1932 | if 'request' in attrs: | |
1936 | session = attrs['request'].session |
|
1933 | session = attrs['request'].session | |
1937 | del attrs['request'] |
|
1934 | del attrs['request'] | |
|
1935 | else: | |||
|
1936 | raise ValueError( | |||
|
1937 | 'Calling this form requires request= to be passed as argument') | |||
1938 |
|
1938 | |||
1939 | form = insecure_form(form_url, method, multipart, **attrs) |
|
1939 | form = insecure_form(form_url, method, multipart, **attrs) | |
1940 | token = literal( |
|
1940 | token = literal( |
@@ -23,19 +23,18 b' Index schema for RhodeCode' | |||||
23 | """ |
|
23 | """ | |
24 |
|
24 | |||
25 | from __future__ import absolute_import |
|
25 | from __future__ import absolute_import | |
26 | import logging |
|
|||
27 | import os |
|
26 | import os | |
28 | import re |
|
27 | import re | |
|
28 | import logging | |||
29 |
|
29 | |||
30 | from rhodecode.translation import temp_translation_factory as _ |
|
30 | from whoosh import query as query_lib | |
31 |
|
||||
32 | from whoosh import query as query_lib, sorting |
|
|||
33 | from whoosh.highlight import HtmlFormatter, ContextFragmenter |
|
31 | from whoosh.highlight import HtmlFormatter, ContextFragmenter | |
34 | from whoosh.index import create_in, open_dir, exists_in, EmptyIndexError |
|
32 | from whoosh.index import create_in, open_dir, exists_in, EmptyIndexError | |
35 | from whoosh.qparser import QueryParser, QueryParserError |
|
33 | from whoosh.qparser import QueryParser, QueryParserError | |
36 |
|
34 | |||
37 | import rhodecode.lib.helpers as h |
|
35 | import rhodecode.lib.helpers as h | |
38 | from rhodecode.lib.index import BaseSearch |
|
36 | from rhodecode.lib.index import BaseSearch | |
|
37 | from rhodecode.lib.utils2 import safe_unicode | |||
39 |
|
38 | |||
40 | log = logging.getLogger(__name__) |
|
39 | log = logging.getLogger(__name__) | |
41 |
|
40 | |||
@@ -122,7 +121,7 b' class Search(BaseSearch):' | |||||
122 | allowed_repos_filter = self._get_repo_filter( |
|
121 | allowed_repos_filter = self._get_repo_filter( | |
123 | search_user, repo_name) |
|
122 | search_user, repo_name) | |
124 | try: |
|
123 | try: | |
125 | query = qp.parse(unicode(query)) |
|
124 | query = qp.parse(safe_unicode(query)) | |
126 | log.debug('query: %s (%s)' % (query, repr(query))) |
|
125 | log.debug('query: %s (%s)' % (query, repr(query))) | |
127 |
|
126 | |||
128 | reverse, sortedby = False, None |
|
127 | reverse, sortedby = False, None | |
@@ -147,20 +146,20 b' class Search(BaseSearch):' | |||||
147 | search_type, res_ln, whoosh_results) |
|
146 | search_type, res_ln, whoosh_results) | |
148 |
|
147 | |||
149 | except QueryParserError: |
|
148 | except QueryParserError: | |
150 |
result['error'] = |
|
149 | result['error'] = 'Invalid search query. Try quoting it.' | |
151 | except (EmptyIndexError, IOError, OSError): |
|
150 | except (EmptyIndexError, IOError, OSError): | |
152 |
msg = |
|
151 | msg = 'There is no index to search in. Please run whoosh indexer' | |
153 | 'Please run whoosh indexer') |
|
|||
154 | log.exception(msg) |
|
152 | log.exception(msg) | |
155 | result['error'] = msg |
|
153 | result['error'] = msg | |
156 | except Exception: |
|
154 | except Exception: | |
157 |
msg = |
|
155 | msg = 'An error occurred during this search operation' | |
158 | log.exception(msg) |
|
156 | log.exception(msg) | |
159 | result['error'] = msg |
|
157 | result['error'] = msg | |
160 |
|
158 | |||
161 | return result |
|
159 | return result | |
162 |
|
160 | |||
163 | def statistics(self): |
|
161 | def statistics(self, translator): | |
|
162 | _ = translator | |||
164 | stats = [ |
|
163 | stats = [ | |
165 | {'key': _('Index Type'), 'value': 'Whoosh'}, |
|
164 | {'key': _('Index Type'), 'value': 'Whoosh'}, | |
166 | {'key': _('File Index'), 'value': str(self.file_index)}, |
|
165 | {'key': _('File Index'), 'value': str(self.file_index)}, |
@@ -796,11 +796,11 b' def suuid(url=None, truncate_to=22, alph' | |||||
796 | return "".join(output)[:truncate_to] |
|
796 | return "".join(output)[:truncate_to] | |
797 |
|
797 | |||
798 |
|
798 | |||
799 | def get_current_rhodecode_user(): |
|
799 | def get_current_rhodecode_user(request=None): | |
800 | """ |
|
800 | """ | |
801 | Gets rhodecode user from request |
|
801 | Gets rhodecode user from request | |
802 | """ |
|
802 | """ | |
803 | pyramid_request = pyramid.threadlocal.get_current_request() |
|
803 | pyramid_request = request or pyramid.threadlocal.get_current_request() | |
804 |
|
804 | |||
805 | # web case |
|
805 | # web case | |
806 | if pyramid_request and hasattr(pyramid_request, 'user'): |
|
806 | if pyramid_request and hasattr(pyramid_request, 'user'): |
@@ -48,7 +48,6 b' import formencode' | |||||
48 | from pkg_resources import resource_filename |
|
48 | from pkg_resources import resource_filename | |
49 | from formencode import All, Pipe |
|
49 | from formencode import All, Pipe | |
50 |
|
50 | |||
51 | from rhodecode.translation import temp_translation_factory as _ |
|
|||
52 | from pyramid.threadlocal import get_current_request |
|
51 | from pyramid.threadlocal import get_current_request | |
53 |
|
52 | |||
54 | from rhodecode import BACKENDS |
|
53 | from rhodecode import BACKENDS |
@@ -30,7 +30,6 b' import logging' | |||||
30 | import cStringIO |
|
30 | import cStringIO | |
31 | import pkg_resources |
|
31 | import pkg_resources | |
32 |
|
32 | |||
33 | from rhodecode.translation import temp_translation_factory as _ |
|
|||
34 | from sqlalchemy import func |
|
33 | from sqlalchemy import func | |
35 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
34 | from zope.cachedescriptors.property import Lazy as LazyProperty | |
36 |
|
35 | |||
@@ -40,7 +39,6 b' from rhodecode.lib.vcs.exceptions import' | |||||
40 | from rhodecode.lib.vcs.nodes import FileNode |
|
39 | from rhodecode.lib.vcs.nodes import FileNode | |
41 | from rhodecode.lib.vcs.backends.base import EmptyCommit |
|
40 | from rhodecode.lib.vcs.backends.base import EmptyCommit | |
42 | from rhodecode.lib import helpers as h |
|
41 | from rhodecode.lib import helpers as h | |
43 |
|
||||
44 | from rhodecode.lib.auth import ( |
|
42 | from rhodecode.lib.auth import ( | |
45 | HasRepoPermissionAny, HasRepoGroupPermissionAny, |
|
43 | HasRepoPermissionAny, HasRepoGroupPermissionAny, | |
46 | HasUserGroupPermissionAny) |
|
44 | HasUserGroupPermissionAny) | |
@@ -748,14 +746,14 b' class ScmModel(BaseModel):' | |||||
748 | def get_unread_journal(self): |
|
746 | def get_unread_journal(self): | |
749 | return self.sa.query(UserLog).count() |
|
747 | return self.sa.query(UserLog).count() | |
750 |
|
748 | |||
751 | def get_repo_landing_revs(self, repo=None): |
|
749 | def get_repo_landing_revs(self, translator, repo=None): | |
752 | """ |
|
750 | """ | |
753 | Generates select option with tags branches and bookmarks (for hg only) |
|
751 | Generates select option with tags branches and bookmarks (for hg only) | |
754 | grouped by type |
|
752 | grouped by type | |
755 |
|
753 | |||
756 | :param repo: |
|
754 | :param repo: | |
757 | """ |
|
755 | """ | |
758 |
|
756 | _ = translator | ||
759 | repo = self._get_repo(repo) |
|
757 | repo = self._get_repo(repo) | |
760 |
|
758 | |||
761 | hist_l = [ |
|
759 | hist_l = [ |
@@ -24,11 +24,10 b' users model for RhodeCode' | |||||
24 |
|
24 | |||
25 | import logging |
|
25 | import logging | |
26 | import traceback |
|
26 | import traceback | |
|
27 | import datetime | |||
|
28 | import ipaddress | |||
27 |
|
29 | |||
28 | import datetime |
|
30 | from pyramid.threadlocal import get_current_request | |
29 | from rhodecode.translation import temp_translation_factory as _ |
|
|||
30 |
|
||||
31 | import ipaddress |
|
|||
32 | from sqlalchemy.exc import DatabaseError |
|
31 | from sqlalchemy.exc import DatabaseError | |
33 |
|
32 | |||
34 | from rhodecode import events |
|
33 | from rhodecode import events | |
@@ -163,8 +162,9 b' class UserModel(BaseModel):' | |||||
163 | user = self._get_user(user) |
|
162 | user = self._get_user(user) | |
164 | if user.username == User.DEFAULT_USER: |
|
163 | if user.username == User.DEFAULT_USER: | |
165 | raise DefaultUserException( |
|
164 | raise DefaultUserException( | |
166 |
|
|
165 | "You can't edit this user (`%(username)s`) since it's " | |
167 |
|
|
166 | "crucial for entire application" % { | |
|
167 | 'username': user.username}) | |||
168 |
|
168 | |||
169 | # first store only defaults |
|
169 | # first store only defaults | |
170 | user_attrs = { |
|
170 | user_attrs = { | |
@@ -247,6 +247,7 b' class UserModel(BaseModel):' | |||||
247 |
|
247 | |||
248 | :returns: new User object with injected `is_new_user` attribute. |
|
248 | :returns: new User object with injected `is_new_user` attribute. | |
249 | """ |
|
249 | """ | |
|
250 | ||||
250 | if not cur_user: |
|
251 | if not cur_user: | |
251 | cur_user = getattr(get_current_rhodecode_user(), 'username', None) |
|
252 | cur_user = getattr(get_current_rhodecode_user(), 'username', None) | |
252 |
|
253 | |||
@@ -330,8 +331,9 b' class UserModel(BaseModel):' | |||||
330 | # we're not allowed to edit default user |
|
331 | # we're not allowed to edit default user | |
331 | if user.username == User.DEFAULT_USER: |
|
332 | if user.username == User.DEFAULT_USER: | |
332 | raise DefaultUserException( |
|
333 | raise DefaultUserException( | |
333 |
|
|
334 | "You can't edit this user (`%(username)s`) since it's " | |
334 |
|
|
335 | "crucial for entire application" | |
|
336 | % {'username': user.username}) | |||
335 |
|
337 | |||
336 | # inject special attribute that will tell us if User is new or old |
|
338 | # inject special attribute that will tell us if User is new or old | |
337 | new_user.is_new_user = not edit |
|
339 | new_user.is_new_user = not edit | |
@@ -497,40 +499,43 b' class UserModel(BaseModel):' | |||||
497 | def delete(self, user, cur_user=None, handle_repos=None, |
|
499 | def delete(self, user, cur_user=None, handle_repos=None, | |
498 | handle_repo_groups=None, handle_user_groups=None): |
|
500 | handle_repo_groups=None, handle_user_groups=None): | |
499 | if not cur_user: |
|
501 | if not cur_user: | |
500 | cur_user = getattr(get_current_rhodecode_user(), 'username', None) |
|
502 | cur_user = getattr( | |
|
503 | get_current_rhodecode_user(), 'username', None) | |||
501 | user = self._get_user(user) |
|
504 | user = self._get_user(user) | |
502 |
|
505 | |||
503 | try: |
|
506 | try: | |
504 | if user.username == User.DEFAULT_USER: |
|
507 | if user.username == User.DEFAULT_USER: | |
505 | raise DefaultUserException( |
|
508 | raise DefaultUserException( | |
506 |
|
|
509 | u"You can't remove this user since it's" | |
507 |
|
|
510 | u" crucial for entire application") | |
508 |
|
511 | |||
509 | left_overs = self._handle_user_repos( |
|
512 | left_overs = self._handle_user_repos( | |
510 | user.username, user.repositories, handle_repos) |
|
513 | user.username, user.repositories, handle_repos) | |
511 | if left_overs and user.repositories: |
|
514 | if left_overs and user.repositories: | |
512 | repos = [x.repo_name for x in user.repositories] |
|
515 | repos = [x.repo_name for x in user.repositories] | |
513 | raise UserOwnsReposException( |
|
516 | raise UserOwnsReposException( | |
514 |
|
|
517 | u'user "%(username)s" still owns %(len_repos)s repositories and cannot be ' | |
515 |
|
|
518 | u'removed. Switch owners or remove those repositories:%(list_repos)s' | |
516 |
% |
|
519 | % {'username': user.username, 'len_repos': len(repos), | |
|
520 | 'list_repos': ', '.join(repos)}) | |||
517 |
|
521 | |||
518 | left_overs = self._handle_user_repo_groups( |
|
522 | left_overs = self._handle_user_repo_groups( | |
519 | user.username, user.repository_groups, handle_repo_groups) |
|
523 | user.username, user.repository_groups, handle_repo_groups) | |
520 | if left_overs and user.repository_groups: |
|
524 | if left_overs and user.repository_groups: | |
521 | repo_groups = [x.group_name for x in user.repository_groups] |
|
525 | repo_groups = [x.group_name for x in user.repository_groups] | |
522 | raise UserOwnsRepoGroupsException( |
|
526 | raise UserOwnsRepoGroupsException( | |
523 |
|
|
527 | u'user "%(username)s" still owns %(len_repo_groups)s repository groups and cannot be ' | |
524 |
|
|
528 | u'removed. Switch owners or remove those repository groups:%(list_repo_groups)s' | |
525 |
% |
|
529 | % {'username': user.username, 'len_repo_groups': len(repo_groups), | |
|
530 | 'list_repo_groups': ', '.join(repo_groups)}) | |||
526 |
|
531 | |||
527 | left_overs = self._handle_user_user_groups( |
|
532 | left_overs = self._handle_user_user_groups( | |
528 | user.username, user.user_groups, handle_user_groups) |
|
533 | user.username, user.user_groups, handle_user_groups) | |
529 | if left_overs and user.user_groups: |
|
534 | if left_overs and user.user_groups: | |
530 | user_groups = [x.users_group_name for x in user.user_groups] |
|
535 | user_groups = [x.users_group_name for x in user.user_groups] | |
531 | raise UserOwnsUserGroupsException( |
|
536 | raise UserOwnsUserGroupsException( | |
532 |
|
|
537 | u'user "%s" still owns %s user groups and cannot be ' | |
533 |
|
|
538 | u'removed. Switch owners or remove those user groups:%s' | |
534 | % (user.username, len(user_groups), ', '.join(user_groups))) |
|
539 | % (user.username, len(user_groups), ', '.join(user_groups))) | |
535 |
|
540 | |||
536 | # we might change the user data with detach/delete, make sure |
|
541 | # we might change the user data with detach/delete, make sure |
@@ -37,7 +37,6 b' from formencode.validators import (' | |||||
37 |
|
37 | |||
38 | from sqlalchemy.sql.expression import true |
|
38 | from sqlalchemy.sql.expression import true | |
39 | from sqlalchemy.util import OrderedSet |
|
39 | from sqlalchemy.util import OrderedSet | |
40 | from webhelpers.pylonslib.secure_form import authentication_token |
|
|||
41 |
|
40 | |||
42 | from rhodecode.authentication import ( |
|
41 | from rhodecode.authentication import ( | |
43 | legacy_plugin_prefix, _import_legacy_plugin) |
|
42 | legacy_plugin_prefix, _import_legacy_plugin) | |
@@ -455,21 +454,6 b' def ValidAuth(localizer):' | |||||
455 | return _validator |
|
454 | return _validator | |
456 |
|
455 | |||
457 |
|
456 | |||
458 | def ValidAuthToken(localizer): |
|
|||
459 | _ = localizer |
|
|||
460 |
|
||||
461 | class _validator(formencode.validators.FancyValidator): |
|
|||
462 | messages = { |
|
|||
463 | 'invalid_token': _(u'Token mismatch') |
|
|||
464 | } |
|
|||
465 |
|
||||
466 | def validate_python(self, value, state): |
|
|||
467 | if value != authentication_token(): |
|
|||
468 | msg = M(self, 'invalid_token', state) |
|
|||
469 | raise formencode.Invalid(msg, value, state) |
|
|||
470 | return _validator |
|
|||
471 |
|
||||
472 |
|
||||
473 | def ValidRepoName(localizer, edit=False, old_data=None): |
|
457 | def ValidRepoName(localizer, edit=False, old_data=None): | |
474 | old_data = old_data or {} |
|
458 | old_data = old_data or {} | |
475 | _ = localizer |
|
459 | _ = localizer |
@@ -195,12 +195,6 b' def write_js_routes_if_enabled(event):' | |||||
195 | ) |
|
195 | ) | |
196 |
|
196 | |||
197 | def get_routes(): |
|
197 | def get_routes(): | |
198 | # pylons routes |
|
|||
199 | # TODO(marcink): remove when pyramid migration is finished |
|
|||
200 | if 'routes.map' in rhodecode.CONFIG: |
|
|||
201 | for route in rhodecode.CONFIG['routes.map'].jsroutes(): |
|
|||
202 | yield route |
|
|||
203 |
|
||||
204 | # pyramid routes |
|
198 | # pyramid routes | |
205 | for route in mapper.get_routes(): |
|
199 | for route in mapper.get_routes(): | |
206 | if not route.name.startswith('__'): |
|
200 | if not route.name.startswith('__'): |
@@ -85,7 +85,8 b' def _get_backend(backend_type):' | |||||
85 | class DBBackend(object): |
|
85 | class DBBackend(object): | |
86 | _store = os.path.dirname(os.path.abspath(__file__)) |
|
86 | _store = os.path.dirname(os.path.abspath(__file__)) | |
87 | _type = None |
|
87 | _type = None | |
88 |
_base_ini_config = [{'app:main': {'vcs.start_server': 'false' |
|
88 | _base_ini_config = [{'app:main': {'vcs.start_server': 'false', | |
|
89 | 'startup.import_repos': 'false'}}] | |||
89 | _db_url = [{'app:main': {'sqlalchemy.db1.url': ''}}] |
|
90 | _db_url = [{'app:main': {'sqlalchemy.db1.url': ''}}] | |
90 | _base_db_name = 'rhodecode_test_db_backend' |
|
91 | _base_db_name = 'rhodecode_test_db_backend' | |
91 |
|
92 | |||
@@ -183,7 +184,7 b' class DBBackend(object):' | |||||
183 | if not os.path.isdir(self._repos_location): |
|
184 | if not os.path.isdir(self._repos_location): | |
184 | os.makedirs(self._repos_location) |
|
185 | os.makedirs(self._repos_location) | |
185 | self.execute( |
|
186 | self.execute( | |
186 |
" |
|
187 | "rc-upgrade-db {0} --force-yes".format(ini_file)) | |
187 |
|
188 | |||
188 | def setup_db(self): |
|
189 | def setup_db(self): | |
189 | raise NotImplementedError |
|
190 | raise NotImplementedError |
@@ -56,11 +56,22 b' class TestSessionBehaviorOnPasswordChang' | |||||
56 |
|
56 | |||
57 | def test_sessions_invalidated_when_password_is_changed( |
|
57 | def test_sessions_invalidated_when_password_is_changed( | |
58 | self, app, autologin_user): |
|
58 | self, app, autologin_user): | |
|
59 | response = app.get(route_path('home'), status=200) | |||
|
60 | session = response.get_session_from_response() | |||
|
61 | ||||
|
62 | # now mark as password change | |||
59 | self.password_changed_mock.return_value = True |
|
63 | self.password_changed_mock.return_value = True | |
|
64 | ||||
|
65 | # flushes session first | |||
|
66 | app.get(route_path('home')) | |||
|
67 | ||||
|
68 | # second call is now "different" with flushed empty session | |||
60 | response = app.get(route_path('home')) |
|
69 | response = app.get(route_path('home')) | |
|
70 | session = response.get_session_from_response() | |||
|
71 | ||||
|
72 | assert 'rhodecode_user' not in session | |||
|
73 | ||||
61 | assert_response = response.assert_response() |
|
74 | assert_response = response.assert_response() | |
62 | assert_response.element_contains('#quick_login_link .user', 'Sign in') |
|
75 | assert_response.element_contains('#quick_login_link .user', 'Sign in') | |
63 |
|
76 | |||
64 | session = response.get_session_from_response() |
|
77 | ||
65 | assert 'rhodecode_user' not in session |
|
|||
66 | assert session.was_invalidated is True |
|
@@ -74,8 +74,7 b' def get_environ(url, request_method):' | |||||
74 |
|
74 | |||
75 | ]) |
|
75 | ]) | |
76 | def test_get_action(url, expected_action, request_method, baseapp, request_stub): |
|
76 | def test_get_action(url, expected_action, request_method, baseapp, request_stub): | |
77 | app = simplegit.SimpleGit(application=None, |
|
77 | app = simplegit.SimpleGit(config={'auth_ret_code': '', 'base_path': ''}, | |
78 | config={'auth_ret_code': '', 'base_path': ''}, |
|
|||
79 | registry=request_stub.registry) |
|
78 | registry=request_stub.registry) | |
80 | assert expected_action == app._get_action(get_environ(url, request_method)) |
|
79 | assert expected_action == app._get_action(get_environ(url, request_method)) | |
81 |
|
80 | |||
@@ -103,8 +102,7 b' def test_get_action(url, expected_action' | |||||
103 |
|
102 | |||
104 | ]) |
|
103 | ]) | |
105 | def test_get_repository_name(url, expected_repo_name, request_method, baseapp, request_stub): |
|
104 | def test_get_repository_name(url, expected_repo_name, request_method, baseapp, request_stub): | |
106 | app = simplegit.SimpleGit(application=None, |
|
105 | app = simplegit.SimpleGit(config={'auth_ret_code': '', 'base_path': ''}, | |
107 | config={'auth_ret_code': '', 'base_path': ''}, |
|
|||
108 | registry=request_stub.registry) |
|
106 | registry=request_stub.registry) | |
109 | assert expected_repo_name == app._get_repository_name( |
|
107 | assert expected_repo_name == app._get_repository_name( | |
110 | get_environ(url, request_method)) |
|
108 | get_environ(url, request_method)) | |
@@ -112,8 +110,7 b' def test_get_repository_name(url, expect' | |||||
112 |
|
110 | |||
113 | def test_get_config(user_util, baseapp, request_stub): |
|
111 | def test_get_config(user_util, baseapp, request_stub): | |
114 | repo = user_util.create_repo(repo_type='git') |
|
112 | repo = user_util.create_repo(repo_type='git') | |
115 | app = simplegit.SimpleGit(application=None, |
|
113 | app = simplegit.SimpleGit(config={'auth_ret_code': '', 'base_path': ''}, | |
116 | config={'auth_ret_code': '', 'base_path': ''}, |
|
|||
117 | registry=request_stub.registry) |
|
114 | registry=request_stub.registry) | |
118 | extras = {'foo': 'FOO', 'bar': 'BAR'} |
|
115 | extras = {'foo': 'FOO', 'bar': 'BAR'} | |
119 |
|
116 | |||
@@ -137,6 +134,6 b' def test_create_wsgi_app_uses_scm_app_fr' | |||||
137 | 'vcs.scm_app_implementation': |
|
134 | 'vcs.scm_app_implementation': | |
138 | 'rhodecode.tests.lib.middleware.mock_scm_app', |
|
135 | 'rhodecode.tests.lib.middleware.mock_scm_app', | |
139 | } |
|
136 | } | |
140 |
app = simplegit.SimpleGit( |
|
137 | app = simplegit.SimpleGit(config=config, registry=request_stub.registry) | |
141 | wsgi_app = app._create_wsgi_app('/tmp/test', 'test_repo', {}) |
|
138 | wsgi_app = app._create_wsgi_app('/tmp/test', 'test_repo', {}) | |
142 | assert wsgi_app is mock_scm_app.mock_git_wsgi |
|
139 | assert wsgi_app is mock_scm_app.mock_git_wsgi |
@@ -54,8 +54,7 b' def get_environ(url):' | |||||
54 | ('/foo/bar?key=tip', 'pull'), |
|
54 | ('/foo/bar?key=tip', 'pull'), | |
55 | ]) |
|
55 | ]) | |
56 | def test_get_action(url, expected_action, request_stub): |
|
56 | def test_get_action(url, expected_action, request_stub): | |
57 | app = simplehg.SimpleHg(application=None, |
|
57 | app = simplehg.SimpleHg(config={'auth_ret_code': '', 'base_path': ''}, | |
58 | config={'auth_ret_code': '', 'base_path': ''}, |
|
|||
59 | registry=request_stub.registry) |
|
58 | registry=request_stub.registry) | |
60 | assert expected_action == app._get_action(get_environ(url)) |
|
59 | assert expected_action == app._get_action(get_environ(url)) | |
61 |
|
60 | |||
@@ -72,16 +71,14 b' def test_get_action(url, expected_action' | |||||
72 | ('/foo/bar/baz/?cmd=listkeys&key=tip', 'foo/bar/baz'), |
|
71 | ('/foo/bar/baz/?cmd=listkeys&key=tip', 'foo/bar/baz'), | |
73 | ]) |
|
72 | ]) | |
74 | def test_get_repository_name(url, expected_repo_name, request_stub): |
|
73 | def test_get_repository_name(url, expected_repo_name, request_stub): | |
75 | app = simplehg.SimpleHg(application=None, |
|
74 | app = simplehg.SimpleHg(config={'auth_ret_code': '', 'base_path': ''}, | |
76 | config={'auth_ret_code': '', 'base_path': ''}, |
|
|||
77 | registry=request_stub.registry) |
|
75 | registry=request_stub.registry) | |
78 | assert expected_repo_name == app._get_repository_name(get_environ(url)) |
|
76 | assert expected_repo_name == app._get_repository_name(get_environ(url)) | |
79 |
|
77 | |||
80 |
|
78 | |||
81 | def test_get_config(user_util, baseapp, request_stub): |
|
79 | def test_get_config(user_util, baseapp, request_stub): | |
82 | repo = user_util.create_repo(repo_type='git') |
|
80 | repo = user_util.create_repo(repo_type='git') | |
83 | app = simplehg.SimpleHg(application=None, |
|
81 | app = simplehg.SimpleHg(config={'auth_ret_code': '', 'base_path': ''}, | |
84 | config={'auth_ret_code': '', 'base_path': ''}, |
|
|||
85 | registry=request_stub.registry) |
|
82 | registry=request_stub.registry) | |
86 | extras = [('foo', 'FOO', 'bar', 'BAR')] |
|
83 | extras = [('foo', 'FOO', 'bar', 'BAR')] | |
87 |
|
84 | |||
@@ -123,7 +120,6 b' def test_create_wsgi_app_uses_scm_app_fr' | |||||
123 | 'vcs.scm_app_implementation': |
|
120 | 'vcs.scm_app_implementation': | |
124 | 'rhodecode.tests.lib.middleware.mock_scm_app', |
|
121 | 'rhodecode.tests.lib.middleware.mock_scm_app', | |
125 | } |
|
122 | } | |
126 | app = simplehg.SimpleHg( |
|
123 | app = simplehg.SimpleHg(config=config, registry=request_stub.registry) | |
127 | application=None, config=config, registry=request_stub.registry) |
|
|||
128 | wsgi_app = app._create_wsgi_app('/tmp/test', 'test_repo', {}) |
|
124 | wsgi_app = app._create_wsgi_app('/tmp/test', 'test_repo', {}) | |
129 | assert wsgi_app is mock_scm_app.mock_hg_wsgi |
|
125 | assert wsgi_app is mock_scm_app.mock_hg_wsgi |
@@ -23,17 +23,16 b' from StringIO import StringIO' | |||||
23 | import pytest |
|
23 | import pytest | |
24 | from mock import patch, Mock |
|
24 | from mock import patch, Mock | |
25 |
|
25 | |||
26 | import rhodecode |
|
|||
27 | from rhodecode.lib.middleware.simplesvn import SimpleSvn, SimpleSvnApp |
|
26 | from rhodecode.lib.middleware.simplesvn import SimpleSvn, SimpleSvnApp | |
|
27 | from rhodecode.lib.utils import get_rhodecode_base_path | |||
28 |
|
28 | |||
29 |
|
29 | |||
30 | class TestSimpleSvn(object): |
|
30 | class TestSimpleSvn(object): | |
31 | @pytest.fixture(autouse=True) |
|
31 | @pytest.fixture(autouse=True) | |
32 | def simple_svn(self, baseapp, request_stub): |
|
32 | def simple_svn(self, baseapp, request_stub): | |
|
33 | base_path = get_rhodecode_base_path() | |||
33 | self.app = SimpleSvn( |
|
34 | self.app = SimpleSvn( | |
34 | application='None', |
|
35 | config={'auth_ret_code': '', 'base_path': base_path}, | |
35 | config={'auth_ret_code': '', |
|
|||
36 | 'base_path': rhodecode.CONFIG['base_path']}, |
|
|||
37 | registry=request_stub.registry) |
|
36 | registry=request_stub.registry) | |
38 |
|
37 | |||
39 | def test_get_config(self): |
|
38 | def test_get_config(self): | |
@@ -102,7 +101,6 b' class TestSimpleSvn(object):' | |||||
102 | assert wsgi_app == wsgi_app_mock() |
|
101 | assert wsgi_app == wsgi_app_mock() | |
103 |
|
102 | |||
104 |
|
103 | |||
105 |
|
||||
106 | class TestSimpleSvnApp(object): |
|
104 | class TestSimpleSvnApp(object): | |
107 | data = '<xml></xml>' |
|
105 | data = '<xml></xml>' | |
108 | path = '/group/my-repo' |
|
106 | path = '/group/my-repo' | |
@@ -121,8 +119,10 b' class TestSimpleSvnApp(object):' | |||||
121 |
|
119 | |||
122 | def setup_method(self, method): |
|
120 | def setup_method(self, method): | |
123 | self.host = 'http://localhost/' |
|
121 | self.host = 'http://localhost/' | |
|
122 | base_path = get_rhodecode_base_path() | |||
124 | self.app = SimpleSvnApp( |
|
123 | self.app = SimpleSvnApp( | |
125 |
config={'subversion_http_server_url': self.host |
|
124 | config={'subversion_http_server_url': self.host, | |
|
125 | 'base_path': base_path}) | |||
126 |
|
126 | |||
127 | def test_get_request_headers_with_content_type(self): |
|
127 | def test_get_request_headers_with_content_type(self): | |
128 | expected_headers = { |
|
128 | expected_headers = { |
@@ -79,8 +79,8 b' def vcscontroller(baseapp, config_stub, ' | |||||
79 | config_stub.include('rhodecode.authentication') |
|
79 | config_stub.include('rhodecode.authentication') | |
80 |
|
80 | |||
81 | controller = StubVCSController( |
|
81 | controller = StubVCSController( | |
82 |
baseapp |
|
82 | baseapp.config.get_settings(), request_stub.registry) | |
83 | app = HttpsFixup(controller, baseapp.config) |
|
83 | app = HttpsFixup(controller, baseapp.config.get_settings()) | |
84 | app = CustomTestApp(app) |
|
84 | app = CustomTestApp(app) | |
85 |
|
85 | |||
86 | _remove_default_user_from_query_cache() |
|
86 | _remove_default_user_from_query_cache() | |
@@ -136,8 +136,8 b' class StubFailVCSController(simplevcs.Si' | |||||
136 | @pytest.fixture(scope='module') |
|
136 | @pytest.fixture(scope='module') | |
137 | def fail_controller(baseapp): |
|
137 | def fail_controller(baseapp): | |
138 | controller = StubFailVCSController( |
|
138 | controller = StubFailVCSController( | |
139 |
baseapp |
|
139 | baseapp.config.get_settings(), baseapp.config) | |
140 | controller = HttpsFixup(controller, baseapp.config) |
|
140 | controller = HttpsFixup(controller, baseapp.config.get_settings()) | |
141 | controller = CustomTestApp(controller) |
|
141 | controller = CustomTestApp(controller) | |
142 | return controller |
|
142 | return controller | |
143 |
|
143 | |||
@@ -153,17 +153,15 b' def test_provides_traceback_for_appenlig' | |||||
153 |
|
153 | |||
154 |
|
154 | |||
155 | def test_provides_utils_scm_app_as_scm_app_by_default(baseapp, request_stub): |
|
155 | def test_provides_utils_scm_app_as_scm_app_by_default(baseapp, request_stub): | |
156 | controller = StubVCSController( |
|
156 | controller = StubVCSController(baseapp.config.get_settings(), request_stub.registry) | |
157 | baseapp, baseapp.config, request_stub.registry) |
|
|||
158 | assert controller.scm_app is scm_app_http |
|
157 | assert controller.scm_app is scm_app_http | |
159 |
|
158 | |||
160 |
|
159 | |||
161 | def test_allows_to_override_scm_app_via_config(baseapp, request_stub): |
|
160 | def test_allows_to_override_scm_app_via_config(baseapp, request_stub): | |
162 | config = baseapp.config.copy() |
|
161 | config = baseapp.config.get_settings().copy() | |
163 | config['vcs.scm_app_implementation'] = ( |
|
162 | config['vcs.scm_app_implementation'] = ( | |
164 | 'rhodecode.tests.lib.middleware.mock_scm_app') |
|
163 | 'rhodecode.tests.lib.middleware.mock_scm_app') | |
165 | controller = StubVCSController( |
|
164 | controller = StubVCSController(config, request_stub.registry) | |
166 | baseapp, config, request_stub.registry) |
|
|||
167 | assert controller.scm_app is mock_scm_app |
|
165 | assert controller.scm_app is mock_scm_app | |
168 |
|
166 | |||
169 |
|
167 | |||
@@ -225,7 +223,7 b' class TestShadowRepoExposure(object):' | |||||
225 | underlying wsgi app. |
|
223 | underlying wsgi app. | |
226 | """ |
|
224 | """ | |
227 | controller = StubVCSController( |
|
225 | controller = StubVCSController( | |
228 |
baseapp |
|
226 | baseapp.config.get_settings(), request_stub.registry) | |
229 | controller._check_ssl = mock.Mock() |
|
227 | controller._check_ssl = mock.Mock() | |
230 | controller.is_shadow_repo = True |
|
228 | controller.is_shadow_repo = True | |
231 | controller._action = 'pull' |
|
229 | controller._action = 'pull' | |
@@ -250,7 +248,7 b' class TestShadowRepoExposure(object):' | |||||
250 | underlying wsgi app. |
|
248 | underlying wsgi app. | |
251 | """ |
|
249 | """ | |
252 | controller = StubVCSController( |
|
250 | controller = StubVCSController( | |
253 |
baseapp |
|
251 | baseapp.config.get_settings(), request_stub.registry) | |
254 | controller._check_ssl = mock.Mock() |
|
252 | controller._check_ssl = mock.Mock() | |
255 | controller.is_shadow_repo = True |
|
253 | controller.is_shadow_repo = True | |
256 | controller._action = 'pull' |
|
254 | controller._action = 'pull' | |
@@ -274,7 +272,7 b' class TestShadowRepoExposure(object):' | |||||
274 | Check that a push action to a shadow repo is aborted. |
|
272 | Check that a push action to a shadow repo is aborted. | |
275 | """ |
|
273 | """ | |
276 | controller = StubVCSController( |
|
274 | controller = StubVCSController( | |
277 |
baseapp |
|
275 | baseapp.config.get_settings(), request_stub.registry) | |
278 | controller._check_ssl = mock.Mock() |
|
276 | controller._check_ssl = mock.Mock() | |
279 | controller.is_shadow_repo = True |
|
277 | controller.is_shadow_repo = True | |
280 | controller._action = 'push' |
|
278 | controller._action = 'push' | |
@@ -300,7 +298,7 b' class TestShadowRepoExposure(object):' | |||||
300 | """ |
|
298 | """ | |
301 | environ_stub = {} |
|
299 | environ_stub = {} | |
302 | controller = StubVCSController( |
|
300 | controller = StubVCSController( | |
303 |
baseapp |
|
301 | baseapp.config.get_settings(), request_stub.registry) | |
304 | controller._name = 'RepoGroup/MyRepo' |
|
302 | controller._name = 'RepoGroup/MyRepo' | |
305 | controller.set_repo_names(environ_stub) |
|
303 | controller.set_repo_names(environ_stub) | |
306 | assert not controller.is_shadow_repo |
|
304 | assert not controller.is_shadow_repo | |
@@ -324,7 +322,7 b' class TestShadowRepoExposure(object):' | |||||
324 | pr_segment=TestShadowRepoRegularExpression.pr_segment, |
|
322 | pr_segment=TestShadowRepoRegularExpression.pr_segment, | |
325 | shadow_segment=TestShadowRepoRegularExpression.shadow_segment) |
|
323 | shadow_segment=TestShadowRepoRegularExpression.shadow_segment) | |
326 | controller = StubVCSController( |
|
324 | controller = StubVCSController( | |
327 |
baseapp |
|
325 | baseapp.config.get_settings(), request_stub.registry) | |
328 | controller._name = shadow_url |
|
326 | controller._name = shadow_url | |
329 | controller.set_repo_names({}) |
|
327 | controller.set_repo_names({}) | |
330 |
|
328 | |||
@@ -352,7 +350,7 b' class TestShadowRepoExposure(object):' | |||||
352 | pr_segment=TestShadowRepoRegularExpression.pr_segment, |
|
350 | pr_segment=TestShadowRepoRegularExpression.pr_segment, | |
353 | shadow_segment=TestShadowRepoRegularExpression.shadow_segment) |
|
351 | shadow_segment=TestShadowRepoRegularExpression.shadow_segment) | |
354 | controller = StubVCSController( |
|
352 | controller = StubVCSController( | |
355 |
baseapp |
|
353 | baseapp.config.get_settings(), request_stub.registry) | |
356 | controller._name = shadow_url |
|
354 | controller._name = shadow_url | |
357 | controller.set_repo_names({}) |
|
355 | controller.set_repo_names({}) | |
358 |
|
356 | |||
@@ -362,7 +360,7 b' class TestShadowRepoExposure(object):' | |||||
362 | controller.vcs_repo_name) |
|
360 | controller.vcs_repo_name) | |
363 |
|
361 | |||
364 |
|
362 | |||
365 |
@pytest.mark.usefixtures(' |
|
363 | @pytest.mark.usefixtures('baseapp') | |
366 | class TestGenerateVcsResponse(object): |
|
364 | class TestGenerateVcsResponse(object): | |
367 |
|
365 | |||
368 | def test_ensures_that_start_response_is_called_early_enough(self): |
|
366 | def test_ensures_that_start_response_is_called_early_enough(self): | |
@@ -429,7 +427,7 b' class TestGenerateVcsResponse(object):' | |||||
429 | 'vcs.hooks.direct_calls': False, |
|
427 | 'vcs.hooks.direct_calls': False, | |
430 | } |
|
428 | } | |
431 | registry = AttributeDict() |
|
429 | registry = AttributeDict() | |
432 |
controller = StubVCSController( |
|
430 | controller = StubVCSController(settings, registry) | |
433 | controller._invalidate_cache = mock.Mock() |
|
431 | controller._invalidate_cache = mock.Mock() | |
434 | controller.stub_response_body = response_body |
|
432 | controller.stub_response_body = response_body | |
435 | self.start_response = mock.Mock() |
|
433 | self.start_response = mock.Mock() | |
@@ -482,7 +480,7 b' class TestPrepareHooksDaemon(object):' | |||||
482 | expected_extras = {'extra1': 'value1'} |
|
480 | expected_extras = {'extra1': 'value1'} | |
483 | daemon = DummyHooksCallbackDaemon() |
|
481 | daemon = DummyHooksCallbackDaemon() | |
484 |
|
482 | |||
485 |
controller = StubVCSController( |
|
483 | controller = StubVCSController(app_settings, request_stub.registry) | |
486 | prepare_patcher = mock.patch.object( |
|
484 | prepare_patcher = mock.patch.object( | |
487 | simplevcs, 'prepare_callback_daemon', |
|
485 | simplevcs, 'prepare_callback_daemon', | |
488 | return_value=(daemon, expected_extras)) |
|
486 | return_value=(daemon, expected_extras)) |
@@ -44,10 +44,8 b' def test_vcs_unavailable_returns_vcs_err' | |||||
44 | # Patch remote repo to raise an exception instead of making a RPC. |
|
44 | # Patch remote repo to raise an exception instead of making a RPC. | |
45 | with mock.patch.object(RemoteRepo, '__getattr__') as remote_mock: |
|
45 | with mock.patch.object(RemoteRepo, '__getattr__') as remote_mock: | |
46 | remote_mock.side_effect = VCSCommunicationError() |
|
46 | remote_mock.side_effect = VCSCommunicationError() | |
47 | # Patch pylons error handling middleware to not re-raise exceptions. |
|
47 | ||
48 | with mock.patch.object(PylonsErrorHandlingMiddleware, 'reraise') as r: |
|
48 | response = app.get(url, expect_errors=True) | |
49 | r.return_value = False |
|
|||
50 | response = app.get(url, expect_errors=True) |
|
|||
51 |
|
49 | |||
52 | assert response.status_code == 502 |
|
50 | assert response.status_code == 502 | |
53 | assert 'Could not connect to VCS Server' in response.body |
|
51 | assert 'Could not connect to VCS Server' in response.body |
@@ -29,6 +29,6 b' from rhodecode.model.db import UserLog' | |||||
29 | 'user_closed_pull_request', |
|
29 | 'user_closed_pull_request', | |
30 | 'user_merged_pull_request' |
|
30 | 'user_merged_pull_request' | |
31 | ]) |
|
31 | ]) | |
32 | def test_action_map_pr_values(baseapp, pr_key): |
|
32 | def test_action_map_pr_values(request_stub, baseapp, pr_key): | |
33 | parser = ActionParser(UserLog(action="test:test")) |
|
33 | parser = ActionParser(request_stub, UserLog(action="test:test")) | |
34 | assert pr_key in parser.action_map |
|
34 | assert pr_key in parser.action_map |
@@ -23,7 +23,7 b' import textwrap' | |||||
23 | import pytest |
|
23 | import pytest | |
24 |
|
24 | |||
25 | from rhodecode.lib.diffs import ( |
|
25 | from rhodecode.lib.diffs import ( | |
26 |
DiffProcessor, |
|
26 | DiffProcessor, | |
27 | NEW_FILENODE, DEL_FILENODE, MOD_FILENODE, RENAMED_FILENODE, |
|
27 | NEW_FILENODE, DEL_FILENODE, MOD_FILENODE, RENAMED_FILENODE, | |
28 | CHMOD_FILENODE, BIN_FILENODE, COPIED_FILENODE) |
|
28 | CHMOD_FILENODE, BIN_FILENODE, COPIED_FILENODE) | |
29 | from rhodecode.tests.fixture import Fixture |
|
29 | from rhodecode.tests.fixture import Fixture | |
@@ -34,23 +34,6 b' from rhodecode.lib.vcs.backends.svn.repo' | |||||
34 | fixture = Fixture() |
|
34 | fixture = Fixture() | |
35 |
|
35 | |||
36 |
|
36 | |||
37 | def test_wrapped_diff_limited_file_diff(vcsbackend_random): |
|
|||
38 | vcsbackend = vcsbackend_random |
|
|||
39 | repo = vcsbackend.create_repo() |
|
|||
40 | vcsbackend.add_file(repo, 'a_file', content="line 1\nline 2\nline3\n") |
|
|||
41 | commit = repo.get_commit() |
|
|||
42 | file_node = commit.get_node('a_file') |
|
|||
43 |
|
||||
44 | # Only limit the file diff to trigger the code path |
|
|||
45 | result = wrapped_diff( |
|
|||
46 | None, file_node, diff_limit=10000, file_limit=1) |
|
|||
47 | data = result[5] |
|
|||
48 |
|
||||
49 | # Verify that the limits were applied |
|
|||
50 | assert data['exceeds_limit'] is True |
|
|||
51 | assert data['is_limited_diff'] is True |
|
|||
52 |
|
||||
53 |
|
||||
54 | def test_diffprocessor_as_html_with_comments(): |
|
37 | def test_diffprocessor_as_html_with_comments(): | |
55 | raw_diff = textwrap.dedent(''' |
|
38 | raw_diff = textwrap.dedent(''' | |
56 | diff --git a/setup.py b/setup.py |
|
39 | diff --git a/setup.py b/setup.py |
@@ -158,7 +158,7 b' def test_formatted_json():' | |||||
158 | assert formatted_json(data) == expected_data |
|
158 | assert formatted_json(data) == expected_data | |
159 |
|
159 | |||
160 |
|
160 | |||
161 |
def test_ |
|
161 | def test_lazy_translation_string(baseapp): | |
162 | data = {'label': _('hello')} |
|
162 | data = {'label': _('hello')} | |
163 | data2 = {'label2': _pluralize('singular', 'plural', 1)} |
|
163 | data2 = {'label2': _pluralize('singular', 'plural', 1)} | |
164 |
|
164 |
@@ -65,7 +65,7 b' class TestPullRequestModel(object):' | |||||
65 | 'rhodecode.model.notification.NotificationModel.create') |
|
65 | 'rhodecode.model.notification.NotificationModel.create') | |
66 | self.notification_patcher.start() |
|
66 | self.notification_patcher.start() | |
67 | self.helper_patcher = mock.patch( |
|
67 | self.helper_patcher = mock.patch( | |
68 |
'rhodecode.lib.helpers. |
|
68 | 'rhodecode.lib.helpers.route_path') | |
69 | self.helper_patcher.start() |
|
69 | self.helper_patcher.start() | |
70 |
|
70 | |||
71 | self.hook_patcher = mock.patch.object(PullRequestModel, |
|
71 | self.hook_patcher = mock.patch.object(PullRequestModel, |
@@ -183,7 +183,7 b' def test_get_non_unicode_reference(backe' | |||||
183 | tags=non_unicode_list, alias=backend.alias) |
|
183 | tags=non_unicode_list, alias=backend.alias) | |
184 |
|
184 | |||
185 | repo = Mock(__class__=db.Repository, scm_instance=scm_instance) |
|
185 | repo = Mock(__class__=db.Repository, scm_instance=scm_instance) | |
186 | choices, __ = model.get_repo_landing_revs(repo=repo) |
|
186 | choices, __ = model.get_repo_landing_revs(translator=lambda s: s, repo=repo) | |
187 | if backend.alias == 'hg': |
|
187 | if backend.alias == 'hg': | |
188 | valid_choices = [ |
|
188 | valid_choices = [ | |
189 | 'rev:tip', u'branch:Ad\xc4\xb1n\xc4\xb1', |
|
189 | 'rev:tip', u'branch:Ad\xc4\xb1n\xc4\xb1', |
@@ -209,12 +209,6 b' def test_ValidAuth(localizer, config_stu' | |||||
209 | formencode.Invalid, validator.to_python, invalid_creds) |
|
209 | formencode.Invalid, validator.to_python, invalid_creds) | |
210 |
|
210 | |||
211 |
|
211 | |||
212 | def test_ValidAuthToken(localizer): |
|
|||
213 | validator = v.ValidAuthToken(localizer) |
|
|||
214 | pytest.raises(formencode.Invalid, validator.to_python, 'BadToken') |
|
|||
215 | validator |
|
|||
216 |
|
||||
217 |
|
||||
218 | def test_ValidRepoName(localizer): |
|
212 | def test_ValidRepoName(localizer): | |
219 | validator = v.ValidRepoName(localizer) |
|
213 | validator = v.ValidRepoName(localizer) | |
220 |
|
214 |
@@ -23,8 +23,6 b' from pyramid.threadlocal import get_curr' | |||||
23 |
|
23 | |||
24 | _ = TranslationStringFactory('rhodecode') |
|
24 | _ = TranslationStringFactory('rhodecode') | |
25 |
|
25 | |||
26 | temp_translation_factory = _ |
|
|||
27 |
|
||||
28 |
|
26 | |||
29 | class _LazyString(object): |
|
27 | class _LazyString(object): | |
30 | def __init__(self, *args, **kw): |
|
28 | def __init__(self, *args, **kw): |
General Comments 0
You need to be logged in to leave comments.
Login now