##// END OF EJS Templates
ssh: fixed tests for disabled ssh support
marcink -
r2047:863217cc default
parent child Browse files
Show More
@@ -1,286 +1,300 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 mock
21 import pytest
22 import pytest
22 from rhodecode.model.db import User, UserIpMap
23 from rhodecode.model.db import User, UserIpMap
23 from rhodecode.model.meta import Session
24 from rhodecode.model.meta import Session
24 from rhodecode.model.permission import PermissionModel
25 from rhodecode.model.permission import PermissionModel
25 from rhodecode.model.ssh_key import SshKeyModel
26 from rhodecode.model.ssh_key import SshKeyModel
26 from rhodecode.tests import (
27 from rhodecode.tests import (
27 TestController, clear_all_caches, assert_session_flash)
28 TestController, clear_all_caches, assert_session_flash)
28
29
29
30
30 def route_path(name, params=None, **kwargs):
31 def route_path(name, params=None, **kwargs):
31 import urllib
32 import urllib
32 from rhodecode.apps._base import ADMIN_PREFIX
33 from rhodecode.apps._base import ADMIN_PREFIX
33
34
34 base_url = {
35 base_url = {
35 'edit_user_ips':
36 'edit_user_ips':
36 ADMIN_PREFIX + '/users/{user_id}/edit/ips',
37 ADMIN_PREFIX + '/users/{user_id}/edit/ips',
37 'edit_user_ips_add':
38 'edit_user_ips_add':
38 ADMIN_PREFIX + '/users/{user_id}/edit/ips/new',
39 ADMIN_PREFIX + '/users/{user_id}/edit/ips/new',
39 'edit_user_ips_delete':
40 'edit_user_ips_delete':
40 ADMIN_PREFIX + '/users/{user_id}/edit/ips/delete',
41 ADMIN_PREFIX + '/users/{user_id}/edit/ips/delete',
41
42
42 'admin_permissions_application':
43 'admin_permissions_application':
43 ADMIN_PREFIX + '/permissions/application',
44 ADMIN_PREFIX + '/permissions/application',
44 'admin_permissions_application_update':
45 'admin_permissions_application_update':
45 ADMIN_PREFIX + '/permissions/application/update',
46 ADMIN_PREFIX + '/permissions/application/update',
46
47
47 'admin_permissions_global':
48 'admin_permissions_global':
48 ADMIN_PREFIX + '/permissions/global',
49 ADMIN_PREFIX + '/permissions/global',
49 'admin_permissions_global_update':
50 'admin_permissions_global_update':
50 ADMIN_PREFIX + '/permissions/global/update',
51 ADMIN_PREFIX + '/permissions/global/update',
51
52
52 'admin_permissions_object':
53 'admin_permissions_object':
53 ADMIN_PREFIX + '/permissions/object',
54 ADMIN_PREFIX + '/permissions/object',
54 'admin_permissions_object_update':
55 'admin_permissions_object_update':
55 ADMIN_PREFIX + '/permissions/object/update',
56 ADMIN_PREFIX + '/permissions/object/update',
56
57
57 'admin_permissions_ips':
58 'admin_permissions_ips':
58 ADMIN_PREFIX + '/permissions/ips',
59 ADMIN_PREFIX + '/permissions/ips',
59 'admin_permissions_overview':
60 'admin_permissions_overview':
60 ADMIN_PREFIX + '/permissions/overview',
61 ADMIN_PREFIX + '/permissions/overview',
61
62
62 'admin_permissions_ssh_keys':
63 'admin_permissions_ssh_keys':
63 ADMIN_PREFIX + '/permissions/ssh_keys',
64 ADMIN_PREFIX + '/permissions/ssh_keys',
64 'admin_permissions_ssh_keys_data':
65 'admin_permissions_ssh_keys_data':
65 ADMIN_PREFIX + '/permissions/ssh_keys/data',
66 ADMIN_PREFIX + '/permissions/ssh_keys/data',
66 'admin_permissions_ssh_keys_update':
67 'admin_permissions_ssh_keys_update':
67 ADMIN_PREFIX + '/permissions/ssh_keys/update'
68 ADMIN_PREFIX + '/permissions/ssh_keys/update'
68
69
69 }[name].format(**kwargs)
70 }[name].format(**kwargs)
70
71
71 if params:
72 if params:
72 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
73 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
73 return base_url
74 return base_url
74
75
75
76
76 class TestAdminPermissionsController(TestController):
77 class TestAdminPermissionsController(TestController):
77
78
78 @pytest.fixture(scope='class', autouse=True)
79 @pytest.fixture(scope='class', autouse=True)
79 def prepare(self, request):
80 def prepare(self, request):
80 # cleanup and reset to default permissions after
81 # cleanup and reset to default permissions after
81 @request.addfinalizer
82 @request.addfinalizer
82 def cleanup():
83 def cleanup():
83 PermissionModel().create_default_user_permissions(
84 PermissionModel().create_default_user_permissions(
84 User.get_default_user(), force=True)
85 User.get_default_user(), force=True)
85
86
86 def test_index_application(self):
87 def test_index_application(self):
87 self.log_user()
88 self.log_user()
88 self.app.get(route_path('admin_permissions_application'))
89 self.app.get(route_path('admin_permissions_application'))
89
90
90 @pytest.mark.parametrize(
91 @pytest.mark.parametrize(
91 'anonymous, default_register, default_register_message, default_password_reset,'
92 'anonymous, default_register, default_register_message, default_password_reset,'
92 'default_extern_activate, expect_error, expect_form_error', [
93 'default_extern_activate, expect_error, expect_form_error', [
93 (True, 'hg.register.none', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
94 (True, 'hg.register.none', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
94 False, False),
95 False, False),
95 (True, 'hg.register.manual_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.auto',
96 (True, 'hg.register.manual_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.auto',
96 False, False),
97 False, False),
97 (True, 'hg.register.auto_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
98 (True, 'hg.register.auto_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
98 False, False),
99 False, False),
99 (True, 'hg.register.auto_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
100 (True, 'hg.register.auto_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
100 False, False),
101 False, False),
101 (True, 'hg.register.XXX', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
102 (True, 'hg.register.XXX', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual',
102 False, True),
103 False, True),
103 (True, '', '', 'hg.password_reset.enabled', '', True, False),
104 (True, '', '', 'hg.password_reset.enabled', '', True, False),
104 ])
105 ])
105 def test_update_application_permissions(
106 def test_update_application_permissions(
106 self, anonymous, default_register, default_register_message, default_password_reset,
107 self, anonymous, default_register, default_register_message, default_password_reset,
107 default_extern_activate, expect_error, expect_form_error):
108 default_extern_activate, expect_error, expect_form_error):
108
109
109 self.log_user()
110 self.log_user()
110
111
111 # TODO: anonymous access set here to False, breaks some other tests
112 # TODO: anonymous access set here to False, breaks some other tests
112 params = {
113 params = {
113 'csrf_token': self.csrf_token,
114 'csrf_token': self.csrf_token,
114 'anonymous': anonymous,
115 'anonymous': anonymous,
115 'default_register': default_register,
116 'default_register': default_register,
116 'default_register_message': default_register_message,
117 'default_register_message': default_register_message,
117 'default_password_reset': default_password_reset,
118 'default_password_reset': default_password_reset,
118 'default_extern_activate': default_extern_activate,
119 'default_extern_activate': default_extern_activate,
119 }
120 }
120 response = self.app.post(route_path('admin_permissions_application_update'),
121 response = self.app.post(route_path('admin_permissions_application_update'),
121 params=params)
122 params=params)
122 if expect_form_error:
123 if expect_form_error:
123 assert response.status_int == 200
124 assert response.status_int == 200
124 response.mustcontain('Value must be one of')
125 response.mustcontain('Value must be one of')
125 else:
126 else:
126 if expect_error:
127 if expect_error:
127 msg = 'Error occurred during update of permissions'
128 msg = 'Error occurred during update of permissions'
128 else:
129 else:
129 msg = 'Application permissions updated successfully'
130 msg = 'Application permissions updated successfully'
130 assert_session_flash(response, msg)
131 assert_session_flash(response, msg)
131
132
132 def test_index_object(self):
133 def test_index_object(self):
133 self.log_user()
134 self.log_user()
134 self.app.get(route_path('admin_permissions_object'))
135 self.app.get(route_path('admin_permissions_object'))
135
136
136 @pytest.mark.parametrize(
137 @pytest.mark.parametrize(
137 'repo, repo_group, user_group, expect_error, expect_form_error', [
138 'repo, repo_group, user_group, expect_error, expect_form_error', [
138 ('repository.none', 'group.none', 'usergroup.none', False, False),
139 ('repository.none', 'group.none', 'usergroup.none', False, False),
139 ('repository.read', 'group.read', 'usergroup.read', False, False),
140 ('repository.read', 'group.read', 'usergroup.read', False, False),
140 ('repository.write', 'group.write', 'usergroup.write',
141 ('repository.write', 'group.write', 'usergroup.write',
141 False, False),
142 False, False),
142 ('repository.admin', 'group.admin', 'usergroup.admin',
143 ('repository.admin', 'group.admin', 'usergroup.admin',
143 False, False),
144 False, False),
144 ('repository.XXX', 'group.admin', 'usergroup.admin', False, True),
145 ('repository.XXX', 'group.admin', 'usergroup.admin', False, True),
145 ('', '', '', True, False),
146 ('', '', '', True, False),
146 ])
147 ])
147 def test_update_object_permissions(self, repo, repo_group, user_group,
148 def test_update_object_permissions(self, repo, repo_group, user_group,
148 expect_error, expect_form_error):
149 expect_error, expect_form_error):
149 self.log_user()
150 self.log_user()
150
151
151 params = {
152 params = {
152 'csrf_token': self.csrf_token,
153 'csrf_token': self.csrf_token,
153 'default_repo_perm': repo,
154 'default_repo_perm': repo,
154 'overwrite_default_repo': False,
155 'overwrite_default_repo': False,
155 'default_group_perm': repo_group,
156 'default_group_perm': repo_group,
156 'overwrite_default_group': False,
157 'overwrite_default_group': False,
157 'default_user_group_perm': user_group,
158 'default_user_group_perm': user_group,
158 'overwrite_default_user_group': False,
159 'overwrite_default_user_group': False,
159 }
160 }
160 response = self.app.post(route_path('admin_permissions_object_update'),
161 response = self.app.post(route_path('admin_permissions_object_update'),
161 params=params)
162 params=params)
162 if expect_form_error:
163 if expect_form_error:
163 assert response.status_int == 200
164 assert response.status_int == 200
164 response.mustcontain('Value must be one of')
165 response.mustcontain('Value must be one of')
165 else:
166 else:
166 if expect_error:
167 if expect_error:
167 msg = 'Error occurred during update of permissions'
168 msg = 'Error occurred during update of permissions'
168 else:
169 else:
169 msg = 'Object permissions updated successfully'
170 msg = 'Object permissions updated successfully'
170 assert_session_flash(response, msg)
171 assert_session_flash(response, msg)
171
172
172 def test_index_global(self):
173 def test_index_global(self):
173 self.log_user()
174 self.log_user()
174 self.app.get(route_path('admin_permissions_global'))
175 self.app.get(route_path('admin_permissions_global'))
175
176
176 @pytest.mark.parametrize(
177 @pytest.mark.parametrize(
177 'repo_create, repo_create_write, user_group_create, repo_group_create,'
178 'repo_create, repo_create_write, user_group_create, repo_group_create,'
178 'fork_create, inherit_default_permissions, expect_error,'
179 'fork_create, inherit_default_permissions, expect_error,'
179 'expect_form_error', [
180 'expect_form_error', [
180 ('hg.create.none', 'hg.create.write_on_repogroup.false',
181 ('hg.create.none', 'hg.create.write_on_repogroup.false',
181 'hg.usergroup.create.false', 'hg.repogroup.create.false',
182 'hg.usergroup.create.false', 'hg.repogroup.create.false',
182 'hg.fork.none', 'hg.inherit_default_perms.false', False, False),
183 'hg.fork.none', 'hg.inherit_default_perms.false', False, False),
183 ('hg.create.repository', 'hg.create.write_on_repogroup.true',
184 ('hg.create.repository', 'hg.create.write_on_repogroup.true',
184 'hg.usergroup.create.true', 'hg.repogroup.create.true',
185 'hg.usergroup.create.true', 'hg.repogroup.create.true',
185 'hg.fork.repository', 'hg.inherit_default_perms.false',
186 'hg.fork.repository', 'hg.inherit_default_perms.false',
186 False, False),
187 False, False),
187 ('hg.create.XXX', 'hg.create.write_on_repogroup.true',
188 ('hg.create.XXX', 'hg.create.write_on_repogroup.true',
188 'hg.usergroup.create.true', 'hg.repogroup.create.true',
189 'hg.usergroup.create.true', 'hg.repogroup.create.true',
189 'hg.fork.repository', 'hg.inherit_default_perms.false',
190 'hg.fork.repository', 'hg.inherit_default_perms.false',
190 False, True),
191 False, True),
191 ('', '', '', '', '', '', True, False),
192 ('', '', '', '', '', '', True, False),
192 ])
193 ])
193 def test_update_global_permissions(
194 def test_update_global_permissions(
194 self, repo_create, repo_create_write, user_group_create,
195 self, repo_create, repo_create_write, user_group_create,
195 repo_group_create, fork_create, inherit_default_permissions,
196 repo_group_create, fork_create, inherit_default_permissions,
196 expect_error, expect_form_error):
197 expect_error, expect_form_error):
197 self.log_user()
198 self.log_user()
198
199
199 params = {
200 params = {
200 'csrf_token': self.csrf_token,
201 'csrf_token': self.csrf_token,
201 'default_repo_create': repo_create,
202 'default_repo_create': repo_create,
202 'default_repo_create_on_write': repo_create_write,
203 'default_repo_create_on_write': repo_create_write,
203 'default_user_group_create': user_group_create,
204 'default_user_group_create': user_group_create,
204 'default_repo_group_create': repo_group_create,
205 'default_repo_group_create': repo_group_create,
205 'default_fork_create': fork_create,
206 'default_fork_create': fork_create,
206 'default_inherit_default_permissions': inherit_default_permissions
207 'default_inherit_default_permissions': inherit_default_permissions
207 }
208 }
208 response = self.app.post(route_path('admin_permissions_global_update'),
209 response = self.app.post(route_path('admin_permissions_global_update'),
209 params=params)
210 params=params)
210 if expect_form_error:
211 if expect_form_error:
211 assert response.status_int == 200
212 assert response.status_int == 200
212 response.mustcontain('Value must be one of')
213 response.mustcontain('Value must be one of')
213 else:
214 else:
214 if expect_error:
215 if expect_error:
215 msg = 'Error occurred during update of permissions'
216 msg = 'Error occurred during update of permissions'
216 else:
217 else:
217 msg = 'Global permissions updated successfully'
218 msg = 'Global permissions updated successfully'
218 assert_session_flash(response, msg)
219 assert_session_flash(response, msg)
219
220
220 def test_index_ips(self):
221 def test_index_ips(self):
221 self.log_user()
222 self.log_user()
222 response = self.app.get(route_path('admin_permissions_ips'))
223 response = self.app.get(route_path('admin_permissions_ips'))
223 # TODO: Test response...
224 # TODO: Test response...
224 response.mustcontain('All IP addresses are allowed')
225 response.mustcontain('All IP addresses are allowed')
225
226
226 def test_add_delete_ips(self):
227 def test_add_delete_ips(self):
227 self.log_user()
228 self.log_user()
228 clear_all_caches()
229 clear_all_caches()
229
230
230 # ADD
231 # ADD
231 default_user_id = User.get_default_user().user_id
232 default_user_id = User.get_default_user().user_id
232 self.app.post(
233 self.app.post(
233 route_path('edit_user_ips_add', user_id=default_user_id),
234 route_path('edit_user_ips_add', user_id=default_user_id),
234 params={'new_ip': '127.0.0.0/24', 'csrf_token': self.csrf_token})
235 params={'new_ip': '127.0.0.0/24', 'csrf_token': self.csrf_token})
235
236
236 response = self.app.get(route_path('admin_permissions_ips'))
237 response = self.app.get(route_path('admin_permissions_ips'))
237 response.mustcontain('127.0.0.0/24')
238 response.mustcontain('127.0.0.0/24')
238 response.mustcontain('127.0.0.0 - 127.0.0.255')
239 response.mustcontain('127.0.0.0 - 127.0.0.255')
239
240
240 # DELETE
241 # DELETE
241 default_user_id = User.get_default_user().user_id
242 default_user_id = User.get_default_user().user_id
242 del_ip_id = UserIpMap.query().filter(UserIpMap.user_id ==
243 del_ip_id = UserIpMap.query().filter(UserIpMap.user_id ==
243 default_user_id).first().ip_id
244 default_user_id).first().ip_id
244
245
245 response = self.app.post(
246 response = self.app.post(
246 route_path('edit_user_ips_delete', user_id=default_user_id),
247 route_path('edit_user_ips_delete', user_id=default_user_id),
247 params={'del_ip_id': del_ip_id, 'csrf_token': self.csrf_token})
248 params={'del_ip_id': del_ip_id, 'csrf_token': self.csrf_token})
248
249
249 assert_session_flash(response, 'Removed ip address from user whitelist')
250 assert_session_flash(response, 'Removed ip address from user whitelist')
250
251
251 clear_all_caches()
252 clear_all_caches()
252 response = self.app.get(route_path('admin_permissions_ips'))
253 response = self.app.get(route_path('admin_permissions_ips'))
253 response.mustcontain('All IP addresses are allowed')
254 response.mustcontain('All IP addresses are allowed')
254 response.mustcontain(no=['127.0.0.0/24'])
255 response.mustcontain(no=['127.0.0.0/24'])
255 response.mustcontain(no=['127.0.0.0 - 127.0.0.255'])
256 response.mustcontain(no=['127.0.0.0 - 127.0.0.255'])
256
257
257 def test_index_overview(self):
258 def test_index_overview(self):
258 self.log_user()
259 self.log_user()
259 self.app.get(route_path('admin_permissions_overview'))
260 self.app.get(route_path('admin_permissions_overview'))
260
261
261 def test_ssh_keys(self):
262 def test_ssh_keys(self):
262 self.log_user()
263 self.log_user()
263 self.app.get(route_path('admin_permissions_ssh_keys'), status=200)
264 self.app.get(route_path('admin_permissions_ssh_keys'), status=200)
264
265
265 def test_ssh_keys_data(self, user_util, xhr_header):
266 def test_ssh_keys_data(self, user_util, xhr_header):
266 self.log_user()
267 self.log_user()
267 response = self.app.get(route_path('admin_permissions_ssh_keys_data'),
268 response = self.app.get(route_path('admin_permissions_ssh_keys_data'),
268 extra_environ=xhr_header)
269 extra_environ=xhr_header)
269 assert response.json == {u'data': [], u'draw': None,
270 assert response.json == {u'data': [], u'draw': None,
270 u'recordsFiltered': 0, u'recordsTotal': 0}
271 u'recordsFiltered': 0, u'recordsTotal': 0}
271
272
272 dummy_user = user_util.create_user()
273 dummy_user = user_util.create_user()
273 SshKeyModel().create(dummy_user, 'ab:cd:ef', 'KEYKEY', 'test_key')
274 SshKeyModel().create(dummy_user, 'ab:cd:ef', 'KEYKEY', 'test_key')
274 Session().commit()
275 Session().commit()
275 response = self.app.get(route_path('admin_permissions_ssh_keys_data'),
276 response = self.app.get(route_path('admin_permissions_ssh_keys_data'),
276 extra_environ=xhr_header)
277 extra_environ=xhr_header)
277 assert response.json['data'][0]['fingerprint'] == 'ab:cd:ef'
278 assert response.json['data'][0]['fingerprint'] == 'ab:cd:ef'
278
279
279 def test_ssh_keys_update(self):
280 def test_ssh_keys_update(self):
280 self.log_user()
281 self.log_user()
281 response = self.app.post(
282 response = self.app.post(
282 route_path('admin_permissions_ssh_keys_update'),
283 route_path('admin_permissions_ssh_keys_update'),
283 dict(csrf_token=self.csrf_token), status=302)
284 dict(csrf_token=self.csrf_token), status=302)
284
285
285 assert_session_flash(
286 assert_session_flash(
286 response, 'SSH key support is disabled in .ini file')
287 response, 'Updated SSH keys file')
288
289 def test_ssh_keys_update_disabled(self):
290 self.log_user()
291
292 from rhodecode.apps.admin.views.permissions import AdminPermissionsView
293 with mock.patch.object(AdminPermissionsView, 'ssh_enabled',
294 return_value=False):
295 response = self.app.post(
296 route_path('admin_permissions_ssh_keys_update'),
297 dict(csrf_token=self.csrf_token), status=302)
298
299 assert_session_flash(
300 response, 'SSH key support is disabled in .ini file') No newline at end of file
@@ -1,475 +1,479 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 import datetime
25 from pyramid.interfaces import IRoutesMapper
25 from pyramid.interfaces import IRoutesMapper
26
26
27 from pyramid.view import view_config
27 from pyramid.view import view_config
28 from pyramid.httpexceptions import HTTPFound
28 from pyramid.httpexceptions import HTTPFound
29 from pyramid.renderers import render
29 from pyramid.renderers import render
30 from pyramid.response import Response
30 from pyramid.response import Response
31
31
32 from rhodecode.apps._base import BaseAppView, DataGridAppView
32 from rhodecode.apps._base import BaseAppView, DataGridAppView
33 from rhodecode.apps.ssh_support import SshKeyFileChangeEvent
33 from rhodecode.apps.ssh_support import SshKeyFileChangeEvent
34 from rhodecode.events import trigger
34 from rhodecode.events import trigger
35
35
36 from rhodecode.lib import helpers as h
36 from rhodecode.lib import helpers as h
37 from rhodecode.lib.auth import (
37 from rhodecode.lib.auth import (
38 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
38 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
39 from rhodecode.lib.utils2 import aslist, safe_unicode
39 from rhodecode.lib.utils2 import aslist, safe_unicode
40 from rhodecode.model.db import or_, joinedload, coalesce, User, UserIpMap, UserSshKeys
40 from rhodecode.model.db import or_, joinedload, coalesce, User, UserIpMap, UserSshKeys
41 from rhodecode.model.forms import (
41 from rhodecode.model.forms import (
42 ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm)
42 ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm)
43 from rhodecode.model.meta import Session
43 from rhodecode.model.meta import Session
44 from rhodecode.model.permission import PermissionModel
44 from rhodecode.model.permission import PermissionModel
45 from rhodecode.model.settings import SettingsModel
45 from rhodecode.model.settings import SettingsModel
46
46
47
47
48 log = logging.getLogger(__name__)
48 log = logging.getLogger(__name__)
49
49
50
50
51 class AdminPermissionsView(BaseAppView, DataGridAppView):
51 class AdminPermissionsView(BaseAppView, DataGridAppView):
52 def load_default_context(self):
52 def load_default_context(self):
53 c = self._get_local_tmpl_context()
53 c = self._get_local_tmpl_context()
54
54
55 self._register_global_c(c)
55 self._register_global_c(c)
56 PermissionModel().set_global_permission_choices(
56 PermissionModel().set_global_permission_choices(
57 c, gettext_translator=self.request.translate)
57 c, gettext_translator=self.request.translate)
58 return c
58 return c
59
59
60 @LoginRequired()
60 @LoginRequired()
61 @HasPermissionAllDecorator('hg.admin')
61 @HasPermissionAllDecorator('hg.admin')
62 @view_config(
62 @view_config(
63 route_name='admin_permissions_application', request_method='GET',
63 route_name='admin_permissions_application', request_method='GET',
64 renderer='rhodecode:templates/admin/permissions/permissions.mako')
64 renderer='rhodecode:templates/admin/permissions/permissions.mako')
65 def permissions_application(self):
65 def permissions_application(self):
66 c = self.load_default_context()
66 c = self.load_default_context()
67 c.active = 'application'
67 c.active = 'application'
68
68
69 c.user = User.get_default_user(refresh=True)
69 c.user = User.get_default_user(refresh=True)
70
70
71 app_settings = SettingsModel().get_all_settings()
71 app_settings = SettingsModel().get_all_settings()
72 defaults = {
72 defaults = {
73 'anonymous': c.user.active,
73 'anonymous': c.user.active,
74 'default_register_message': app_settings.get(
74 'default_register_message': app_settings.get(
75 'rhodecode_register_message')
75 'rhodecode_register_message')
76 }
76 }
77 defaults.update(c.user.get_default_perms())
77 defaults.update(c.user.get_default_perms())
78
78
79 data = render('rhodecode:templates/admin/permissions/permissions.mako',
79 data = render('rhodecode:templates/admin/permissions/permissions.mako',
80 self._get_template_context(c), self.request)
80 self._get_template_context(c), self.request)
81 html = formencode.htmlfill.render(
81 html = formencode.htmlfill.render(
82 data,
82 data,
83 defaults=defaults,
83 defaults=defaults,
84 encoding="UTF-8",
84 encoding="UTF-8",
85 force_defaults=False
85 force_defaults=False
86 )
86 )
87 return Response(html)
87 return Response(html)
88
88
89 @LoginRequired()
89 @LoginRequired()
90 @HasPermissionAllDecorator('hg.admin')
90 @HasPermissionAllDecorator('hg.admin')
91 @CSRFRequired()
91 @CSRFRequired()
92 @view_config(
92 @view_config(
93 route_name='admin_permissions_application_update', request_method='POST',
93 route_name='admin_permissions_application_update', request_method='POST',
94 renderer='rhodecode:templates/admin/permissions/permissions.mako')
94 renderer='rhodecode:templates/admin/permissions/permissions.mako')
95 def permissions_application_update(self):
95 def permissions_application_update(self):
96 _ = self.request.translate
96 _ = self.request.translate
97 c = self.load_default_context()
97 c = self.load_default_context()
98 c.active = 'application'
98 c.active = 'application'
99
99
100 _form = ApplicationPermissionsForm(
100 _form = ApplicationPermissionsForm(
101 [x[0] for x in c.register_choices],
101 [x[0] for x in c.register_choices],
102 [x[0] for x in c.password_reset_choices],
102 [x[0] for x in c.password_reset_choices],
103 [x[0] for x in c.extern_activate_choices])()
103 [x[0] for x in c.extern_activate_choices])()
104
104
105 try:
105 try:
106 form_result = _form.to_python(dict(self.request.POST))
106 form_result = _form.to_python(dict(self.request.POST))
107 form_result.update({'perm_user_name': User.DEFAULT_USER})
107 form_result.update({'perm_user_name': User.DEFAULT_USER})
108 PermissionModel().update_application_permissions(form_result)
108 PermissionModel().update_application_permissions(form_result)
109
109
110 settings = [
110 settings = [
111 ('register_message', 'default_register_message'),
111 ('register_message', 'default_register_message'),
112 ]
112 ]
113 for setting, form_key in settings:
113 for setting, form_key in settings:
114 sett = SettingsModel().create_or_update_setting(
114 sett = SettingsModel().create_or_update_setting(
115 setting, form_result[form_key])
115 setting, form_result[form_key])
116 Session().add(sett)
116 Session().add(sett)
117
117
118 Session().commit()
118 Session().commit()
119 h.flash(_('Application permissions updated successfully'),
119 h.flash(_('Application permissions updated successfully'),
120 category='success')
120 category='success')
121
121
122 except formencode.Invalid as errors:
122 except formencode.Invalid as errors:
123 defaults = errors.value
123 defaults = errors.value
124
124
125 data = render(
125 data = render(
126 'rhodecode:templates/admin/permissions/permissions.mako',
126 'rhodecode:templates/admin/permissions/permissions.mako',
127 self._get_template_context(c), self.request)
127 self._get_template_context(c), self.request)
128 html = formencode.htmlfill.render(
128 html = formencode.htmlfill.render(
129 data,
129 data,
130 defaults=defaults,
130 defaults=defaults,
131 errors=errors.error_dict or {},
131 errors=errors.error_dict or {},
132 prefix_error=False,
132 prefix_error=False,
133 encoding="UTF-8",
133 encoding="UTF-8",
134 force_defaults=False
134 force_defaults=False
135 )
135 )
136 return Response(html)
136 return Response(html)
137
137
138 except Exception:
138 except Exception:
139 log.exception("Exception during update of permissions")
139 log.exception("Exception during update of permissions")
140 h.flash(_('Error occurred during update of permissions'),
140 h.flash(_('Error occurred during update of permissions'),
141 category='error')
141 category='error')
142
142
143 raise HTTPFound(h.route_path('admin_permissions_application'))
143 raise HTTPFound(h.route_path('admin_permissions_application'))
144
144
145 @LoginRequired()
145 @LoginRequired()
146 @HasPermissionAllDecorator('hg.admin')
146 @HasPermissionAllDecorator('hg.admin')
147 @view_config(
147 @view_config(
148 route_name='admin_permissions_object', request_method='GET',
148 route_name='admin_permissions_object', request_method='GET',
149 renderer='rhodecode:templates/admin/permissions/permissions.mako')
149 renderer='rhodecode:templates/admin/permissions/permissions.mako')
150 def permissions_objects(self):
150 def permissions_objects(self):
151 c = self.load_default_context()
151 c = self.load_default_context()
152 c.active = 'objects'
152 c.active = 'objects'
153
153
154 c.user = User.get_default_user(refresh=True)
154 c.user = User.get_default_user(refresh=True)
155 defaults = {}
155 defaults = {}
156 defaults.update(c.user.get_default_perms())
156 defaults.update(c.user.get_default_perms())
157
157
158 data = render(
158 data = render(
159 'rhodecode:templates/admin/permissions/permissions.mako',
159 'rhodecode:templates/admin/permissions/permissions.mako',
160 self._get_template_context(c), self.request)
160 self._get_template_context(c), self.request)
161 html = formencode.htmlfill.render(
161 html = formencode.htmlfill.render(
162 data,
162 data,
163 defaults=defaults,
163 defaults=defaults,
164 encoding="UTF-8",
164 encoding="UTF-8",
165 force_defaults=False
165 force_defaults=False
166 )
166 )
167 return Response(html)
167 return Response(html)
168
168
169 @LoginRequired()
169 @LoginRequired()
170 @HasPermissionAllDecorator('hg.admin')
170 @HasPermissionAllDecorator('hg.admin')
171 @CSRFRequired()
171 @CSRFRequired()
172 @view_config(
172 @view_config(
173 route_name='admin_permissions_object_update', request_method='POST',
173 route_name='admin_permissions_object_update', request_method='POST',
174 renderer='rhodecode:templates/admin/permissions/permissions.mako')
174 renderer='rhodecode:templates/admin/permissions/permissions.mako')
175 def permissions_objects_update(self):
175 def permissions_objects_update(self):
176 _ = self.request.translate
176 _ = self.request.translate
177 c = self.load_default_context()
177 c = self.load_default_context()
178 c.active = 'objects'
178 c.active = 'objects'
179
179
180 _form = ObjectPermissionsForm(
180 _form = ObjectPermissionsForm(
181 [x[0] for x in c.repo_perms_choices],
181 [x[0] for x in c.repo_perms_choices],
182 [x[0] for x in c.group_perms_choices],
182 [x[0] for x in c.group_perms_choices],
183 [x[0] for x in c.user_group_perms_choices])()
183 [x[0] for x in c.user_group_perms_choices])()
184
184
185 try:
185 try:
186 form_result = _form.to_python(dict(self.request.POST))
186 form_result = _form.to_python(dict(self.request.POST))
187 form_result.update({'perm_user_name': User.DEFAULT_USER})
187 form_result.update({'perm_user_name': User.DEFAULT_USER})
188 PermissionModel().update_object_permissions(form_result)
188 PermissionModel().update_object_permissions(form_result)
189
189
190 Session().commit()
190 Session().commit()
191 h.flash(_('Object permissions updated successfully'),
191 h.flash(_('Object permissions updated successfully'),
192 category='success')
192 category='success')
193
193
194 except formencode.Invalid as errors:
194 except formencode.Invalid as errors:
195 defaults = errors.value
195 defaults = errors.value
196
196
197 data = render(
197 data = render(
198 'rhodecode:templates/admin/permissions/permissions.mako',
198 'rhodecode:templates/admin/permissions/permissions.mako',
199 self._get_template_context(c), self.request)
199 self._get_template_context(c), self.request)
200 html = formencode.htmlfill.render(
200 html = formencode.htmlfill.render(
201 data,
201 data,
202 defaults=defaults,
202 defaults=defaults,
203 errors=errors.error_dict or {},
203 errors=errors.error_dict or {},
204 prefix_error=False,
204 prefix_error=False,
205 encoding="UTF-8",
205 encoding="UTF-8",
206 force_defaults=False
206 force_defaults=False
207 )
207 )
208 return Response(html)
208 return Response(html)
209 except Exception:
209 except Exception:
210 log.exception("Exception during update of permissions")
210 log.exception("Exception during update of permissions")
211 h.flash(_('Error occurred during update of permissions'),
211 h.flash(_('Error occurred during update of permissions'),
212 category='error')
212 category='error')
213
213
214 raise HTTPFound(h.route_path('admin_permissions_object'))
214 raise HTTPFound(h.route_path('admin_permissions_object'))
215
215
216 @LoginRequired()
216 @LoginRequired()
217 @HasPermissionAllDecorator('hg.admin')
217 @HasPermissionAllDecorator('hg.admin')
218 @view_config(
218 @view_config(
219 route_name='admin_permissions_global', request_method='GET',
219 route_name='admin_permissions_global', request_method='GET',
220 renderer='rhodecode:templates/admin/permissions/permissions.mako')
220 renderer='rhodecode:templates/admin/permissions/permissions.mako')
221 def permissions_global(self):
221 def permissions_global(self):
222 c = self.load_default_context()
222 c = self.load_default_context()
223 c.active = 'global'
223 c.active = 'global'
224
224
225 c.user = User.get_default_user(refresh=True)
225 c.user = User.get_default_user(refresh=True)
226 defaults = {}
226 defaults = {}
227 defaults.update(c.user.get_default_perms())
227 defaults.update(c.user.get_default_perms())
228
228
229 data = render(
229 data = render(
230 'rhodecode:templates/admin/permissions/permissions.mako',
230 'rhodecode:templates/admin/permissions/permissions.mako',
231 self._get_template_context(c), self.request)
231 self._get_template_context(c), self.request)
232 html = formencode.htmlfill.render(
232 html = formencode.htmlfill.render(
233 data,
233 data,
234 defaults=defaults,
234 defaults=defaults,
235 encoding="UTF-8",
235 encoding="UTF-8",
236 force_defaults=False
236 force_defaults=False
237 )
237 )
238 return Response(html)
238 return Response(html)
239
239
240 @LoginRequired()
240 @LoginRequired()
241 @HasPermissionAllDecorator('hg.admin')
241 @HasPermissionAllDecorator('hg.admin')
242 @CSRFRequired()
242 @CSRFRequired()
243 @view_config(
243 @view_config(
244 route_name='admin_permissions_global_update', request_method='POST',
244 route_name='admin_permissions_global_update', request_method='POST',
245 renderer='rhodecode:templates/admin/permissions/permissions.mako')
245 renderer='rhodecode:templates/admin/permissions/permissions.mako')
246 def permissions_global_update(self):
246 def permissions_global_update(self):
247 _ = self.request.translate
247 _ = self.request.translate
248 c = self.load_default_context()
248 c = self.load_default_context()
249 c.active = 'global'
249 c.active = 'global'
250
250
251 _form = UserPermissionsForm(
251 _form = UserPermissionsForm(
252 [x[0] for x in c.repo_create_choices],
252 [x[0] for x in c.repo_create_choices],
253 [x[0] for x in c.repo_create_on_write_choices],
253 [x[0] for x in c.repo_create_on_write_choices],
254 [x[0] for x in c.repo_group_create_choices],
254 [x[0] for x in c.repo_group_create_choices],
255 [x[0] for x in c.user_group_create_choices],
255 [x[0] for x in c.user_group_create_choices],
256 [x[0] for x in c.fork_choices],
256 [x[0] for x in c.fork_choices],
257 [x[0] for x in c.inherit_default_permission_choices])()
257 [x[0] for x in c.inherit_default_permission_choices])()
258
258
259 try:
259 try:
260 form_result = _form.to_python(dict(self.request.POST))
260 form_result = _form.to_python(dict(self.request.POST))
261 form_result.update({'perm_user_name': User.DEFAULT_USER})
261 form_result.update({'perm_user_name': User.DEFAULT_USER})
262 PermissionModel().update_user_permissions(form_result)
262 PermissionModel().update_user_permissions(form_result)
263
263
264 Session().commit()
264 Session().commit()
265 h.flash(_('Global permissions updated successfully'),
265 h.flash(_('Global permissions updated successfully'),
266 category='success')
266 category='success')
267
267
268 except formencode.Invalid as errors:
268 except formencode.Invalid as errors:
269 defaults = errors.value
269 defaults = errors.value
270
270
271 data = render(
271 data = render(
272 'rhodecode:templates/admin/permissions/permissions.mako',
272 'rhodecode:templates/admin/permissions/permissions.mako',
273 self._get_template_context(c), self.request)
273 self._get_template_context(c), self.request)
274 html = formencode.htmlfill.render(
274 html = formencode.htmlfill.render(
275 data,
275 data,
276 defaults=defaults,
276 defaults=defaults,
277 errors=errors.error_dict or {},
277 errors=errors.error_dict or {},
278 prefix_error=False,
278 prefix_error=False,
279 encoding="UTF-8",
279 encoding="UTF-8",
280 force_defaults=False
280 force_defaults=False
281 )
281 )
282 return Response(html)
282 return Response(html)
283 except Exception:
283 except Exception:
284 log.exception("Exception during update of permissions")
284 log.exception("Exception during update of permissions")
285 h.flash(_('Error occurred during update of permissions'),
285 h.flash(_('Error occurred during update of permissions'),
286 category='error')
286 category='error')
287
287
288 raise HTTPFound(h.route_path('admin_permissions_global'))
288 raise HTTPFound(h.route_path('admin_permissions_global'))
289
289
290 @LoginRequired()
290 @LoginRequired()
291 @HasPermissionAllDecorator('hg.admin')
291 @HasPermissionAllDecorator('hg.admin')
292 @view_config(
292 @view_config(
293 route_name='admin_permissions_ips', request_method='GET',
293 route_name='admin_permissions_ips', request_method='GET',
294 renderer='rhodecode:templates/admin/permissions/permissions.mako')
294 renderer='rhodecode:templates/admin/permissions/permissions.mako')
295 def permissions_ips(self):
295 def permissions_ips(self):
296 c = self.load_default_context()
296 c = self.load_default_context()
297 c.active = 'ips'
297 c.active = 'ips'
298
298
299 c.user = User.get_default_user(refresh=True)
299 c.user = User.get_default_user(refresh=True)
300 c.user_ip_map = (
300 c.user_ip_map = (
301 UserIpMap.query().filter(UserIpMap.user == c.user).all())
301 UserIpMap.query().filter(UserIpMap.user == c.user).all())
302
302
303 return self._get_template_context(c)
303 return self._get_template_context(c)
304
304
305 @LoginRequired()
305 @LoginRequired()
306 @HasPermissionAllDecorator('hg.admin')
306 @HasPermissionAllDecorator('hg.admin')
307 @view_config(
307 @view_config(
308 route_name='admin_permissions_overview', request_method='GET',
308 route_name='admin_permissions_overview', request_method='GET',
309 renderer='rhodecode:templates/admin/permissions/permissions.mako')
309 renderer='rhodecode:templates/admin/permissions/permissions.mako')
310 def permissions_overview(self):
310 def permissions_overview(self):
311 c = self.load_default_context()
311 c = self.load_default_context()
312 c.active = 'perms'
312 c.active = 'perms'
313
313
314 c.user = User.get_default_user(refresh=True)
314 c.user = User.get_default_user(refresh=True)
315 c.perm_user = c.user.AuthUser()
315 c.perm_user = c.user.AuthUser()
316 return self._get_template_context(c)
316 return self._get_template_context(c)
317
317
318 @LoginRequired()
318 @LoginRequired()
319 @HasPermissionAllDecorator('hg.admin')
319 @HasPermissionAllDecorator('hg.admin')
320 @view_config(
320 @view_config(
321 route_name='admin_permissions_auth_token_access', request_method='GET',
321 route_name='admin_permissions_auth_token_access', request_method='GET',
322 renderer='rhodecode:templates/admin/permissions/permissions.mako')
322 renderer='rhodecode:templates/admin/permissions/permissions.mako')
323 def auth_token_access(self):
323 def auth_token_access(self):
324 from rhodecode import CONFIG
324 from rhodecode import CONFIG
325
325
326 c = self.load_default_context()
326 c = self.load_default_context()
327 c.active = 'auth_token_access'
327 c.active = 'auth_token_access'
328
328
329 c.user = User.get_default_user(refresh=True)
329 c.user = User.get_default_user(refresh=True)
330 c.perm_user = c.user.AuthUser()
330 c.perm_user = c.user.AuthUser()
331
331
332 mapper = self.request.registry.queryUtility(IRoutesMapper)
332 mapper = self.request.registry.queryUtility(IRoutesMapper)
333 c.view_data = []
333 c.view_data = []
334
334
335 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
335 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
336 introspector = self.request.registry.introspector
336 introspector = self.request.registry.introspector
337
337
338 view_intr = {}
338 view_intr = {}
339 for view_data in introspector.get_category('views'):
339 for view_data in introspector.get_category('views'):
340 intr = view_data['introspectable']
340 intr = view_data['introspectable']
341
341
342 if 'route_name' in intr and intr['attr']:
342 if 'route_name' in intr and intr['attr']:
343 view_intr[intr['route_name']] = '{}:{}'.format(
343 view_intr[intr['route_name']] = '{}:{}'.format(
344 str(intr['derived_callable'].func_name), intr['attr']
344 str(intr['derived_callable'].func_name), intr['attr']
345 )
345 )
346
346
347 c.whitelist_key = 'api_access_controllers_whitelist'
347 c.whitelist_key = 'api_access_controllers_whitelist'
348 c.whitelist_file = CONFIG.get('__file__')
348 c.whitelist_file = CONFIG.get('__file__')
349 whitelist_views = aslist(
349 whitelist_views = aslist(
350 CONFIG.get(c.whitelist_key), sep=',')
350 CONFIG.get(c.whitelist_key), sep=',')
351
351
352 for route_info in mapper.get_routes():
352 for route_info in mapper.get_routes():
353 if not route_info.name.startswith('__'):
353 if not route_info.name.startswith('__'):
354 routepath = route_info.pattern
354 routepath = route_info.pattern
355
355
356 def replace(matchobj):
356 def replace(matchobj):
357 if matchobj.group(1):
357 if matchobj.group(1):
358 return "{%s}" % matchobj.group(1).split(':')[0]
358 return "{%s}" % matchobj.group(1).split(':')[0]
359 else:
359 else:
360 return "{%s}" % matchobj.group(2)
360 return "{%s}" % matchobj.group(2)
361
361
362 routepath = _argument_prog.sub(replace, routepath)
362 routepath = _argument_prog.sub(replace, routepath)
363
363
364 if not routepath.startswith('/'):
364 if not routepath.startswith('/'):
365 routepath = '/' + routepath
365 routepath = '/' + routepath
366
366
367 view_fqn = view_intr.get(route_info.name, 'NOT AVAILABLE')
367 view_fqn = view_intr.get(route_info.name, 'NOT AVAILABLE')
368 active = view_fqn in whitelist_views
368 active = view_fqn in whitelist_views
369 c.view_data.append((route_info.name, view_fqn, routepath, active))
369 c.view_data.append((route_info.name, view_fqn, routepath, active))
370
370
371 c.whitelist_views = whitelist_views
371 c.whitelist_views = whitelist_views
372 return self._get_template_context(c)
372 return self._get_template_context(c)
373
373
374 def ssh_enabled(self):
375 return self.request.registry.settings.get(
376 'ssh.generate_authorized_keyfile')
377
374 @LoginRequired()
378 @LoginRequired()
375 @HasPermissionAllDecorator('hg.admin')
379 @HasPermissionAllDecorator('hg.admin')
376 @view_config(
380 @view_config(
377 route_name='admin_permissions_ssh_keys', request_method='GET',
381 route_name='admin_permissions_ssh_keys', request_method='GET',
378 renderer='rhodecode:templates/admin/permissions/permissions.mako')
382 renderer='rhodecode:templates/admin/permissions/permissions.mako')
379 def ssh_keys(self):
383 def ssh_keys(self):
380 c = self.load_default_context()
384 c = self.load_default_context()
381 c.active = 'ssh_keys'
385 c.active = 'ssh_keys'
386 c.ssh_enabled = self.ssh_enabled()
382 return self._get_template_context(c)
387 return self._get_template_context(c)
383
388
384 @LoginRequired()
389 @LoginRequired()
385 @HasPermissionAllDecorator('hg.admin')
390 @HasPermissionAllDecorator('hg.admin')
386 @view_config(
391 @view_config(
387 route_name='admin_permissions_ssh_keys_data', request_method='GET',
392 route_name='admin_permissions_ssh_keys_data', request_method='GET',
388 renderer='json_ext', xhr=True)
393 renderer='json_ext', xhr=True)
389 def ssh_keys_data(self):
394 def ssh_keys_data(self):
390 _ = self.request.translate
395 _ = self.request.translate
391 column_map = {
396 column_map = {
392 'fingerprint': 'ssh_key_fingerprint',
397 'fingerprint': 'ssh_key_fingerprint',
393 'username': User.username
398 'username': User.username
394 }
399 }
395 draw, start, limit = self._extract_chunk(self.request)
400 draw, start, limit = self._extract_chunk(self.request)
396 search_q, order_by, order_dir = self._extract_ordering(
401 search_q, order_by, order_dir = self._extract_ordering(
397 self.request, column_map=column_map)
402 self.request, column_map=column_map)
398
403
399 ssh_keys_data_total_count = UserSshKeys.query()\
404 ssh_keys_data_total_count = UserSshKeys.query()\
400 .count()
405 .count()
401
406
402 # json generate
407 # json generate
403 base_q = UserSshKeys.query().join(UserSshKeys.user)
408 base_q = UserSshKeys.query().join(UserSshKeys.user)
404
409
405 if search_q:
410 if search_q:
406 like_expression = u'%{}%'.format(safe_unicode(search_q))
411 like_expression = u'%{}%'.format(safe_unicode(search_q))
407 base_q = base_q.filter(or_(
412 base_q = base_q.filter(or_(
408 User.username.ilike(like_expression),
413 User.username.ilike(like_expression),
409 UserSshKeys.ssh_key_fingerprint.ilike(like_expression),
414 UserSshKeys.ssh_key_fingerprint.ilike(like_expression),
410 ))
415 ))
411
416
412 users_data_total_filtered_count = base_q.count()
417 users_data_total_filtered_count = base_q.count()
413
418
414 sort_col = self._get_order_col(order_by, UserSshKeys)
419 sort_col = self._get_order_col(order_by, UserSshKeys)
415 if sort_col:
420 if sort_col:
416 if order_dir == 'asc':
421 if order_dir == 'asc':
417 # handle null values properly to order by NULL last
422 # handle null values properly to order by NULL last
418 if order_by in ['created_on']:
423 if order_by in ['created_on']:
419 sort_col = coalesce(sort_col, datetime.date.max)
424 sort_col = coalesce(sort_col, datetime.date.max)
420 sort_col = sort_col.asc()
425 sort_col = sort_col.asc()
421 else:
426 else:
422 # handle null values properly to order by NULL last
427 # handle null values properly to order by NULL last
423 if order_by in ['created_on']:
428 if order_by in ['created_on']:
424 sort_col = coalesce(sort_col, datetime.date.min)
429 sort_col = coalesce(sort_col, datetime.date.min)
425 sort_col = sort_col.desc()
430 sort_col = sort_col.desc()
426
431
427 base_q = base_q.order_by(sort_col)
432 base_q = base_q.order_by(sort_col)
428 base_q = base_q.offset(start).limit(limit)
433 base_q = base_q.offset(start).limit(limit)
429
434
430 ssh_keys = base_q.all()
435 ssh_keys = base_q.all()
431
436
432 ssh_keys_data = []
437 ssh_keys_data = []
433 for ssh_key in ssh_keys:
438 for ssh_key in ssh_keys:
434 ssh_keys_data.append({
439 ssh_keys_data.append({
435 "username": h.gravatar_with_user(self.request, ssh_key.user.username),
440 "username": h.gravatar_with_user(self.request, ssh_key.user.username),
436 "fingerprint": ssh_key.ssh_key_fingerprint,
441 "fingerprint": ssh_key.ssh_key_fingerprint,
437 "description": ssh_key.description,
442 "description": ssh_key.description,
438 "created_on": h.format_date(ssh_key.created_on),
443 "created_on": h.format_date(ssh_key.created_on),
439 "action": h.link_to(
444 "action": h.link_to(
440 _('Edit'), h.route_path('edit_user_ssh_keys',
445 _('Edit'), h.route_path('edit_user_ssh_keys',
441 user_id=ssh_key.user.user_id))
446 user_id=ssh_key.user.user_id))
442 })
447 })
443
448
444 data = ({
449 data = ({
445 'draw': draw,
450 'draw': draw,
446 'data': ssh_keys_data,
451 'data': ssh_keys_data,
447 'recordsTotal': ssh_keys_data_total_count,
452 'recordsTotal': ssh_keys_data_total_count,
448 'recordsFiltered': users_data_total_filtered_count,
453 'recordsFiltered': users_data_total_filtered_count,
449 })
454 })
450
455
451 return data
456 return data
452
457
453 @LoginRequired()
458 @LoginRequired()
454 @HasPermissionAllDecorator('hg.admin')
459 @HasPermissionAllDecorator('hg.admin')
455 @CSRFRequired()
460 @CSRFRequired()
456 @view_config(
461 @view_config(
457 route_name='admin_permissions_ssh_keys_update', request_method='POST',
462 route_name='admin_permissions_ssh_keys_update', request_method='POST',
458 renderer='rhodecode:templates/admin/permissions/permissions.mako')
463 renderer='rhodecode:templates/admin/permissions/permissions.mako')
459 def ssh_keys_update(self):
464 def ssh_keys_update(self):
460 _ = self.request.translate
465 _ = self.request.translate
461 self.load_default_context()
466 self.load_default_context()
462
467
463 ssh_enabled = self.request.registry.settings.get(
468 ssh_enabled = self.ssh_enabled()
464 'ssh.generate_authorized_keyfile')
465 key_file = self.request.registry.settings.get(
469 key_file = self.request.registry.settings.get(
466 'ssh.authorized_keys_file_path')
470 'ssh.authorized_keys_file_path')
467 if ssh_enabled:
471 if ssh_enabled:
468 trigger(SshKeyFileChangeEvent(), self.request.registry)
472 trigger(SshKeyFileChangeEvent(), self.request.registry)
469 h.flash(_('Updated SSH keys file: {}').format(key_file),
473 h.flash(_('Updated SSH keys file: {}').format(key_file),
470 category='success')
474 category='success')
471 else:
475 else:
472 h.flash(_('SSH key support is disabled in .ini file'),
476 h.flash(_('SSH key support is disabled in .ini file'),
473 category='warning')
477 category='warning')
474
478
475 raise HTTPFound(h.route_path('admin_permissions_ssh_keys'))
479 raise HTTPFound(h.route_path('admin_permissions_ssh_keys'))
@@ -1,777 +1,777 b''
1
1
2
2
3 ################################################################################
3 ################################################################################
4 ## RHODECODE COMMUNITY EDITION CONFIGURATION ##
4 ## RHODECODE COMMUNITY EDITION CONFIGURATION ##
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10
10
11 ################################################################################
11 ################################################################################
12 ## EMAIL CONFIGURATION ##
12 ## EMAIL CONFIGURATION ##
13 ## Uncomment and replace with the email address which should receive ##
13 ## Uncomment and replace with the email address which should receive ##
14 ## any error reports after an application crash ##
14 ## any error reports after an application crash ##
15 ## Additionally these settings will be used by the RhodeCode mailing system ##
15 ## Additionally these settings will be used by the RhodeCode mailing system ##
16 ################################################################################
16 ################################################################################
17
17
18 ## prefix all emails subjects with given prefix, helps filtering out emails
18 ## prefix all emails subjects with given prefix, helps filtering out emails
19 #email_prefix = [RhodeCode]
19 #email_prefix = [RhodeCode]
20
20
21 ## email FROM address all mails will be sent
21 ## email FROM address all mails will be sent
22 #app_email_from = rhodecode-noreply@localhost
22 #app_email_from = rhodecode-noreply@localhost
23
23
24 ## Uncomment and replace with the address which should receive any error report
24 ## Uncomment and replace with the address which should receive any error report
25 ## note: using appenlight for error handling doesn't need this to be uncommented
25 ## note: using appenlight for error handling doesn't need this to be uncommented
26 #email_to = admin@localhost
26 #email_to = admin@localhost
27
27
28 ## in case of Application errors, sent an error email form
28 ## in case of Application errors, sent an error email form
29 #error_email_from = rhodecode_error@localhost
29 #error_email_from = rhodecode_error@localhost
30
30
31 ## additional error message to be send in case of server crash
31 ## additional error message to be send in case of server crash
32 #error_message =
32 #error_message =
33
33
34
34
35 #smtp_server = mail.server.com
35 #smtp_server = mail.server.com
36 #smtp_username =
36 #smtp_username =
37 #smtp_password =
37 #smtp_password =
38 #smtp_port =
38 #smtp_port =
39 #smtp_use_tls = false
39 #smtp_use_tls = false
40 #smtp_use_ssl = true
40 #smtp_use_ssl = true
41 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
41 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
42 #smtp_auth =
42 #smtp_auth =
43
43
44 [server:main]
44 [server:main]
45 ## COMMON ##
45 ## COMMON ##
46 host = 0.0.0.0
46 host = 0.0.0.0
47 port = 5000
47 port = 5000
48
48
49 ##################################
49 ##################################
50 ## WAITRESS WSGI SERVER ##
50 ## WAITRESS WSGI SERVER ##
51 ## Recommended for Development ##
51 ## Recommended for Development ##
52 ##################################
52 ##################################
53
53
54 use = egg:waitress#main
54 use = egg:waitress#main
55 ## number of worker threads
55 ## number of worker threads
56 threads = 5
56 threads = 5
57 ## MAX BODY SIZE 100GB
57 ## MAX BODY SIZE 100GB
58 max_request_body_size = 107374182400
58 max_request_body_size = 107374182400
59 ## Use poll instead of select, fixes file descriptors limits problems.
59 ## Use poll instead of select, fixes file descriptors limits problems.
60 ## May not work on old windows systems.
60 ## May not work on old windows systems.
61 asyncore_use_poll = true
61 asyncore_use_poll = true
62
62
63
63
64 ##########################
64 ##########################
65 ## GUNICORN WSGI SERVER ##
65 ## GUNICORN WSGI SERVER ##
66 ##########################
66 ##########################
67 ## run with gunicorn --log-config rhodecode.ini --paste rhodecode.ini
67 ## run with gunicorn --log-config rhodecode.ini --paste rhodecode.ini
68
68
69 #use = egg:gunicorn#main
69 #use = egg:gunicorn#main
70 ## Sets the number of process workers. You must set `instance_id = *`
70 ## Sets the number of process workers. You must set `instance_id = *`
71 ## when this option is set to more than one worker, recommended
71 ## when this option is set to more than one worker, recommended
72 ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers
72 ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers
73 ## The `instance_id = *` must be set in the [app:main] section below
73 ## The `instance_id = *` must be set in the [app:main] section below
74 #workers = 2
74 #workers = 2
75 ## number of threads for each of the worker, must be set to 1 for gevent
75 ## number of threads for each of the worker, must be set to 1 for gevent
76 ## generally recommened to be at 1
76 ## generally recommened to be at 1
77 #threads = 1
77 #threads = 1
78 ## process name
78 ## process name
79 #proc_name = rhodecode
79 #proc_name = rhodecode
80 ## type of worker class, one of sync, gevent
80 ## type of worker class, one of sync, gevent
81 ## recommended for bigger setup is using of of other than sync one
81 ## recommended for bigger setup is using of of other than sync one
82 #worker_class = sync
82 #worker_class = sync
83 ## The maximum number of simultaneous clients. Valid only for Gevent
83 ## The maximum number of simultaneous clients. Valid only for Gevent
84 #worker_connections = 10
84 #worker_connections = 10
85 ## max number of requests that worker will handle before being gracefully
85 ## max number of requests that worker will handle before being gracefully
86 ## restarted, could prevent memory leaks
86 ## restarted, could prevent memory leaks
87 #max_requests = 1000
87 #max_requests = 1000
88 #max_requests_jitter = 30
88 #max_requests_jitter = 30
89 ## amount of time a worker can spend with handling a request before it
89 ## amount of time a worker can spend with handling a request before it
90 ## gets killed and restarted. Set to 6hrs
90 ## gets killed and restarted. Set to 6hrs
91 #timeout = 21600
91 #timeout = 21600
92
92
93 ## UWSGI ##
93 ## UWSGI ##
94 ## run with uwsgi --ini-paste-logged <inifile.ini>
94 ## run with uwsgi --ini-paste-logged <inifile.ini>
95 #[uwsgi]
95 #[uwsgi]
96 #socket = /tmp/uwsgi.sock
96 #socket = /tmp/uwsgi.sock
97 #master = true
97 #master = true
98 #http = 127.0.0.1:5000
98 #http = 127.0.0.1:5000
99
99
100 ## set as deamon and redirect all output to file
100 ## set as deamon and redirect all output to file
101 #daemonize = ./uwsgi_rhodecode.log
101 #daemonize = ./uwsgi_rhodecode.log
102
102
103 ## master process PID
103 ## master process PID
104 #pidfile = ./uwsgi_rhodecode.pid
104 #pidfile = ./uwsgi_rhodecode.pid
105
105
106 ## stats server with workers statistics, use uwsgitop
106 ## stats server with workers statistics, use uwsgitop
107 ## for monitoring, `uwsgitop 127.0.0.1:1717`
107 ## for monitoring, `uwsgitop 127.0.0.1:1717`
108 #stats = 127.0.0.1:1717
108 #stats = 127.0.0.1:1717
109 #memory-report = true
109 #memory-report = true
110
110
111 ## log 5XX errors
111 ## log 5XX errors
112 #log-5xx = true
112 #log-5xx = true
113
113
114 ## Set the socket listen queue size.
114 ## Set the socket listen queue size.
115 #listen = 256
115 #listen = 256
116
116
117 ## Gracefully Reload workers after the specified amount of managed requests
117 ## Gracefully Reload workers after the specified amount of managed requests
118 ## (avoid memory leaks).
118 ## (avoid memory leaks).
119 #max-requests = 1000
119 #max-requests = 1000
120
120
121 ## enable large buffers
121 ## enable large buffers
122 #buffer-size=65535
122 #buffer-size=65535
123
123
124 ## socket and http timeouts ##
124 ## socket and http timeouts ##
125 #http-timeout=3600
125 #http-timeout=3600
126 #socket-timeout=3600
126 #socket-timeout=3600
127
127
128 ## Log requests slower than the specified number of milliseconds.
128 ## Log requests slower than the specified number of milliseconds.
129 #log-slow = 10
129 #log-slow = 10
130
130
131 ## Exit if no app can be loaded.
131 ## Exit if no app can be loaded.
132 #need-app = true
132 #need-app = true
133
133
134 ## Set lazy mode (load apps in workers instead of master).
134 ## Set lazy mode (load apps in workers instead of master).
135 #lazy = true
135 #lazy = true
136
136
137 ## scaling ##
137 ## scaling ##
138 ## set cheaper algorithm to use, if not set default will be used
138 ## set cheaper algorithm to use, if not set default will be used
139 #cheaper-algo = spare
139 #cheaper-algo = spare
140
140
141 ## minimum number of workers to keep at all times
141 ## minimum number of workers to keep at all times
142 #cheaper = 1
142 #cheaper = 1
143
143
144 ## number of workers to spawn at startup
144 ## number of workers to spawn at startup
145 #cheaper-initial = 1
145 #cheaper-initial = 1
146
146
147 ## maximum number of workers that can be spawned
147 ## maximum number of workers that can be spawned
148 #workers = 4
148 #workers = 4
149
149
150 ## how many workers should be spawned at a time
150 ## how many workers should be spawned at a time
151 #cheaper-step = 1
151 #cheaper-step = 1
152
152
153 ## prefix middleware for RhodeCode.
153 ## prefix middleware for RhodeCode.
154 ## recommended when using proxy setup.
154 ## recommended when using proxy setup.
155 ## allows to set RhodeCode under a prefix in server.
155 ## allows to set RhodeCode under a prefix in server.
156 ## eg https://server.com/custom_prefix. Enable `filter-with =` option below as well.
156 ## eg https://server.com/custom_prefix. Enable `filter-with =` option below as well.
157 ## And set your prefix like: `prefix = /custom_prefix`
157 ## And set your prefix like: `prefix = /custom_prefix`
158 ## be sure to also set beaker.session.cookie_path = /custom_prefix if you need
158 ## be sure to also set beaker.session.cookie_path = /custom_prefix if you need
159 ## to make your cookies only work on prefix url
159 ## to make your cookies only work on prefix url
160 [filter:proxy-prefix]
160 [filter:proxy-prefix]
161 use = egg:PasteDeploy#prefix
161 use = egg:PasteDeploy#prefix
162 prefix = /
162 prefix = /
163
163
164 [app:main]
164 [app:main]
165 is_test = True
165 is_test = True
166 use = egg:rhodecode-enterprise-ce
166 use = egg:rhodecode-enterprise-ce
167
167
168 ## enable proxy prefix middleware, defined above
168 ## enable proxy prefix middleware, defined above
169 #filter-with = proxy-prefix
169 #filter-with = proxy-prefix
170
170
171
171
172 ## RHODECODE PLUGINS ##
172 ## RHODECODE PLUGINS ##
173 rhodecode.includes = rhodecode.api
173 rhodecode.includes = rhodecode.api
174
174
175 # api prefix url
175 # api prefix url
176 rhodecode.api.url = /_admin/api
176 rhodecode.api.url = /_admin/api
177
177
178
178
179 ## END RHODECODE PLUGINS ##
179 ## END RHODECODE PLUGINS ##
180
180
181 ## encryption key used to encrypt social plugin tokens,
181 ## encryption key used to encrypt social plugin tokens,
182 ## remote_urls with credentials etc, if not set it defaults to
182 ## remote_urls with credentials etc, if not set it defaults to
183 ## `beaker.session.secret`
183 ## `beaker.session.secret`
184 #rhodecode.encrypted_values.secret =
184 #rhodecode.encrypted_values.secret =
185
185
186 ## decryption strict mode (enabled by default). It controls if decryption raises
186 ## decryption strict mode (enabled by default). It controls if decryption raises
187 ## `SignatureVerificationError` in case of wrong key, or damaged encryption data.
187 ## `SignatureVerificationError` in case of wrong key, or damaged encryption data.
188 #rhodecode.encrypted_values.strict = false
188 #rhodecode.encrypted_values.strict = false
189
189
190 ## return gzipped responses from Rhodecode (static files/application)
190 ## return gzipped responses from Rhodecode (static files/application)
191 gzip_responses = false
191 gzip_responses = false
192
192
193 ## autogenerate javascript routes file on startup
193 ## autogenerate javascript routes file on startup
194 generate_js_files = false
194 generate_js_files = false
195
195
196 ## Optional Languages
196 ## Optional Languages
197 ## en(default), be, de, es, fr, it, ja, pl, pt, ru, zh
197 ## en(default), be, de, es, fr, it, ja, pl, pt, ru, zh
198 lang = en
198 lang = en
199
199
200 ## perform a full repository scan on each server start, this should be
200 ## perform a full repository scan on each server start, this should be
201 ## set to false after first startup, to allow faster server restarts.
201 ## set to false after first startup, to allow faster server restarts.
202 startup.import_repos = true
202 startup.import_repos = true
203
203
204 ## Uncomment and set this path to use archive download cache.
204 ## Uncomment and set this path to use archive download cache.
205 ## Once enabled, generated archives will be cached at this location
205 ## Once enabled, generated archives will be cached at this location
206 ## and served from the cache during subsequent requests for the same archive of
206 ## and served from the cache during subsequent requests for the same archive of
207 ## the repository.
207 ## the repository.
208 #archive_cache_dir = /tmp/tarballcache
208 #archive_cache_dir = /tmp/tarballcache
209
209
210 ## change this to unique ID for security
210 ## change this to unique ID for security
211 app_instance_uuid = rc-production
211 app_instance_uuid = rc-production
212
212
213 ## cut off limit for large diffs (size in bytes)
213 ## cut off limit for large diffs (size in bytes)
214 cut_off_limit_diff = 1024000
214 cut_off_limit_diff = 1024000
215 cut_off_limit_file = 256000
215 cut_off_limit_file = 256000
216
216
217 ## use cache version of scm repo everywhere
217 ## use cache version of scm repo everywhere
218 vcs_full_cache = false
218 vcs_full_cache = false
219
219
220 ## force https in RhodeCode, fixes https redirects, assumes it's always https
220 ## force https in RhodeCode, fixes https redirects, assumes it's always https
221 ## Normally this is controlled by proper http flags sent from http server
221 ## Normally this is controlled by proper http flags sent from http server
222 force_https = false
222 force_https = false
223
223
224 ## use Strict-Transport-Security headers
224 ## use Strict-Transport-Security headers
225 use_htsts = false
225 use_htsts = false
226
226
227 ## number of commits stats will parse on each iteration
227 ## number of commits stats will parse on each iteration
228 commit_parse_limit = 25
228 commit_parse_limit = 25
229
229
230 ## git rev filter option, --all is the default filter, if you need to
230 ## git rev filter option, --all is the default filter, if you need to
231 ## hide all refs in changelog switch this to --branches --tags
231 ## hide all refs in changelog switch this to --branches --tags
232 git_rev_filter = --all
232 git_rev_filter = --all
233
233
234 # Set to true if your repos are exposed using the dumb protocol
234 # Set to true if your repos are exposed using the dumb protocol
235 git_update_server_info = false
235 git_update_server_info = false
236
236
237 ## RSS/ATOM feed options
237 ## RSS/ATOM feed options
238 rss_cut_off_limit = 256000
238 rss_cut_off_limit = 256000
239 rss_items_per_page = 10
239 rss_items_per_page = 10
240 rss_include_diff = false
240 rss_include_diff = false
241
241
242 ## gist URL alias, used to create nicer urls for gist. This should be an
242 ## gist URL alias, used to create nicer urls for gist. This should be an
243 ## url that does rewrites to _admin/gists/{gistid}.
243 ## url that does rewrites to _admin/gists/{gistid}.
244 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
244 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
245 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/{gistid}
245 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/{gistid}
246 gist_alias_url =
246 gist_alias_url =
247
247
248 ## List of views (using glob pattern syntax) that AUTH TOKENS could be
248 ## List of views (using glob pattern syntax) that AUTH TOKENS could be
249 ## used for access.
249 ## used for access.
250 ## Adding ?auth_token=TOKEN_HASH to the url authenticates this request as if it
250 ## Adding ?auth_token=TOKEN_HASH to the url authenticates this request as if it
251 ## came from the the logged in user who own this authentication token.
251 ## came from the the logged in user who own this authentication token.
252 ## Additionally @TOKEN syntaxt can be used to bound the view to specific
252 ## Additionally @TOKEN syntaxt can be used to bound the view to specific
253 ## authentication token. Such view would be only accessible when used together
253 ## authentication token. Such view would be only accessible when used together
254 ## with this authentication token
254 ## with this authentication token
255 ##
255 ##
256 ## list of all views can be found under `/_admin/permissions/auth_token_access`
256 ## list of all views can be found under `/_admin/permissions/auth_token_access`
257 ## The list should be "," separated and on a single line.
257 ## The list should be "," separated and on a single line.
258 ##
258 ##
259 ## Most common views to enable:
259 ## Most common views to enable:
260 # RepoCommitsView:repo_commit_download
260 # RepoCommitsView:repo_commit_download
261 # RepoCommitsView:repo_commit_patch
261 # RepoCommitsView:repo_commit_patch
262 # RepoCommitsView:repo_commit_raw
262 # RepoCommitsView:repo_commit_raw
263 # RepoCommitsView:repo_commit_raw@TOKEN
263 # RepoCommitsView:repo_commit_raw@TOKEN
264 # RepoFilesView:repo_files_diff
264 # RepoFilesView:repo_files_diff
265 # RepoFilesView:repo_archivefile
265 # RepoFilesView:repo_archivefile
266 # RepoFilesView:repo_file_raw
266 # RepoFilesView:repo_file_raw
267 # GistView:*
267 # GistView:*
268 api_access_controllers_whitelist =
268 api_access_controllers_whitelist =
269
269
270 ## default encoding used to convert from and to unicode
270 ## default encoding used to convert from and to unicode
271 ## can be also a comma separated list of encoding in case of mixed encodings
271 ## can be also a comma separated list of encoding in case of mixed encodings
272 default_encoding = UTF-8
272 default_encoding = UTF-8
273
273
274 ## instance-id prefix
274 ## instance-id prefix
275 ## a prefix key for this instance used for cache invalidation when running
275 ## a prefix key for this instance used for cache invalidation when running
276 ## multiple instances of rhodecode, make sure it's globally unique for
276 ## multiple instances of rhodecode, make sure it's globally unique for
277 ## all running rhodecode instances. Leave empty if you don't use it
277 ## all running rhodecode instances. Leave empty if you don't use it
278 instance_id =
278 instance_id =
279
279
280 ## Fallback authentication plugin. Set this to a plugin ID to force the usage
280 ## Fallback authentication plugin. Set this to a plugin ID to force the usage
281 ## of an authentication plugin also if it is disabled by it's settings.
281 ## of an authentication plugin also if it is disabled by it's settings.
282 ## This could be useful if you are unable to log in to the system due to broken
282 ## This could be useful if you are unable to log in to the system due to broken
283 ## authentication settings. Then you can enable e.g. the internal rhodecode auth
283 ## authentication settings. Then you can enable e.g. the internal rhodecode auth
284 ## module to log in again and fix the settings.
284 ## module to log in again and fix the settings.
285 ##
285 ##
286 ## Available builtin plugin IDs (hash is part of the ID):
286 ## Available builtin plugin IDs (hash is part of the ID):
287 ## egg:rhodecode-enterprise-ce#rhodecode
287 ## egg:rhodecode-enterprise-ce#rhodecode
288 ## egg:rhodecode-enterprise-ce#pam
288 ## egg:rhodecode-enterprise-ce#pam
289 ## egg:rhodecode-enterprise-ce#ldap
289 ## egg:rhodecode-enterprise-ce#ldap
290 ## egg:rhodecode-enterprise-ce#jasig_cas
290 ## egg:rhodecode-enterprise-ce#jasig_cas
291 ## egg:rhodecode-enterprise-ce#headers
291 ## egg:rhodecode-enterprise-ce#headers
292 ## egg:rhodecode-enterprise-ce#crowd
292 ## egg:rhodecode-enterprise-ce#crowd
293 #rhodecode.auth_plugin_fallback = egg:rhodecode-enterprise-ce#rhodecode
293 #rhodecode.auth_plugin_fallback = egg:rhodecode-enterprise-ce#rhodecode
294
294
295 ## alternative return HTTP header for failed authentication. Default HTTP
295 ## alternative return HTTP header for failed authentication. Default HTTP
296 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
296 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
297 ## handling that causing a series of failed authentication calls.
297 ## handling that causing a series of failed authentication calls.
298 ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code
298 ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code
299 ## This will be served instead of default 401 on bad authnetication
299 ## This will be served instead of default 401 on bad authnetication
300 auth_ret_code =
300 auth_ret_code =
301
301
302 ## use special detection method when serving auth_ret_code, instead of serving
302 ## use special detection method when serving auth_ret_code, instead of serving
303 ## ret_code directly, use 401 initially (Which triggers credentials prompt)
303 ## ret_code directly, use 401 initially (Which triggers credentials prompt)
304 ## and then serve auth_ret_code to clients
304 ## and then serve auth_ret_code to clients
305 auth_ret_code_detection = false
305 auth_ret_code_detection = false
306
306
307 ## locking return code. When repository is locked return this HTTP code. 2XX
307 ## locking return code. When repository is locked return this HTTP code. 2XX
308 ## codes don't break the transactions while 4XX codes do
308 ## codes don't break the transactions while 4XX codes do
309 lock_ret_code = 423
309 lock_ret_code = 423
310
310
311 ## allows to change the repository location in settings page
311 ## allows to change the repository location in settings page
312 allow_repo_location_change = true
312 allow_repo_location_change = true
313
313
314 ## allows to setup custom hooks in settings page
314 ## allows to setup custom hooks in settings page
315 allow_custom_hooks_settings = true
315 allow_custom_hooks_settings = true
316
316
317 ## generated license token, goto license page in RhodeCode settings to obtain
317 ## generated license token, goto license page in RhodeCode settings to obtain
318 ## new token
318 ## new token
319 license_token = abra-cada-bra1-rce3
319 license_token = abra-cada-bra1-rce3
320
320
321 ## supervisor connection uri, for managing supervisor and logs.
321 ## supervisor connection uri, for managing supervisor and logs.
322 supervisor.uri =
322 supervisor.uri =
323 ## supervisord group name/id we only want this RC instance to handle
323 ## supervisord group name/id we only want this RC instance to handle
324 supervisor.group_id = dev
324 supervisor.group_id = dev
325
325
326 ## Display extended labs settings
326 ## Display extended labs settings
327 labs_settings_active = true
327 labs_settings_active = true
328
328
329 ####################################
329 ####################################
330 ### CELERY CONFIG ####
330 ### CELERY CONFIG ####
331 ####################################
331 ####################################
332 use_celery = false
332 use_celery = false
333 broker.host = localhost
333 broker.host = localhost
334 broker.vhost = rabbitmqhost
334 broker.vhost = rabbitmqhost
335 broker.port = 5672
335 broker.port = 5672
336 broker.user = rabbitmq
336 broker.user = rabbitmq
337 broker.password = qweqwe
337 broker.password = qweqwe
338
338
339 celery.imports = rhodecode.lib.celerylib.tasks
339 celery.imports = rhodecode.lib.celerylib.tasks
340
340
341 celery.result.backend = amqp
341 celery.result.backend = amqp
342 celery.result.dburi = amqp://
342 celery.result.dburi = amqp://
343 celery.result.serialier = json
343 celery.result.serialier = json
344
344
345 #celery.send.task.error.emails = true
345 #celery.send.task.error.emails = true
346 #celery.amqp.task.result.expires = 18000
346 #celery.amqp.task.result.expires = 18000
347
347
348 celeryd.concurrency = 2
348 celeryd.concurrency = 2
349 #celeryd.log.file = celeryd.log
349 #celeryd.log.file = celeryd.log
350 celeryd.log.level = debug
350 celeryd.log.level = debug
351 celeryd.max.tasks.per.child = 1
351 celeryd.max.tasks.per.child = 1
352
352
353 ## tasks will never be sent to the queue, but executed locally instead.
353 ## tasks will never be sent to the queue, but executed locally instead.
354 celery.always.eager = false
354 celery.always.eager = false
355
355
356 ####################################
356 ####################################
357 ### BEAKER CACHE ####
357 ### BEAKER CACHE ####
358 ####################################
358 ####################################
359 # default cache dir for templates. Putting this into a ramdisk
359 # default cache dir for templates. Putting this into a ramdisk
360 ## can boost performance, eg. %(here)s/data_ramdisk
360 ## can boost performance, eg. %(here)s/data_ramdisk
361 cache_dir = %(here)s/data
361 cache_dir = %(here)s/data
362
362
363 ## locking and default file storage for Beaker. Putting this into a ramdisk
363 ## locking and default file storage for Beaker. Putting this into a ramdisk
364 ## can boost performance, eg. %(here)s/data_ramdisk/cache/beaker_data
364 ## can boost performance, eg. %(here)s/data_ramdisk/cache/beaker_data
365 beaker.cache.data_dir = %(here)s/rc/data/cache/beaker_data
365 beaker.cache.data_dir = %(here)s/rc/data/cache/beaker_data
366 beaker.cache.lock_dir = %(here)s/rc/data/cache/beaker_lock
366 beaker.cache.lock_dir = %(here)s/rc/data/cache/beaker_lock
367
367
368 beaker.cache.regions = super_short_term, short_term, long_term, sql_cache_short, auth_plugins, repo_cache_long
368 beaker.cache.regions = super_short_term, short_term, long_term, sql_cache_short, auth_plugins, repo_cache_long
369
369
370 beaker.cache.super_short_term.type = memory
370 beaker.cache.super_short_term.type = memory
371 beaker.cache.super_short_term.expire = 1
371 beaker.cache.super_short_term.expire = 1
372 beaker.cache.super_short_term.key_length = 256
372 beaker.cache.super_short_term.key_length = 256
373
373
374 beaker.cache.short_term.type = memory
374 beaker.cache.short_term.type = memory
375 beaker.cache.short_term.expire = 60
375 beaker.cache.short_term.expire = 60
376 beaker.cache.short_term.key_length = 256
376 beaker.cache.short_term.key_length = 256
377
377
378 beaker.cache.long_term.type = memory
378 beaker.cache.long_term.type = memory
379 beaker.cache.long_term.expire = 36000
379 beaker.cache.long_term.expire = 36000
380 beaker.cache.long_term.key_length = 256
380 beaker.cache.long_term.key_length = 256
381
381
382 beaker.cache.sql_cache_short.type = memory
382 beaker.cache.sql_cache_short.type = memory
383 beaker.cache.sql_cache_short.expire = 1
383 beaker.cache.sql_cache_short.expire = 1
384 beaker.cache.sql_cache_short.key_length = 256
384 beaker.cache.sql_cache_short.key_length = 256
385
385
386 ## default is memory cache, configure only if required
386 ## default is memory cache, configure only if required
387 ## using multi-node or multi-worker setup
387 ## using multi-node or multi-worker setup
388 #beaker.cache.auth_plugins.type = ext:database
388 #beaker.cache.auth_plugins.type = ext:database
389 #beaker.cache.auth_plugins.lock_dir = %(here)s/data/cache/auth_plugin_lock
389 #beaker.cache.auth_plugins.lock_dir = %(here)s/data/cache/auth_plugin_lock
390 #beaker.cache.auth_plugins.url = postgresql://postgres:secret@localhost/rhodecode
390 #beaker.cache.auth_plugins.url = postgresql://postgres:secret@localhost/rhodecode
391 #beaker.cache.auth_plugins.url = mysql://root:secret@127.0.0.1/rhodecode
391 #beaker.cache.auth_plugins.url = mysql://root:secret@127.0.0.1/rhodecode
392 #beaker.cache.auth_plugins.sa.pool_recycle = 3600
392 #beaker.cache.auth_plugins.sa.pool_recycle = 3600
393 #beaker.cache.auth_plugins.sa.pool_size = 10
393 #beaker.cache.auth_plugins.sa.pool_size = 10
394 #beaker.cache.auth_plugins.sa.max_overflow = 0
394 #beaker.cache.auth_plugins.sa.max_overflow = 0
395
395
396 beaker.cache.repo_cache_long.type = memorylru_base
396 beaker.cache.repo_cache_long.type = memorylru_base
397 beaker.cache.repo_cache_long.max_items = 4096
397 beaker.cache.repo_cache_long.max_items = 4096
398 beaker.cache.repo_cache_long.expire = 2592000
398 beaker.cache.repo_cache_long.expire = 2592000
399
399
400 ## default is memorylru_base cache, configure only if required
400 ## default is memorylru_base cache, configure only if required
401 ## using multi-node or multi-worker setup
401 ## using multi-node or multi-worker setup
402 #beaker.cache.repo_cache_long.type = ext:memcached
402 #beaker.cache.repo_cache_long.type = ext:memcached
403 #beaker.cache.repo_cache_long.url = localhost:11211
403 #beaker.cache.repo_cache_long.url = localhost:11211
404 #beaker.cache.repo_cache_long.expire = 1209600
404 #beaker.cache.repo_cache_long.expire = 1209600
405 #beaker.cache.repo_cache_long.key_length = 256
405 #beaker.cache.repo_cache_long.key_length = 256
406
406
407 ####################################
407 ####################################
408 ### BEAKER SESSION ####
408 ### BEAKER SESSION ####
409 ####################################
409 ####################################
410
410
411 ## .session.type is type of storage options for the session, current allowed
411 ## .session.type is type of storage options for the session, current allowed
412 ## types are file, ext:memcached, ext:database, and memory (default).
412 ## types are file, ext:memcached, ext:database, and memory (default).
413 beaker.session.type = file
413 beaker.session.type = file
414 beaker.session.data_dir = %(here)s/rc/data/sessions/data
414 beaker.session.data_dir = %(here)s/rc/data/sessions/data
415
415
416 ## db based session, fast, and allows easy management over logged in users
416 ## db based session, fast, and allows easy management over logged in users
417 #beaker.session.type = ext:database
417 #beaker.session.type = ext:database
418 #beaker.session.table_name = db_session
418 #beaker.session.table_name = db_session
419 #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
419 #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
420 #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode
420 #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode
421 #beaker.session.sa.pool_recycle = 3600
421 #beaker.session.sa.pool_recycle = 3600
422 #beaker.session.sa.echo = false
422 #beaker.session.sa.echo = false
423
423
424 beaker.session.key = rhodecode
424 beaker.session.key = rhodecode
425 beaker.session.secret = test-rc-uytcxaz
425 beaker.session.secret = test-rc-uytcxaz
426 beaker.session.lock_dir = %(here)s/rc/data/sessions/lock
426 beaker.session.lock_dir = %(here)s/rc/data/sessions/lock
427
427
428 ## Secure encrypted cookie. Requires AES and AES python libraries
428 ## Secure encrypted cookie. Requires AES and AES python libraries
429 ## you must disable beaker.session.secret to use this
429 ## you must disable beaker.session.secret to use this
430 #beaker.session.encrypt_key = key_for_encryption
430 #beaker.session.encrypt_key = key_for_encryption
431 #beaker.session.validate_key = validation_key
431 #beaker.session.validate_key = validation_key
432
432
433 ## sets session as invalid(also logging out user) if it haven not been
433 ## sets session as invalid(also logging out user) if it haven not been
434 ## accessed for given amount of time in seconds
434 ## accessed for given amount of time in seconds
435 beaker.session.timeout = 2592000
435 beaker.session.timeout = 2592000
436 beaker.session.httponly = true
436 beaker.session.httponly = true
437 ## Path to use for the cookie. Set to prefix if you use prefix middleware
437 ## Path to use for the cookie. Set to prefix if you use prefix middleware
438 #beaker.session.cookie_path = /custom_prefix
438 #beaker.session.cookie_path = /custom_prefix
439
439
440 ## uncomment for https secure cookie
440 ## uncomment for https secure cookie
441 beaker.session.secure = false
441 beaker.session.secure = false
442
442
443 ## auto save the session to not to use .save()
443 ## auto save the session to not to use .save()
444 beaker.session.auto = false
444 beaker.session.auto = false
445
445
446 ## default cookie expiration time in seconds, set to `true` to set expire
446 ## default cookie expiration time in seconds, set to `true` to set expire
447 ## at browser close
447 ## at browser close
448 #beaker.session.cookie_expires = 3600
448 #beaker.session.cookie_expires = 3600
449
449
450 ###################################
450 ###################################
451 ## SEARCH INDEXING CONFIGURATION ##
451 ## SEARCH INDEXING CONFIGURATION ##
452 ###################################
452 ###################################
453 ## Full text search indexer is available in rhodecode-tools under
453 ## Full text search indexer is available in rhodecode-tools under
454 ## `rhodecode-tools index` command
454 ## `rhodecode-tools index` command
455
455
456 ## WHOOSH Backend, doesn't require additional services to run
456 ## WHOOSH Backend, doesn't require additional services to run
457 ## it works good with few dozen repos
457 ## it works good with few dozen repos
458 search.module = rhodecode.lib.index.whoosh
458 search.module = rhodecode.lib.index.whoosh
459 search.location = %(here)s/data/index
459 search.location = %(here)s/data/index
460
460
461 ########################################
461 ########################################
462 ### CHANNELSTREAM CONFIG ####
462 ### CHANNELSTREAM CONFIG ####
463 ########################################
463 ########################################
464 ## channelstream enables persistent connections and live notification
464 ## channelstream enables persistent connections and live notification
465 ## in the system. It's also used by the chat system
465 ## in the system. It's also used by the chat system
466
466
467 channelstream.enabled = false
467 channelstream.enabled = false
468
468
469 ## server address for channelstream server on the backend
469 ## server address for channelstream server on the backend
470 channelstream.server = 127.0.0.1:9800
470 channelstream.server = 127.0.0.1:9800
471 ## location of the channelstream server from outside world
471 ## location of the channelstream server from outside world
472 ## use ws:// for http or wss:// for https. This address needs to be handled
472 ## use ws:// for http or wss:// for https. This address needs to be handled
473 ## by external HTTP server such as Nginx or Apache
473 ## by external HTTP server such as Nginx or Apache
474 ## see nginx/apache configuration examples in our docs
474 ## see nginx/apache configuration examples in our docs
475 channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
475 channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
476 channelstream.secret = secret
476 channelstream.secret = secret
477 channelstream.history.location = %(here)s/channelstream_history
477 channelstream.history.location = %(here)s/channelstream_history
478
478
479 ## Internal application path that Javascript uses to connect into.
479 ## Internal application path that Javascript uses to connect into.
480 ## If you use proxy-prefix the prefix should be added before /_channelstream
480 ## If you use proxy-prefix the prefix should be added before /_channelstream
481 channelstream.proxy_path = /_channelstream
481 channelstream.proxy_path = /_channelstream
482
482
483
483
484 ###################################
484 ###################################
485 ## APPENLIGHT CONFIG ##
485 ## APPENLIGHT CONFIG ##
486 ###################################
486 ###################################
487
487
488 ## Appenlight is tailored to work with RhodeCode, see
488 ## Appenlight is tailored to work with RhodeCode, see
489 ## http://appenlight.com for details how to obtain an account
489 ## http://appenlight.com for details how to obtain an account
490
490
491 ## appenlight integration enabled
491 ## appenlight integration enabled
492 appenlight = false
492 appenlight = false
493
493
494 appenlight.server_url = https://api.appenlight.com
494 appenlight.server_url = https://api.appenlight.com
495 appenlight.api_key = YOUR_API_KEY
495 appenlight.api_key = YOUR_API_KEY
496 #appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5
496 #appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5
497
497
498 # used for JS client
498 # used for JS client
499 appenlight.api_public_key = YOUR_API_PUBLIC_KEY
499 appenlight.api_public_key = YOUR_API_PUBLIC_KEY
500
500
501 ## TWEAK AMOUNT OF INFO SENT HERE
501 ## TWEAK AMOUNT OF INFO SENT HERE
502
502
503 ## enables 404 error logging (default False)
503 ## enables 404 error logging (default False)
504 appenlight.report_404 = false
504 appenlight.report_404 = false
505
505
506 ## time in seconds after request is considered being slow (default 1)
506 ## time in seconds after request is considered being slow (default 1)
507 appenlight.slow_request_time = 1
507 appenlight.slow_request_time = 1
508
508
509 ## record slow requests in application
509 ## record slow requests in application
510 ## (needs to be enabled for slow datastore recording and time tracking)
510 ## (needs to be enabled for slow datastore recording and time tracking)
511 appenlight.slow_requests = true
511 appenlight.slow_requests = true
512
512
513 ## enable hooking to application loggers
513 ## enable hooking to application loggers
514 appenlight.logging = true
514 appenlight.logging = true
515
515
516 ## minimum log level for log capture
516 ## minimum log level for log capture
517 appenlight.logging.level = WARNING
517 appenlight.logging.level = WARNING
518
518
519 ## send logs only from erroneous/slow requests
519 ## send logs only from erroneous/slow requests
520 ## (saves API quota for intensive logging)
520 ## (saves API quota for intensive logging)
521 appenlight.logging_on_error = false
521 appenlight.logging_on_error = false
522
522
523 ## list of additonal keywords that should be grabbed from environ object
523 ## list of additonal keywords that should be grabbed from environ object
524 ## can be string with comma separated list of words in lowercase
524 ## can be string with comma separated list of words in lowercase
525 ## (by default client will always send following info:
525 ## (by default client will always send following info:
526 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
526 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
527 ## start with HTTP* this list be extended with additional keywords here
527 ## start with HTTP* this list be extended with additional keywords here
528 appenlight.environ_keys_whitelist =
528 appenlight.environ_keys_whitelist =
529
529
530 ## list of keywords that should be blanked from request object
530 ## list of keywords that should be blanked from request object
531 ## can be string with comma separated list of words in lowercase
531 ## can be string with comma separated list of words in lowercase
532 ## (by default client will always blank keys that contain following words
532 ## (by default client will always blank keys that contain following words
533 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
533 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
534 ## this list be extended with additional keywords set here
534 ## this list be extended with additional keywords set here
535 appenlight.request_keys_blacklist =
535 appenlight.request_keys_blacklist =
536
536
537 ## list of namespaces that should be ignores when gathering log entries
537 ## list of namespaces that should be ignores when gathering log entries
538 ## can be string with comma separated list of namespaces
538 ## can be string with comma separated list of namespaces
539 ## (by default the client ignores own entries: appenlight_client.client)
539 ## (by default the client ignores own entries: appenlight_client.client)
540 appenlight.log_namespace_blacklist =
540 appenlight.log_namespace_blacklist =
541
541
542
542
543 ################################################################################
543 ################################################################################
544 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
544 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
545 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
545 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
546 ## execute malicious code after an exception is raised. ##
546 ## execute malicious code after an exception is raised. ##
547 ################################################################################
547 ################################################################################
548 set debug = false
548 set debug = false
549
549
550
550
551 ##############
551 ##############
552 ## STYLING ##
552 ## STYLING ##
553 ##############
553 ##############
554 debug_style = false
554 debug_style = false
555
555
556 ###########################################
556 ###########################################
557 ### MAIN RHODECODE DATABASE CONFIG ###
557 ### MAIN RHODECODE DATABASE CONFIG ###
558 ###########################################
558 ###########################################
559 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode_test.db?timeout=30
559 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode_test.db?timeout=30
560 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode_test
560 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode_test
561 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode_test
561 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode_test
562 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode_test.db?timeout=30
562 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode_test.db?timeout=30
563
563
564 # see sqlalchemy docs for other advanced settings
564 # see sqlalchemy docs for other advanced settings
565
565
566 ## print the sql statements to output
566 ## print the sql statements to output
567 sqlalchemy.db1.echo = false
567 sqlalchemy.db1.echo = false
568 ## recycle the connections after this amount of seconds
568 ## recycle the connections after this amount of seconds
569 sqlalchemy.db1.pool_recycle = 3600
569 sqlalchemy.db1.pool_recycle = 3600
570 sqlalchemy.db1.convert_unicode = true
570 sqlalchemy.db1.convert_unicode = true
571
571
572 ## the number of connections to keep open inside the connection pool.
572 ## the number of connections to keep open inside the connection pool.
573 ## 0 indicates no limit
573 ## 0 indicates no limit
574 #sqlalchemy.db1.pool_size = 5
574 #sqlalchemy.db1.pool_size = 5
575
575
576 ## the number of connections to allow in connection pool "overflow", that is
576 ## the number of connections to allow in connection pool "overflow", that is
577 ## connections that can be opened above and beyond the pool_size setting,
577 ## connections that can be opened above and beyond the pool_size setting,
578 ## which defaults to five.
578 ## which defaults to five.
579 #sqlalchemy.db1.max_overflow = 10
579 #sqlalchemy.db1.max_overflow = 10
580
580
581
581
582 ##################
582 ##################
583 ### VCS CONFIG ###
583 ### VCS CONFIG ###
584 ##################
584 ##################
585 vcs.server.enable = true
585 vcs.server.enable = true
586 vcs.server = localhost:9901
586 vcs.server = localhost:9901
587
587
588 ## Web server connectivity protocol, responsible for web based VCS operatations
588 ## Web server connectivity protocol, responsible for web based VCS operatations
589 ## Available protocols are:
589 ## Available protocols are:
590 ## `http` - use http-rpc backend (default)
590 ## `http` - use http-rpc backend (default)
591 vcs.server.protocol = http
591 vcs.server.protocol = http
592
592
593 ## Push/Pull operations protocol, available options are:
593 ## Push/Pull operations protocol, available options are:
594 ## `http` - use http-rpc backend (default)
594 ## `http` - use http-rpc backend (default)
595 ## `vcsserver.scm_app` - internal app (EE only)
595 ## `vcsserver.scm_app` - internal app (EE only)
596 vcs.scm_app_implementation = http
596 vcs.scm_app_implementation = http
597
597
598 ## Push/Pull operations hooks protocol, available options are:
598 ## Push/Pull operations hooks protocol, available options are:
599 ## `http` - use http-rpc backend (default)
599 ## `http` - use http-rpc backend (default)
600 vcs.hooks.protocol = http
600 vcs.hooks.protocol = http
601
601
602 vcs.server.log_level = debug
602 vcs.server.log_level = debug
603 ## Start VCSServer with this instance as a subprocess, usefull for development
603 ## Start VCSServer with this instance as a subprocess, usefull for development
604 vcs.start_server = false
604 vcs.start_server = false
605
605
606 ## List of enabled VCS backends, available options are:
606 ## List of enabled VCS backends, available options are:
607 ## `hg` - mercurial
607 ## `hg` - mercurial
608 ## `git` - git
608 ## `git` - git
609 ## `svn` - subversion
609 ## `svn` - subversion
610 vcs.backends = hg, git, svn
610 vcs.backends = hg, git, svn
611
611
612 vcs.connection_timeout = 3600
612 vcs.connection_timeout = 3600
613 ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out.
613 ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out.
614 ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible, pre-1.9-compatible
614 ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible, pre-1.9-compatible
615 #vcs.svn.compatible_version = pre-1.8-compatible
615 #vcs.svn.compatible_version = pre-1.8-compatible
616
616
617
617
618 ############################################################
618 ############################################################
619 ### Subversion proxy support (mod_dav_svn) ###
619 ### Subversion proxy support (mod_dav_svn) ###
620 ### Maps RhodeCode repo groups into SVN paths for Apache ###
620 ### Maps RhodeCode repo groups into SVN paths for Apache ###
621 ############################################################
621 ############################################################
622 ## Enable or disable the config file generation.
622 ## Enable or disable the config file generation.
623 svn.proxy.generate_config = false
623 svn.proxy.generate_config = false
624 ## Generate config file with `SVNListParentPath` set to `On`.
624 ## Generate config file with `SVNListParentPath` set to `On`.
625 svn.proxy.list_parent_path = true
625 svn.proxy.list_parent_path = true
626 ## Set location and file name of generated config file.
626 ## Set location and file name of generated config file.
627 svn.proxy.config_file_path = %(here)s/mod_dav_svn.conf
627 svn.proxy.config_file_path = %(here)s/mod_dav_svn.conf
628 ## Used as a prefix to the `Location` block in the generated config file.
628 ## Used as a prefix to the `Location` block in the generated config file.
629 ## In most cases it should be set to `/`.
629 ## In most cases it should be set to `/`.
630 svn.proxy.location_root = /
630 svn.proxy.location_root = /
631 ## Command to reload the mod dav svn configuration on change.
631 ## Command to reload the mod dav svn configuration on change.
632 ## Example: `/etc/init.d/apache2 reload`
632 ## Example: `/etc/init.d/apache2 reload`
633 #svn.proxy.reload_cmd = /etc/init.d/apache2 reload
633 #svn.proxy.reload_cmd = /etc/init.d/apache2 reload
634 ## If the timeout expires before the reload command finishes, the command will
634 ## If the timeout expires before the reload command finishes, the command will
635 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
635 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
636 #svn.proxy.reload_timeout = 10
636 #svn.proxy.reload_timeout = 10
637
637
638 ############################################################
638 ############################################################
639 ### SSH Support Settings ###
639 ### SSH Support Settings ###
640 ############################################################
640 ############################################################
641
641
642 ## Defines if the authorized_keys file should be written on any change of
642 ## Defines if the authorized_keys file should be written on any change of
643 ## user ssh keys, setting this to false also disables posibility of adding
643 ## user ssh keys, setting this to false also disables posibility of adding
644 ## ssh keys for users from web interface.
644 ## ssh keys for users from web interface.
645 ssh.generate_authorized_keyfile = false
645 ssh.generate_authorized_keyfile = true
646
646
647 ## Options for ssh, default is `no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding`
647 ## Options for ssh, default is `no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding`
648 # ssh.authorized_keys_ssh_opts =
648 # ssh.authorized_keys_ssh_opts =
649
649
650 ## File to generate the authorized keys together with options
650 ## File to generate the authorized keys together with options
651 ## It is possible to have multiple key files specified in `sshd_config` e.g.
651 ## It is possible to have multiple key files specified in `sshd_config` e.g.
652 ## AuthorizedKeysFile %h/.ssh/authorized_keys %h/.ssh/authorized_keys_rhodecode
652 ## AuthorizedKeysFile %h/.ssh/authorized_keys %h/.ssh/authorized_keys_rhodecode
653 ssh.authorized_keys_file_path = ~/.ssh/authorized_keys_rhodecode
653 ssh.authorized_keys_file_path = %(here)s/rc/authorized_keys_rhodecode
654
654
655 ## Command to execute the SSH wrapper. The binary is available in the
655 ## Command to execute the SSH wrapper. The binary is available in the
656 ## rhodecode installation directory.
656 ## rhodecode installation directory.
657 ## e.g ~/.rccontrol/community-1/profile/bin/rcssh-wrapper
657 ## e.g ~/.rccontrol/community-1/profile/bin/rcssh-wrapper
658 ssh.wrapper_cmd = ~/.rccontrol/community-1/rcssh-wrapper
658 ssh.wrapper_cmd = ~/.rccontrol/community-1/rcssh-wrapper
659
659
660 ## Allow shell when executing the ssh-wrapper command
660 ## Allow shell when executing the ssh-wrapper command
661 ssh.wrapper_cmd_allow_shell = false
661 ssh.wrapper_cmd_allow_shell = false
662
662
663 ## Enables logging, and detailed output send back to the client. Usefull for
663 ## Enables logging, and detailed output send back to the client. Usefull for
664 ## debugging, shouldn't be used in production.
664 ## debugging, shouldn't be used in production.
665 ssh.enable_debug_logging = false
665 ssh.enable_debug_logging = false
666
666
667 ## API KEY for user who has access to fetch other user permission information
667 ## API KEY for user who has access to fetch other user permission information
668 ## most likely an super-admin account with some IP restrictions.
668 ## most likely an super-admin account with some IP restrictions.
669 ssh.api_key =
669 ssh.api_key =
670
670
671 ## API Host, the server address of RhodeCode instance that the api_key will
671 ## API Host, the server address of RhodeCode instance that the api_key will
672 ## access
672 ## access
673 ssh.api_host = http://localhost
673 ssh.api_host = http://localhost
674
674
675 ## Paths to binary executrables, by default they are the names, but we can
675 ## Paths to binary executrables, by default they are the names, but we can
676 ## override them if we want to use a custom one
676 ## override them if we want to use a custom one
677 ssh.executable.hg = ~/.rccontrol/vcsserver-1/profile/bin/hg
677 ssh.executable.hg = ~/.rccontrol/vcsserver-1/profile/bin/hg
678 ssh.executable.git = ~/.rccontrol/vcsserver-1/profile/bin/git
678 ssh.executable.git = ~/.rccontrol/vcsserver-1/profile/bin/git
679 ssh.executable.svn = ~/.rccontrol/vcsserver-1/profile/bin/svnserve
679 ssh.executable.svn = ~/.rccontrol/vcsserver-1/profile/bin/svnserve
680
680
681
681
682 ## Dummy marker to add new entries after.
682 ## Dummy marker to add new entries after.
683 ## Add any custom entries below. Please don't remove.
683 ## Add any custom entries below. Please don't remove.
684 custom.conf = 1
684 custom.conf = 1
685
685
686
686
687 ################################
687 ################################
688 ### LOGGING CONFIGURATION ####
688 ### LOGGING CONFIGURATION ####
689 ################################
689 ################################
690 [loggers]
690 [loggers]
691 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, ssh_wrapper
691 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, ssh_wrapper
692
692
693 [handlers]
693 [handlers]
694 keys = console, console_sql
694 keys = console, console_sql
695
695
696 [formatters]
696 [formatters]
697 keys = generic, color_formatter, color_formatter_sql
697 keys = generic, color_formatter, color_formatter_sql
698
698
699 #############
699 #############
700 ## LOGGERS ##
700 ## LOGGERS ##
701 #############
701 #############
702 [logger_root]
702 [logger_root]
703 level = NOTSET
703 level = NOTSET
704 handlers = console
704 handlers = console
705
705
706 [logger_routes]
706 [logger_routes]
707 level = DEBUG
707 level = DEBUG
708 handlers =
708 handlers =
709 qualname = routes.middleware
709 qualname = routes.middleware
710 ## "level = DEBUG" logs the route matched and routing variables.
710 ## "level = DEBUG" logs the route matched and routing variables.
711 propagate = 1
711 propagate = 1
712
712
713 [logger_beaker]
713 [logger_beaker]
714 level = DEBUG
714 level = DEBUG
715 handlers =
715 handlers =
716 qualname = beaker.container
716 qualname = beaker.container
717 propagate = 1
717 propagate = 1
718
718
719 [logger_templates]
719 [logger_templates]
720 level = INFO
720 level = INFO
721 handlers =
721 handlers =
722 qualname = pylons.templating
722 qualname = pylons.templating
723 propagate = 1
723 propagate = 1
724
724
725 [logger_rhodecode]
725 [logger_rhodecode]
726 level = DEBUG
726 level = DEBUG
727 handlers =
727 handlers =
728 qualname = rhodecode
728 qualname = rhodecode
729 propagate = 1
729 propagate = 1
730
730
731 [logger_sqlalchemy]
731 [logger_sqlalchemy]
732 level = ERROR
732 level = ERROR
733 handlers = console_sql
733 handlers = console_sql
734 qualname = sqlalchemy.engine
734 qualname = sqlalchemy.engine
735 propagate = 0
735 propagate = 0
736
736
737 [logger_ssh_wrapper]
737 [logger_ssh_wrapper]
738 level = DEBUG
738 level = DEBUG
739 handlers =
739 handlers =
740 qualname = ssh_wrapper
740 qualname = ssh_wrapper
741 propagate = 1
741 propagate = 1
742
742
743
743
744 ##############
744 ##############
745 ## HANDLERS ##
745 ## HANDLERS ##
746 ##############
746 ##############
747
747
748 [handler_console]
748 [handler_console]
749 class = StreamHandler
749 class = StreamHandler
750 args = (sys.stderr,)
750 args = (sys.stderr,)
751 level = DEBUG
751 level = DEBUG
752 formatter = generic
752 formatter = generic
753
753
754 [handler_console_sql]
754 [handler_console_sql]
755 class = StreamHandler
755 class = StreamHandler
756 args = (sys.stderr,)
756 args = (sys.stderr,)
757 level = WARN
757 level = WARN
758 formatter = generic
758 formatter = generic
759
759
760 ################
760 ################
761 ## FORMATTERS ##
761 ## FORMATTERS ##
762 ################
762 ################
763
763
764 [formatter_generic]
764 [formatter_generic]
765 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
765 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
766 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
766 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
767 datefmt = %Y-%m-%d %H:%M:%S
767 datefmt = %Y-%m-%d %H:%M:%S
768
768
769 [formatter_color_formatter]
769 [formatter_color_formatter]
770 class = rhodecode.lib.logging_formatter.ColorFormatter
770 class = rhodecode.lib.logging_formatter.ColorFormatter
771 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
771 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
772 datefmt = %Y-%m-%d %H:%M:%S
772 datefmt = %Y-%m-%d %H:%M:%S
773
773
774 [formatter_color_formatter_sql]
774 [formatter_color_formatter_sql]
775 class = rhodecode.lib.logging_formatter.ColorFormatterSql
775 class = rhodecode.lib.logging_formatter.ColorFormatterSql
776 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
776 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
777 datefmt = %Y-%m-%d %H:%M:%S
777 datefmt = %Y-%m-%d %H:%M:%S
General Comments 0
You need to be logged in to leave comments. Login now