pylons: fixed code and test suite after removal of pylons.

This commit is contained in:
Marcin Kuzminski 2017-11-16 18:27:09 +01:00
parent b0071bb7c7
commit 1d332c03ad
44 changed files with 186 additions and 281 deletions

View file

@ -40,7 +40,7 @@ BACKENDS = {
CELERY_ENABLED = False
CELERY_EAGER = False
# link to config for pylons
# link to config for pyramid
CONFIG = {}
# Populated with the settings dictionary from application init in

View file

@ -911,7 +911,8 @@ def update_repo(
repo_enable_downloads=enable_downloads
if not isinstance(enable_downloads, Optional) else repo.enable_downloads)
ref_choices, _labels = ScmModel().get_repo_landing_revs(repo=repo)
ref_choices, _labels = ScmModel().get_repo_landing_revs(
request.translate, repo=repo)
old_values = repo.get_api_data()
schema = repo_schema.RepoSchema().bind(

View file

@ -32,7 +32,7 @@ def assert_auth_settings_updated(response):
@pytest.mark.usefixtures("autologin_user", "app")
class TestAuthSettingsController(object):
class TestAuthSettingsView(object):
def _enable_plugins(self, plugins_list, csrf_token, override=None,
verify_response=False):

View file

@ -385,7 +385,7 @@ class TestAdminUsersView(TestController):
'csrf_token': self.csrf_token,
})
msg = '???'
msg = u'Username "%(username)s" is forbidden'
msg = h.html_escape(msg % {'username': 'new_user'})
response.mustcontain('<span class="error-message">%s</span>' % msg)
response.mustcontain(

View file

@ -53,8 +53,6 @@ log = logging.getLogger(__name__)
class AdminPermissionsView(BaseAppView, DataGridAppView):
def load_default_context(self):
c = self._get_local_tmpl_context()
PermissionModel().set_global_permission_choices(
c, gettext_translator=self.request.translate)
return c

View file

@ -58,7 +58,7 @@ class AdminReposView(BaseAppView, DataGridAppView):
c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups)
c.landing_revs_choices, c.landing_revs = \
ScmModel().get_repo_landing_revs()
ScmModel().get_repo_landing_revs(self.request.translate)
c.personal_repo_group = self._rhodecode_user.personal_repo_group
@LoginRequired()

View file

@ -660,7 +660,7 @@ class AdminSettingsView(BaseAppView):
c.active = 'search'
searcher = searcher_from_config(self.request.registry.settings)
c.statistics = searcher.statistics()
c.statistics = searcher.statistics(self.request.translate)
return self._get_template_context(c)

View file

@ -259,7 +259,6 @@ class UsersView(UserAppView):
PermissionModel().set_global_permission_choices(
c, gettext_translator=req.translate)
return c
@LoginRequired()

View file

@ -88,32 +88,31 @@ class TestLoginController(object):
def test_login_admin_ok(self):
response = self.app.post(route_path('login'),
{'username': 'test_admin',
'password': 'test12'})
assert response.status == '302 Found'
'password': 'test12'}, status=302)
response = response.follow()
session = response.get_session_from_response()
username = session['rhodecode_user'].get('username')
assert username == 'test_admin'
response = response.follow()
response.mustcontain('/%s' % HG_REPO)
def test_login_regular_ok(self):
response = self.app.post(route_path('login'),
{'username': 'test_regular',
'password': 'test12'})
'password': 'test12'}, status=302)
assert response.status == '302 Found'
response = response.follow()
session = response.get_session_from_response()
username = session['rhodecode_user'].get('username')
assert username == 'test_regular'
response = response.follow()
response.mustcontain('/%s' % HG_REPO)
def test_login_ok_came_from(self):
test_came_from = '/_admin/users?branch=stable'
_url = '{}?came_from={}'.format(route_path('login'), test_came_from)
response = self.app.post(
_url, {'username': 'test_admin', 'password': 'test12'})
assert response.status == '302 Found'
_url, {'username': 'test_admin', 'password': 'test12'}, status=302)
assert 'branch=stable' in response.location
response = response.follow()
@ -124,8 +123,8 @@ class TestLoginController(object):
with fixture.anon_access(False):
kwargs = {'branch': 'stable'}
response = self.app.get(
h.route_path('repo_summary', repo_name=HG_REPO, _query=kwargs))
assert response.status == '302 Found'
h.route_path('repo_summary', repo_name=HG_REPO, _query=kwargs),
status=302)
response_query = urlparse.parse_qsl(response.location)
assert 'branch=stable' in response_query[0][1]
@ -200,13 +199,12 @@ class TestLoginController(object):
self.destroy_users.add(temp_user)
response = self.app.post(route_path('login'),
{'username': temp_user,
'password': 'test123'})
'password': 'test123'}, status=302)
assert response.status == '302 Found'
response = response.follow()
session = response.get_session_from_response()
username = session['rhodecode_user'].get('username')
assert username == temp_user
response = response.follow()
response.mustcontain('/%s' % HG_REPO)
# new password should be bcrypted, after log-in and transfer
@ -233,7 +231,7 @@ class TestLoginController(object):
)
assertr = response.assert_response()
msg = '???'
msg = 'Username "%(username)s" already exists'
msg = msg % {'username': uname}
assertr.element_contains('#username+.error-message', msg)
@ -251,7 +249,7 @@ class TestLoginController(object):
)
assertr = response.assert_response()
msg = '???'
msg = u'This e-mail address is already taken'
assertr.element_contains('#email+.error-message', msg)
def test_register_err_same_email_case_sensitive(self):
@ -267,7 +265,7 @@ class TestLoginController(object):
}
)
assertr = response.assert_response()
msg = '???'
msg = u'This e-mail address is already taken'
assertr.element_contains('#email+.error-message', msg)
def test_register_err_wrong_data(self):
@ -321,7 +319,7 @@ class TestLoginController(object):
)
assertr = response.assert_response()
msg = '???'
msg = u'Username "%(username)s" already exists'
msg = msg % {'username': usr}
assertr.element_contains('#username+.error-message', msg)
@ -338,7 +336,7 @@ class TestLoginController(object):
}
)
msg = '???'
msg = u'Invalid characters (non-ascii) in password'
response.mustcontain(msg)
def test_register_password_mismatch(self):
@ -353,7 +351,7 @@ class TestLoginController(object):
'lastname': 'test'
}
)
msg = '???'
msg = u'Passwords do not match'
response.mustcontain(msg)
def test_register_ok(self):
@ -363,6 +361,11 @@ class TestLoginController(object):
name = 'testname'
lastname = 'testlastname'
# this initializes a session
response = self.app.get(route_path('register'))
response.mustcontain('Create an Account')
response = self.app.post(
route_path('register'),
{
@ -373,9 +376,10 @@ class TestLoginController(object):
'firstname': name,
'lastname': lastname,
'admin': True
}
) # This should be overriden
assert response.status == '302 Found'
},
status=302
) # This should be overridden
assert_session_flash(
response, 'You have successfully registered with RhodeCode')
@ -391,6 +395,9 @@ class TestLoginController(object):
def test_forgot_password_wrong_mail(self):
bad_email = 'marcin@wrongmail.org'
# this initializes a session
self.app.get(route_path('reset_password'))
response = self.app.post(
route_path('reset_password'), {'email': bad_email, }
)
@ -398,8 +405,8 @@ class TestLoginController(object):
'If such email exists, a password reset link was sent to it.')
def test_forgot_password(self, user_util):
response = self.app.get(route_path('reset_password'))
assert response.status == '200 OK'
# this initializes a session
self.app.get(route_path('reset_password'))
user = user_util.create_user()
user_id = user.user_id
@ -412,8 +419,7 @@ class TestLoginController(object):
# BAD KEY
confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), 'badkey')
response = self.app.get(confirm_url)
assert response.status == '302 Found'
response = self.app.get(confirm_url, status=302)
assert response.location.endswith(route_path('reset_password'))
assert_session_flash(response, 'Given reset token is invalid')

