##// END OF EJS Templates
home: moved home and repo group views into pyramid....
marcink -
r1774:90a81bb6 default
parent child
Show More
@@ -0,0 +1,33
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 from rhodecode.apps._base import add_route_with_slash
21
22
23 def includeme(config):
24
25 # Summary
26 add_route_with_slash(
27 config,
28 name='repo_group_home',
29 pattern='/{repo_group_name:.*?[^/]}', repo_group_route=True)
30
31 # Scan module for configuration decorators.
32 config.scan()
33
@@ -28,7 +28,7 from rhodecode.api.tests.utils import (
28
28
29 @pytest.mark.usefixtures("testuser_api", "app")
29 @pytest.mark.usefixtures("testuser_api", "app")
30 class TestApiGetGist(object):
30 class TestApiGetGist(object):
31 def test_api_get_gist(self, gist_util):
31 def test_api_get_gist(self, gist_util, http_host_stub):
32 gist = gist_util.create_gist()
32 gist = gist_util.create_gist()
33 gist_id = gist.gist_access_id
33 gist_id = gist.gist_access_id
34 gist_created_on = gist.created_on
34 gist_created_on = gist.created_on
@@ -45,14 +45,14 class TestApiGetGist(object):
45 'expires': -1.0,
45 'expires': -1.0,
46 'gist_id': int(gist_id),
46 'gist_id': int(gist_id),
47 'type': 'public',
47 'type': 'public',
48 'url': 'http://test.example.com:80/_admin/gists/%s' % (gist_id,),
48 'url': 'http://%s/_admin/gists/%s' % (http_host_stub, gist_id,),
49 'acl_level': Gist.ACL_LEVEL_PUBLIC,
49 'acl_level': Gist.ACL_LEVEL_PUBLIC,
50 'content': None,
50 'content': None,
51 }
51 }
52
52
53 assert_ok(id_, expected, given=response.body)
53 assert_ok(id_, expected, given=response.body)
54
54
55 def test_api_get_gist_with_content(self, gist_util):
55 def test_api_get_gist_with_content(self, gist_util, http_host_stub):
56 mapping = {
56 mapping = {
57 u'filename1.txt': {'content': u'hello world'},
57 u'filename1.txt': {'content': u'hello world'},
58 u'filename1ą.txt': {'content': u'hello worldę'}
58 u'filename1ą.txt': {'content': u'hello worldę'}
@@ -73,7 +73,7 class TestApiGetGist(object):
73 'expires': -1.0,
73 'expires': -1.0,
74 'gist_id': int(gist_id),
74 'gist_id': int(gist_id),
75 'type': 'public',
75 'type': 'public',
76 'url': 'http://test.example.com:80/_admin/gists/%s' % (gist_id,),
76 'url': 'http://%s/_admin/gists/%s' % (http_host_stub, gist_id,),
77 'acl_level': Gist.ACL_LEVEL_PUBLIC,
77 'acl_level': Gist.ACL_LEVEL_PUBLIC,
78 'content': {
78 'content': {
79 u'filename1.txt': u'hello world',
79 u'filename1.txt': u'hello world',
@@ -19,13 +19,13
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 import mock
23 import pytest
22 import pytest
24 import urlobject
23 import urlobject
25 from pylons import url
24 from pylons import url
26
25
27 from rhodecode.api.tests.utils import (
26 from rhodecode.api.tests.utils import (
28 build_data, api_call, assert_error, assert_ok)
27 build_data, api_call, assert_error, assert_ok)
28 from rhodecode.lib.utils2 import safe_unicode
29
29
30 pytestmark = pytest.mark.backends("git", "hg")
30 pytestmark = pytest.mark.backends("git", "hg")
31
31
@@ -33,7 +33,7 pytestmark = pytest.mark.backends("git",
33 @pytest.mark.usefixtures("testuser_api", "app")
33 @pytest.mark.usefixtures("testuser_api", "app")
34 class TestGetPullRequest(object):
34 class TestGetPullRequest(object):
35
35
36 def test_api_get_pull_request(self, pr_util):
36 def test_api_get_pull_request(self, pr_util, http_host_stub, http_host_only_stub):
37 from rhodecode.model.pull_request import PullRequestModel
37 from rhodecode.model.pull_request import PullRequestModel
38 pull_request = pr_util.create_pull_request(mergeable=True)
38 pull_request = pr_util.create_pull_request(mergeable=True)
39 id_, params = build_data(
39 id_, params = build_data(
@@ -50,16 +50,16 class TestGetPullRequest(object):
50 'pullrequest_show',
50 'pullrequest_show',
51 repo_name=pull_request.target_repo.repo_name,
51 repo_name=pull_request.target_repo.repo_name,
52 pull_request_id=pull_request.pull_request_id, qualified=True))
52 pull_request_id=pull_request.pull_request_id, qualified=True))
53 pr_url = unicode(
53
54 url_obj.with_netloc('test.example.com:80'))
54 pr_url = safe_unicode(
55 source_url = unicode(
55 url_obj.with_netloc(http_host_stub))
56 pull_request.source_repo.clone_url()
56 source_url = safe_unicode(
57 .with_netloc('test.example.com:80'))
57 pull_request.source_repo.clone_url().with_netloc(http_host_only_stub))
58 target_url = unicode(
58 target_url = safe_unicode(
59 pull_request.target_repo.clone_url()
59 pull_request.target_repo.clone_url().with_netloc(http_host_only_stub))
60 .with_netloc('test.example.com:80'))
60 shadow_url = safe_unicode(
61 shadow_url = unicode(
62 PullRequestModel().get_shadow_clone_url(pull_request))
61 PullRequestModel().get_shadow_clone_url(pull_request))
62
63 expected = {
63 expected = {
64 'pull_request_id': pull_request.pull_request_id,
64 'pull_request_id': pull_request.pull_request_id,
65 'url': pr_url,
65 'url': pr_url,
@@ -26,7 +26,7 from rhodecode.tests import TEST_USER_AD
26 from rhodecode.api.tests.utils import (
26 from rhodecode.api.tests.utils import (
27 build_data, api_call, assert_error, assert_ok, crash, jsonify)
27 build_data, api_call, assert_error, assert_ok, crash, jsonify)
28 from rhodecode.tests.fixture import Fixture
28 from rhodecode.tests.fixture import Fixture
29
29 from rhodecode.tests.plugin import http_host_stub, http_host_only_stub
30
30
31 fixture = Fixture()
31 fixture = Fixture()
32
32
@@ -71,14 +71,15 class TestApiUpdateRepo(object):
71 ({'repo_name': 'new_repo_name'},
71 ({'repo_name': 'new_repo_name'},
72 {
72 {
73 'repo_name': 'new_repo_name',
73 'repo_name': 'new_repo_name',
74 'url': 'http://test.example.com:80/new_repo_name'
74 'url': 'http://{}/new_repo_name'.format(http_host_only_stub())
75 }),
75 }),
76
76
77 ({'repo_name': 'test_group_for_update/{}'.format(UPDATE_REPO_NAME),
77 ({'repo_name': 'test_group_for_update/{}'.format(UPDATE_REPO_NAME),
78 '_group': 'test_group_for_update'},
78 '_group': 'test_group_for_update'},
79 {
79 {
80 'repo_name': 'test_group_for_update/{}'.format(UPDATE_REPO_NAME),
80 'repo_name': 'test_group_for_update/{}'.format(UPDATE_REPO_NAME),
81 'url': 'http://test.example.com:80/test_group_for_update/{}'.format(UPDATE_REPO_NAME)
81 'url': 'http://{}/test_group_for_update/{}'.format(
82 http_host_only_stub(), UPDATE_REPO_NAME)
82 }),
83 }),
83 ])
84 ])
84 def test_api_update_repo(self, updates, expected, backend):
85 def test_api_update_repo(self, updates, expected, backend):
@@ -0,0 +1,19
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
@@ -29,6 +29,7 from rhodecode.lib.utils2 import StrictA
29 from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
29 from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
30 from rhodecode.lib.ext_json import json
30 from rhodecode.lib.ext_json import json
31 from rhodecode.model import repo
31 from rhodecode.model import repo
32 from rhodecode.model import repo_group
32 from rhodecode.model.db import User
33 from rhodecode.model.db import User
33 from rhodecode.model.scm import ScmModel
34 from rhodecode.model.scm import ScmModel
34
35
@@ -39,6 +40,12 ADMIN_PREFIX = '/_admin'
39 STATIC_FILE_PREFIX = '/_static'
40 STATIC_FILE_PREFIX = '/_static'
40
41
41
42
43 def add_route_with_slash(config,name, pattern, **kw):
44 config.add_route(name, pattern, **kw)
45 if not pattern.endswith('/'):
46 config.add_route(name + '_slash', pattern + '/', **kw)
47
48
42 def get_format_ref_id(repo):
49 def get_format_ref_id(repo):
43 """Returns a `repo` specific reference formatter function"""
50 """Returns a `repo` specific reference formatter function"""
44 if h.is_svn(repo):
51 if h.is_svn(repo):
@@ -253,8 +260,7 class RepoRoutePredicate(object):
253 repo_name = info['match']['repo_name']
260 repo_name = info['match']['repo_name']
254 repo_model = repo.RepoModel()
261 repo_model = repo.RepoModel()
255 by_name_match = repo_model.get_by_repo_name(repo_name, cache=True)
262 by_name_match = repo_model.get_by_repo_name(repo_name, cache=True)
256 # if we match quickly from database, short circuit the operation,
263
257 # and validate repo based on the type.
258 if by_name_match:
264 if by_name_match:
259 # register this as request object we can re-use later
265 # register this as request object we can re-use later
260 request.db_repo = by_name_match
266 request.db_repo = by_name_match
@@ -300,9 +306,33 class RepoTypeRoutePredicate(object):
300 return False
306 return False
301
307
302
308
309 class RepoGroupRoutePredicate(object):
310 def __init__(self, val, config):
311 self.val = val
312
313 def text(self):
314 return 'repo_group_route = %s' % self.val
315
316 phash = text
317
318 def __call__(self, info, request):
319 repo_group_name = info['match']['repo_group_name']
320 repo_group_model = repo_group.RepoGroupModel()
321 by_name_match = repo_group_model.get_by_group_name(
322 repo_group_name, cache=True)
323
324 if by_name_match:
325 # register this as request object we can re-use later
326 request.db_repo_group = by_name_match
327 return True
328
329 return False
330
303
331
304 def includeme(config):
332 def includeme(config):
305 config.add_route_predicate(
333 config.add_route_predicate(
306 'repo_route', RepoRoutePredicate)
334 'repo_route', RepoRoutePredicate)
307 config.add_route_predicate(
335 config.add_route_predicate(
308 'repo_accepted_types', RepoTypeRoutePredicate) No newline at end of file
336 'repo_accepted_types', RepoTypeRoutePredicate)
337 config.add_route_predicate(
338 'repo_group_route', RepoGroupRoutePredicate)
@@ -28,18 +28,25 from rhodecode.model.meta import Session
28 from rhodecode.model.repo import RepoModel
28 from rhodecode.model.repo import RepoModel
29 from rhodecode.model.repo_group import RepoGroupModel
29 from rhodecode.model.repo_group import RepoGroupModel
30 from rhodecode.model.settings import SettingsModel
30 from rhodecode.model.settings import SettingsModel
31 from rhodecode.tests import TestController, url
31 from rhodecode.tests import TestController
32 from rhodecode.tests.fixture import Fixture
32 from rhodecode.tests.fixture import Fixture
33
33
34
34
35 fixture = Fixture()
35 fixture = Fixture()
36
36
37
37
38 def route_path(name, **kwargs):
39 return {
40 'home': '/',
41 'repo_group_home': '/{repo_group_name}'
42 }[name].format(**kwargs)
43
44
38 class TestHomeController(TestController):
45 class TestHomeController(TestController):
39
46
40 def test_index(self):
47 def test_index(self):
41 self.log_user()
48 self.log_user()
42 response = self.app.get(url(controller='home', action='index'))
49 response = self.app.get(route_path('home'))
43 # if global permission is set
50 # if global permission is set
44 response.mustcontain('Add Repository')
51 response.mustcontain('Add Repository')
45
52
@@ -49,7 +56,7 class TestHomeController(TestController)
49
56
50 def test_index_contains_statics_with_ver(self):
57 def test_index_contains_statics_with_ver(self):
51 self.log_user()
58 self.log_user()
52 response = self.app.get(url(controller='home', action='index'))
59 response = self.app.get(route_path('home'))
53
60
54 rhodecode_version_hash = c.rhodecode_version_hash
61 rhodecode_version_hash = c.rhodecode_version_hash
55 response.mustcontain('style.css?ver={0}'.format(rhodecode_version_hash))
62 response.mustcontain('style.css?ver={0}'.format(rhodecode_version_hash))
@@ -57,7 +64,7 class TestHomeController(TestController)
57
64
58 def test_index_contains_backend_specific_details(self, backend):
65 def test_index_contains_backend_specific_details(self, backend):
59 self.log_user()
66 self.log_user()
60 response = self.app.get(url(controller='home', action='index'))
67 response = self.app.get(route_path('home'))
61 tip = backend.repo.get_commit().raw_id
68 tip = backend.repo.get_commit().raw_id
62
69
63 # html in javascript variable:
70 # html in javascript variable:
@@ -69,17 +76,16 class TestHomeController(TestController)
69
76
70 def test_index_with_anonymous_access_disabled(self):
77 def test_index_with_anonymous_access_disabled(self):
71 with fixture.anon_access(False):
78 with fixture.anon_access(False):
72 response = self.app.get(url(controller='home', action='index'),
79 response = self.app.get(route_path('home'), status=302)
73 status=302)
74 assert 'login' in response.location
80 assert 'login' in response.location
75
81
76 def test_index_page_on_groups(self, autologin_user, repo_group):
82 def test_index_page_on_groups(self, autologin_user, repo_group):
77 response = self.app.get(url('repo_group_home', group_name='gr1'))
83 response = self.app.get(route_path('repo_group_home', repo_group_name='gr1'))
78 response.mustcontain("gr1/repo_in_group")
84 response.mustcontain("gr1/repo_in_group")
79
85
80 def test_index_page_on_group_with_trailing_slash(
86 def test_index_page_on_group_with_trailing_slash(
81 self, autologin_user, repo_group):
87 self, autologin_user, repo_group):
82 response = self.app.get(url('repo_group_home', group_name='gr1') + '/')
88 response = self.app.get(route_path('repo_group_home', repo_group_name='gr1') + '/')
83 response.mustcontain("gr1/repo_in_group")
89 response.mustcontain("gr1/repo_in_group")
84
90
85 @pytest.fixture(scope='class')
91 @pytest.fixture(scope='class')
@@ -93,15 +99,17 class TestHomeController(TestController)
93 RepoGroupModel().delete(repo_group='gr1', force_delete=True)
99 RepoGroupModel().delete(repo_group='gr1', force_delete=True)
94 Session().commit()
100 Session().commit()
95
101
96 def test_index_with_name_with_tags(self, autologin_user):
102 def test_index_with_name_with_tags(self, user_util, autologin_user):
97 user = User.get_by_username('test_admin')
103 user = user_util.create_user()
104 username = user.username
98 user.name = '<img src="/image1" onload="alert(\'Hello, World!\');">'
105 user.name = '<img src="/image1" onload="alert(\'Hello, World!\');">'
99 user.lastname = (
106 user.lastname = (
100 '<img src="/image2" onload="alert(\'Hello, World!\');">')
107 '<img src="/image2" onload="alert(\'Hello, World!\');">')
101 Session().add(user)
108 Session().add(user)
102 Session().commit()
109 Session().commit()
110 user_util.create_repo(owner=username)
103
111
104 response = self.app.get(url(controller='home', action='index'))
112 response = self.app.get(route_path('home'))
105 response.mustcontain(
113 response.mustcontain(
106 '&lt;img src=&#34;/image1&#34; onload=&#34;'
114 '&lt;img src=&#34;/image1&#34; onload=&#34;'
107 'alert(&#39;Hello, World!&#39;);&#34;&gt;')
115 'alert(&#39;Hello, World!&#39;);&#34;&gt;')
@@ -122,7 +130,7 class TestHomeController(TestController)
122 Session().commit()
130 Session().commit()
123 SettingsModel().invalidate_settings_cache()
131 SettingsModel().invalidate_settings_cache()
124
132
125 response = self.app.get(url(controller='home', action='index'))
133 response = self.app.get(route_path('home'))
126 if state is True:
134 if state is True:
127 response.mustcontain(version_string)
135 response.mustcontain(version_string)
128 if state is False:
136 if state is False:
@@ -25,12 +25,15 from pyramid.view import view_config
25
25
26 from rhodecode.apps._base import BaseAppView
26 from rhodecode.apps._base import BaseAppView
27 from rhodecode.lib import helpers as h
27 from rhodecode.lib import helpers as h
28 from rhodecode.lib.auth import LoginRequired, NotAnonymous
28 from rhodecode.lib.auth import LoginRequired, NotAnonymous, \
29 HasRepoGroupPermissionAnyDecorator
29 from rhodecode.lib.index import searcher_from_config
30 from rhodecode.lib.index import searcher_from_config
30 from rhodecode.lib.utils2 import safe_unicode, str2bool
31 from rhodecode.lib.utils2 import safe_unicode, str2bool
32 from rhodecode.lib.ext_json import json
31 from rhodecode.model.db import func, Repository, RepoGroup
33 from rhodecode.model.db import func, Repository, RepoGroup
32 from rhodecode.model.repo import RepoModel
34 from rhodecode.model.repo import RepoModel
33 from rhodecode.model.scm import ScmModel
35 from rhodecode.model.repo_group import RepoGroupModel
36 from rhodecode.model.scm import ScmModel, RepoGroupList, RepoList
34 from rhodecode.model.user import UserModel
37 from rhodecode.model.user import UserModel
35 from rhodecode.model.user_group import UserGroupModel
38 from rhodecode.model.user_group import UserGroupModel
36
39
@@ -143,7 +146,7 class HomeView(BaseAppView):
143 'text': obj.group_name,
146 'text': obj.group_name,
144 'type': 'group',
147 'type': 'group',
145 'obj': {},
148 'obj': {},
146 'url': h.url('repo_group_home', group_name=obj.group_name)
149 'url': h.route_path('repo_group_home', repo_group_name=obj.group_name)
147 }
150 }
148 for obj in repo_groups_iter]
151 for obj in repo_groups_iter]
149
152
@@ -246,3 +249,56 class HomeView(BaseAppView):
246 'results': res
249 'results': res
247 }
250 }
248 return data
251 return data
252
253 def _get_groups_and_repos(self, repo_group_id=None):
254 # repo groups groups
255 repo_group_list = RepoGroup.get_all_repo_groups(group_id=repo_group_id)
256 _perms = ['group.read', 'group.write', 'group.admin']
257 repo_group_list_acl = RepoGroupList(repo_group_list, perm_set=_perms)
258 repo_group_data = RepoGroupModel().get_repo_groups_as_dict(
259 repo_group_list=repo_group_list_acl, admin=False)
260
261 # repositories
262 repo_list = Repository.get_all_repos(group_id=repo_group_id)
263 _perms = ['repository.read', 'repository.write', 'repository.admin']
264 repo_list_acl = RepoList(repo_list, perm_set=_perms)
265 repo_data = RepoModel().get_repos_as_dict(
266 repo_list=repo_list_acl, admin=False)
267
268 return repo_data, repo_group_data
269
270 @LoginRequired()
271 @view_config(
272 route_name='home', request_method='GET',
273 renderer='rhodecode:templates/index.mako')
274 def main_page(self):
275 c = self.load_default_context()
276 c.repo_group = None
277
278 repo_data, repo_group_data = self._get_groups_and_repos()
279 # json used to render the grids
280 c.repos_data = json.dumps(repo_data)
281 c.repo_groups_data = json.dumps(repo_group_data)
282
283 return self._get_template_context(c)
284
285 @LoginRequired()
286 @HasRepoGroupPermissionAnyDecorator(
287 'group.read', 'group.write', 'group.admin')
288 @view_config(
289 route_name='repo_group_home', request_method='GET',
290 renderer='rhodecode:templates/index_repo_group.mako')
291 @view_config(
292 route_name='repo_group_home_slash', request_method='GET',
293 renderer='rhodecode:templates/index_repo_group.mako')
294 def repo_group_main_page(self):
295 c = self.load_default_context()
296 c.repo_group = self.request.db_repo_group
297 repo_data, repo_group_data = self._get_groups_and_repos(
298 c.repo_group.group_id)
299
300 # json used to render the grids
301 c.repos_data = json.dumps(repo_data)
302 c.repo_groups_data = json.dumps(repo_group_data)
303
304 return self._get_template_context(c)
@@ -25,7 +25,6 import formencode
25 import logging
25 import logging
26 import urlparse
26 import urlparse
27
27
28 from pylons import url
29 from pyramid.httpexceptions import HTTPFound
28 from pyramid.httpexceptions import HTTPFound
30 from pyramid.view import view_config
29 from pyramid.view import view_config
31 from recaptcha.client.captcha import submit
30 from recaptcha.client.captcha import submit
@@ -91,20 +90,21 def get_came_from(request):
91 came_from = safe_str(request.GET.get('came_from', ''))
90 came_from = safe_str(request.GET.get('came_from', ''))
92 parsed = urlparse.urlparse(came_from)
91 parsed = urlparse.urlparse(came_from)
93 allowed_schemes = ['http', 'https']
92 allowed_schemes = ['http', 'https']
93 default_came_from = h.route_path('home')
94 if parsed.scheme and parsed.scheme not in allowed_schemes:
94 if parsed.scheme and parsed.scheme not in allowed_schemes:
95 log.error('Suspicious URL scheme detected %s for url %s' %
95 log.error('Suspicious URL scheme detected %s for url %s' %
96 (parsed.scheme, parsed))
96 (parsed.scheme, parsed))
97 came_from = url('home')
97 came_from = default_came_from
98 elif parsed.netloc and request.host != parsed.netloc:
98 elif parsed.netloc and request.host != parsed.netloc:
99 log.error('Suspicious NETLOC detected %s for url %s server url '
99 log.error('Suspicious NETLOC detected %s for url %s server url '
100 'is: %s' % (parsed.netloc, parsed, request.host))
100 'is: %s' % (parsed.netloc, parsed, request.host))
101 came_from = url('home')
101 came_from = default_came_from
102 elif any(bad_str in parsed.path for bad_str in ('\r', '\n')):
102 elif any(bad_str in parsed.path for bad_str in ('\r', '\n')):
103 log.error('Header injection detected `%s` for url %s server url ' %
103 log.error('Header injection detected `%s` for url %s server url ' %
104 (parsed.path, parsed))
104 (parsed.path, parsed))
105 came_from = url('home')
105 came_from = default_came_from
106
106
107 return came_from or url('home')
107 return came_from or default_came_from
108
108
109
109
110 class LoginView(BaseAppView):
110 class LoginView(BaseAppView):
@@ -215,7 +215,7 class LoginView(BaseAppView):
215 action='user.logout', action_data=action_data,
215 action='user.logout', action_data=action_data,
216 user=auth_user, commit=True)
216 user=auth_user, commit=True)
217 self.session.delete()
217 self.session.delete()
218 return HTTPFound(url('home'))
218 return HTTPFound(h.route_path('home'))
219
219
220 @HasPermissionAnyDecorator(
220 @HasPermissionAnyDecorator(
221 'hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')
221 'hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')
@@ -132,6 +132,7 class TestMyAccountPassword(TestControll
132 self.app.post(route_path('my_account_password'), form_data)
132 self.app.post(route_path('my_account_password'), form_data)
133
133
134 response = self.app.get(route_path('home'))
134 response = self.app.get(route_path('home'))
135 new_password_hash = response.session['rhodecode_user']['password']
135 session = response.get_session_from_response()
136 new_password_hash = session['rhodecode_user']['password']
136
137
137 assert old_password_hash != new_password_hash No newline at end of file
138 assert old_password_hash != new_password_hash
@@ -23,6 +23,10 def includeme(config):
23
23
24 # Summary
24 # Summary
25 config.add_route(
25 config.add_route(
26 name='repo_summary',
27 pattern='/{repo_name:.*?[^/]}', repo_route=True)
28
29 config.add_route(
26 name='repo_summary_explicit',
30 name='repo_summary_explicit',
27 pattern='/{repo_name:.*?[^/]}/summary', repo_route=True)
31 pattern='/{repo_name:.*?[^/]}/summary', repo_route=True)
28
32
@@ -292,6 +292,7 def includeme(config):
292 config.include('rhodecode.apps.login')
292 config.include('rhodecode.apps.login')
293 config.include('rhodecode.apps.home')
293 config.include('rhodecode.apps.home')
294 config.include('rhodecode.apps.repository')
294 config.include('rhodecode.apps.repository')
295 config.include('rhodecode.apps.repo_group')
295 config.include('rhodecode.apps.search')
296 config.include('rhodecode.apps.search')
296 config.include('rhodecode.apps.user_profile')
297 config.include('rhodecode.apps.user_profile')
297 config.include('rhodecode.apps.my_account')
298 config.include('rhodecode.apps.my_account')
@@ -184,9 +184,6 def make_map(config):
184 # CUSTOM ROUTES HERE
184 # CUSTOM ROUTES HERE
185 #==========================================================================
185 #==========================================================================
186
186
187 # MAIN PAGE
188 rmap.connect('home', '/', controller='home', action='index')
189
190 # ping and pylons error test
187 # ping and pylons error test
191 rmap.connect('ping', '%s/ping' % (ADMIN_PREFIX,), controller='home', action='ping')
188 rmap.connect('ping', '%s/ping' % (ADMIN_PREFIX,), controller='home', action='ping')
192 rmap.connect('error_test', '%s/error_test' % (ADMIN_PREFIX,), controller='home', action='error_test')
189 rmap.connect('error_test', '%s/error_test' % (ADMIN_PREFIX,), controller='home', action='error_test')
@@ -1002,13 +999,6 def make_map(config):
1002 conditions={'function': check_repo},
999 conditions={'function': check_repo},
1003 requirements=URL_NAME_REQUIREMENTS)
1000 requirements=URL_NAME_REQUIREMENTS)
1004
1001
1005 # must be here for proper group/repo catching pattern
1006 _connect_with_slash(
1007 rmap, 'repo_group_home', '/{group_name}',
1008 controller='home', action='index_repo_group',
1009 conditions={'function': check_group},
1010 requirements=URL_NAME_REQUIREMENTS)
1011
1012 # catch all, at the end
1002 # catch all, at the end
1013 _connect_with_slash(
1003 _connect_with_slash(
1014 rmap, 'summary_home', '/{repo_name}', jsroute=True,
1004 rmap, 'summary_home', '/{repo_name}', jsroute=True,
@@ -193,10 +193,10 class RepoGroupsController(BaseControlle
193 _new_group_name = form_result['group_name_full']
193 _new_group_name = form_result['group_name_full']
194 repo_group_url = h.link_to(
194 repo_group_url = h.link_to(
195 _new_group_name,
195 _new_group_name,
196 h.url('repo_group_home', group_name=_new_group_name))
196 h.route_path('repo_group_home', repo_group_name=_new_group_name))
197 h.flash(h.literal(_('Created repository group %s')
197 h.flash(h.literal(_('Created repository group %s')
198 % repo_group_url), category='success')
198 % repo_group_url), category='success')
199 # TODO: in futureaction_logger(, '', '', '', self.sa)
199 # TODO: in future action_logger(, '', '', '', self.sa)
200 except formencode.Invalid as errors:
200 except formencode.Invalid as errors:
201 return htmlfill.render(
201 return htmlfill.render(
202 render('admin/repo_groups/repo_group_add.mako'),
202 render('admin/repo_groups/repo_group_add.mako'),
@@ -234,7 +234,6 class RepoGroupsController(BaseControlle
234 # <input type="hidden" name="_method" value="PUT" />
234 # <input type="hidden" name="_method" value="PUT" />
235 # Or using helpers:
235 # Or using helpers:
236 # h.form(url('repos_group', group_name=GROUP_NAME), method='put')
236 # h.form(url('repos_group', group_name=GROUP_NAME), method='put')
237 # url('repo_group_home', group_name=GROUP_NAME)
238
237
239 c.repo_group = RepoGroupModel()._get_repo_group(group_name)
238 c.repo_group = RepoGroupModel()._get_repo_group(group_name)
240 can_create_in_root = self._can_create_repo_group()
239 can_create_in_root = self._can_create_repo_group()
@@ -284,7 +283,6 class RepoGroupsController(BaseControlle
284 # <input type="hidden" name="_method" value="DELETE" />
283 # <input type="hidden" name="_method" value="DELETE" />
285 # Or using helpers:
284 # Or using helpers:
286 # h.form(url('repos_group', group_name=GROUP_NAME), method='delete')
285 # h.form(url('repos_group', group_name=GROUP_NAME), method='delete')
287 # url('repo_group_home', group_name=GROUP_NAME)
288
286
289 gr = c.repo_group = RepoGroupModel()._get_repo_group(group_name)
287 gr = c.repo_group = RepoGroupModel()._get_repo_group(group_name)
290 repos = gr.repositories.all()
288 repos = gr.repositories.all()
@@ -185,7 +185,7 class ReposController(BaseRepoController
185 except Exception as e:
185 except Exception as e:
186 msg = self._log_creation_exception(e, form_result.get('repo_name'))
186 msg = self._log_creation_exception(e, form_result.get('repo_name'))
187 h.flash(msg, category='error')
187 h.flash(msg, category='error')
188 return redirect(url('home'))
188 return redirect(h.route_path('home'))
189
189
190 return redirect(h.url('repo_creating_home',
190 return redirect(h.url('repo_creating_home',
191 repo_name=form_result['repo_name_full'],
191 repo_name=form_result['repo_name_full'],
@@ -265,7 +265,7 class ReposController(BaseRepoController
265 if task.failed():
265 if task.failed():
266 msg = self._log_creation_exception(task.result, c.repo)
266 msg = self._log_creation_exception(task.result, c.repo)
267 h.flash(msg, category='error')
267 h.flash(msg, category='error')
268 return redirect(url('home'), code=501)
268 return redirect(h.route_path('home'), code=501)
269
269
270 repo = Repository.get_by_repo_name(repo_name)
270 repo = Repository.get_by_repo_name(repo_name)
271 if repo and repo.repo_state == Repository.STATE_CREATED:
271 if repo and repo.repo_state == Repository.STATE_CREATED:
@@ -139,7 +139,7 class ForksController(BaseRepoController
139 c.repo_info = Repository.get_by_repo_name(repo_name)
139 c.repo_info = Repository.get_by_repo_name(repo_name)
140 if not c.repo_info:
140 if not c.repo_info:
141 h.not_mapped_error(repo_name)
141 h.not_mapped_error(repo_name)
142 return redirect(url('home'))
142 return redirect(h.route_path('home'))
143
143
144 defaults = self.__load_data(repo_name)
144 defaults = self.__load_data(repo_name)
145
145
@@ -65,46 +65,3 class HomeController(BaseController):
65 msg = ('RhodeCode Enterprise %s test exception. Generation time: %s'
65 msg = ('RhodeCode Enterprise %s test exception. Generation time: %s'
66 % (c.rhodecode_name, time.time()))
66 % (c.rhodecode_name, time.time()))
67 raise TestException(msg)
67 raise TestException(msg)
68
69 def _get_groups_and_repos(self, repo_group_id=None):
70 # repo groups groups
71 repo_group_list = RepoGroup.get_all_repo_groups(group_id=repo_group_id)
72 _perms = ['group.read', 'group.write', 'group.admin']
73 repo_group_list_acl = RepoGroupList(repo_group_list, perm_set=_perms)
74 repo_group_data = RepoGroupModel().get_repo_groups_as_dict(
75 repo_group_list=repo_group_list_acl, admin=False)
76
77 # repositories
78 repo_list = Repository.get_all_repos(group_id=repo_group_id)
79 _perms = ['repository.read', 'repository.write', 'repository.admin']
80 repo_list_acl = RepoList(repo_list, perm_set=_perms)
81 repo_data = RepoModel().get_repos_as_dict(
82 repo_list=repo_list_acl, admin=False)
83
84 return repo_data, repo_group_data
85
86 @LoginRequired()
87 def index(self):
88 c.repo_group = None
89
90 repo_data, repo_group_data = self._get_groups_and_repos()
91 # json used to render the grids
92 c.repos_data = json.dumps(repo_data)
93 c.repo_groups_data = json.dumps(repo_group_data)
94
95 return render('/index.mako')
96
97 @LoginRequired()
98 @HasRepoGroupPermissionAnyDecorator('group.read', 'group.write',
99 'group.admin')
100 def index_repo_group(self, group_name):
101 """GET /repo_group_name: Show a specific item"""
102 c.repo_group = RepoGroupModel()._get_repo_group(group_name)
103 repo_data, repo_group_data = self._get_groups_and_repos(
104 c.repo_group.group_id)
105
106 # json used to render the grids
107 c.repos_data = json.dumps(repo_data)
108 c.repo_groups_data = json.dumps(repo_group_data)
109
110 return render('index_repo_group.mako')
@@ -82,7 +82,7 class RhodecodeEvent(object):
82 if self.request:
82 if self.request:
83 from rhodecode.lib import helpers as h
83 from rhodecode.lib import helpers as h
84 try:
84 try:
85 return h.url('home', qualified=True)
85 return h.route_url('home')
86 except Exception:
86 except Exception:
87 log.exception('Failed to fetch URL for server')
87 log.exception('Failed to fetch URL for server')
88 return default
88 return default
@@ -1377,7 +1377,7 class PermsDecorator(object):
1377 if anonymous:
1377 if anonymous:
1378 came_from = self._get_came_from()
1378 came_from = self._get_came_from()
1379 h.flash(_('You need to be signed in to view this page'),
1379 h.flash(_('You need to be signed in to view this page'),
1380 category='warning')
1380 category='warning')
1381 raise HTTPFound(
1381 raise HTTPFound(
1382 h.route_path('login', _query={'came_from': came_from}))
1382 h.route_path('login', _query={'came_from': came_from}))
1383
1383
@@ -1429,10 +1429,16 class HasRepoPermissionAllDecorator(Perm
1429 def check_permissions(self, user):
1429 def check_permissions(self, user):
1430 perms = user.permissions
1430 perms = user.permissions
1431 repo_name = self._get_repo_name()
1431 repo_name = self._get_repo_name()
1432
1432 try:
1433 try:
1433 user_perms = set([perms['repositories'][repo_name]])
1434 user_perms = set([perms['repositories'][repo_name]])
1434 except KeyError:
1435 except KeyError:
1436 log.debug('cannot locate repo with name: `%s` in permissions defs',
1437 repo_name)
1435 return False
1438 return False
1439
1440 log.debug('checking `%s` permissions for repo `%s`',
1441 user_perms, repo_name)
1436 if self.required_perms.issubset(user_perms):
1442 if self.required_perms.issubset(user_perms):
1437 return True
1443 return True
1438 return False
1444 return False
@@ -1450,11 +1456,16 class HasRepoPermissionAnyDecorator(Perm
1450 def check_permissions(self, user):
1456 def check_permissions(self, user):
1451 perms = user.permissions
1457 perms = user.permissions
1452 repo_name = self._get_repo_name()
1458 repo_name = self._get_repo_name()
1459
1453 try:
1460 try:
1454 user_perms = set([perms['repositories'][repo_name]])
1461 user_perms = set([perms['repositories'][repo_name]])
1455 except KeyError:
1462 except KeyError:
1463 log.debug('cannot locate repo with name: `%s` in permissions defs',
1464 repo_name)
1456 return False
1465 return False
1457
1466
1467 log.debug('checking `%s` permissions for repo `%s`',
1468 user_perms, repo_name)
1458 if self.required_perms.intersection(user_perms):
1469 if self.required_perms.intersection(user_perms):
1459 return True
1470