##// END OF EJS Templates
ssh-keys: added admin panel for managing globally all SSH Keys....
marcink -
r2042:e367c94a default
parent child Browse files
Show More
@@ -0,0 +1,91 b''
1
2 <div class="panel panel-default">
3 <div class="panel-heading">
4 <h3 class="panel-title">${_('SSH Keys')} - <span id="ssh_keys_count"></span></h3>
5
6 ${h.secure_form(h.route_path('admin_permissions_ssh_keys_update'), method='POST', request=request)}
7 <button class="btn btn-link pull-right" type="submit">${_('Update SSH keys file')}</button>
8 ${h.end_form()}
9 </div>
10 <div class="panel-body">
11 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" placeholder="${_('quick filter...')}" value=""/>
12
13 <div id="repos_list_wrap">
14 <table id="ssh_keys_table" class="display"></table>
15 </div>
16 </div>
17 </div>
18
19
20 <script type="text/javascript">
21
22 $(document).ready(function() {
23 var $sshKeyListTable = $('#ssh_keys_table');
24
25 var getDatatableCount = function(){
26 var table = $sshKeyListTable.dataTable();
27 var page = table.api().page.info();
28 var active = page.recordsDisplay;
29 var total = page.recordsTotal;
30
31 var _text = _gettext("{0} out of {1} ssh keys").format(active, total);
32 $('#ssh_keys_count').text(_text);
33 };
34
35 // user list
36 $sshKeyListTable.DataTable({
37 processing: true,
38 serverSide: true,
39 ajax: "${h.route_path('admin_permissions_ssh_keys_data')}",
40 dom: 'rtp',
41 pageLength: ${c.visual.admin_grid_items},
42 order: [[ 0, "asc" ]],
43 columns: [
44 { data: {"_": "username",
45 "sort": "username"}, title: "${_('Username')}", className: "td-user" },
46 { data: {"_": "fingerprint",
47 "sort": "fingerprint"}, title: "${_('Fingerprint')}", className: "td-type" },
48 { data: {"_": "description",
49 "sort": "description"}, title: "${_('Description')}", className: "td-type" },
50 { data: {"_": "created_on",
51 "sort": "created_on"}, title: "${_('Created on')}", className: "td-time" },
52 { data: {"_": "action",
53 "sort": "action"}, title: "${_('Action')}", className: "td-action", orderable: false }
54 ],
55 language: {
56 paginate: DEFAULT_GRID_PAGINATION,
57 sProcessing: _gettext('loading...'),
58 emptyTable: _gettext("No ssh keys available yet.")
59 },
60
61 "createdRow": function ( row, data, index ) {
62 if (!data['active_raw']){
63 $(row).addClass('closed')
64 }
65 }
66 });
67
68 $sshKeyListTable.on('xhr.dt', function(e, settings, json, xhr){
69 $sshKeyListTable.css('opacity', 1);
70 });
71
72 $sshKeyListTable.on('preXhr.dt', function(e, settings, data){
73 $sshKeyListTable.css('opacity', 0.3);
74 });
75
76 // refresh counters on draw
77 $sshKeyListTable.on('draw.dt', function(){
78 getDatatableCount();
79 });
80
81 // filter
82 $('#q_filter').on('keyup',
83 $.debounce(250, function() {
84 $sshKeyListTable.DataTable().search(
85 $('#q_filter').val()
86 ).draw();
87 })
88 );
89
90 });
91 </script>
@@ -1,235 +1,245 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
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 from rhodecode.apps.admin.navigation import NavigationRegistry
22 from rhodecode.apps.admin.navigation import NavigationRegistry
23 from rhodecode.config.routing import ADMIN_PREFIX
23 from rhodecode.config.routing import ADMIN_PREFIX
24 from rhodecode.lib.utils2 import str2bool
24 from rhodecode.lib.utils2 import str2bool
25
25
26
26
27 def admin_routes(config):
27 def admin_routes(config):
28 """
28 """
29 Admin prefixed routes
29 Admin prefixed routes
30 """
30 """
31
31
32 config.add_route(
32 config.add_route(
33 name='admin_audit_logs',
33 name='admin_audit_logs',
34 pattern='/audit_logs')
34 pattern='/audit_logs')
35
35
36 config.add_route(
36 config.add_route(
37 name='pull_requests_global_0', # backward compat
37 name='pull_requests_global_0', # backward compat
38 pattern='/pull_requests/{pull_request_id:\d+}')
38 pattern='/pull_requests/{pull_request_id:\d+}')
39 config.add_route(
39 config.add_route(
40 name='pull_requests_global_1', # backward compat
40 name='pull_requests_global_1', # backward compat
41 pattern='/pull-requests/{pull_request_id:\d+}')
41 pattern='/pull-requests/{pull_request_id:\d+}')
42 config.add_route(
42 config.add_route(
43 name='pull_requests_global',
43 name='pull_requests_global',
44 pattern='/pull-request/{pull_request_id:\d+}')
44 pattern='/pull-request/{pull_request_id:\d+}')
45
45
46 config.add_route(
46 config.add_route(
47 name='admin_settings_open_source',
47 name='admin_settings_open_source',
48 pattern='/settings/open_source')
48 pattern='/settings/open_source')
49 config.add_route(
49 config.add_route(
50 name='admin_settings_vcs_svn_generate_cfg',
50 name='admin_settings_vcs_svn_generate_cfg',
51 pattern='/settings/vcs/svn_generate_cfg')
51 pattern='/settings/vcs/svn_generate_cfg')
52
52
53 config.add_route(
53 config.add_route(
54 name='admin_settings_system',
54 name='admin_settings_system',
55 pattern='/settings/system')
55 pattern='/settings/system')
56 config.add_route(
56 config.add_route(
57 name='admin_settings_system_update',
57 name='admin_settings_system_update',
58 pattern='/settings/system/updates')
58 pattern='/settings/system/updates')
59
59
60 config.add_route(
60 config.add_route(
61 name='admin_settings_sessions',
61 name='admin_settings_sessions',
62 pattern='/settings/sessions')
62 pattern='/settings/sessions')
63 config.add_route(
63 config.add_route(
64 name='admin_settings_sessions_cleanup',
64 name='admin_settings_sessions_cleanup',
65 pattern='/settings/sessions/cleanup')
65 pattern='/settings/sessions/cleanup')
66
66
67 config.add_route(
67 config.add_route(
68 name='admin_settings_process_management',
68 name='admin_settings_process_management',
69 pattern='/settings/process_management')
69 pattern='/settings/process_management')
70 config.add_route(
70 config.add_route(
71 name='admin_settings_process_management_signal',
71 name='admin_settings_process_management_signal',
72 pattern='/settings/process_management/signal')
72 pattern='/settings/process_management/signal')
73
73
74 # global permissions
74 # global permissions
75
75
76 config.add_route(
76 config.add_route(
77 name='admin_permissions_application',
77 name='admin_permissions_application',
78 pattern='/permissions/application')
78 pattern='/permissions/application')
79 config.add_route(
79 config.add_route(
80 name='admin_permissions_application_update',
80 name='admin_permissions_application_update',
81 pattern='/permissions/application/update')
81 pattern='/permissions/application/update')
82
82
83 config.add_route(
83 config.add_route(
84 name='admin_permissions_global',
84 name='admin_permissions_global',
85 pattern='/permissions/global')
85 pattern='/permissions/global')
86 config.add_route(
86 config.add_route(
87 name='admin_permissions_global_update',
87 name='admin_permissions_global_update',
88 pattern='/permissions/global/update')
88 pattern='/permissions/global/update')
89
89
90 config.add_route(
90 config.add_route(
91 name='admin_permissions_object',
91 name='admin_permissions_object',
92 pattern='/permissions/object')
92 pattern='/permissions/object')
93 config.add_route(
93 config.add_route(
94 name='admin_permissions_object_update',
94 name='admin_permissions_object_update',
95 pattern='/permissions/object/update')
95 pattern='/permissions/object/update')
96
96
97 config.add_route(
97 config.add_route(
98 name='admin_permissions_ips',
98 name='admin_permissions_ips',
99 pattern='/permissions/ips')
99 pattern='/permissions/ips')
100
100
101 config.add_route(
101 config.add_route(
102 name='admin_permissions_overview',
102 name='admin_permissions_overview',
103 pattern='/permissions/overview')
103 pattern='/permissions/overview')
104
104
105 config.add_route(
105 config.add_route(
106 name='admin_permissions_auth_token_access',
106 name='admin_permissions_auth_token_access',
107 pattern='/permissions/auth_token_access')
107 pattern='/permissions/auth_token_access')
108
108
109 config.add_route(
110 name='admin_permissions_ssh_keys',
111 pattern='/permissions/ssh_keys')
112 config.add_route(
113 name='admin_permissions_ssh_keys_data',
114 pattern='/permissions/ssh_keys/data')
115 config.add_route(
116 name='admin_permissions_ssh_keys_update',
117 pattern='/permissions/ssh_keys/update')
118
109 # users admin
119 # users admin
110 config.add_route(
120 config.add_route(
111 name='users',
121 name='users',
112 pattern='/users')
122 pattern='/users')
113
123
114 config.add_route(
124 config.add_route(
115 name='users_data',
125 name='users_data',
116 pattern='/users_data')
126 pattern='/users_data')
117
127
118 # user auth tokens
128 # user auth tokens
119 config.add_route(
129 config.add_route(
120 name='edit_user_auth_tokens',
130 name='edit_user_auth_tokens',
121 pattern='/users/{user_id:\d+}/edit/auth_tokens')
131 pattern='/users/{user_id:\d+}/edit/auth_tokens')
122 config.add_route(
132 config.add_route(
123 name='edit_user_auth_tokens_add',
133 name='edit_user_auth_tokens_add',
124 pattern='/users/{user_id:\d+}/edit/auth_tokens/new')
134 pattern='/users/{user_id:\d+}/edit/auth_tokens/new')
125 config.add_route(
135 config.add_route(
126 name='edit_user_auth_tokens_delete',
136 name='edit_user_auth_tokens_delete',
127 pattern='/users/{user_id:\d+}/edit/auth_tokens/delete')
137 pattern='/users/{user_id:\d+}/edit/auth_tokens/delete')
128
138
129 # user ssh keys
139 # user ssh keys
130 config.add_route(
140 config.add_route(
131 name='edit_user_ssh_keys',
141 name='edit_user_ssh_keys',
132 pattern='/users/{user_id:\d+}/edit/ssh_keys')
142 pattern='/users/{user_id:\d+}/edit/ssh_keys')
133 config.add_route(
143 config.add_route(
134 name='edit_user_ssh_keys_generate_keypair',
144 name='edit_user_ssh_keys_generate_keypair',
135 pattern='/users/{user_id:\d+}/edit/ssh_keys/generate')
145 pattern='/users/{user_id:\d+}/edit/ssh_keys/generate')
136 config.add_route(
146 config.add_route(
137 name='edit_user_ssh_keys_add',
147 name='edit_user_ssh_keys_add',
138 pattern='/users/{user_id:\d+}/edit/ssh_keys/new')
148 pattern='/users/{user_id:\d+}/edit/ssh_keys/new')
139 config.add_route(
149 config.add_route(
140 name='edit_user_ssh_keys_delete',
150 name='edit_user_ssh_keys_delete',
141 pattern='/users/{user_id:\d+}/edit/ssh_keys/delete')
151 pattern='/users/{user_id:\d+}/edit/ssh_keys/delete')
142
152
143 # user emails
153 # user emails
144 config.add_route(
154 config.add_route(
145 name='edit_user_emails',
155 name='edit_user_emails',
146 pattern='/users/{user_id:\d+}/edit/emails')
156 pattern='/users/{user_id:\d+}/edit/emails')
147 config.add_route(
157 config.add_route(
148 name='edit_user_emails_add',
158 name='edit_user_emails_add',
149 pattern='/users/{user_id:\d+}/edit/emails/new')
159 pattern='/users/{user_id:\d+}/edit/emails/new')
150 config.add_route(
160 config.add_route(
151 name='edit_user_emails_delete',
161 name='edit_user_emails_delete',
152 pattern='/users/{user_id:\d+}/edit/emails/delete')
162 pattern='/users/{user_id:\d+}/edit/emails/delete')
153
163
154 # user IPs
164 # user IPs
155 config.add_route(
165 config.add_route(
156 name='edit_user_ips',
166 name='edit_user_ips',
157 pattern='/users/{user_id:\d+}/edit/ips')
167 pattern='/users/{user_id:\d+}/edit/ips')
158 config.add_route(
168 config.add_route(
159 name='edit_user_ips_add',
169 name='edit_user_ips_add',
160 pattern='/users/{user_id:\d+}/edit/ips/new')
170 pattern='/users/{user_id:\d+}/edit/ips/new')
161 config.add_route(
171 config.add_route(
162 name='edit_user_ips_delete',
172 name='edit_user_ips_delete',
163 pattern='/users/{user_id:\d+}/edit/ips/delete')
173 pattern='/users/{user_id:\d+}/edit/ips/delete')
164
174
165 # user perms
175 # user perms
166 config.add_route(
176 config.add_route(
167 name='edit_user_perms_summary',
177 name='edit_user_perms_summary',
168 pattern='/users/{user_id:\d+}/edit/permissions_summary')
178 pattern='/users/{user_id:\d+}/edit/permissions_summary')
169 config.add_route(
179 config.add_route(
170 name='edit_user_perms_summary_json',
180 name='edit_user_perms_summary_json',
171 pattern='/users/{user_id:\d+}/edit/permissions_summary/json')
181 pattern='/users/{user_id:\d+}/edit/permissions_summary/json')
172
182
173 # user groups management
183 # user groups management
174 config.add_route(
184 config.add_route(
175 name='edit_user_groups_management',
185 name='edit_user_groups_management',
176 pattern='/users/{user_id:\d+}/edit/groups_management')
186 pattern='/users/{user_id:\d+}/edit/groups_management')
177
187
178 config.add_route(
188 config.add_route(
179 name='edit_user_groups_management_updates',
189 name='edit_user_groups_management_updates',
180 pattern='/users/{user_id:\d+}/edit/edit_user_groups_management/updates')
190 pattern='/users/{user_id:\d+}/edit/edit_user_groups_management/updates')
181
191
182 # user audit logs
192 # user audit logs
183 config.add_route(
193 config.add_route(
184 name='edit_user_audit_logs',
194 name='edit_user_audit_logs',
185 pattern='/users/{user_id:\d+}/edit/audit')
195 pattern='/users/{user_id:\d+}/edit/audit')
186
196
187 # user groups admin
197 # user groups admin
188 config.add_route(
198 config.add_route(
189 name='user_groups',
199 name='user_groups',
190 pattern='/user_groups')
200 pattern='/user_groups')
191
201
192 config.add_route(
202 config.add_route(
193 name='user_groups_data',
203 name='user_groups_data',
194 pattern='/user_groups_data')
204 pattern='/user_groups_data')
195
205
196 config.add_route(
206 config.add_route(
197 name='user_group_members_data',
207 name='user_group_members_data',
198 pattern='/user_groups/{user_group_id:\d+}/members')
208 pattern='/user_groups/{user_group_id:\d+}/members')
199
209
200 # user groups perms
210 # user groups perms
201 config.add_route(
211 config.add_route(
202 name='edit_user_group_perms_summary',
212 name='edit_user_group_perms_summary',
203 pattern='/user_groups/{user_group_id:\d+}/edit/permissions_summary')
213 pattern='/user_groups/{user_group_id:\d+}/edit/permissions_summary')
204 config.add_route(
214 config.add_route(
205 name='edit_user_group_perms_summary_json',
215 name='edit_user_group_perms_summary_json',
206 pattern='/user_groups/{user_group_id:\d+}/edit/permissions_summary/json')
216 pattern='/user_groups/{user_group_id:\d+}/edit/permissions_summary/json')
207
217
208 # repos admin
218 # repos admin
209 config.add_route(
219 config.add_route(
210 name='repos',
220 name='repos',
211 pattern='/repos')
221 pattern='/repos')
212
222
213 config.add_route(
223 config.add_route(
214 name='repo_new',
224 name='repo_new',
215 pattern='/repos/new')
225 pattern='/repos/new')
216
226
217 config.add_route(
227 config.add_route(
218 name='repo_create',
228 name='repo_create',
219 pattern='/repos/create')
229 pattern='/repos/create')
220
230
221
231
222 def includeme(config):
232 def includeme(config):
223 settings = config.get_settings()
233 settings = config.get_settings()
224
234
225 # Create admin navigation registry and add it to the pyramid registry.
235 # Create admin navigation registry and add it to the pyramid registry.
226 labs_active = str2bool(settings.get('labs_settings_active', False))
236 labs_active = str2bool(settings.get('labs_settings_active', False))
227 navigation_registry = NavigationRegistry(labs_active=labs_active)
237 navigation_registry = NavigationRegistry(labs_active=labs_active)
228 config.registry.registerUtility(navigation_registry)
238 config.registry.registerUtility(navigation_registry)
229
239
230 # main admin routes
240 # main admin routes
231 config.add_route(name='admin_home', pattern=ADMIN_PREFIX)
241 config.add_route(name='admin_home', pattern=ADMIN_PREFIX)
232 config.include(admin_routes, route_prefix=ADMIN_PREFIX)
242 config.include(admin_routes, route_prefix=ADMIN_PREFIX)
233
243
234 # Scan module for configuration decorators.
244 # Scan module for configuration decorators.
235 config.scan('.views', ignore='.tests')
245 config.scan('.views', ignore='.tests')
@@ -1,250 +1,286 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
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 import pytest
21 import pytest
22 from rhodecode.model.db import User, UserIpMap
22 from rhodecode.model.db import User, UserIpMap
23 from rhodecode.model.meta import Session
23 from rhodecode.model.permission import PermissionModel
24 from rhodecode.model.permission import PermissionModel
25 from rhodecode.model.ssh_key import SshKeyModel
24 from rhodecode.tests import (
26 from rhodecode.tests import (
25 TestController, clear_all_caches, assert_session_flash)
27 TestController, clear_all_caches, assert_session_flash)
26
28
27
29
28 def route_path(name, params=None, **kwargs):
30 def route_path(name, params=None, **kwargs):
29 import urllib
31 import urllib
30 from rhodecode.apps._base import ADMIN_PREFIX
32 from rhodecode.apps._base import ADMIN_PREFIX
31
33
32 base_url = {
34 base_url = {
33 'edit_user_ips':
35 'edit_user_ips':
34 ADMIN_PREFIX + '/users/{user_id}/edit/ips',
36 ADMIN_PREFIX + '/users/{user_id}/edit/ips',
35 'edit_user_ips_add':
37 'edit_user_ips_add':
36 ADMIN_PREFIX + '/users/{user_id}/edit/ips/new',
38 ADMIN_PREFIX + '/users/{user_id}/edit/ips/new',
37 'edit_user_ips_delete':
39 'edit_user_ips_delete':
38 ADMIN_PREFIX + '/users/{user_id}/edit/ips/delete',
40 ADMIN_PREFIX + '/users/{user_id}/edit/ips/delete',
39
41
40 'admin_permissions_application':
42 'admin_permissions_application':
41 ADMIN_PREFIX + '/permissions/application',
43 ADMIN_PREFIX + '/permissions/application',
42 'admin_permissions_application_update':
44 'admin_permissions_application_update':
43 ADMIN_PREFIX + '/permissions/application/update',
45 ADMIN_PREFIX + '/permissions/application/update',
44
46
45 'admin_permissions_global':
47 'admin_permissions_global':
46 ADMIN_PREFIX + '/permissions/global',
48 ADMIN_PREFIX + '/permissions/global',
47 'admin_permissions_global_update':
49 'admin_permissions_global_update':
48 ADMIN_PREFIX + '/permissions/global/update',
50 ADMIN_PREFIX + '/permissions/global/update',
49
51
50 'admin_permissions_object':
52 'admin_permissions_object':
51 ADMIN_PREFIX + '/permissions/object',
53 ADMIN_PREFIX + '/permissions/object',
52 'admin_permissions_object_update':
54 'admin_permissions_object_update':
53 ADMIN_PREFIX + '/permissions/object/update',
55 ADMIN_PREFIX + '/permissions/object/update',
54
56
55 'admin_permissions_ips':
57 'admin_permissions_ips':
56 ADMIN_PREFIX + '/permissions/ips',
58 ADMIN_PREFIX + '/permissions/ips',
57 'admin_permissions_overview':
59 'admin_permissions_overview':
58 ADMIN_PREFIX + '/permissions/overview'
60 ADMIN_PREFIX + '/permissions/overview',
61
62 'admin_permissions_ssh_keys':
63 ADMIN_PREFIX + '/permissions/ssh_keys',
64 'admin_permissions_ssh_keys_data':
65 ADMIN_PREFIX + '/permissions/ssh_keys/data',
66 'admin_permissions_ssh_keys_update':
67 ADMIN_PREFIX + '/permissions/ssh_keys/update'
59
68
60 }[name].format(**kwargs)
69 }[name].format(**kwargs)
61
70
62 if params:
71 if params:
63 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
72 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
64 return base_url
73 return base_url
65
74
66
75
67 class TestAdminPermissionsController(TestController):
76 class TestAdminPermissionsController(TestController):
68
77
69 @pytest.fixture(scope='class', autouse=True)
78 @pytest.fixture(scope='class', autouse=True)
70 def prepare(self, request):
79 def prepare(self, request):
71 # cleanup and reset to default permissions after
80 # cleanup and reset to default permissions after
72 @request.addfinalizer
81 @request.addfinalizer
73 def cleanup():
82 def cleanup():
74 PermissionModel().create_default_user_permissions(
83 PermissionModel().create_default_user_permissions(
75 User.get_default_user(), force=True)
84 User.get_default_user(), force=True)
76
85
77 def test_index_application(self):
86 def test_index_application(self):
78 self.log_user()
87 self.log_user()
79 self.app.get(route_path('admin_permissions_application'))
88 self.app.get(route_path('admin_permissions_application'))
80
89
81 @pytest.mark.parametrize(
90 @pytest.mark.parametrize(
82 'anonymous, default_register, default_register_message, default_password_reset,'
91 'anonymous, default_register, default_register_message, default_password_reset,'
83 'default_extern_activate, expect_error, expect_form_error', [
92 'default_extern_activate, expect_error, expect_form_error', [
84 (True, 'hg.register.none', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
93 (True, 'hg.register.none', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
85 False, False),
94 False, False),
86 (True, 'hg.register.manual_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.auto',
95 (True, 'hg.register.manual_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.auto',
87 False, False),
96 False, False),
88 (True, 'hg.register.auto_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
97 (True, 'hg.register.auto_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
89 False, False),
98 False, False),
90 (True, 'hg.register.auto_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
99 (True, 'hg.register.auto_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
91 False, False),
100 False, False),
92 (True, 'hg.register.XXX', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
101 (True, 'hg.register.XXX', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
93 False, True),
102 False, True),
94 (True, '', '', 'hg.password_reset.enabled', '', True, False),
103 (True, '', '', 'hg.password_reset.enabled', '', True, False),
95 ])
104 ])
96 def test_update_application_permissions(
105 def test_update_application_permissions(
97 self, anonymous, default_register, default_register_message, default_password_reset,
106 self, anonymous, default_register, default_register_message, default_password_reset,
98 default_extern_activate, expect_error, expect_form_error):
107 default_extern_activate, expect_error, expect_form_error):
99
108
100 self.log_user()
109 self.log_user()
101
110
102 # TODO: anonymous access set here to False, breaks some other tests
111 # TODO: anonymous access set here to False, breaks some other tests
103 params = {
112 params = {
104 'csrf_token': self.csrf_token,
113 'csrf_token': self.csrf_token,
105 'anonymous': anonymous,
114 'anonymous': anonymous,
106 'default_register': default_register,
115 'default_register': default_register,
107 'default_register_message': default_register_message,
116 'default_register_message': default_register_message,
108 'default_password_reset': default_password_reset,
117 'default_password_reset': default_password_reset,
109 'default_extern_activate': default_extern_activate,
118 'default_extern_activate': default_extern_activate,
110 }
119 }
111 response = self.app.post(route_path('admin_permissions_application_update'),
120 response = self.app.post(route_path('admin_permissions_application_update'),
112 params=params)
121 params=params)
113 if expect_form_error:
122 if expect_form_error:
114 assert response.status_int == 200
123 assert response.status_int == 200
115 response.mustcontain('Value must be one of')
124 response.mustcontain('Value must be one of')
116 else:
125 else:
117 if expect_error:
126 if expect_error:
118 msg = 'Error occurred during update of permissions'
127 msg = 'Error occurred during update of permissions'
119 else:
128 else:
120 msg = 'Application permissions updated successfully'
129 msg = 'Application permissions updated successfully'
121 assert_session_flash(response, msg)
130 assert_session_flash(response, msg)
122
131
123 def test_index_object(self):
132 def test_index_object(self):
124 self.log_user()
133 self.log_user()
125 self.app.get(route_path('admin_permissions_object'))
134 self.app.get(route_path('admin_permissions_object'))
126
135
127 @pytest.mark.parametrize(
136 @pytest.mark.parametrize(
128 'repo, repo_group, user_group, expect_error, expect_form_error', [
137 'repo, repo_group, user_group, expect_error, expect_form_error', [
129 ('repository.none', 'group.none', 'usergroup.none', False, False),
138 ('repository.none', 'group.none', 'usergroup.none', False, False),
130 ('repository.read', 'group.read', 'usergroup.read', False, False),
139 ('repository.read', 'group.read', 'usergroup.read', False, False),
131 ('repository.write', 'group.write', 'usergroup.write',
140 ('repository.write', 'group.write', 'usergroup.write',
132 False, False),
141 False, False),
133 ('repository.admin', 'group.admin', 'usergroup.admin',
142 ('repository.admin', 'group.admin', 'usergroup.admin',
134 False, False),
143 False, False),
135 ('repository.XXX', 'group.admin', 'usergroup.admin', False, True),
144 ('repository.XXX', 'group.admin', 'usergroup.admin', False, True),
136 ('', '', '', True, False),
145 ('', '', '', True, False),
137 ])
146 ])
138 def test_update_object_permissions(self, repo, repo_group, user_group,
147 def test_update_object_permissions(self, repo, repo_group, user_group,
139 expect_error, expect_form_error):
148 expect_error, expect_form_error):
140 self.log_user()
149 self.log_user()
141
150
142 params = {
151 params = {
143 'csrf_token': self.csrf_token,
152 'csrf_token': self.csrf_token,
144 'default_repo_perm': repo,
153 'default_repo_perm': repo,
145 'overwrite_default_repo': False,
154 'overwrite_default_repo': False,
146 'default_group_perm': repo_group,
155 'default_group_perm': repo_group,
147 'overwrite_default_group': False,
156 'overwrite_default_group': False,
148 'default_user_group_perm': user_group,
157 'default_user_group_perm': user_group,
149 'overwrite_default_user_group': False,
158 'overwrite_default_user_group': False,
150 }
159 }
151 response = self.app.post(route_path('admin_permissions_object_update'),
160 response = self.app.post(route_path('admin_permissions_object_update'),
152 params=params)
161 params=params)
153 if expect_form_error:
162 if expect_form_error:
154 assert response.status_int == 200
163 assert response.status_int == 200
155 response.mustcontain('Value must be one of')
164 response.mustcontain('Value must be one of')
156 else:
165 else:
157 if expect_error:
166 if expect_error:
158 msg = 'Error occurred during update of permissions'
167 msg = 'Error occurred during update of permissions'
159 else:
168 else:
160 msg = 'Object permissions updated successfully'
169 msg = 'Object permissions updated successfully'
161 assert_session_flash(response, msg)
170 assert_session_flash(response, msg)
162
171
163 def test_index_global(self):
172 def test_index_global(self):
164 self.log_user()
173 self.log_user()
165 self.app.get(route_path('admin_permissions_global'))
174 self.app.get(route_path('admin_permissions_global'))
166
175
167 @pytest.mark.parametrize(
176 @pytest.mark.parametrize(
168 'repo_create, repo_create_write, user_group_create, repo_group_create,'
177 'repo_create, repo_create_write, user_group_create, repo_group_create,'
169 'fork_create, inherit_default_permissions, expect_error,'
178 'fork_create, inherit_default_permissions, expect_error,'
170 'expect_form_error', [
179 'expect_form_error', [
171 ('hg.create.none', 'hg.create.write_on_repogroup.false',
180 ('hg.create.none', 'hg.create.write_on_repogroup.false',
172 'hg.usergroup.create.false', 'hg.repogroup.create.false',
181 'hg.usergroup.create.false', 'hg.repogroup.create.false',
173 'hg.fork.none', 'hg.inherit_default_perms.false', False, False),
182 'hg.fork.none', 'hg.inherit_default_perms.false', False, False),
174 ('hg.create.repository', 'hg.create.write_on_repogroup.true',
183 ('hg.create.repository', 'hg.create.write_on_repogroup.true',
175 'hg.usergroup.create.true', 'hg.repogroup.create.true',
184 'hg.usergroup.create.true', 'hg.repogroup.create.true',
176 'hg.fork.repository', 'hg.inherit_default_perms.false',
185 'hg.fork.repository', 'hg.inherit_default_perms.false',
177 False, False),
186 False, False),
178 ('hg.create.XXX', 'hg.create.write_on_repogroup.true',
187 ('hg.create.XXX', 'hg.create.write_on_repogroup.true',
179 'hg.usergroup.create.true', 'hg.repogroup.create.true',
188 'hg.usergroup.create.true', 'hg.repogroup.create.true',
180 'hg.fork.repository', 'hg.inherit_default_perms.false',
189 'hg.fork.repository', 'hg.inherit_default_perms.false',
181 False, True),
190 False, True),
182 ('', '', '', '', '', '', True, False),
191 ('', '', '', '', '', '', True, False),
183 ])
192 ])
184 def test_update_global_permissions(
193 def test_update_global_permissions(
185 self, repo_create, repo_create_write, user_group_create,
194 self, repo_create, repo_create_write, user_group_create,
186 repo_group_create, fork_create, inherit_default_permissions,
195 repo_group_create, fork_create, inherit_default_permissions,
187 expect_error, expect_form_error):
196 expect_error, expect_form_error):
188 self.log_user()
197 self.log_user()
189
198
190 params = {
199 params = {
191 'csrf_token': self.csrf_token,
200 'csrf_token': self.csrf_token,
192 'default_repo_create': repo_create,
201 'default_repo_create': repo_create,
193 'default_repo_create_on_write': repo_create_write,
202 'default_repo_create_on_write': repo_create_write,
194 'default_user_group_create': user_group_create,
203 'default_user_group_create': user_group_create,
195 'default_repo_group_create': repo_group_create,
204 'default_repo_group_create': repo_group_create,
196 'default_fork_create': fork_create,
205 'default_fork_create': fork_create,
197 'default_inherit_default_permissions': inherit_default_permissions
206 'default_inherit_default_permissions': inherit_default_permissions
198 }
207 }
199 response = self.app.post(route_path('admin_permissions_global_update'),
208 response = self.app.post(route_path('admin_permissions_global_update'),
200 params=params)
209 params=params)
201 if expect_form_error:
210 if expect_form_error:
202 assert response.status_int == 200
211 assert response.status_int == 200
203 response.mustcontain('Value must be one of')
212 response.mustcontain('Value must be one of')
204 else:
213 else:
205 if expect_error:
214 if expect_error:
206 msg = 'Error occurred during update of permissions'
215 msg = 'Error occurred during update of permissions'
207 else:
216 else:
208 msg = 'Global permissions updated successfully'
217 msg = 'Global permissions updated successfully'
209 assert_session_flash(response, msg)
218 assert_session_flash(response, msg)
210
219
211 def test_index_ips(self):
220 def test_index_ips(self):
212 self.log_user()
221 self.log_user()
213 response = self.app.get(route_path('admin_permissions_ips'))
222 response = self.app.get(route_path('admin_permissions_ips'))
214 # TODO: Test response...
223 # TODO: Test response...
215 response.mustcontain('All IP addresses are allowed')
224 response.mustcontain('All IP addresses are allowed')
216
225
217 def test_add_delete_ips(self):
226 def test_add_delete_ips(self):
218 self.log_user()
227 self.log_user()
219 clear_all_caches()
228 clear_all_caches()
220
229
221 # ADD
230 # ADD
222 default_user_id = User.get_default_user().user_id
231 default_user_id = User.get_default_user().user_id
223 self.app.post(
232 self.app.post(
224 route_path('edit_user_ips_add', user_id=default_user_id),
233 route_path('edit_user_ips_add', user_id=default_user_id),
225 params={'new_ip': '127.0.0.0/24', 'csrf_token': self.csrf_token})
234 params={'new_ip': '127.0.0.0/24', 'csrf_token': self.csrf_token})
226
235
227 response = self.app.get(route_path('admin_permissions_ips'))
236 response = self.app.get(route_path('admin_permissions_ips'))
228 response.mustcontain('127.0.0.0/24')
237 response.mustcontain('127.0.0.0/24')
229 response.mustcontain('127.0.0.0 - 127.0.0.255')
238 response.mustcontain('127.0.0.0 - 127.0.0.255')
230
239
231 # DELETE
240 # DELETE
232 default_user_id = User.get_default_user().user_id
241 default_user_id = User.get_default_user().user_id
233 del_ip_id = UserIpMap.query().filter(UserIpMap.user_id ==
242 del_ip_id = UserIpMap.query().filter(UserIpMap.user_id ==
234 default_user_id).first().ip_id
243 default_user_id).first().ip_id
235
244
236 response = self.app.post(
245 response = self.app.post(
237 route_path('edit_user_ips_delete', user_id=default_user_id),
246 route_path('edit_user_ips_delete', user_id=default_user_id),
238 params={'del_ip_id': del_ip_id, 'csrf_token': self.csrf_token})
247 params={'del_ip_id': del_ip_id, 'csrf_token': self.csrf_token})
239
248
240 assert_session_flash(response, 'Removed ip address from user whitelist')
249 assert_session_flash(response, 'Removed ip address from user whitelist')
241
250
242 clear_all_caches()
251 clear_all_caches()
243 response = self.app.get(route_path('admin_permissions_ips'))
252 response = self.app.get(route_path('admin_permissions_ips'))
244 response.mustcontain('All IP addresses are allowed')
253 response.mustcontain('All IP addresses are allowed')
245 response.mustcontain(no=['127.0.0.0/24'])
254 response.mustcontain(no=['127.0.0.0/24'])
246 response.mustcontain(no=['127.0.0.0 - 127.0.0.255'])
255 response.mustcontain(no=['127.0.0.0 - 127.0.0.255'])
247
256
248 def test_index_overview(self):
257 def test_index_overview(self):
249 self.log_user()
258 self.log_user()
250 self.app.get(route_path('admin_permissions_overview'))
259 self.app.get(route_path('admin_permissions_overview'))
260
261 def test_ssh_keys(self):
262 self.log_user()
263 self.app.get(route_path('admin_permissions_ssh_keys'), status=200)
264
265 def test_ssh_keys_data(self, user_util, xhr_header):
266 self.log_user()
267 response = self.app.get(route_path('admin_permissions_ssh_keys_data'),
268 extra_environ=xhr_header)
269 assert response.json == {u'data': [], u'draw': None,
270 u'recordsFiltered': 0, u'recordsTotal': 0}
271
272 dummy_user = user_util.create_user()
273 SshKeyModel().create(dummy_user, 'ab:cd:ef', 'KEYKEY', 'test_key')
274 Session().commit()
275 response = self.app.get(route_path('admin_permissions_ssh_keys_data'),
276 extra_environ=xhr_header)
277 assert response.json['data'][0]['fingerprint'] == 'ab:cd:ef'
278
279 def test_ssh_keys_update(self):
280 self.log_user()
281 response = self.app.post(
282 route_path('admin_permissions_ssh_keys_update'),
283 dict(csrf_token=self.csrf_token), status=302)
284
285 assert_session_flash(
286 response, 'SSH key support is disabled in .ini file')
@@ -1,369 +1,475 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
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 import re
21 import re
22 import logging
22 import logging
23 import formencode
23 import formencode
24 import datetime
24 from pyramid.interfaces import IRoutesMapper
25 from pyramid.interfaces import IRoutesMapper
25
26
26 from pyramid.view import view_config
27 from pyramid.view import view_config
27 from pyramid.httpexceptions import HTTPFound
28 from pyramid.httpexceptions import HTTPFound
28 from pyramid.renderers import render
29 from pyramid.renderers import render
29 from pyramid.response import Response
30 from pyramid.response import Response
30
31
31 from rhodecode.apps._base import BaseAppView
32 from rhodecode.apps._base import BaseAppView, DataGridAppView
33 from rhodecode.apps.ssh_support import SshKeyFileChangeEvent
34 from rhodecode.events import trigger
32
35
33 from rhodecode.lib import helpers as h
36 from rhodecode.lib import helpers as h
34 from rhodecode.lib.auth import (
37 from rhodecode.lib.auth import (
35 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
38 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
36 from rhodecode.lib.utils2 import aslist
39 from rhodecode.lib.utils2 import aslist, safe_unicode
37 from rhodecode.model.db import User, UserIpMap
40 from rhodecode.model.db import or_, joinedload, coalesce, User, UserIpMap, UserSshKeys
38 from rhodecode.model.forms import (
41 from rhodecode.model.forms import (
39 ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm)
42 ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm)
40 from rhodecode.model.meta import Session
43 from rhodecode.model.meta import Session
41 from rhodecode.model.permission import PermissionModel
44 from rhodecode.model.permission import PermissionModel
42 from rhodecode.model.settings import SettingsModel
45 from rhodecode.model.settings import SettingsModel
43
46
44
47
45 log = logging.getLogger(__name__)
48 log = logging.getLogger(__name__)
46
49
47
50
48 class AdminPermissionsView(BaseAppView):
51 class AdminPermissionsView(BaseAppView, DataGridAppView):
49 def load_default_context(self):
52 def load_default_context(self):
50 c = self._get_local_tmpl_context()
53 c = self._get_local_tmpl_context()
51
54
52 self._register_global_c(c)
55 self._register_global_c(c)
53 PermissionModel().set_global_permission_choices(
56 PermissionModel().set_global_permission_choices(
54 c, gettext_translator=self.request.translate)
57 c, gettext_translator=self.request.translate)
55 return c
58 return c
56
59
57 @LoginRequired()
60 @LoginRequired()
58 @HasPermissionAllDecorator('hg.admin')
61 @HasPermissionAllDecorator('hg.admin')
59 @view_config(
62 @view_config(
60 route_name='admin_permissions_application', request_method='GET',
63 route_name='admin_permissions_application', request_method='GET',
61 renderer='rhodecode:templates/admin/permissions/permissions.mako')
64 renderer='rhodecode:templates/admin/permissions/permissions.mako')
62 def permissions_application(self):
65 def permissions_application(self):
63 c = self.load_default_context()
66 c = self.load_default_context()
64 c.active = 'application'
67 c.active = 'application'
65
68
66 c.user = User.get_default_user(refresh=True)
69 c.user = User.get_default_user(refresh=True)
67
70
68 app_settings = SettingsModel().get_all_settings()
71 app_settings = SettingsModel().get_all_settings()
69 defaults = {
72 defaults = {
70 'anonymous': c.user.active,
73 'anonymous': c.user.active,
71 'default_register_message': app_settings.get(
74 'default_register_message': app_settings.get(
72 'rhodecode_register_message')
75 'rhodecode_register_message')
73 }
76 }
74 defaults.update(c.user.get_default_perms())
77 defaults.update(c.user.get_default_perms())
75
78
76 data = render('rhodecode:templates/admin/permissions/permissions.mako',
79 data = render('rhodecode:templates/admin/permissions/permissions.mako',
77 self._get_template_context(c), self.request)
80 self._get_template_context(c), self.request)
78 html = formencode.htmlfill.render(
81 html = formencode.htmlfill.render(
79 data,
82 data,
80 defaults=defaults,
83 defaults=defaults,
81 encoding="UTF-8",
84 encoding="UTF-8",
82 force_defaults=False
85 force_defaults=False
83 )
86 )
84 return Response(html)
87 return Response(html)
85
88
86 @LoginRequired()
89 @LoginRequired()
87 @HasPermissionAllDecorator('hg.admin')
90 @HasPermissionAllDecorator('hg.admin')
88 @CSRFRequired()
91 @CSRFRequired()
89 @view_config(
92 @view_config(
90 route_name='admin_permissions_application_update', request_method='POST',
93 route_name='admin_permissions_application_update', request_method='POST',
91 renderer='rhodecode:templates/admin/permissions/permissions.mako')
94 renderer='rhodecode:templates/admin/permissions/permissions.mako')
92 def permissions_application_update(self):
95 def permissions_application_update(self):
93 _ = self.request.translate
96 _ = self.request.translate
94 c = self.load_default_context()
97 c = self.load_default_context()
95 c.active = 'application'
98 c.active = 'application'
96
99
97 _form = ApplicationPermissionsForm(
100 _form = ApplicationPermissionsForm(
98 [x[0] for x in c.register_choices],
101 [x[0] for x in c.register_choices],
99 [x[0] for x in c.password_reset_choices],
102 [x[0] for x in c.password_reset_choices],
100 [x[0] for x in c.extern_activate_choices])()
103 [x[0] for x in c.extern_activate_choices])()
101
104
102 try:
105 try:
103 form_result = _form.to_python(dict(self.request.POST))
106 form_result = _form.to_python(dict(self.request.POST))
104 form_result.update({'perm_user_name': User.DEFAULT_USER})
107 form_result.update({'perm_user_name': User.DEFAULT_USER})
105 PermissionModel().update_application_permissions(form_result)
108 PermissionModel().update_application_permissions(form_result)
106
109
107 settings = [
110 settings = [
108 ('register_message', 'default_register_message'),
111 ('register_message', 'default_register_message'),
109 ]
112 ]
110 for setting, form_key in settings:
113 for setting, form_key in settings:
111 sett = SettingsModel().create_or_update_setting(
114 sett = SettingsModel().create_or_update_setting(
112 setting, form_result[form_key])
115 setting, form_result[form_key])
113 Session().add(sett)
116 Session().add(sett)
114
117
115 Session().commit()
118 Session().commit()
116 h.flash(_('Application permissions updated successfully'),
119 h.flash(_('Application permissions updated successfully'),
117 category='success')
120 category='success')
118
121
119 except formencode.Invalid as errors:
122 except formencode.Invalid as errors:
120 defaults = errors.value
123 defaults = errors.value
121
124
122 data = render(
125 data = render(
123 'rhodecode:templates/admin/permissions/permissions.mako',
126 'rhodecode:templates/admin/permissions/permissions.mako',
124 self._get_template_context(c), self.request)
127 self._get_template_context(c), self.request)
125 html = formencode.htmlfill.render(
128 html = formencode.htmlfill.render(
126 data,
129 data,
127 defaults=defaults,
130 defaults=defaults,
128 errors=errors.error_dict or {},
131 errors=errors.error_dict or {},
129 prefix_error=False,
132 prefix_error=False,
130 encoding="UTF-8",
133 encoding="UTF-8",
131 force_defaults=False
134 force_defaults=False
132 )
135 )
133 return Response(html)
136 return Response(html)
134
137
135 except Exception:
138 except Exception:
136 log.exception("Exception during update of permissions")
139 log.exception("Exception during update of permissions")
137 h.flash(_('Error occurred during update of permissions'),
140 h.flash(_('Error occurred during update of permissions'),
138 category='error')
141 category='error')
139
142
140 raise HTTPFound(h.route_path('admin_permissions_application'))
143 raise HTTPFound(h.route_path('admin_permissions_application'))
141
144
142 @LoginRequired()
145 @LoginRequired()
143 @HasPermissionAllDecorator('hg.admin')
146 @HasPermissionAllDecorator('hg.admin')
144 @view_config(
147 @view_config(
145 route_name='admin_permissions_object', request_method='GET',
148 route_name='admin_permissions_object', request_method='GET',
146 renderer='rhodecode:templates/admin/permissions/permissions.mako')
149 renderer='rhodecode:templates/admin/permissions/permissions.mako')
147 def permissions_objects(self):
150 def permissions_objects(self):
148 c = self.load_default_context()
151 c = self.load_default_context()
149 c.active = 'objects'
152 c.active = 'objects'
150
153
151 c.user = User.get_default_user(refresh=True)
154 c.user = User.get_default_user(refresh=True)
152 defaults = {}
155 defaults = {}
153 defaults.update(c.user.get_default_perms())
156 defaults.update(c.user.get_default_perms())
154
157
155 data = render(
158 data = render(
156 'rhodecode:templates/admin/permissions/permissions.mako',
159 'rhodecode:templates/admin/permissions/permissions.mako',
157 self._get_template_context(c), self.request)
160 self._get_template_context(c), self.request)
158 html = formencode.htmlfill.render(
161 html = formencode.htmlfill.render(
159 data,
162 data,
160 defaults=defaults,
163 defaults=defaults,
161 encoding="UTF-8",
164 encoding="UTF-8",
162 force_defaults=False
165 force_defaults=False
163 )
166 )
164 return Response(html)
167 return Response(html)
165
168
166 @LoginRequired()
169 @LoginRequired()
167 @HasPermissionAllDecorator('hg.admin')
170 @HasPermissionAllDecorator('hg.admin')
168 @CSRFRequired()
171 @CSRFRequired()
169 @view_config(
172 @view_config(
170 route_name='admin_permissions_object_update', request_method='POST',
173 route_name='admin_permissions_object_update', request_method='POST',
171 renderer='rhodecode:templates/admin/permissions/permissions.mako')
174 renderer='rhodecode:templates/admin/permissions/permissions.mako')
172 def permissions_objects_update(self):
175 def permissions_objects_update(self):
173 _ = self.request.translate
176 _ = self.request.translate
174 c = self.load_default_context()
177 c = self.load_default_context()
175 c.active = 'objects'
178 c.active = 'objects'
176
179
177 _form = ObjectPermissionsForm(
180 _form = ObjectPermissionsForm(
178 [x[0] for x in c.repo_perms_choices],
181 [x[0] for x in c.repo_perms_choices],
179 [x[0] for x in c.group_perms_choices],
182 [x[0] for x in c.group_perms_choices],
180 [x[0] for x in c.user_group_perms_choices])()
183 [x[0] for x in c.user_group_perms_choices])()
181
184
182 try:
185 try:
183 form_result = _form.to_python(dict(self.request.POST))
186 form_result = _form.to_python(dict(self.request.POST))
184 form_result.update({'perm_user_name': User.DEFAULT_USER})
187 form_result.update({'perm_user_name': User.DEFAULT_USER})
185 PermissionModel().update_object_permissions(form_result)
188 PermissionModel().update_object_permissions(form_result)
186
189
187 Session().commit()
190 Session().commit()
188 h.flash(_('Object permissions updated successfully'),
191 h.flash(_('Object permissions updated successfully'),
189 category='success')
192 category='success')
190
193
191 except formencode.Invalid as errors:
194 except formencode.Invalid as errors:
192 defaults = errors.value
195 defaults = errors.value
193
196
194 data = render(
197 data = render(
195 'rhodecode:templates/admin/permissions/permissions.mako',
198 'rhodecode:templates/admin/permissions/permissions.mako',
196 self._get_template_context(c), self.request)
199 self._get_template_context(c), self.request)
197 html = formencode.htmlfill.render(
200 html = formencode.htmlfill.render(
198 data,
201 data,
199 defaults=defaults,
202 defaults=defaults,
200 errors=errors.error_dict or {},
203 errors=errors.error_dict or {},
201 prefix_error=False,
204 prefix_error=False,
202 encoding="UTF-8",
205 encoding="UTF-8",
203 force_defaults=False
206 force_defaults=False
204 )
207 )
205 return Response(html)
208 return Response(html)
206 except Exception:
209 except Exception:
207 log.exception("Exception during update of permissions")
210 log.exception("Exception during update of permissions")
208 h.flash(_('Error occurred during update of permissions'),
211 h.flash(_('Error occurred during update of permissions'),
209 category='error')
212 category='error')
210
213
211 raise HTTPFound(h.route_path('admin_permissions_object'))
214 raise HTTPFound(h.route_path('admin_permissions_object'))
212
215
213 @LoginRequired()
216 @LoginRequired()
214 @HasPermissionAllDecorator('hg.admin')
217 @HasPermissionAllDecorator('hg.admin')
215 @view_config(
218 @view_config(
216 route_name='admin_permissions_global', request_method='GET',
219 route_name='admin_permissions_global', request_method='GET',
217 renderer='rhodecode:templates/admin/permissions/permissions.mako')
220 renderer='rhodecode:templates/admin/permissions/permissions.mako')
218 def permissions_global(self):
221 def permissions_global(self):
219 c = self.load_default_context()
222 c = self.load_default_context()
220 c.active = 'global'
223 c.active = 'global'
221
224
222 c.user = User.get_default_user(refresh=True)
225 c.user = User.get_default_user(refresh=True)
223 defaults = {}
226 defaults = {}
224 defaults.update(c.user.get_default_perms())
227 defaults.update(c.user.get_default_perms())
225
228
226 data = render(
229 data = render(
227 'rhodecode:templates/admin/permissions/permissions.mako',
230 'rhodecode:templates/admin/permissions/permissions.mako',
228 self._get_template_context(c), self.request)
231 self._get_template_context(c), self.request)
229 html = formencode.htmlfill.render(
232 html = formencode.htmlfill.render(
230 data,
233 data,
231 defaults=defaults,
234 defaults=defaults,
232 encoding="UTF-8",
235 encoding="UTF-8",
233 force_defaults=False
236 force_defaults=False
234 )
237 )
235 return Response(html)
238 return Response(html)
236
239
237 @LoginRequired()
240 @LoginRequired()
238 @HasPermissionAllDecorator('hg.admin')
241 @HasPermissionAllDecorator('hg.admin')
239 @CSRFRequired()
242 @CSRFRequired()
240 @view_config(
243 @view_config(
241 route_name='admin_permissions_global_update', request_method='POST',
244 route_name='admin_permissions_global_update', request_method='POST',
242 renderer='rhodecode:templates/admin/permissions/permissions.mako')
245 renderer='rhodecode:templates/admin/permissions/permissions.mako')
243 def permissions_global_update(self):
246 def permissions_global_update(self):
244 _ = self.request.translate
247 _ = self.request.translate
245 c = self.load_default_context()
248 c = self.load_default_context()
246 c.active = 'global'
249 c.active = 'global'
247
250
248 _form = UserPermissionsForm(
251 _form = UserPermissionsForm(
249 [x[0] for x in c.repo_create_choices],
252 [x[0] for x in c.repo_create_choices],
250 [x[0] for x in c.repo_create_on_write_choices],
253 [x[0] for x in c.repo_create_on_write_choices],
251 [x[0] for x in c.repo_group_create_choices],
254 [x[0] for x in c.repo_group_create_choices],
252 [x[0] for x in c.user_group_create_choices],
255 [x[0] for x in c.user_group_create_choices],
253 [x[0] for x in c.fork_choices],
256 [x[0] for x in c.fork_choices],
254 [x[0] for x in c.inherit_default_permission_choices])()
257 [x[0] for x in c.inherit_default_permission_choices])()
255
258
256 try:
259 try:
257 form_result = _form.to_python(dict(self.request.POST))
260 form_result = _form.to_python(dict(self.request.POST))
258 form_result.update({'perm_user_name': User.DEFAULT_USER})
261 form_result.update({'perm_user_name': User.DEFAULT_USER})
259 PermissionModel().update_user_permissions(form_result)
262 PermissionModel().update_user_permissions(form_result)
260
263
261 Session().commit()
264 Session().commit()
262 h.flash(_('Global permissions updated successfully'),
265 h.flash(_('Global permissions updated successfully'),
263 category='success')
266 category='success')
264
267
265 except formencode.Invalid as errors:
268 except formencode.Invalid as errors:
266 defaults = errors.value
269 defaults = errors.value
267
270
268 data = render(
271 data = render(
269 'rhodecode:templates/admin/permissions/permissions.mako',
272 'rhodecode:templates/admin/permissions/permissions.mako',
270 self._get_template_context(c), self.request)
273 self._get_template_context(c), self.request)
271 html = formencode.htmlfill.render(
274 html = formencode.htmlfill.render(
272 data,
275 data,
273 defaults=defaults,
276 defaults=defaults,
274 errors=errors.error_dict or {},
277 errors=errors.error_dict or {},
275 prefix_error=False,
278 prefix_error=False,
276 encoding="UTF-8",
279 encoding="UTF-8",
277 force_defaults=False
280 force_defaults=False
278 )
281 )
279 return Response(html)
282 return Response(html)
280 except Exception:
283 except Exception:
281 log.exception("Exception during update of permissions")
284 log.exception("Exception during update of permissions")
282 h.flash(_('Error occurred during update of permissions'),
285 h.flash(_('Error occurred during update of permissions'),
283 category='error')
286 category='error')
284
287
285 raise HTTPFound(h.route_path('admin_permissions_global'))
288 raise HTTPFound(h.route_path('admin_permissions_global'))
286
289
287 @LoginRequired()
290 @LoginRequired()
288 @HasPermissionAllDecorator('hg.admin')
291 @HasPermissionAllDecorator('hg.admin')
289 @view_config(
292 @view_config(
290 route_name='admin_permissions_ips', request_method='GET',
293 route_name='admin_permissions_ips', request_method='GET',
291 renderer='rhodecode:templates/admin/permissions/permissions.mako')
294 renderer='rhodecode:templates/admin/permissions/permissions.mako')
292 def permissions_ips(self):
295 def permissions_ips(self):
293 c = self.load_default_context()
296 c = self.load_default_context()
294 c.active = 'ips'
297 c.active = 'ips'
295
298
296 c.user = User.get_default_user(refresh=True)
299 c.user = User.get_default_user(refresh=True)
297 c.user_ip_map = (
300 c.user_ip_map = (
298 UserIpMap.query().filter(UserIpMap.user == c.user).all())
301 UserIpMap.query().filter(UserIpMap.user == c.user).all())
299
302
300 return self._get_template_context(c)
303 return self._get_template_context(c)
301
304
302 @LoginRequired()
305 @LoginRequired()
303 @HasPermissionAllDecorator('hg.admin')
306 @HasPermissionAllDecorator('hg.admin')
304 @view_config(
307 @view_config(
305 route_name='admin_permissions_overview', request_method='GET',
308 route_name='admin_permissions_overview', request_method='GET',
306 renderer='rhodecode:templates/admin/permissions/permissions.mako')
309 renderer='rhodecode:templates/admin/permissions/permissions.mako')
307 def permissions_overview(self):
310 def permissions_overview(self):
308 c = self.load_default_context()
311 c = self.load_default_context()
309 c.active = 'perms'
312 c.active = 'perms'
310
313
311 c.user = User.get_default_user(refresh=True)
314 c.user = User.get_default_user(refresh=True)
312 c.perm_user = c.user.AuthUser()
315 c.perm_user = c.user.AuthUser()
313 return self._get_template_context(c)
316 return self._get_template_context(c)
314
317
315 @LoginRequired()
318 @LoginRequired()
316 @HasPermissionAllDecorator('hg.admin')
319 @HasPermissionAllDecorator('hg.admin')
317 @view_config(
320 @view_config(
318 route_name='admin_permissions_auth_token_access', request_method='GET',
321 route_name='admin_permissions_auth_token_access', request_method='GET',
319 renderer='rhodecode:templates/admin/permissions/permissions.mako')
322 renderer='rhodecode:templates/admin/permissions/permissions.mako')
320 def auth_token_access(self):
323 def auth_token_access(self):
321 from rhodecode import CONFIG
324 from rhodecode import CONFIG
322
325
323 c = self.load_default_context()
326 c = self.load_default_context()
324 c.active = 'auth_token_access'
327 c.active = 'auth_token_access'
325
328
326 c.user = User.get_default_user(refresh=True)
329 c.user = User.get_default_user(refresh=True)
327 c.perm_user = c.user.AuthUser()
330 c.perm_user = c.user.AuthUser()
328
331
329 mapper = self.request.registry.queryUtility(IRoutesMapper)
332 mapper = self.request.registry.queryUtility(IRoutesMapper)
330 c.view_data = []
333 c.view_data = []
331
334
332 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
335 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
333 introspector = self.request.registry.introspector
336 introspector = self.request.registry.introspector
334
337
335 view_intr = {}
338 view_intr = {}
336 for view_data in introspector.get_category('views'):
339 for view_data in introspector.get_category('views'):
337 intr = view_data['introspectable']
340 intr = view_data['introspectable']
338
341
339 if 'route_name' in intr and intr['attr']:
342 if 'route_name' in intr and intr['attr']:
340 view_intr[intr['route_name']] = '{}:{}'.format(
343 view_intr[intr['route_name']] = '{}:{}'.format(
341 str(intr['derived_callable'].func_name), intr['attr']
344 str(intr['derived_callable'].func_name), intr['attr']
342 )
345 )
343
346
344 c.whitelist_key = 'api_access_controllers_whitelist'
347 c.whitelist_key = 'api_access_controllers_whitelist'
345 c.whitelist_file = CONFIG.get('__file__')
348 c.whitelist_file = CONFIG.get('__file__')
346 whitelist_views = aslist(
349 whitelist_views = aslist(
347 CONFIG.get(c.whitelist_key), sep=',')
350 CONFIG.get(c.whitelist_key), sep=',')
348
351
349 for route_info in mapper.get_routes():
352 for route_info in mapper.get_routes():
350 if not route_info.name.startswith('__'):
353 if not route_info.name.startswith('__'):
351 routepath = route_info.pattern
354 routepath = route_info.pattern
352
355
353 def replace(matchobj):
356 def replace(matchobj):
354 if matchobj.group(1):
357 if matchobj.group(1):
355 return "{%s}" % matchobj.group(1).split(':')[0]
358 return "{%s}" % matchobj.group(1).split(':')[0]
356 else:
359 else:
357 return "{%s}" % matchobj.group(2)
360 return "{%s}" % matchobj.group(2)
358
361
359 routepath = _argument_prog.sub(replace, routepath)
362 routepath = _argument_prog.sub(replace, routepath)
360
363
361 if not routepath.startswith('/'):
364 if not routepath.startswith('/'):
362 routepath = '/' + routepath
365 routepath = '/' + routepath
363
366
364 view_fqn = view_intr.get(route_info.name, 'NOT AVAILABLE')
367 view_fqn = view_intr.get(route_info.name, 'NOT AVAILABLE')
365 active = view_fqn in whitelist_views
368 active = view_fqn in whitelist_views
366 c.view_data.append((route_info.name, view_fqn, routepath, active))
369 c.view_data.append((route_info.name, view_fqn, routepath, active))
367
370
368 c.whitelist_views = whitelist_views
371 c.whitelist_views = whitelist_views
369 return self._get_template_context(c)
372 return self._get_template_context(c)
373
374 @LoginRequired()
375 @HasPermissionAllDecorator('hg.admin')
376 @view_config(
377 route_name='admin_permissions_ssh_keys', request_method='GET',
378 renderer='rhodecode:templates/admin/permissions/permissions.mako')
379 def ssh_keys(self):
380 c = self.load_default_context()
381 c.active = 'ssh_keys'
382 return self._get_template_context(c)
383
384 @LoginRequired()
385 @HasPermissionAllDecorator('hg.admin')
386 @view_config(
387 route_name='admin_permissions_ssh_keys_data', request_method='GET',
388 renderer='json_ext', xhr=True)
389 def ssh_keys_data(self):
390 _ = self.request.translate
391 column_map = {
392 'fingerprint': 'ssh_key_fingerprint',
393 'username': User.username
394 }
395 draw, start, limit = self._extract_chunk(self.request)
396 search_q, order_by, order_dir = self._extract_ordering(
397 self.request, column_map=column_map)
398
399 ssh_keys_data_total_count = UserSshKeys.query()\
400 .count()
401
402 # json generate
403 base_q = UserSshKeys.query().join(UserSshKeys.user)
404
405 if search_q:
406 like_expression = u'%{}%'.format(safe_unicode(search_q))
407 base_q = base_q.filter(or_(
408 User.username.ilike(like_expression),
409 UserSshKeys.ssh_key_fingerprint.ilike(like_expression),
410 ))
411
412 users_data_total_filtered_count = base_q.count()
413
414 sort_col = self._get_order_col(order_by, UserSshKeys)
415 if sort_col:
416 if order_dir == 'asc':
417 # handle null values properly to order by NULL last
418 if order_by in ['created_on']:
419 sort_col = coalesce(sort_col, datetime.date.max)
420 sort_col = sort_col.asc()
421 else:
422 # handle null values properly to order by NULL last
423 if order_by in ['created_on']:
424 sort_col = coalesce(sort_col, datetime.date.min)
425 sort_col = sort_col.desc()
426
427 base_q = base_q.order_by(sort_col)
428 base_q = base_q.offset(start).limit(limit)
429
430 ssh_keys = base_q.all()
431
432 ssh_keys_data = []
433 for ssh_key in ssh_keys:
434 ssh_keys_data.append({
435 "username": h.gravatar_with_user(self.request, ssh_key.user.username),
436 "fingerprint": ssh_key.ssh_key_fingerprint,
437 "description": ssh_key.description,
438 "created_on": h.format_date(ssh_key.created_on),
439 "action": h.link_to(
440 _('Edit'), h.route_path('edit_user_ssh_keys',
441 user_id=ssh_key.user.user_id))
442 })
443
444 data = ({
445 'draw': draw,
446 'data': ssh_keys_data,
447 'recordsTotal': ssh_keys_data_total_count,
448 'recordsFiltered': users_data_total_filtered_count,
449 })
450
451 return data
452
453 @LoginRequired()
454 @HasPermissionAllDecorator('hg.admin')
455 @CSRFRequired()
456 @view_config(
457 route_name='admin_permissions_ssh_keys_update', request_method='POST',
458 renderer='rhodecode:templates/admin/permissions/permissions.mako')
459 def ssh_keys_update(self):
460 _ = self.request.translate
461 self.load_default_context()
462
463 ssh_enabled = self.request.registry.settings.get(
464 'ssh.generate_authorized_keyfile')
465 key_file = self.request.registry.settings.get(
466 'ssh.authorized_keys_file_path')
467 if ssh_enabled:
468 trigger(SshKeyFileChangeEvent(), self.request.registry)
469 h.flash(_('Updated SSH keys file: {}').format(key_file),
470 category='success')
471 else:
472 h.flash(_('SSH key support is disabled in .ini file'),
473 category='warning')
474
475 raise HTTPFound(h.route_path('admin_permissions_ssh_keys'))
@@ -1,251 +1,254 b''
1
1
2 /******************************************************************************
2 /******************************************************************************
3 * *
3 * *
4 * DO NOT CHANGE THIS FILE MANUALLY *
4 * DO NOT CHANGE THIS FILE MANUALLY *
5 * *
5 * *
6 * *
6 * *
7 * This file is automatically generated when the app starts up with *
7 * This file is automatically generated when the app starts up with *
8 * generate_js_files = true *
8 * generate_js_files = true *
9 * *
9 * *
10 * To add a route here pass jsroute=True to the route definition in the app *
10 * To add a route here pass jsroute=True to the route definition in the app *
11 * *
11 * *
12 ******************************************************************************/
12 ******************************************************************************/
13 function registerRCRoutes() {
13 function registerRCRoutes() {
14 // routes registration
14 // routes registration
15 pyroutes.register('edit_user', '/_admin/users/%(user_id)s/edit', ['user_id']);
15 pyroutes.register('edit_user', '/_admin/users/%(user_id)s/edit', ['user_id']);
16 pyroutes.register('favicon', '/favicon.ico', []);
16 pyroutes.register('favicon', '/favicon.ico', []);
17 pyroutes.register('robots', '/robots.txt', []);
17 pyroutes.register('robots', '/robots.txt', []);
18 pyroutes.register('auth_home', '/_admin/auth*traverse', []);
18 pyroutes.register('auth_home', '/_admin/auth*traverse', []);
19 pyroutes.register('global_integrations_new', '/_admin/integrations/new', []);
19 pyroutes.register('global_integrations_new', '/_admin/integrations/new', []);
20 pyroutes.register('global_integrations_home', '/_admin/integrations', []);
20 pyroutes.register('global_integrations_home', '/_admin/integrations', []);
21 pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']);
21 pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']);
22 pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
22 pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
23 pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
23 pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
24 pyroutes.register('repo_group_integrations_home', '/%(repo_group_name)s/settings/integrations', ['repo_group_name']);
24 pyroutes.register('repo_group_integrations_home', '/%(repo_group_name)s/settings/integrations', ['repo_group_name']);
25 pyroutes.register('repo_group_integrations_new', '/%(repo_group_name)s/settings/integrations/new', ['repo_group_name']);
25 pyroutes.register('repo_group_integrations_new', '/%(repo_group_name)s/settings/integrations/new', ['repo_group_name']);
26 pyroutes.register('repo_group_integrations_list', '/%(repo_group_name)s/settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
26 pyroutes.register('repo_group_integrations_list', '/%(repo_group_name)s/settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
27 pyroutes.register('repo_group_integrations_create', '/%(repo_group_name)s/settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
27 pyroutes.register('repo_group_integrations_create', '/%(repo_group_name)s/settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
28 pyroutes.register('repo_group_integrations_edit', '/%(repo_group_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
28 pyroutes.register('repo_group_integrations_edit', '/%(repo_group_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
29 pyroutes.register('repo_integrations_home', '/%(repo_name)s/settings/integrations', ['repo_name']);
29 pyroutes.register('repo_integrations_home', '/%(repo_name)s/settings/integrations', ['repo_name']);
30 pyroutes.register('repo_integrations_new', '/%(repo_name)s/settings/integrations/new', ['repo_name']);
30 pyroutes.register('repo_integrations_new', '/%(repo_name)s/settings/integrations/new', ['repo_name']);
31 pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
31 pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
32 pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
32 pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
33 pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
33 pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
34 pyroutes.register('ops_ping', '/_admin/ops/ping', []);
34 pyroutes.register('ops_ping', '/_admin/ops/ping', []);
35 pyroutes.register('ops_error_test', '/_admin/ops/error', []);
35 pyroutes.register('ops_error_test', '/_admin/ops/error', []);
36 pyroutes.register('ops_redirect_test', '/_admin/ops/redirect', []);
36 pyroutes.register('ops_redirect_test', '/_admin/ops/redirect', []);
37 pyroutes.register('admin_home', '/_admin', []);
37 pyroutes.register('admin_home', '/_admin', []);
38 pyroutes.register('admin_audit_logs', '/_admin/audit_logs', []);
38 pyroutes.register('admin_audit_logs', '/_admin/audit_logs', []);
39 pyroutes.register('pull_requests_global_0', '/_admin/pull_requests/%(pull_request_id)s', ['pull_request_id']);
39 pyroutes.register('pull_requests_global_0', '/_admin/pull_requests/%(pull_request_id)s', ['pull_request_id']);
40 pyroutes.register('pull_requests_global_1', '/_admin/pull-requests/%(pull_request_id)s', ['pull_request_id']);
40 pyroutes.register('pull_requests_global_1', '/_admin/pull-requests/%(pull_request_id)s', ['pull_request_id']);
41 pyroutes.register('pull_requests_global', '/_admin/pull-request/%(pull_request_id)s', ['pull_request_id']);
41 pyroutes.register('pull_requests_global', '/_admin/pull-request/%(pull_request_id)s', ['pull_request_id']);
42 pyroutes.register('admin_settings_open_source', '/_admin/settings/open_source', []);
42 pyroutes.register('admin_settings_open_source', '/_admin/settings/open_source', []);
43 pyroutes.register('admin_settings_vcs_svn_generate_cfg', '/_admin/settings/vcs/svn_generate_cfg', []);
43 pyroutes.register('admin_settings_vcs_svn_generate_cfg', '/_admin/settings/vcs/svn_generate_cfg', []);
44 pyroutes.register('admin_settings_system', '/_admin/settings/system', []);
44 pyroutes.register('admin_settings_system', '/_admin/settings/system', []);
45 pyroutes.register('admin_settings_system_update', '/_admin/settings/system/updates', []);
45 pyroutes.register('admin_settings_system_update', '/_admin/settings/system/updates', []);
46 pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []);
46 pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []);
47 pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []);
47 pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []);
48 pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []);
48 pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []);
49 pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []);
49 pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []);
50 pyroutes.register('admin_permissions_application', '/_admin/permissions/application', []);
50 pyroutes.register('admin_permissions_application', '/_admin/permissions/application', []);
51 pyroutes.register('admin_permissions_application_update', '/_admin/permissions/application/update', []);
51 pyroutes.register('admin_permissions_application_update', '/_admin/permissions/application/update', []);
52 pyroutes.register('admin_permissions_global', '/_admin/permissions/global', []);
52 pyroutes.register('admin_permissions_global', '/_admin/permissions/global', []);
53 pyroutes.register('admin_permissions_global_update', '/_admin/permissions/global/update', []);
53 pyroutes.register('admin_permissions_global_update', '/_admin/permissions/global/update', []);
54 pyroutes.register('admin_permissions_object', '/_admin/permissions/object', []);
54 pyroutes.register('admin_permissions_object', '/_admin/permissions/object', []);
55 pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []);
55 pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []);
56 pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []);
56 pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []);
57 pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []);
57 pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []);
58 pyroutes.register('admin_permissions_auth_token_access', '/_admin/permissions/auth_token_access', []);
58 pyroutes.register('admin_permissions_auth_token_access', '/_admin/permissions/auth_token_access', []);
59 pyroutes.register('admin_permissions_ssh_keys', '/_admin/permissions/ssh_keys', []);
60 pyroutes.register('admin_permissions_ssh_keys_data', '/_admin/permissions/ssh_keys/data', []);
61 pyroutes.register('admin_permissions_ssh_keys_update', '/_admin/permissions/ssh_keys/update', []);
59 pyroutes.register('users', '/_admin/users', []);
62 pyroutes.register('users', '/_admin/users', []);
60 pyroutes.register('users_data', '/_admin/users_data', []);
63 pyroutes.register('users_data', '/_admin/users_data', []);
61 pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']);
64 pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']);
62 pyroutes.register('edit_user_auth_tokens_add', '/_admin/users/%(user_id)s/edit/auth_tokens/new', ['user_id']);
65 pyroutes.register('edit_user_auth_tokens_add', '/_admin/users/%(user_id)s/edit/auth_tokens/new', ['user_id']);
63 pyroutes.register('edit_user_auth_tokens_delete', '/_admin/users/%(user_id)s/edit/auth_tokens/delete', ['user_id']);
66 pyroutes.register('edit_user_auth_tokens_delete', '/_admin/users/%(user_id)s/edit/auth_tokens/delete', ['user_id']);
64 pyroutes.register('edit_user_ssh_keys', '/_admin/users/%(user_id)s/edit/ssh_keys', ['user_id']);
67 pyroutes.register('edit_user_ssh_keys', '/_admin/users/%(user_id)s/edit/ssh_keys', ['user_id']);
65 pyroutes.register('edit_user_ssh_keys_generate_keypair', '/_admin/users/%(user_id)s/edit/ssh_keys/generate', ['user_id']);
68 pyroutes.register('edit_user_ssh_keys_generate_keypair', '/_admin/users/%(user_id)s/edit/ssh_keys/generate', ['user_id']);
66 pyroutes.register('edit_user_ssh_keys_add', '/_admin/users/%(user_id)s/edit/ssh_keys/new', ['user_id']);
69 pyroutes.register('edit_user_ssh_keys_add', '/_admin/users/%(user_id)s/edit/ssh_keys/new', ['user_id']);
67 pyroutes.register('edit_user_ssh_keys_delete', '/_admin/users/%(user_id)s/edit/ssh_keys/delete', ['user_id']);
70 pyroutes.register('edit_user_ssh_keys_delete', '/_admin/users/%(user_id)s/edit/ssh_keys/delete', ['user_id']);
68 pyroutes.register('edit_user_emails', '/_admin/users/%(user_id)s/edit/emails', ['user_id']);
71 pyroutes.register('edit_user_emails', '/_admin/users/%(user_id)s/edit/emails', ['user_id']);
69 pyroutes.register('edit_user_emails_add', '/_admin/users/%(user_id)s/edit/emails/new', ['user_id']);
72 pyroutes.register('edit_user_emails_add', '/_admin/users/%(user_id)s/edit/emails/new', ['user_id']);
70 pyroutes.register('edit_user_emails_delete', '/_admin/users/%(user_id)s/edit/emails/delete', ['user_id']);
73 pyroutes.register('edit_user_emails_delete', '/_admin/users/%(user_id)s/edit/emails/delete', ['user_id']);
71 pyroutes.register('edit_user_ips', '/_admin/users/%(user_id)s/edit/ips', ['user_id']);
74 pyroutes.register('edit_user_ips', '/_admin/users/%(user_id)s/edit/ips', ['user_id']);
72 pyroutes.register('edit_user_ips_add', '/_admin/users/%(user_id)s/edit/ips/new', ['user_id']);
75 pyroutes.register('edit_user_ips_add', '/_admin/users/%(user_id)s/edit/ips/new', ['user_id']);
73 pyroutes.register('edit_user_ips_delete', '/_admin/users/%(user_id)s/edit/ips/delete', ['user_id']);
76 pyroutes.register('edit_user_ips_delete', '/_admin/users/%(user_id)s/edit/ips/delete', ['user_id']);
74 pyroutes.register('edit_user_perms_summary', '/_admin/users/%(user_id)s/edit/permissions_summary', ['user_id']);
77 pyroutes.register('edit_user_perms_summary', '/_admin/users/%(user_id)s/edit/permissions_summary', ['user_id']);
75 pyroutes.register('edit_user_perms_summary_json', '/_admin/users/%(user_id)s/edit/permissions_summary/json', ['user_id']);
78 pyroutes.register('edit_user_perms_summary_json', '/_admin/users/%(user_id)s/edit/permissions_summary/json', ['user_id']);
76 pyroutes.register('edit_user_groups_management', '/_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
79 pyroutes.register('edit_user_groups_management', '/_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
77 pyroutes.register('edit_user_groups_management_updates', '/_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
80 pyroutes.register('edit_user_groups_management_updates', '/_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
78 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
81 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
79 pyroutes.register('user_groups', '/_admin/user_groups', []);
82 pyroutes.register('user_groups', '/_admin/user_groups', []);
80 pyroutes.register('user_groups_data', '/_admin/user_groups_data', []);
83 pyroutes.register('user_groups_data', '/_admin/user_groups_data', []);
81 pyroutes.register('user_group_members_data', '/_admin/user_groups/%(user_group_id)s/members', ['user_group_id']);
84 pyroutes.register('user_group_members_data', '/_admin/user_groups/%(user_group_id)s/members', ['user_group_id']);
82 pyroutes.register('edit_user_group_perms_summary', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary', ['user_group_id']);
85 pyroutes.register('edit_user_group_perms_summary', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary', ['user_group_id']);
83 pyroutes.register('edit_user_group_perms_summary_json', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary/json', ['user_group_id']);
86 pyroutes.register('edit_user_group_perms_summary_json', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary/json', ['user_group_id']);
84 pyroutes.register('repos', '/_admin/repos', []);
87 pyroutes.register('repos', '/_admin/repos', []);
85 pyroutes.register('repo_new', '/_admin/repos/new', []);
88 pyroutes.register('repo_new', '/_admin/repos/new', []);
86 pyroutes.register('repo_create', '/_admin/repos/create', []);
89 pyroutes.register('repo_create', '/_admin/repos/create', []);
87 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
90 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
88 pyroutes.register('channelstream_subscribe', '/_admin/channelstream/subscribe', []);
91 pyroutes.register('channelstream_subscribe', '/_admin/channelstream/subscribe', []);
89 pyroutes.register('channelstream_proxy', '/_channelstream', []);
92 pyroutes.register('channelstream_proxy', '/_channelstream', []);
90 pyroutes.register('login', '/_admin/login', []);
93 pyroutes.register('login', '/_admin/login', []);
91 pyroutes.register('logout', '/_admin/logout', []);
94 pyroutes.register('logout', '/_admin/logout', []);
92 pyroutes.register('register', '/_admin/register', []);
95 pyroutes.register('register', '/_admin/register', []);
93 pyroutes.register('reset_password', '/_admin/password_reset', []);
96 pyroutes.register('reset_password', '/_admin/password_reset', []);
94 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
97 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
95 pyroutes.register('home', '/', []);
98 pyroutes.register('home', '/', []);
96 pyroutes.register('user_autocomplete_data', '/_users', []);
99 pyroutes.register('user_autocomplete_data', '/_users', []);
97 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
100 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
98 pyroutes.register('repo_list_data', '/_repos', []);
101 pyroutes.register('repo_list_data', '/_repos', []);
99 pyroutes.register('goto_switcher_data', '/_goto_data', []);
102 pyroutes.register('goto_switcher_data', '/_goto_data', []);
100 pyroutes.register('journal', '/_admin/journal', []);
103 pyroutes.register('journal', '/_admin/journal', []);
101 pyroutes.register('journal_rss', '/_admin/journal/rss', []);
104 pyroutes.register('journal_rss', '/_admin/journal/rss', []);
102 pyroutes.register('journal_atom', '/_admin/journal/atom', []);
105 pyroutes.register('journal_atom', '/_admin/journal/atom', []);
103 pyroutes.register('journal_public', '/_admin/public_journal', []);
106 pyroutes.register('journal_public', '/_admin/public_journal', []);
104 pyroutes.register('journal_public_atom', '/_admin/public_journal/atom', []);
107 pyroutes.register('journal_public_atom', '/_admin/public_journal/atom', []);
105 pyroutes.register('journal_public_atom_old', '/_admin/public_journal_atom', []);
108 pyroutes.register('journal_public_atom_old', '/_admin/public_journal_atom', []);
106 pyroutes.register('journal_public_rss', '/_admin/public_journal/rss', []);
109 pyroutes.register('journal_public_rss', '/_admin/public_journal/rss', []);
107 pyroutes.register('journal_public_rss_old', '/_admin/public_journal_rss', []);
110 pyroutes.register('journal_public_rss_old', '/_admin/public_journal_rss', []);
108 pyroutes.register('toggle_following', '/_admin/toggle_following', []);
111 pyroutes.register('toggle_following', '/_admin/toggle_following', []);
109 pyroutes.register('repo_creating', '/%(repo_name)s/repo_creating', ['repo_name']);
112 pyroutes.register('repo_creating', '/%(repo_name)s/repo_creating', ['repo_name']);
110 pyroutes.register('repo_creating_check', '/%(repo_name)s/repo_creating_check', ['repo_name']);
113 pyroutes.register('repo_creating_check', '/%(repo_name)s/repo_creating_check', ['repo_name']);
111 pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']);
114 pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']);
112 pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']);
115 pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']);
113 pyroutes.register('repo_commit', '/%(repo_name)s/changeset/%(commit_id)s', ['repo_name', 'commit_id']);
116 pyroutes.register('repo_commit', '/%(repo_name)s/changeset/%(commit_id)s', ['repo_name', 'commit_id']);
114 pyroutes.register('repo_commit_children', '/%(repo_name)s/changeset_children/%(commit_id)s', ['repo_name', 'commit_id']);
117 pyroutes.register('repo_commit_children', '/%(repo_name)s/changeset_children/%(commit_id)s', ['repo_name', 'commit_id']);
115 pyroutes.register('repo_commit_parents', '/%(repo_name)s/changeset_parents/%(commit_id)s', ['repo_name', 'commit_id']);
118 pyroutes.register('repo_commit_parents', '/%(repo_name)s/changeset_parents/%(commit_id)s', ['repo_name', 'commit_id']);
116 pyroutes.register('repo_commit_raw', '/%(repo_name)s/changeset-diff/%(commit_id)s', ['repo_name', 'commit_id']);
119 pyroutes.register('repo_commit_raw', '/%(repo_name)s/changeset-diff/%(commit_id)s', ['repo_name', 'commit_id']);
117 pyroutes.register('repo_commit_patch', '/%(repo_name)s/changeset-patch/%(commit_id)s', ['repo_name', 'commit_id']);
120 pyroutes.register('repo_commit_patch', '/%(repo_name)s/changeset-patch/%(commit_id)s', ['repo_name', 'commit_id']);
118 pyroutes.register('repo_commit_download', '/%(repo_name)s/changeset-download/%(commit_id)s', ['repo_name', 'commit_id']);
121 pyroutes.register('repo_commit_download', '/%(repo_name)s/changeset-download/%(commit_id)s', ['repo_name', 'commit_id']);
119 pyroutes.register('repo_commit_data', '/%(repo_name)s/changeset-data/%(commit_id)s', ['repo_name', 'commit_id']);
122 pyroutes.register('repo_commit_data', '/%(repo_name)s/changeset-data/%(commit_id)s', ['repo_name', 'commit_id']);
120 pyroutes.register('repo_commit_comment_create', '/%(repo_name)s/changeset/%(commit_id)s/comment/create', ['repo_name', 'commit_id']);
123 pyroutes.register('repo_commit_comment_create', '/%(repo_name)s/changeset/%(commit_id)s/comment/create', ['repo_name', 'commit_id']);
121 pyroutes.register('repo_commit_comment_preview', '/%(repo_name)s/changeset/%(commit_id)s/comment/preview', ['repo_name', 'commit_id']);
124 pyroutes.register('repo_commit_comment_preview', '/%(repo_name)s/changeset/%(commit_id)s/comment/preview', ['repo_name', 'commit_id']);
122 pyroutes.register('repo_commit_comment_delete', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/delete', ['repo_name', 'commit_id', 'comment_id']);
125 pyroutes.register('repo_commit_comment_delete', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/delete', ['repo_name', 'commit_id', 'comment_id']);
123 pyroutes.register('repo_commit_raw_deprecated', '/%(repo_name)s/raw-changeset/%(commit_id)s', ['repo_name', 'commit_id']);
126 pyroutes.register('repo_commit_raw_deprecated', '/%(repo_name)s/raw-changeset/%(commit_id)s', ['repo_name', 'commit_id']);
124 pyroutes.register('repo_archivefile', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']);
127 pyroutes.register('repo_archivefile', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']);
125 pyroutes.register('repo_files_diff', '/%(repo_name)s/diff/%(f_path)s', ['repo_name', 'f_path']);
128 pyroutes.register('repo_files_diff', '/%(repo_name)s/diff/%(f_path)s', ['repo_name', 'f_path']);
126 pyroutes.register('repo_files_diff_2way_redirect', '/%(repo_name)s/diff-2way/%(f_path)s', ['repo_name', 'f_path']);
129 pyroutes.register('repo_files_diff_2way_redirect', '/%(repo_name)s/diff-2way/%(f_path)s', ['repo_name', 'f_path']);
127 pyroutes.register('repo_files', '/%(repo_name)s/files/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
130 pyroutes.register('repo_files', '/%(repo_name)s/files/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
128 pyroutes.register('repo_files:default_path', '/%(repo_name)s/files/%(commit_id)s/', ['repo_name', 'commit_id']);
131 pyroutes.register('repo_files:default_path', '/%(repo_name)s/files/%(commit_id)s/', ['repo_name', 'commit_id']);
129 pyroutes.register('repo_files:default_commit', '/%(repo_name)s/files', ['repo_name']);
132 pyroutes.register('repo_files:default_commit', '/%(repo_name)s/files', ['repo_name']);
130 pyroutes.register('repo_files:rendered', '/%(repo_name)s/render/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
133 pyroutes.register('repo_files:rendered', '/%(repo_name)s/render/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
131 pyroutes.register('repo_files:annotated', '/%(repo_name)s/annotate/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
134 pyroutes.register('repo_files:annotated', '/%(repo_name)s/annotate/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
132 pyroutes.register('repo_files:annotated_previous', '/%(repo_name)s/annotate-previous/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
135 pyroutes.register('repo_files:annotated_previous', '/%(repo_name)s/annotate-previous/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
133 pyroutes.register('repo_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
136 pyroutes.register('repo_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
134 pyroutes.register('repo_nodetree_full:default_path', '/%(repo_name)s/nodetree_full/%(commit_id)s/', ['repo_name', 'commit_id']);
137 pyroutes.register('repo_nodetree_full:default_path', '/%(repo_name)s/nodetree_full/%(commit_id)s/', ['repo_name', 'commit_id']);
135 pyroutes.register('repo_files_nodelist', '/%(repo_name)s/nodelist/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
138 pyroutes.register('repo_files_nodelist', '/%(repo_name)s/nodelist/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
136 pyroutes.register('repo_file_raw', '/%(repo_name)s/raw/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
139 pyroutes.register('repo_file_raw', '/%(repo_name)s/raw/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
137 pyroutes.register('repo_file_download', '/%(repo_name)s/download/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
140 pyroutes.register('repo_file_download', '/%(repo_name)s/download/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
138 pyroutes.register('repo_file_download:legacy', '/%(repo_name)s/rawfile/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
141 pyroutes.register('repo_file_download:legacy', '/%(repo_name)s/rawfile/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
139 pyroutes.register('repo_file_history', '/%(repo_name)s/history/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
142 pyroutes.register('repo_file_history', '/%(repo_name)s/history/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
140 pyroutes.register('repo_file_authors', '/%(repo_name)s/authors/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
143 pyroutes.register('repo_file_authors', '/%(repo_name)s/authors/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
141 pyroutes.register('repo_files_remove_file', '/%(repo_name)s/remove_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
144 pyroutes.register('repo_files_remove_file', '/%(repo_name)s/remove_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
142 pyroutes.register('repo_files_delete_file', '/%(repo_name)s/delete_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
145 pyroutes.register('repo_files_delete_file', '/%(repo_name)s/delete_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
143 pyroutes.register('repo_files_edit_file', '/%(repo_name)s/edit_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
146 pyroutes.register('repo_files_edit_file', '/%(repo_name)s/edit_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
144 pyroutes.register('repo_files_update_file', '/%(repo_name)s/update_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
147 pyroutes.register('repo_files_update_file', '/%(repo_name)s/update_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
145 pyroutes.register('repo_files_add_file', '/%(repo_name)s/add_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
148 pyroutes.register('repo_files_add_file', '/%(repo_name)s/add_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
146 pyroutes.register('repo_files_create_file', '/%(repo_name)s/create_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
149 pyroutes.register('repo_files_create_file', '/%(repo_name)s/create_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
147 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
150 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
148 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
151 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
149 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
152 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
150 pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']);
153 pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']);
151 pyroutes.register('repo_changelog_file', '/%(repo_name)s/changelog/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
154 pyroutes.register('repo_changelog_file', '/%(repo_name)s/changelog/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
152 pyroutes.register('repo_changelog_elements', '/%(repo_name)s/changelog_elements', ['repo_name']);
155 pyroutes.register('repo_changelog_elements', '/%(repo_name)s/changelog_elements', ['repo_name']);
153 pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']);
156 pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']);
154 pyroutes.register('repo_compare', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
157 pyroutes.register('repo_compare', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
155 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
158 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
156 pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
159 pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
157 pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
160 pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
158 pyroutes.register('repo_fork_new', '/%(repo_name)s/fork', ['repo_name']);
161 pyroutes.register('repo_fork_new', '/%(repo_name)s/fork', ['repo_name']);
159 pyroutes.register('repo_fork_create', '/%(repo_name)s/fork/create', ['repo_name']);
162 pyroutes.register('repo_fork_create', '/%(repo_name)s/fork/create', ['repo_name']);
160 pyroutes.register('repo_forks_show_all', '/%(repo_name)s/forks', ['repo_name']);
163 pyroutes.register('repo_forks_show_all', '/%(repo_name)s/forks', ['repo_name']);
161 pyroutes.register('repo_forks_data', '/%(repo_name)s/forks/data', ['repo_name']);
164 pyroutes.register('repo_forks_data', '/%(repo_name)s/forks/data', ['repo_name']);
162 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
165 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
163 pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
166 pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
164 pyroutes.register('pullrequest_show_all_data', '/%(repo_name)s/pull-request-data', ['repo_name']);
167 pyroutes.register('pullrequest_show_all_data', '/%(repo_name)s/pull-request-data', ['repo_name']);
165 pyroutes.register('pullrequest_repo_refs', '/%(repo_name)s/pull-request/refs/%(target_repo_name)s', ['repo_name', 'target_repo_name']);
168 pyroutes.register('pullrequest_repo_refs', '/%(repo_name)s/pull-request/refs/%(target_repo_name)s', ['repo_name', 'target_repo_name']);
166 pyroutes.register('pullrequest_repo_destinations', '/%(repo_name)s/pull-request/repo-destinations', ['repo_name']);
169 pyroutes.register('pullrequest_repo_destinations', '/%(repo_name)s/pull-request/repo-destinations', ['repo_name']);
167 pyroutes.register('pullrequest_new', '/%(repo_name)s/pull-request/new', ['repo_name']);
170 pyroutes.register('pullrequest_new', '/%(repo_name)s/pull-request/new', ['repo_name']);
168 pyroutes.register('pullrequest_create', '/%(repo_name)s/pull-request/create', ['repo_name']);
171 pyroutes.register('pullrequest_create', '/%(repo_name)s/pull-request/create', ['repo_name']);
169 pyroutes.register('pullrequest_update', '/%(repo_name)s/pull-request/%(pull_request_id)s/update', ['repo_name', 'pull_request_id']);
172 pyroutes.register('pullrequest_update', '/%(repo_name)s/pull-request/%(pull_request_id)s/update', ['repo_name', 'pull_request_id']);
170 pyroutes.register('pullrequest_merge', '/%(repo_name)s/pull-request/%(pull_request_id)s/merge', ['repo_name', 'pull_request_id']);
173 pyroutes.register('pullrequest_merge', '/%(repo_name)s/pull-request/%(pull_request_id)s/merge', ['repo_name', 'pull_request_id']);
171 pyroutes.register('pullrequest_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/delete', ['repo_name', 'pull_request_id']);
174 pyroutes.register('pullrequest_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/delete', ['repo_name', 'pull_request_id']);
172 pyroutes.register('pullrequest_comment_create', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment', ['repo_name', 'pull_request_id']);
175 pyroutes.register('pullrequest_comment_create', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment', ['repo_name', 'pull_request_id']);
173 pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment/%(comment_id)s/delete', ['repo_name', 'pull_request_id', 'comment_id']);
176 pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment/%(comment_id)s/delete', ['repo_name', 'pull_request_id', 'comment_id']);
174 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
177 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
175 pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
178 pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
176 pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
179 pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
177 pyroutes.register('edit_repo_advanced_locking', '/%(repo_name)s/settings/advanced/locking', ['repo_name']);
180 pyroutes.register('edit_repo_advanced_locking', '/%(repo_name)s/settings/advanced/locking', ['repo_name']);
178 pyroutes.register('edit_repo_advanced_journal', '/%(repo_name)s/settings/advanced/journal', ['repo_name']);
181 pyroutes.register('edit_repo_advanced_journal', '/%(repo_name)s/settings/advanced/journal', ['repo_name']);
179 pyroutes.register('edit_repo_advanced_fork', '/%(repo_name)s/settings/advanced/fork', ['repo_name']);
182 pyroutes.register('edit_repo_advanced_fork', '/%(repo_name)s/settings/advanced/fork', ['repo_name']);
180 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
183 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
181 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
184 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
182 pyroutes.register('edit_repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']);
185 pyroutes.register('edit_repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']);
183 pyroutes.register('edit_repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']);
186 pyroutes.register('edit_repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']);
184 pyroutes.register('edit_repo_fields', '/%(repo_name)s/settings/fields', ['repo_name']);
187 pyroutes.register('edit_repo_fields', '/%(repo_name)s/settings/fields', ['repo_name']);
185 pyroutes.register('edit_repo_fields_create', '/%(repo_name)s/settings/fields/create', ['repo_name']);
188 pyroutes.register('edit_repo_fields_create', '/%(repo_name)s/settings/fields/create', ['repo_name']);
186 pyroutes.register('edit_repo_fields_delete', '/%(repo_name)s/settings/fields/%(field_id)s/delete', ['repo_name', 'field_id']);
189 pyroutes.register('edit_repo_fields_delete', '/%(repo_name)s/settings/fields/%(field_id)s/delete', ['repo_name', 'field_id']);
187 pyroutes.register('repo_edit_toggle_locking', '/%(repo_name)s/settings/toggle_locking', ['repo_name']);
190 pyroutes.register('repo_edit_toggle_locking', '/%(repo_name)s/settings/toggle_locking', ['repo_name']);
188 pyroutes.register('edit_repo_remote', '/%(repo_name)s/settings/remote', ['repo_name']);
191 pyroutes.register('edit_repo_remote', '/%(repo_name)s/settings/remote', ['repo_name']);
189 pyroutes.register('edit_repo_remote_pull', '/%(repo_name)s/settings/remote/pull', ['repo_name']);
192 pyroutes.register('edit_repo_remote_pull', '/%(repo_name)s/settings/remote/pull', ['repo_name']);
190 pyroutes.register('edit_repo_statistics', '/%(repo_name)s/settings/statistics', ['repo_name']);
193 pyroutes.register('edit_repo_statistics', '/%(repo_name)s/settings/statistics', ['repo_name']);
191 pyroutes.register('edit_repo_statistics_reset', '/%(repo_name)s/settings/statistics/update', ['repo_name']);
194 pyroutes.register('edit_repo_statistics_reset', '/%(repo_name)s/settings/statistics/update', ['repo_name']);
192 pyroutes.register('edit_repo_issuetracker', '/%(repo_name)s/settings/issue_trackers', ['repo_name']);
195 pyroutes.register('edit_repo_issuetracker', '/%(repo_name)s/settings/issue_trackers', ['repo_name']);
193 pyroutes.register('edit_repo_issuetracker_test', '/%(repo_name)s/settings/issue_trackers/test', ['repo_name']);
196 pyroutes.register('edit_repo_issuetracker_test', '/%(repo_name)s/settings/issue_trackers/test', ['repo_name']);
194 pyroutes.register('edit_repo_issuetracker_delete', '/%(repo_name)s/settings/issue_trackers/delete', ['repo_name']);
197 pyroutes.register('edit_repo_issuetracker_delete', '/%(repo_name)s/settings/issue_trackers/delete', ['repo_name']);
195 pyroutes.register('edit_repo_issuetracker_update', '/%(repo_name)s/settings/issue_trackers/update', ['repo_name']);
198 pyroutes.register('edit_repo_issuetracker_update', '/%(repo_name)s/settings/issue_trackers/update', ['repo_name']);
196 pyroutes.register('edit_repo_vcs', '/%(repo_name)s/settings/vcs', ['repo_name']);
199 pyroutes.register('edit_repo_vcs', '/%(repo_name)s/settings/vcs', ['repo_name']);
197 pyroutes.register('edit_repo_vcs_update', '/%(repo_name)s/settings/vcs/update', ['repo_name']);
200 pyroutes.register('edit_repo_vcs_update', '/%(repo_name)s/settings/vcs/update', ['repo_name']);
198 pyroutes.register('edit_repo_vcs_svn_pattern_delete', '/%(repo_name)s/settings/vcs/svn_pattern/delete', ['repo_name']);
201 pyroutes.register('edit_repo_vcs_svn_pattern_delete', '/%(repo_name)s/settings/vcs/svn_pattern/delete', ['repo_name']);
199 pyroutes.register('repo_reviewers', '/%(repo_name)s/settings/review/rules', ['repo_name']);
202 pyroutes.register('repo_reviewers', '/%(repo_name)s/settings/review/rules', ['repo_name']);
200 pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/settings/review/default-reviewers', ['repo_name']);
203 pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/settings/review/default-reviewers', ['repo_name']);
201 pyroutes.register('edit_repo_strip', '/%(repo_name)s/settings/strip', ['repo_name']);
204 pyroutes.register('edit_repo_strip', '/%(repo_name)s/settings/strip', ['repo_name']);
202 pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']);
205 pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']);
203 pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']);
206 pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']);
204 pyroutes.register('rss_feed_home', '/%(repo_name)s/feed/rss', ['repo_name']);
207 pyroutes.register('rss_feed_home', '/%(repo_name)s/feed/rss', ['repo_name']);
205 pyroutes.register('atom_feed_home', '/%(repo_name)s/feed/atom', ['repo_name']);
208 pyroutes.register('atom_feed_home', '/%(repo_name)s/feed/atom', ['repo_name']);
206 pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']);
209 pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']);
207 pyroutes.register('repo_summary_slash', '/%(repo_name)s/', ['repo_name']);
210 pyroutes.register('repo_summary_slash', '/%(repo_name)s/', ['repo_name']);
208 pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']);
211 pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']);
209 pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']);
212 pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']);
210 pyroutes.register('search', '/_admin/search', []);
213 pyroutes.register('search', '/_admin/search', []);
211 pyroutes.register('search_repo', '/%(repo_name)s/search', ['repo_name']);
214 pyroutes.register('search_repo', '/%(repo_name)s/search', ['repo_name']);
212 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
215 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
213 pyroutes.register('my_account_profile', '/_admin/my_account/profile', []);
216 pyroutes.register('my_account_profile', '/_admin/my_account/profile', []);
214 pyroutes.register('my_account_edit', '/_admin/my_account/edit', []);
217 pyroutes.register('my_account_edit', '/_admin/my_account/edit', []);
215 pyroutes.register('my_account_update', '/_admin/my_account/update', []);
218 pyroutes.register('my_account_update', '/_admin/my_account/update', []);
216 pyroutes.register('my_account_password', '/_admin/my_account/password', []);
219 pyroutes.register('my_account_password', '/_admin/my_account/password', []);
217 pyroutes.register('my_account_password_update', '/_admin/my_account/password/update', []);
220 pyroutes.register('my_account_password_update', '/_admin/my_account/password/update', []);
218 pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []);
221 pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []);
219 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
222 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
220 pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []);
223 pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []);
221 pyroutes.register('my_account_emails', '/_admin/my_account/emails', []);
224 pyroutes.register('my_account_emails', '/_admin/my_account/emails', []);
222 pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []);
225 pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []);
223 pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []);
226 pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []);
224 pyroutes.register('my_account_repos', '/_admin/my_account/repos', []);
227 pyroutes.register('my_account_repos', '/_admin/my_account/repos', []);
225 pyroutes.register('my_account_watched', '/_admin/my_account/watched', []);
228 pyroutes.register('my_account_watched', '/_admin/my_account/watched', []);
226 pyroutes.register('my_account_perms', '/_admin/my_account/perms', []);
229 pyroutes.register('my_account_perms', '/_admin/my_account/perms', []);
227 pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []);
230 pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []);
228 pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []);
231 pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []);
229 pyroutes.register('my_account_pullrequests', '/_admin/my_account/pull_requests', []);
232 pyroutes.register('my_account_pullrequests', '/_admin/my_account/pull_requests', []);
230 pyroutes.register('my_account_pullrequests_data', '/_admin/my_account/pull_requests/data', []);
233 pyroutes.register('my_account_pullrequests_data', '/_admin/my_account/pull_requests/data', []);
231 pyroutes.register('notifications_show_all', '/_admin/notifications', []);
234 pyroutes.register('notifications_show_all', '/_admin/notifications', []);
232 pyroutes.register('notifications_mark_all_read', '/_admin/notifications/mark_all_read', []);
235 pyroutes.register('notifications_mark_all_read', '/_admin/notifications/mark_all_read', []);
233 pyroutes.register('notifications_show', '/_admin/notifications/%(notification_id)s', ['notification_id']);
236 pyroutes.register('notifications_show', '/_admin/notifications/%(notification_id)s', ['notification_id']);
234 pyroutes.register('notifications_update', '/_admin/notifications/%(notification_id)s/update', ['notification_id']);
237 pyroutes.register('notifications_update', '/_admin/notifications/%(notification_id)s/update', ['notification_id']);
235 pyroutes.register('notifications_delete', '/_admin/notifications/%(notification_id)s/delete', ['notification_id']);
238 pyroutes.register('notifications_delete', '/_admin/notifications/%(notification_id)s/delete', ['notification_id']);
236 pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []);
239 pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []);
237 pyroutes.register('gists_show', '/_admin/gists', []);
240 pyroutes.register('gists_show', '/_admin/gists', []);
238 pyroutes.register('gists_new', '/_admin/gists/new', []);
241 pyroutes.register('gists_new', '/_admin/gists/new', []);
239 pyroutes.register('gists_create', '/_admin/gists/create', []);
242 pyroutes.register('gists_create', '/_admin/gists/create', []);
240 pyroutes.register('gist_show', '/_admin/gists/%(gist_id)s', ['gist_id']);
243 pyroutes.register('gist_show', '/_admin/gists/%(gist_id)s', ['gist_id']);
241 pyroutes.register('gist_delete', '/_admin/gists/%(gist_id)s/delete', ['gist_id']);
244 pyroutes.register('gist_delete', '/_admin/gists/%(gist_id)s/delete', ['gist_id']);
242 pyroutes.register('gist_edit', '/_admin/gists/%(gist_id)s/edit', ['gist_id']);
245 pyroutes.register('gist_edit', '/_admin/gists/%(gist_id)s/edit', ['gist_id']);
243 pyroutes.register('gist_edit_check_revision', '/_admin/gists/%(gist_id)s/edit/check_revision', ['gist_id']);
246 pyroutes.register('gist_edit_check_revision', '/_admin/gists/%(gist_id)s/edit/check_revision', ['gist_id']);
244 pyroutes.register('gist_update', '/_admin/gists/%(gist_id)s/update', ['gist_id']);
247 pyroutes.register('gist_update', '/_admin/gists/%(gist_id)s/update', ['gist_id']);
245 pyroutes.register('gist_show_rev', '/_admin/gists/%(gist_id)s/%(revision)s', ['gist_id', 'revision']);
248 pyroutes.register('gist_show_rev', '/_admin/gists/%(gist_id)s/%(revision)s', ['gist_id', 'revision']);
246 pyroutes.register('gist_show_formatted', '/_admin/gists/%(gist_id)s/%(revision)s/%(format)s', ['gist_id', 'revision', 'format']);
249 pyroutes.register('gist_show_formatted', '/_admin/gists/%(gist_id)s/%(revision)s/%(format)s', ['gist_id', 'revision', 'format']);
247 pyroutes.register('gist_show_formatted_path', '/_admin/gists/%(gist_id)s/%(revision)s/%(format)s/%(f_path)s', ['gist_id', 'revision', 'format', 'f_path']);
250 pyroutes.register('gist_show_formatted_path', '/_admin/gists/%(gist_id)s/%(revision)s/%(format)s/%(f_path)s', ['gist_id', 'revision', 'format', 'f_path']);
248 pyroutes.register('debug_style_home', '/_admin/debug_style', []);
251 pyroutes.register('debug_style_home', '/_admin/debug_style', []);
249 pyroutes.register('debug_style_template', '/_admin/debug_style/t/%(t_path)s', ['t_path']);
252 pyroutes.register('debug_style_template', '/_admin/debug_style/t/%(t_path)s', ['t_path']);
250 pyroutes.register('apiv2', '/_admin/api', []);
253 pyroutes.register('apiv2', '/_admin/api', []);
251 }
254 }
@@ -1,59 +1,62 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.mako"/>
2 <%inherit file="/base/base.mako"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('Permissions Administration')}
5 ${_('Permissions Administration')}
6 %if c.rhodecode_name:
6 %if c.rhodecode_name:
7 &middot; ${h.branding(c.rhodecode_name)}
7 &middot; ${h.branding(c.rhodecode_name)}
8 %endif
8 %endif
9 </%def>
9 </%def>
10
10
11 <%def name="breadcrumbs_links()">
11 <%def name="breadcrumbs_links()">
12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 &raquo;
13 &raquo;
14 ${_('Permissions')}
14 ${_('Permissions')}
15 </%def>
15 </%def>
16
16
17 <%def name="menu_bar_nav()">
17 <%def name="menu_bar_nav()">
18 ${self.menu_items(active='admin')}
18 ${self.menu_items(active='admin')}
19 </%def>
19 </%def>
20
20
21
21
22 <%def name="main()">
22 <%def name="main()">
23 <div class="box">
23 <div class="box">
24 <div class="title">
24 <div class="title">
25 ${self.breadcrumbs()}
25 ${self.breadcrumbs()}
26 </div>
26 </div>
27
27
28 <div class="sidebar-col-wrapper scw-small">
28 <div class="sidebar-col-wrapper scw-small">
29 ##main
29 ##main
30 <div class="sidebar">
30 <div class="sidebar">
31 <ul class="nav nav-pills nav-stacked">
31 <ul class="nav nav-pills nav-stacked">
32 <li class="${'active' if c.active=='application' else ''}">
32 <li class="${'active' if c.active=='application' else ''}">
33 <a href="${h.route_path('admin_permissions_application')}">${_('Application')}</a>
33 <a href="${h.route_path('admin_permissions_application')}">${_('Application')}</a>
34 </li>
34 </li>
35 <li class="${'active' if c.active=='global' else ''}">
35 <li class="${'active' if c.active=='global' else ''}">
36 <a href="${h.route_path('admin_permissions_global')}">${_('Global')}</a>
36 <a href="${h.route_path('admin_permissions_global')}">${_('Global')}</a>
37 </li>
37 </li>
38 <li class="${'active' if c.active=='objects' else ''}">
38 <li class="${'active' if c.active=='objects' else ''}">
39 <a href="${h.route_path('admin_permissions_object')}">${_('Object')}</a>
39 <a href="${h.route_path('admin_permissions_object')}">${_('Object')}</a>
40 </li>
40 </li>
41 <li class="${'active' if c.active=='ips' else ''}">
41 <li class="${'active' if c.active=='ips' else ''}">
42 <a href="${h.route_path('admin_permissions_ips')}">${_('IP Whitelist')}</a>
42 <a href="${h.route_path('admin_permissions_ips')}">${_('IP Whitelist')}</a>
43 </li>
43 </li>
44 <li class="${'active' if c.active=='auth_token_access' else ''}">
44 <li class="${'active' if c.active=='auth_token_access' else ''}">
45 <a href="${h.route_path('admin_permissions_auth_token_access')}">${_('AuthToken Access')}</a>
45 <a href="${h.route_path('admin_permissions_auth_token_access')}">${_('AuthToken Access')}</a>
46 </li>
46 </li>
47 <li class="${'active' if c.active=='ssh_keys' else ''}">
48 <a href="${h.route_path('admin_permissions_ssh_keys')}">${_('SSH Keys')}</a>
49 </li>
47 <li class="${'active' if c.active=='perms' else ''}">
50 <li class="${'active' if c.active=='perms' else ''}">
48 <a href="${h.route_path('admin_permissions_overview')}">${_('Overview')}</a>
51 <a href="${h.route_path('admin_permissions_overview')}">${_('Overview')}</a>
49 </li>
52 </li>
50 </ul>
53 </ul>
51 </div>
54 </div>
52
55
53 <div class="main-content-full-width">
56 <div class="main-content-full-width">
54 <%include file="/admin/permissions/permissions_${c.active}.mako"/>
57 <%include file="/admin/permissions/permissions_${c.active}.mako"/>
55 </div>
58 </div>
56 </div>
59 </div>
57 </div>
60 </div>
58
61
59 </%def>
62 </%def>
General Comments 0
You need to be logged in to leave comments. Login now