View file

@ -58,7 +58,7 @@ class TestRegisterCaptcha(object):
('privkey', '', CaptchaData(True, 'privkey', '')),
('privkey', 'pubkey', CaptchaData(True, 'privkey', 'pubkey')),
])
def test_get_captcha_data(self, private_key, public_key, expected, db,
def test_get_captcha_data(self, private_key, public_key, expected,
request_stub, user_util):
request_stub.user = user_util.create_user().AuthUser()
request_stub.matched_route = AttributeDict({'name': 'login'})

View file

@ -32,7 +32,7 @@ from recaptcha.client.captcha import submit
from rhodecode.apps._base import BaseAppView
from rhodecode.authentication.base import authenticate, HTTP_TYPE
from rhodecode.events import UserRegistered
from rhodecode.events import UserRegistered, trigger
from rhodecode.lib import helpers as h
from rhodecode.lib import audit_logger
from rhodecode.lib.auth import (
@ -147,7 +147,7 @@ class LoginView(BaseAppView):
raise HTTPFound(c.came_from, headers=headers)
except UserCreationError as e:
log.error(e)
self.session.flash(e, queue='error')
h.flash(e, category='error')
return self._get_template_context(c)
@ -201,7 +201,7 @@ class LoginView(BaseAppView):
# the fly can throw this exception signaling that there's issue
# with user creation, explanation should be provided in
# Exception itself
self.session.flash(e, queue='error')
h.flash(e, category='error')
return self._get_template_context(c)
@CSRFRequired()
@ -250,6 +250,7 @@ class LoginView(BaseAppView):
route_name='register', request_method='POST',
renderer='rhodecode:templates/register.mako')
def register_post(self):
self.load_default_context()
captcha = self._get_captcha_data()
auto_active = 'hg.register.auto_activate' in User.get_default_user()\
.AuthUser().permissions['global']
@ -275,10 +276,10 @@ class LoginView(BaseAppView):
new_user = UserModel().create_registration(form_result)
event = UserRegistered(user=new_user, session=self.session)
self.request.registry.notify(event)
self.session.flash(
trigger(event)
h.flash(
_('You have successfully registered with RhodeCode'),
queue='success')
category='success')
Session().commit()
redirect_ro = self.request.route_path('login')
@ -295,16 +296,17 @@ class LoginView(BaseAppView):
# the fly can throw this exception signaling that there's issue
# with user creation, explanation should be provided in
# Exception itself
self.session.flash(e, queue='error')
h.flash(e, category='error')
return self.register()
@view_config(
route_name='reset_password', request_method=('GET', 'POST'),
renderer='rhodecode:templates/password_reset.mako')
def password_reset(self):
c = self.load_default_context()
captcha = self._get_captcha_data()
render_ctx = {
template_context = {
'captcha_active': captcha.active,
'captcha_public_key': captcha.public_key,
'defaults': {},
@ -319,8 +321,8 @@ class LoginView(BaseAppView):
if h.HasPermissionAny('hg.password_reset.disabled')():
_email = self.request.POST.get('email', '')
log.error('Failed attempt to reset password for `%s`.', _email)
self.session.flash(_('Password reset has been disabled.'),
queue='error')
h.flash(_('Password reset has been disabled.'),
category='error')
return HTTPFound(self.request.route_path('reset_password'))
password_reset_form = PasswordResetForm(self.request.translate)()
@ -361,7 +363,7 @@ class LoginView(BaseAppView):
UserModel().reset_password_link(
form_result, password_reset_url)
# Display success message and redirect.
self.session.flash(msg, queue='success')
h.flash(msg, category='success')
action_data = {'email': user_email,
'user_agent': self.request.user_agent}
@ -371,30 +373,30 @@ class LoginView(BaseAppView):
return HTTPFound(self.request.route_path('reset_password'))
except formencode.Invalid as errors:
render_ctx.update({
template_context.update({
'defaults': errors.value,
'errors': errors.error_dict,
})
if not self.request.POST.get('email'):
# case of empty email, we want to report that
return render_ctx
return self._get_template_context(c, **template_context)
if 'recaptcha_field' in errors.error_dict:
# case of failed captcha
return render_ctx
return self._get_template_context(c, **template_context)
log.debug('faking response on invalid password reset')
# make this take 2s, to prevent brute forcing.
time.sleep(2)
self.session.flash(msg, queue='success')
h.flash(msg, category='success')
return HTTPFound(self.request.route_path('reset_password'))
return render_ctx
return self._get_template_context(c, **template_context)
@view_config(route_name='reset_password_confirmation',
request_method='GET')
def password_reset_confirmation(self):
self.load_default_context()
if self.request.GET and self.request.GET.get('key'):
# make this take 2s, to prevent brute forcing.
time.sleep(2)
@ -407,18 +409,18 @@ class LoginView(BaseAppView):
log.debug('Got token with role:%s expected is %s',
getattr(token, 'role', 'EMPTY_TOKEN'),
UserApiKeys.ROLE_PASSWORD_RESET)
self.session.flash(
_('Given reset token is invalid'), queue='error')
h.flash(
_('Given reset token is invalid'), category='error')
return HTTPFound(self.request.route_path('reset_password'))
try:
owner = token.user
data = {'email': owner.email, 'token': token.api_key}
UserModel().reset_password(data)
self.session.flash(
h.flash(
_('Your password reset was successful, '
'a new password has been sent to your email'),
queue='success')
category='success')
except Exception as e:
log.error(e)
return HTTPFound(self.request.route_path('reset_password'))

View file

@ -198,6 +198,6 @@ class TestMyAccountEdit(TestController):
params=params)
response.mustcontain('An email address must contain a single @')
msg = '???'
msg = u'Username "%(username)s" already exists'
msg = h.html_escape(msg % {'username': 'test_admin'})
response.mustcontain(u"%s" % msg)

View file

@ -572,6 +572,7 @@ class MyAccountView(BaseAppView, DataGridAppView):
route_name='my_account_pullrequests_data',
request_method='GET', renderer='json_ext')
def my_account_pullrequests_data(self):
self.load_default_context()
req_get = self.request.GET
closed = str2bool(req_get.get('closed'))

View file

@ -48,6 +48,7 @@ def route_path(name, params=None, **kwargs):
import urllib
base_url = {
'repo_summary': '/{repo_name}',
'repo_archivefile': '/{repo_name}/archive/{fname}',
'repo_files_diff': '/{repo_name}/diff/{f_path}',
'repo_files_diff_2way_redirect': '/{repo_name}/diff-2way/{f_path}',
@ -999,8 +1000,11 @@ class TestFilesViewOtherCases(object):
.format(repo_file_add_url))
def test_access_empty_repo_redirect_to_summary_with_alert_no_write_perms(
self, backend_stub, user_util):
self, backend_stub, autologin_regular_user):
repo = backend_stub.create_repo()
# init session for anon user
route_path('repo_summary', repo_name=repo.repo_name)
repo_file_add_url = route_path(
'repo_files_add_file',
repo_name=repo.repo_name,

View file

@ -53,11 +53,11 @@ class RepoForksView(RepoAppView, DataGridAppView):
perm_set=['group.write', 'group.admin'])
c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups)
choices, c.landing_revs = ScmModel().get_repo_landing_revs()
choices, c.landing_revs = ScmModel().get_repo_landing_revs(
self.request.translate)
c.landing_revs_choices = choices
c.personal_repo_group = c.rhodecode_user.personal_repo_group
return c
@LoginRequired()
@ -78,6 +78,7 @@ class RepoForksView(RepoAppView, DataGridAppView):
renderer='json_ext', xhr=True)
def repo_forks_data(self):
_ = self.request.translate
self.load_default_context()
column_map = {
'fork_name': 'repo_name',
'fork_date': 'created_on',

View file

@ -173,6 +173,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
route_name='pullrequest_show_all_data', request_method='GET',
renderer='json_ext', xhr=True)
def pull_request_list_data(self):
self.load_default_context()
# additional filters
req_get = self.request.GET
@ -675,6 +676,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
route_name='pullrequest_repo_refs', request_method='GET',
renderer='json_ext', xhr=True)
def pull_request_repo_refs(self):
self.load_default_context()
target_repo_name = self.request.matchdict['target_repo_name']
repo = Repository.get_by_repo_name(target_repo_name)
if not repo:
@ -745,6 +747,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
def pull_request_create(self):
_ = self.request.translate
self.assure_not_empty_repo()
self.load_default_context()
controls = peppercorn.parse(self.request.POST.items())
@ -878,6 +881,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
pull_request = PullRequest.get_or_404(
self.request.matchdict['pull_request_id'])
self.load_default_context()
# only owner or admin can update it
allowed_to_update = PullRequestModel().check_user_update(
pull_request, self._rhodecode_user)
@ -976,6 +980,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
pull_request = PullRequest.get_or_404(
self.request.matchdict['pull_request_id'])
self.load_default_context()
check = MergeCheck.validate(pull_request, self._rhodecode_db_user,
translator=self.request.translate)
merge_possible = not check.failed
@ -1048,6 +1053,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
pull_request = PullRequest.get_or_404(
self.request.matchdict['pull_request_id'])
self.load_default_context()
pr_closed = pull_request.is_closed()
allowed_to_delete = PullRequestModel().check_user_delete(

View file

@ -62,10 +62,11 @@ class RepoSettingsView(RepoAppView):
# we might be in missing requirement state, so we load things
# without touching scm_instance()
c.landing_revs_choices, c.landing_revs = \
ScmModel().get_repo_landing_revs()
ScmModel().get_repo_landing_revs(self.request.translate)
else:
c.landing_revs_choices, c.landing_revs = \
ScmModel().get_repo_landing_revs(self.db_repo)
ScmModel().get_repo_landing_revs(
self.request.translate, self.db_repo)
c.personal_repo_group = c.auth_user.personal_repo_group
c.repo_fields = RepositoryField.query()\

View file

@ -428,7 +428,7 @@ class UserGroupsView(UserGroupAppView):
try:
# first stage that verifies the checkbox
_form = UserIndividualPermissionsForm()
_form = UserIndividualPermissionsForm(self.request.translate)
form_result = _form.to_python(dict(self.request.POST))
inherit_perms = form_result['inherit_default_permissions']
user_group.inherit_default_permissions = inherit_perms

View file

@ -74,9 +74,6 @@ def load_pyramid_environment(global_config, settings):
# Initialize the database connection.
utils.initialize_database(settings_merged)
# TODO(marcink): base_path handling ?
# repos_path = list(db_cfg.items('paths'))[0][1]
load_rcextensions(root_path=settings_merged['here'])
# Limit backends to `vcs.backends` from configuration

View file

@ -29,7 +29,6 @@ import socket
import markupsafe
import ipaddress
import pyramid.threadlocal
from paste.auth.basic import AuthBasicAuthenticator
from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden, get_exception
@ -41,15 +40,11 @@ from rhodecode.lib import auth, utils2
from rhodecode.lib import helpers as h
from rhodecode.lib.auth import AuthUser, CookieStoreWrapper
from rhodecode.lib.exceptions import UserCreationError
from rhodecode.lib.utils import (
get_repo_slug, set_rhodecode_config, password_changed,
get_enabled_hook_classes)
from rhodecode.lib.utils import (password_changed, get_enabled_hook_classes)
from rhodecode.lib.utils2 import (
str2bool, safe_unicode, AttributeDict, safe_int, md5, aslist, safe_str)
from rhodecode.model import meta
from rhodecode.model.db import Repository, User, ChangesetComment
from rhodecode.model.notification import NotificationModel
from rhodecode.model.scm import ScmModel
from rhodecode.model.settings import VcsSettingsModel, SettingsModel
log = logging.getLogger(__name__)
@ -440,6 +435,8 @@ def get_auth_user(request):
# AuthUser
auth_user = AuthUser(ip_addr=ip_addr)
# in case someone changes a password for user it triggers session
# flush and forces a re-login
if password_changed(auth_user, session):
session.invalidate()
cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))

View file

@ -23,19 +23,15 @@
Set of diffing helpers, previously part of vcs
"""
import collections
import re
import collections
import difflib
import logging
from itertools import tee, imap
from rhodecode.translation import temp_translation_factory as _
from rhodecode.lib.vcs.exceptions import VCSError
from rhodecode.lib.vcs.nodes import FileNode, SubModuleNode
from rhodecode.lib.vcs.backends.base import EmptyCommit
from rhodecode.lib.helpers import escape
from rhodecode.lib.utils2 import safe_unicode
log = logging.getLogger(__name__)
@ -51,69 +47,6 @@ class OPS(object):
DEL = 'D'
def wrap_to_table(str_):
return '''<table class="code-difftable">
<tr class="line no-comment">
<td class="add-comment-line tooltip" title="%s"><span class="add-comment-content"></span></td>
<td></td>
<td class="lineno new"></td>
<td class="code no-comment"><pre>%s</pre></td>
</tr>
</table>''' % (_('Click to comment'), str_)
def wrapped_diff(filenode_old, filenode_new, diff_limit=None, file_limit=None,
show_full_diff=False, ignore_whitespace=True, line_context=3,
enable_comments=False):
"""
returns a wrapped diff into a table, checks for cut_off_limit for file and
whole diff and presents proper message
"""
if filenode_old is None:
filenode_old = FileNode(filenode_new.path, '', EmptyCommit())
if filenode_old.is_binary or filenode_new.is_binary:
diff = wrap_to_table(_('Binary file'))
stats = None
size = 0
data = None
elif diff_limit != -1 and (diff_limit is None or
(filenode_old.size < diff_limit and filenode_new.size < diff_limit)):
f_gitdiff = get_gitdiff(filenode_old, filenode_new,
ignore_whitespace=ignore_whitespace,
context=line_context)
diff_processor = DiffProcessor(
f_gitdiff, format='gitdiff', diff_limit=diff_limit,
file_limit=file_limit, show_full_diff=show_full_diff)
_parsed = diff_processor.prepare()
diff = diff_processor.as_html(enable_comments=enable_comments)
stats = _parsed[0]['stats'] if _parsed else None
size = len(diff or '')
data = _parsed[0] if _parsed else None
else:
diff = wrap_to_table(_('Changeset was too big and was cut off, use '
'diff menu to display this diff'))
stats = None
size = 0
data = None
if not diff:
submodules = filter(lambda o: isinstance(o, SubModuleNode),
[filenode_new, filenode_old])
if submodules:
diff = wrap_to_table(escape('Submodule %r' % submodules[0]))
else:
diff = wrap_to_table(_('No changes detected'))
cs1 = filenode_old.commit.raw_id
cs2 = filenode_new.commit.raw_id
return size, cs1, cs2, diff, stats, data
def get_gitdiff(filenode_old, filenode_new, ignore_whitespace=True, context=3):
"""
Returns git style diff between given ``filenode_old`` and ``filenode_new``.
@ -916,6 +849,10 @@ class DiffProcessor(object):
"""
Return given diff as html table with customized css classes
"""
# TODO(marcink): not sure how to pass in translator
# here in an efficient way, leave the _ for proper gettext extraction
_ = lambda s: s
def _link_to_if(condition, label, url):
"""
Generates a link if condition is meet or just the label if not.

View file

@ -51,7 +51,7 @@ def _obj_dump(obj):
return str(obj)
elif isinstance(obj, complex):
return [obj.real, obj.imag]
elif rhodecode and isinstance(obj, rhodecode.translation.LazyString):
elif rhodecode and isinstance(obj, rhodecode.translation._LazyString):
return obj.eval()
else:
raise TypeError(repr(obj) + " is not JSON serializable")

View file

@ -1929,12 +1929,12 @@ def secure_form(form_url, method="POST", multipart=False, **attrs):
"""
from webhelpers.pylonslib.secure_form import insecure_form
session = None
# TODO(marcink): after pyramid migration require request variable ALWAYS
if 'request' in attrs:
session = attrs['request'].session
del attrs['request']
else:
raise ValueError(
'Calling this form requires request= to be passed as argument')
form = insecure_form(form_url, method, multipart, **attrs)
token = literal(

View file

@ -23,19 +23,18 @@ Index schema for RhodeCode
"""
from __future__ import absolute_import
import logging
import os
import re
import logging
from rhodecode.translation import temp_translation_factory as _
from whoosh import query as query_lib, sorting
from whoosh import query as query_lib
from whoosh.highlight import HtmlFormatter, ContextFragmenter
from whoosh.index import create_in, open_dir, exists_in, EmptyIndexError
from whoosh.qparser import QueryParser, QueryParserError
import rhodecode.lib.helpers as h
from rhodecode.lib.index import BaseSearch
from rhodecode.lib.utils2 import safe_unicode
log = logging.getLogger(__name__)
@ -122,7 +121,7 @@ class Search(BaseSearch):
allowed_repos_filter = self._get_repo_filter(
search_user, repo_name)
try:
query = qp.parse(unicode(query))
query = qp.parse(safe_unicode(query))
log.debug('query: %s (%s)' % (query, repr(query)))
reverse, sortedby = False, None
@ -147,20 +146,20 @@ class Search(BaseSearch):
search_type, res_ln, whoosh_results)
except QueryParserError:
result['error'] = _('Invalid search query. Try quoting it.')
result['error'] = 'Invalid search query. Try quoting it.'
except (EmptyIndexError, IOError, OSError):
msg = _('There is no index to search in. '
'Please run whoosh indexer')
msg = 'There is no index to search in. Please run whoosh indexer'
log.exception(msg)
result['error'] = msg
except Exception:
msg = _('An error occurred during this search operation')
msg = 'An error occurred during this search operation'
log.exception(msg)
result['error'] = msg
return result
def statistics(self):
def statistics(self, translator):
_ = translator
stats = [
{'key': _('Index Type'), 'value': 'Whoosh'},
{'key': _('File Index'), 'value': str(self.file_index)},

View file

@ -796,11 +796,11 @@ def suuid(url=None, truncate_to=22, alphabet=None):
return "".join(output)[:truncate_to]
def get_current_rhodecode_user():
def get_current_rhodecode_user(request=None):
"""
Gets rhodecode user from request
"""
pyramid_request = pyramid.threadlocal.get_current_request()
pyramid_request = request or pyramid.threadlocal.get_current_request()
# web case
if pyramid_request and hasattr(pyramid_request, 'user'):

View file

@ -48,7 +48,6 @@ import formencode
from pkg_resources import resource_filename
from formencode import All, Pipe
from rhodecode.translation import temp_translation_factory as _
from pyramid.threadlocal import get_current_request
from rhodecode import BACKENDS

View file

@ -30,7 +30,6 @@ import logging
import cStringIO
import pkg_resources
from rhodecode.translation import temp_translation_factory as _
from sqlalchemy import func
from zope.cachedescriptors.property import Lazy as LazyProperty
@ -40,7 +39,6 @@ from rhodecode.lib.vcs.exceptions import RepositoryError, NodeNotChangedError
from rhodecode.lib.vcs.nodes import FileNode
from rhodecode.lib.vcs.backends.base import EmptyCommit
from rhodecode.lib import helpers as h
from rhodecode.lib.auth import (
HasRepoPermissionAny, HasRepoGroupPermissionAny,
HasUserGroupPermissionAny)
@ -748,14 +746,14 @@ class ScmModel(BaseModel):
def get_unread_journal(self):
return self.sa.query(UserLog).count()
def get_repo_landing_revs(self, repo=None):
def get_repo_landing_revs(self, translator, repo=None):
"""
Generates select option with tags branches and bookmarks (for hg only)
grouped by type
:param repo:
"""
_ = translator
repo = self._get_repo(repo)
hist_l = [

View file

@ -24,11 +24,10 @@ users model for RhodeCode
import logging
import traceback
import datetime
from rhodecode.translation import temp_translation_factory as _
import ipaddress
from pyramid.threadlocal import get_current_request
from sqlalchemy.exc import DatabaseError
from rhodecode import events
@ -163,8 +162,9 @@ class UserModel(BaseModel):
user = self._get_user(user)
if user.username == User.DEFAULT_USER:
raise DefaultUserException(
_("You can't Edit this user since it's"
" crucial for entire application"))
"You can't edit this user (`%(username)s`) since it's "
"crucial for entire application" % {
'username': user.username})
# first store only defaults
user_attrs = {
@ -247,6 +247,7 @@ class UserModel(BaseModel):
:returns: new User object with injected `is_new_user` attribute.
"""
if not cur_user:
cur_user = getattr(get_current_rhodecode_user(), 'username', None)
@ -330,8 +331,9 @@ class UserModel(BaseModel):
# we're not allowed to edit default user
if user.username == User.DEFAULT_USER:
raise DefaultUserException(
_("You can't edit this user (`%(username)s`) since it's "
"crucial for entire application") % {'username': user.username})
"You can't edit this user (`%(username)s`) since it's "
"crucial for entire application"
% {'username': user.username})
# inject special attribute that will tell us if User is new or old
new_user.is_new_user = not edit
@ -497,40 +499,43 @@ class UserModel(BaseModel):
def delete(self, user, cur_user=None, handle_repos=None,
handle_repo_groups=None, handle_user_groups=None):
if not cur_user:
cur_user = getattr(get_current_rhodecode_user(), 'username', None)
cur_user = getattr(
get_current_rhodecode_user(), 'username', None)
user = self._get_user(user)
try:
if user.username == User.DEFAULT_USER:
raise DefaultUserException(
_(u"You can't remove this user since it's"
u" crucial for entire application"))
u"You can't remove this user since it's"
u" crucial for entire application")
left_overs = self._handle_user_repos(
user.username, user.repositories, handle_repos)
if left_overs and user.repositories:
repos = [x.repo_name for x in user.repositories]
raise UserOwnsReposException(
_(u'user "%s" still owns %s repositories and cannot be '
u'removed. Switch owners or remove those repositories:%s')
% (user.username, len(repos), ', '.join(repos)))
u'user "%(username)s" still owns %(len_repos)s repositories and cannot be '
u'removed. Switch owners or remove those repositories:%(list_repos)s'
% {'username': user.username, 'len_repos': len(repos),
'list_repos': ', '.join(repos)})
left_overs = self._handle_user_repo_groups(
user.username, user.repository_groups, handle_repo_groups)
if left_overs and user.repository_groups:
repo_groups = [x.group_name for x in user.repository_groups]
raise UserOwnsRepoGroupsException(
_(u'user "%s" still owns %s repository groups and cannot be '
u'removed. Switch owners or remove those repository groups:%s')
% (user.username, len(repo_groups), ', '.join(repo_groups)))
u'user "%(username)s" still owns %(len_repo_groups)s repository groups and cannot be '
u'removed. Switch owners or remove those repository groups:%(list_repo_groups)s'
% {'username': user.username, 'len_repo_groups': len(repo_groups),
'list_repo_groups': ', '.join(repo_groups)})
left_overs = self._handle_user_user_groups(
user.username, user.user_groups, handle_user_groups)
if left_overs and user.user_groups:
user_groups = [x.users_group_name for x in user.user_groups]
raise UserOwnsUserGroupsException(
_(u'user "%s" still owns %s user groups and cannot be '
u'removed. Switch owners or remove those user groups:%s')
u'user "%s" still owns %s user groups and cannot be '
u'removed. Switch owners or remove those user groups:%s'
% (user.username, len(user_groups), ', '.join(user_groups)))
# we might change the user data with detach/delete, make sure

View file

@ -37,7 +37,6 @@ from formencode.validators import (
from sqlalchemy.sql.expression import true
from sqlalchemy.util import OrderedSet
from webhelpers.pylonslib.secure_form import authentication_token
from rhodecode.authentication import (
legacy_plugin_prefix, _import_legacy_plugin)
@ -455,21 +454,6 @@ def ValidAuth(localizer):
return _validator
def ValidAuthToken(localizer):
_ = localizer
class _validator(formencode.validators.FancyValidator):
messages = {
'invalid_token': _(u'Token mismatch')
}
def validate_python(self, value, state):
if value != authentication_token():
msg = M(self, 'invalid_token', state)
raise formencode.Invalid(msg, value, state)
return _validator
def ValidRepoName(localizer, edit=False, old_data=None):
old_data = old_data or {}
_ = localizer

View file

@ -195,12 +195,6 @@ def write_js_routes_if_enabled(event):
)
def get_routes():
# pylons routes
# TODO(marcink): remove when pyramid migration is finished
if 'routes.map' in rhodecode.CONFIG:
for route in rhodecode.CONFIG['routes.map'].jsroutes():
yield route
# pyramid routes
for route in mapper.get_routes():
if not route.name.startswith('__'):

View file

@ -85,7 +85,8 @@ def _get_backend(backend_type):
class DBBackend(object):
_store = os.path.dirname(os.path.abspath(__file__))
_type = None
_base_ini_config = [{'app:main': {'vcs.start_server': 'false'}}]
_base_ini_config = [{'app:main': {'vcs.start_server': 'false',
'startup.import_repos': 'false'}}]
_db_url = [{'app:main': {'sqlalchemy.db1.url': ''}}]
_base_db_name = 'rhodecode_test_db_backend'
@ -183,7 +184,7 @@ class DBBackend(object):
if not os.path.isdir(self._repos_location):
os.makedirs(self._repos_location)
self.execute(
"paster upgrade-db {} --force-yes".format(ini_file))
"rc-upgrade-db {0} --force-yes".format(ini_file))
def setup_db(self):
raise NotImplementedError

View file

@ -56,11 +56,22 @@ class TestSessionBehaviorOnPasswordChange(object):
def test_sessions_invalidated_when_password_is_changed(
self, app, autologin_user):
response = app.get(route_path('home'), status=200)
session = response.get_session_from_response()
# now mark as password change
self.password_changed_mock.return_value = True
# flushes session first
app.get(route_path('home'))
# second call is now "different" with flushed empty session
response = app.get(route_path('home'))
session = response.get_session_from_response()
assert 'rhodecode_user' not in session
assert_response = response.assert_response()
assert_response.element_contains('#quick_login_link .user', 'Sign in')
session = response.get_session_from_response()
assert 'rhodecode_user' not in session
assert session.was_invalidated is True

View file

@ -74,8 +74,7 @@ def get_environ(url, request_method):
])
def test_get_action(url, expected_action, request_method, baseapp, request_stub):
app = simplegit.SimpleGit(application=None,
config={'auth_ret_code': '', 'base_path': ''},
app = simplegit.SimpleGit(config={'auth_ret_code': '', 'base_path': ''},
registry=request_stub.registry)
assert expected_action == app._get_action(get_environ(url, request_method))
@ -103,8 +102,7 @@ def test_get_action(url, expected_action, request_method, baseapp, request_stub)
])
def test_get_repository_name(url, expected_repo_name, request_method, baseapp, request_stub):
app = simplegit.SimpleGit(application=None,
config={'auth_ret_code': '', 'base_path': ''},
app = simplegit.SimpleGit(config={'auth_ret_code': '', 'base_path': ''},
registry=request_stub.registry)
assert expected_repo_name == app._get_repository_name(
get_environ(url, request_method))
@ -112,8 +110,7 @@ def test_get_repository_name(url, expected_repo_name, request_method, baseapp, r
def test_get_config(user_util, baseapp, request_stub):
repo = user_util.create_repo(repo_type='git')
app = simplegit.SimpleGit(application=None,
config={'auth_ret_code': '', 'base_path': ''},
app = simplegit.SimpleGit(config={'auth_ret_code': '', 'base_path': ''},
registry=request_stub.registry)
extras = {'foo': 'FOO', 'bar': 'BAR'}
@ -137,6 +134,6 @@ def test_create_wsgi_app_uses_scm_app_from_simplevcs(baseapp, request_stub):
'vcs.scm_app_implementation':
'rhodecode.tests.lib.middleware.mock_scm_app',
}
app = simplegit.SimpleGit(application=None, config=config, registry=request_stub.registry)
app = simplegit.SimpleGit(config=config, registry=request_stub.registry)
wsgi_app = app._create_wsgi_app('/tmp/test', 'test_repo', {})
assert wsgi_app is mock_scm_app.mock_git_wsgi

View file

@ -54,8 +54,7 @@ def get_environ(url):
('/foo/bar?key=tip', 'pull'),
])
def test_get_action(url, expected_action, request_stub):
app = simplehg.SimpleHg(application=None,
config={'auth_ret_code': '', 'base_path': ''},
app = simplehg.SimpleHg(config={'auth_ret_code': '', 'base_path': ''},
registry=request_stub.registry)
assert expected_action == app._get_action(get_environ(url))
@ -72,16 +71,14 @@ def test_get_action(url, expected_action, request_stub):
('/foo/bar/baz/?cmd=listkeys&key=tip', 'foo/bar/baz'),
])
def test_get_repository_name(url, expected_repo_name, request_stub):
app = simplehg.SimpleHg(application=None,
config={'auth_ret_code': '', 'base_path': ''},
app = simplehg.SimpleHg(config={'auth_ret_code': '', 'base_path': ''},
registry=request_stub.registry)
assert expected_repo_name == app._get_repository_name(get_environ(url))
def test_get_config(user_util, baseapp, request_stub):
repo = user_util.create_repo(repo_type='git')
app = simplehg.SimpleHg(application=None,
config={'auth_ret_code': '', 'base_path': ''},
app = simplehg.SimpleHg(config={'auth_ret_code': '', 'base_path': ''},
registry=request_stub.registry)
extras = [('foo', 'FOO', 'bar', 'BAR')]
@ -123,7 +120,6 @@ def test_create_wsgi_app_uses_scm_app_from_simplevcs(request_stub):
'vcs.scm_app_implementation':
'rhodecode.tests.lib.middleware.mock_scm_app',
}
app = simplehg.SimpleHg(
application=None, config=config, registry=request_stub.registry)
app = simplehg.SimpleHg(config=config, registry=request_stub.registry)
wsgi_app = app._create_wsgi_app('/tmp/test', 'test_repo', {})
assert wsgi_app is mock_scm_app.mock_hg_wsgi

View file

@ -23,17 +23,16 @@ from StringIO import StringIO
import pytest
from mock import patch, Mock
import rhodecode
from rhodecode.lib.middleware.simplesvn import SimpleSvn, SimpleSvnApp
from rhodecode.lib.utils import get_rhodecode_base_path
class TestSimpleSvn(object):
@pytest.fixture(autouse=True)
def simple_svn(self, baseapp, request_stub):
base_path = get_rhodecode_base_path()
self.app = SimpleSvn(
application='None',
config={'auth_ret_code': '',
'base_path': rhodecode.CONFIG['base_path']},
config={'auth_ret_code': '', 'base_path': base_path},
registry=request_stub.registry)
def test_get_config(self):
@ -102,7 +101,6 @@ class TestSimpleSvn(object):
assert wsgi_app == wsgi_app_mock()
class TestSimpleSvnApp(object):
data = '<xml></xml>'
path = '/group/my-repo'
@ -121,8 +119,10 @@ class TestSimpleSvnApp(object):
def setup_method(self, method):
self.host = 'http://localhost/'
base_path = get_rhodecode_base_path()
self.app = SimpleSvnApp(
config={'subversion_http_server_url': self.host})
config={'subversion_http_server_url': self.host,
'base_path': base_path})
def test_get_request_headers_with_content_type(self):
expected_headers = {

View file

@ -79,8 +79,8 @@ def vcscontroller(baseapp, config_stub, request_stub):
config_stub.include('rhodecode.authentication')
controller = StubVCSController(
baseapp, baseapp.config, request_stub.registry)
app = HttpsFixup(controller, baseapp.config)
baseapp.config.get_settings(), request_stub.registry)
app = HttpsFixup(controller, baseapp.config.get_settings())
app = CustomTestApp(app)
_remove_default_user_from_query_cache()
@ -136,8 +136,8 @@ class StubFailVCSController(simplevcs.SimpleVCS):
@pytest.fixture(scope='module')
def fail_controller(baseapp):
controller = StubFailVCSController(
baseapp, baseapp.config, baseapp.config)
controller = HttpsFixup(controller, baseapp.config)
baseapp.config.get_settings(), baseapp.config)
controller = HttpsFixup(controller, baseapp.config.get_settings())
controller = CustomTestApp(controller)
return controller
@ -153,17 +153,15 @@ def test_provides_traceback_for_appenlight(fail_controller):
def test_provides_utils_scm_app_as_scm_app_by_default(baseapp, request_stub):
controller = StubVCSController(
baseapp, baseapp.config, request_stub.registry)
controller = StubVCSController(baseapp.config.get_settings(), request_stub.registry)
assert controller.scm_app is scm_app_http
def test_allows_to_override_scm_app_via_config(baseapp, request_stub):
config = baseapp.config.copy()
config = baseapp.config.get_settings().copy()
config['vcs.scm_app_implementation'] = (
'rhodecode.tests.lib.middleware.mock_scm_app')
controller = StubVCSController(
baseapp, config, request_stub.registry)
controller = StubVCSController(config, request_stub.registry)
assert controller.scm_app is mock_scm_app
@ -225,7 +223,7 @@ class TestShadowRepoExposure(object):
underlying wsgi app.
"""
controller = StubVCSController(
baseapp, baseapp.config, request_stub.registry)
baseapp.config.get_settings(), request_stub.registry)
controller._check_ssl = mock.Mock()
controller.is_shadow_repo = True
controller._action = 'pull'
@ -250,7 +248,7 @@ class TestShadowRepoExposure(object):
underlying wsgi app.
"""
controller = StubVCSController(
baseapp, baseapp.config, request_stub.registry)
baseapp.config.get_settings(), request_stub.registry)
controller._check_ssl = mock.Mock()
controller.is_shadow_repo = True
controller._action = 'pull'
@ -274,7 +272,7 @@ class TestShadowRepoExposure(object):
Check that a push action to a shadow repo is aborted.
"""
controller = StubVCSController(
baseapp, baseapp.config, request_stub.registry)
baseapp.config.get_settings(), request_stub.registry)
controller._check_ssl = mock.Mock()
controller.is_shadow_repo = True
controller._action = 'push'
@ -300,7 +298,7 @@ class TestShadowRepoExposure(object):
"""
environ_stub = {}
controller = StubVCSController(
baseapp, baseapp.config, request_stub.registry)
baseapp.config.get_settings(), request_stub.registry)
controller._name = 'RepoGroup/MyRepo'
controller.set_repo_names(environ_stub)
assert not controller.is_shadow_repo
@ -324,7 +322,7 @@ class TestShadowRepoExposure(object):
pr_segment=TestShadowRepoRegularExpression.pr_segment,
shadow_segment=TestShadowRepoRegularExpression.shadow_segment)
controller = StubVCSController(
baseapp, baseapp.config, request_stub.registry)
baseapp.config.get_settings(), request_stub.registry)
controller._name = shadow_url
controller.set_repo_names({})
@ -352,7 +350,7 @@ class TestShadowRepoExposure(object):
pr_segment=TestShadowRepoRegularExpression.pr_segment,
shadow_segment=TestShadowRepoRegularExpression.shadow_segment)
controller = StubVCSController(
baseapp, baseapp.config, request_stub.registry)
baseapp.config.get_settings(), request_stub.registry)
controller._name = shadow_url
controller.set_repo_names({})
@ -362,7 +360,7 @@ class TestShadowRepoExposure(object):
controller.vcs_repo_name)
@pytest.mark.usefixtures('db')
@pytest.mark.usefixtures('baseapp')
class TestGenerateVcsResponse(object):
def test_ensures_that_start_response_is_called_early_enough(self):
@ -429,7 +427,7 @@ class TestGenerateVcsResponse(object):
'vcs.hooks.direct_calls': False,
}
registry = AttributeDict()
controller = StubVCSController(None, settings, registry)
controller = StubVCSController(settings, registry)
controller._invalidate_cache = mock.Mock()
controller.stub_response_body = response_body
self.start_response = mock.Mock()
@ -482,7 +480,7 @@ class TestPrepareHooksDaemon(object):
expected_extras = {'extra1': 'value1'}
daemon = DummyHooksCallbackDaemon()
controller = StubVCSController(None, app_settings, request_stub.registry)
controller = StubVCSController(app_settings, request_stub.registry)
prepare_patcher = mock.patch.object(
simplevcs, 'prepare_callback_daemon',
return_value=(daemon, expected_extras))

View file

@ -44,10 +44,8 @@ def test_vcs_unavailable_returns_vcs_error_page(app, backend):
# Patch remote repo to raise an exception instead of making a RPC.
with mock.patch.object(RemoteRepo, '__getattr__') as remote_mock:
remote_mock.side_effect = VCSCommunicationError()
# Patch pylons error handling middleware to not re-raise exceptions.
with mock.patch.object(PylonsErrorHandlingMiddleware, 'reraise') as r:
r.return_value = False
response = app.get(url, expect_errors=True)
response = app.get(url, expect_errors=True)
assert response.status_code == 502
assert 'Could not connect to VCS Server' in response.body

View file

@ -29,6 +29,6 @@ from rhodecode.model.db import UserLog
'user_closed_pull_request',
'user_merged_pull_request'
])
def test_action_map_pr_values(baseapp, pr_key):
parser = ActionParser(UserLog(action="test:test"))
def test_action_map_pr_values(request_stub, baseapp, pr_key):
parser = ActionParser(request_stub, UserLog(action="test:test"))
assert pr_key in parser.action_map

View file

@ -23,7 +23,7 @@ import textwrap
import pytest
from rhodecode.lib.diffs import (
DiffProcessor, wrapped_diff,
DiffProcessor,
NEW_FILENODE, DEL_FILENODE, MOD_FILENODE, RENAMED_FILENODE,
CHMOD_FILENODE, BIN_FILENODE, COPIED_FILENODE)
from rhodecode.tests.fixture import Fixture
@ -34,23 +34,6 @@ from rhodecode.lib.vcs.backends.svn.repository import SubversionDiff
fixture = Fixture()
def test_wrapped_diff_limited_file_diff(vcsbackend_random):
vcsbackend = vcsbackend_random
repo = vcsbackend.create_repo()
vcsbackend.add_file(repo, 'a_file', content="line 1\nline 2\nline3\n")
commit = repo.get_commit()
file_node = commit.get_node('a_file')
# Only limit the file diff to trigger the code path
result = wrapped_diff(
None, file_node, diff_limit=10000, file_limit=1)
data = result[5]
# Verify that the limits were applied
assert data['exceeds_limit'] is True
assert data['is_limited_diff'] is True
def test_diffprocessor_as_html_with_comments():
raw_diff = textwrap.dedent('''
diff --git a/setup.py b/setup.py

View file

@ -158,7 +158,7 @@ def test_formatted_json():
assert formatted_json(data) == expected_data
def test_pylons_lazy_translation_string(baseapp):
def test_lazy_translation_string(baseapp):
data = {'label': _('hello')}
data2 = {'label2': _pluralize('singular', 'plural', 1)}

View file

@ -65,7 +65,7 @@ class TestPullRequestModel(object):
'rhodecode.model.notification.NotificationModel.create')
self.notification_patcher.start()
self.helper_patcher = mock.patch(
'rhodecode.lib.helpers.url')
'rhodecode.lib.helpers.route_path')
self.helper_patcher.start()
self.hook_patcher = mock.patch.object(PullRequestModel,

View file

@ -183,7 +183,7 @@ def test_get_non_unicode_reference(backend):
tags=non_unicode_list, alias=backend.alias)
repo = Mock(__class__=db.Repository, scm_instance=scm_instance)
choices, __ = model.get_repo_landing_revs(repo=repo)
choices, __ = model.get_repo_landing_revs(translator=lambda s: s, repo=repo)
if backend.alias == 'hg':
valid_choices = [
'rev:tip', u'branch:Ad\xc4\xb1n\xc4\xb1',

View file

@ -209,12 +209,6 @@ def test_ValidAuth(localizer, config_stub):
formencode.Invalid, validator.to_python, invalid_creds)
def test_ValidAuthToken(localizer):
validator = v.ValidAuthToken(localizer)
pytest.raises(formencode.Invalid, validator.to_python, 'BadToken')
validator
def test_ValidRepoName(localizer):
validator = v.ValidRepoName(localizer)

View file

@ -23,8 +23,6 @@ from pyramid.threadlocal import get_current_request
_ = TranslationStringFactory('rhodecode')
temp_translation_factory = _
class _LazyString(object):
def __init__(self, *args, **kw):