##// END OF EJS Templates
fix(tests): fixed few tests
super-admin -
r5575:521d91fe default
parent child Browse files
Show More
@@ -1,811 +1,804 b''
1
1
2 # Copyright (C) 2010-2023 RhodeCode GmbH
2 # Copyright (C) 2010-2023 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 import pytest
20 import pytest
21
21
22 from rhodecode.lib.auth import AuthUser
22 from rhodecode.lib.auth import AuthUser
23 from rhodecode.model.db import (
23 from rhodecode.model.db import (
24 RepoGroup, User, UserGroupRepoGroupToPerm, Permission, UserToPerm,
24 RepoGroup, User, UserGroupRepoGroupToPerm, Permission, UserToPerm,
25 UserGroupToPerm)
25 UserGroupToPerm)
26 from rhodecode.model.meta import Session
26 from rhodecode.model.meta import Session
27 from rhodecode.model.permission import PermissionModel
27 from rhodecode.model.permission import PermissionModel
28 from rhodecode.model.repo import RepoModel
28 from rhodecode.model.repo import RepoModel
29 from rhodecode.model.repo_group import RepoGroupModel
29 from rhodecode.model.repo_group import RepoGroupModel
30 from rhodecode.model.user import UserModel
30 from rhodecode.model.user import UserModel
31 from rhodecode.model.user_group import UserGroupModel
31 from rhodecode.model.user_group import UserGroupModel
32 from rhodecode.tests.fixture import Fixture
32 from rhodecode.tests.fixture import Fixture
33
33
34
34
35 fixture = Fixture()
35 fixture = Fixture()
36
36
37
37
38 @pytest.fixture()
38 @pytest.fixture()
39 def repo_name(backend_hg):
39 def repo_name(backend_hg):
40 return backend_hg.repo_name
40 return backend_hg.repo_name
41
41
42
42
43 class TestPermissions(object):
43 class TestPermissions(object):
44
44
45 @pytest.fixture(scope='class', autouse=True)
45 @pytest.fixture(scope='class', autouse=True)
46 def default_permissions(self, request, baseapp):
46 def default_permissions(self, request, baseapp):
47 # recreate default user to get a clean start
47 # recreate default user to get a clean start
48 PermissionModel().create_default_user_permissions(
48 PermissionModel().create_default_user_permissions(
49 user=User.DEFAULT_USER, force=True)
49 user=User.DEFAULT_USER, force=True)
50 Session().commit()
50 Session().commit()
51
51
52 @pytest.fixture(autouse=True)
52 @pytest.fixture(autouse=True)
53 def prepare_users(self, request):
53 def prepare_users(self, request):
54 # TODO: User creation is a duplicate of test_nofitications, check
54 # TODO: User creation is a duplicate of test_nofitications, check
55 # if that can be unified
55 # if that can be unified
56 self.u1 = UserModel().create_or_update(
56 self.u1 = UserModel().create_or_update(
57 username=u'u1', password=u'qweqwe',
57 username='u1', password='qweqwe',
58 email=u'u1@rhodecode.org', firstname=u'u1', lastname=u'u1'
58 email='u1@rhodecode.org', firstname='u1', lastname='u1'
59 )
59 )
60 self.u2 = UserModel().create_or_update(
60 self.u2 = UserModel().create_or_update(
61 username=u'u2', password=u'qweqwe',
61 username='u2', password='qweqwe',
62 email=u'u2@rhodecode.org', firstname=u'u2', lastname=u'u2'
62 email='u2@rhodecode.org', firstname='u2', lastname='u2'
63 )
63 )
64 self.u3 = UserModel().create_or_update(
64 self.u3 = UserModel().create_or_update(
65 username=u'u3', password=u'qweqwe',
65 username='u3', password='qweqwe',
66 email=u'u3@rhodecode.org', firstname=u'u3', lastname=u'u3'
66 email='u3@rhodecode.org', firstname='u3', lastname='u3'
67 )
67 )
68 self.anon = User.get_default_user()
68 self.anon = User.get_default_user()
69 self.a1 = UserModel().create_or_update(
69 self.a1 = UserModel().create_or_update(
70 username=u'a1', password=u'qweqwe',
70 username='a1', password='qweqwe',
71 email=u'a1@rhodecode.org', firstname=u'a1', lastname=u'a1',
71 email='a1@rhodecode.org', firstname='a1', lastname='a1',
72 admin=True
72 admin=True
73 )
73 )
74 Session().commit()
74 Session().commit()
75
75
76 request.addfinalizer(self.cleanup)
76 request.addfinalizer(self.cleanup)
77
77
78 def cleanup(self):
78 def cleanup(self):
79 if hasattr(self, 'test_repo'):
79 if hasattr(self, 'test_repo'):
80 RepoModel().delete(repo=self.test_repo)
80 RepoModel().delete(repo=self.test_repo)
81 Session().commit()
81 Session().commit()
82
82
83 if hasattr(self, 'g1'):
83 if hasattr(self, 'g1'):
84 RepoGroupModel().delete(self.g1.group_id)
84 RepoGroupModel().delete(self.g1.group_id)
85 if hasattr(self, 'g2'):
85 if hasattr(self, 'g2'):
86 RepoGroupModel().delete(self.g2.group_id)
86 RepoGroupModel().delete(self.g2.group_id)
87 Session().commit()
87 Session().commit()
88
88
89 UserModel().delete(self.u1, handle_repos='delete', handle_repo_groups='delete')
89 UserModel().delete(self.u1, handle_repos='delete', handle_repo_groups='delete')
90 UserModel().delete(self.u2, handle_repos='delete', handle_repo_groups='delete')
90 UserModel().delete(self.u2, handle_repos='delete', handle_repo_groups='delete')
91 UserModel().delete(self.u3, handle_repos='delete', handle_repo_groups='delete')
91 UserModel().delete(self.u3, handle_repos='delete', handle_repo_groups='delete')
92 UserModel().delete(self.a1, handle_repos='delete', handle_repo_groups='delete')
92 UserModel().delete(self.a1, handle_repos='delete', handle_repo_groups='delete')
93 Session().commit()
93 Session().commit()
94
94
95 if hasattr(self, 'ug1'):
95 if hasattr(self, 'ug1'):
96 UserGroupModel().delete(self.ug1, force=True)
96 UserGroupModel().delete(self.ug1, force=True)
97 Session().commit()
97 Session().commit()
98
98
99 def test_default_perms_set(self, repo_name):
99 def test_default_perms_set(self, repo_name):
100 assert repo_perms(self.u1)[repo_name] == 'repository.read'
100 assert repo_perms(self.u1)[repo_name] == 'repository.read'
101 new_perm = 'repository.write'
101 new_perm = 'repository.write'
102 RepoModel().grant_user_permission(repo=repo_name, user=self.u1,
102 RepoModel().grant_user_permission(repo=repo_name, user=self.u1,
103 perm=new_perm)
103 perm=new_perm)
104 Session().commit()
104 Session().commit()
105 assert repo_perms(self.u1)[repo_name] == new_perm
105 assert repo_perms(self.u1)[repo_name] == new_perm
106
106
107 def test_default_admin_perms_set(self, repo_name):
107 def test_default_admin_perms_set(self, repo_name):
108 assert repo_perms(self.a1)[repo_name] == 'repository.admin'
108 assert repo_perms(self.a1)[repo_name] == 'repository.admin'
109 RepoModel().grant_user_permission(repo=repo_name, user=self.a1,
109 RepoModel().grant_user_permission(repo=repo_name, user=self.a1,
110 perm='repository.write')
110 perm='repository.write')
111 Session().commit()
111 Session().commit()
112 # cannot really downgrade admins permissions !? they still gets set as
112 # cannot really downgrade admins permissions !? they still gets set as
113 # admin !
113 # admin !
114 assert repo_perms(self.a1)[repo_name] == 'repository.admin'
114 assert repo_perms(self.a1)[repo_name] == 'repository.admin'
115
115
116 def test_default_group_perms(self, repo_name):
116 def test_default_group_perms(self, repo_name):
117 self.g1 = fixture.create_repo_group('test1', skip_if_exists=True)
117 self.g1 = fixture.create_repo_group('test1', skip_if_exists=True)
118 self.g2 = fixture.create_repo_group('test2', skip_if_exists=True)
118 self.g2 = fixture.create_repo_group('test2', skip_if_exists=True)
119
119
120 assert repo_perms(self.u1)[repo_name] == 'repository.read'
120 assert repo_perms(self.u1)[repo_name] == 'repository.read'
121 assert group_perms(self.u1) == {
121 assert group_perms(self.u1) == {
122 'test1': 'group.read', 'test2': 'group.read'}
122 'test1': 'group.read', 'test2': 'group.read'}
123 assert global_perms(self.u1) == set(
123 assert global_perms(self.u1) == set(
124 Permission.DEFAULT_USER_PERMISSIONS)
124 Permission.DEFAULT_USER_PERMISSIONS)
125
125
126 def test_default_admin_group_perms(self, repo_name):
126 def test_default_admin_group_perms(self, repo_name):
127 self.g1 = fixture.create_repo_group('test1', skip_if_exists=True)
127 self.g1 = fixture.create_repo_group('test1', skip_if_exists=True)
128 self.g2 = fixture.create_repo_group('test2', skip_if_exists=True)
128 self.g2 = fixture.create_repo_group('test2', skip_if_exists=True)
129
129
130 assert repo_perms(self.a1)[repo_name] == 'repository.admin'
130 assert repo_perms(self.a1)[repo_name] == 'repository.admin'
131 assert group_perms(self.a1) == {
131 assert group_perms(self.a1) == {
132 'test1': 'group.admin', 'test2': 'group.admin'}
132 'test1': 'group.admin', 'test2': 'group.admin'}
133
133
134 def test_default_owner_repo_perms(self, backend, user_util, test_repo):
134 def test_default_owner_repo_perms(self, backend, user_util, test_repo):
135 user = user_util.create_user()
135 user = user_util.create_user()
136 repo = test_repo('minimal', backend.alias)
136 repo = test_repo('minimal', backend.alias)
137 org_owner = repo.user
137 org_owner = repo.user
138 assert repo_perms(user)[repo.repo_name] == 'repository.read'
138 assert repo_perms(user)[repo.repo_name] == 'repository.read'
139
139
140 repo.user = user
140 repo.user = user
141 assert repo_perms(user)[repo.repo_name] == 'repository.admin'
141 assert repo_perms(user)[repo.repo_name] == 'repository.admin'
142 repo.user = org_owner
142 repo.user = org_owner
143
143
144 def test_default_owner_branch_perms(self, user_util, test_user_group):
144 def test_default_owner_branch_perms(self, user_util, test_user_group):
145 user = user_util.create_user()
145 user = user_util.create_user()
146 assert branch_perms(user) == {}
146 assert branch_perms(user) == {}
147
147
148 def test_default_owner_repo_group_perms(self, user_util, test_repo_group):
148 def test_default_owner_repo_group_perms(self, user_util, test_repo_group):
149 user = user_util.create_user()
149 user = user_util.create_user()
150 org_owner = test_repo_group.user
150 org_owner = test_repo_group.user
151
151
152 assert group_perms(user)[test_repo_group.group_name] == 'group.read'
152 assert group_perms(user)[test_repo_group.group_name] == 'group.read'
153
153
154 test_repo_group.user = user
154 test_repo_group.user = user
155 assert group_perms(user)[test_repo_group.group_name] == 'group.admin'
155 assert group_perms(user)[test_repo_group.group_name] == 'group.admin'
156 test_repo_group.user = org_owner
156 test_repo_group.user = org_owner
157
157
158 def test_default_owner_user_group_perms(self, user_util, test_user_group):
158 def test_default_owner_user_group_perms(self, user_util, test_user_group):
159 user = user_util.create_user()
159 user = user_util.create_user()
160 org_owner = test_user_group.user
160 org_owner = test_user_group.user
161
161
162 assert user_group_perms(user)[test_user_group.users_group_name] == 'usergroup.read'
162 assert user_group_perms(user)[test_user_group.users_group_name] == 'usergroup.read'
163
163
164 test_user_group.user = user
164 test_user_group.user = user
165 assert user_group_perms(user)[test_user_group.users_group_name] == 'usergroup.admin'
165 assert user_group_perms(user)[test_user_group.users_group_name] == 'usergroup.admin'
166
166
167 test_user_group.user = org_owner
167 test_user_group.user = org_owner
168
168
169 def test_propagated_permissions_from_repo_group_to_private_repo(self, repo_name):
169 def test_propagated_permissions_from_repo_group_to_private_repo(self, repo_name):
170 # make group
170 # make group
171 self.g1 = fixture.create_repo_group('TOP_LEVEL', skip_if_exists=True)
171 self.g1 = fixture.create_repo_group('TOP_LEVEL', skip_if_exists=True)
172 # both perms should be read !
172 # both perms should be read !
173 assert group_perms(self.anon) == {
173 assert group_perms(self.anon) == {
174 'TOP_LEVEL': 'group.read'
174 'TOP_LEVEL': 'group.read'
175 }
175 }
176
176
177 # Create repo inside the TOP_LEVEL
177 # Create repo inside the TOP_LEVEL
178 repo_name_in_group = RepoGroup.url_sep().join([self.g1.group_name, 'test_perm_on_private_repo'])
178 repo_name_in_group = RepoGroup.url_sep().join([self.g1.group_name, 'test_perm_on_private_repo'])
179 self.test_repo = fixture.create_repo(name=repo_name_in_group,
179 self.test_repo = fixture.create_repo(name=repo_name_in_group,
180 repo_type='hg',
180 repo_type='hg',
181 repo_group=self.g1,
181 repo_group=self.g1,
182 cur_user=self.u1,)
182 cur_user=self.u1,)
183 assert repo_perms(self.anon) == {
183 assert repo_perms(self.anon)[repo_name_in_group] == 'repository.read'
184 repo_name_in_group: 'repository.read',
184 assert repo_perms(self.anon)['vcs_test_git'] == 'repository.read'
185 'vcs_test_git': 'repository.read',
185 assert repo_perms(self.anon)['vcs_test_hg'] == 'repository.read'
186 'vcs_test_hg': 'repository.read',
186 assert repo_perms(self.anon)['vcs_test_svn'] == 'repository.read'
187 'vcs_test_svn': 'repository.read',
187
188 }
189 # Now change default user permissions
188 # Now change default user permissions
190 new_perm = 'repository.write'
189 new_perm = 'repository.write'
191 perm_updates = [
190 perm_updates = [
192 [self.anon.user_id, new_perm, 'user']
191 [self.anon.user_id, new_perm, 'user']
193 ]
192 ]
194 RepoGroupModel().update_permissions(
193 RepoGroupModel().update_permissions(
195 repo_group=self.g1, perm_updates=perm_updates, recursive='all')
194 repo_group=self.g1, perm_updates=perm_updates, recursive='all')
196
195
197 Session().commit()
196 Session().commit()
198 assert repo_perms(self.anon) == {
197 assert repo_perms(self.anon)[repo_name_in_group] == new_perm
199 repo_name_in_group: new_perm,
198 assert repo_perms(self.anon)['vcs_test_git'] == 'repository.read'
200 'vcs_test_git': 'repository.read',
199 assert repo_perms(self.anon)['vcs_test_hg'] == 'repository.read'
201 'vcs_test_hg': 'repository.read',
200 assert repo_perms(self.anon)['vcs_test_svn'] == 'repository.read'
202 'vcs_test_svn': 'repository.read',
203 }
204
201
205 # NOW MARK repo as private
202 # NOW MARK repo as private
206 changes = {
203 changes = {
207 'repo_private': True
204 'repo_private': True
208 }
205 }
209 repo = RepoModel().get_by_repo_name(repo_name_in_group)
206 repo = RepoModel().get_by_repo_name(repo_name_in_group)
210 RepoModel().update(repo, **changes)
207 RepoModel().update(repo, **changes)
211 Session().commit()
208 Session().commit()
212
209
213 # Private repo sets 'none' permission for default user
210 # Private repo sets 'none' permission for default user
214 assert repo_perms(self.anon) == {
211 assert repo_perms(self.anon)[repo_name_in_group] == 'repository.none'
215 repo_name_in_group: 'repository.none',
212 assert repo_perms(self.anon)['vcs_test_git'] == 'repository.read'
216 'vcs_test_git': 'repository.read',
213 assert repo_perms(self.anon)['vcs_test_hg'] == 'repository.read'
217 'vcs_test_hg': 'repository.read',
214 assert repo_perms(self.anon)['vcs_test_svn'] == 'repository.read'
218 'vcs_test_svn': 'repository.read',
219 }
220
215
221 # apply same logic of "updated" recursive, but now the anon permissions should be not be impacted
216 # apply same logic of "updated" recursive, but now the anon permissions should be not be impacted
222 new_perm = 'repository.write'
217 new_perm = 'repository.write'
223 perm_updates = [
218 perm_updates = [
224 [self.anon.user_id, new_perm, 'user']
219 [self.anon.user_id, new_perm, 'user']
225 ]
220 ]
226 RepoGroupModel().update_permissions(
221 RepoGroupModel().update_permissions(
227 repo_group=self.g1, perm_updates=perm_updates, recursive='all')
222 repo_group=self.g1, perm_updates=perm_updates, recursive='all')
228
223
229 Session().commit()
224 Session().commit()
230 assert repo_perms(self.anon) == {
225 assert repo_perms(self.anon)[repo_name_in_group] == 'repository.none'
231 repo_name_in_group: 'repository.none',
226 assert repo_perms(self.anon)['vcs_test_git'] == 'repository.read'
232 'vcs_test_git': 'repository.read',
227 assert repo_perms(self.anon)['vcs_test_hg'] == 'repository.read'
233 'vcs_test_hg': 'repository.read',
228 assert repo_perms(self.anon)['vcs_test_svn'] == 'repository.read'
234 'vcs_test_svn': 'repository.read',
235 }
236
229
237 def test_propagated_permission_from_users_group_by_explicit_perms_exist(
230 def test_propagated_permission_from_users_group_by_explicit_perms_exist(
238 self, repo_name):
231 self, repo_name):
239 # make group
232 # make group
240 self.ug1 = fixture.create_user_group('G1')
233 self.ug1 = fixture.create_user_group('G1')
241 UserGroupModel().add_user_to_group(self.ug1, self.u1)
234 UserGroupModel().add_user_to_group(self.ug1, self.u1)
242
235
243 # set permission to lower
236 # set permission to lower
244 new_perm = 'repository.none'
237 new_perm = 'repository.none'
245 RepoModel().grant_user_permission(
238 RepoModel().grant_user_permission(
246 repo=repo_name, user=self.u1, perm=new_perm)
239 repo=repo_name, user=self.u1, perm=new_perm)
247 Session().commit()
240 Session().commit()
248 assert repo_perms(self.u1)[repo_name] == new_perm
241 assert repo_perms(self.u1)[repo_name] == new_perm
249
242
250 # grant perm for group this should not override permission from user
243 # grant perm for group this should not override permission from user
251 # since it has explicitly set
244 # since it has explicitly set
252 new_perm_gr = 'repository.write'
245 new_perm_gr = 'repository.write'
253 RepoModel().grant_user_group_permission(
246 RepoModel().grant_user_group_permission(
254 repo=repo_name, group_name=self.ug1, perm=new_perm_gr)
247 repo=repo_name, group_name=self.ug1, perm=new_perm_gr)
255 Session().commit()
248 Session().commit()
256
249
257 assert repo_perms(self.u1)[repo_name] == new_perm
250 assert repo_perms(self.u1)[repo_name] == new_perm
258 assert group_perms(self.u1) == {}
251 assert group_perms(self.u1) == {}
259
252
260 def test_propagated_permission_from_users_group(self, repo_name):
253 def test_propagated_permission_from_users_group(self, repo_name):
261 # make group
254 # make group
262 self.ug1 = fixture.create_user_group('G1')
255 self.ug1 = fixture.create_user_group('G1')
263 UserGroupModel().add_user_to_group(self.ug1, self.u3)
256 UserGroupModel().add_user_to_group(self.ug1, self.u3)
264
257
265 # grant perm for group
258 # grant perm for group
266 # this should override default permission from user
259 # this should override default permission from user
267 new_perm_gr = 'repository.write'
260 new_perm_gr = 'repository.write'
268 RepoModel().grant_user_group_permission(
261 RepoModel().grant_user_group_permission(
269 repo=repo_name, group_name=self.ug1, perm=new_perm_gr)
262 repo=repo_name, group_name=self.ug1, perm=new_perm_gr)
270 Session().commit()
263 Session().commit()
271
264
272 assert repo_perms(self.u3)[repo_name] == new_perm_gr
265 assert repo_perms(self.u3)[repo_name] == new_perm_gr
273 assert group_perms(self.u3) == {}
266 assert group_perms(self.u3) == {}
274
267
275 def test_propagated_permission_from_users_group_lower_weight(
268 def test_propagated_permission_from_users_group_lower_weight(
276 self, repo_name):
269 self, repo_name):
277 # make group with user
270 # make group with user
278 self.ug1 = fixture.create_user_group('G1')
271 self.ug1 = fixture.create_user_group('G1')
279 UserGroupModel().add_user_to_group(self.ug1, self.u1)
272 UserGroupModel().add_user_to_group(self.ug1, self.u1)
280
273
281 # set permission to lower
274 # set permission to lower
282 new_perm_h = 'repository.write'
275 new_perm_h = 'repository.write'
283 RepoModel().grant_user_permission(
276 RepoModel().grant_user_permission(
284 repo=repo_name, user=self.u1, perm=new_perm_h)
277 repo=repo_name, user=self.u1, perm=new_perm_h)
285 Session().commit()
278 Session().commit()
286
279
287 assert repo_perms(self.u1)[repo_name] == new_perm_h
280 assert repo_perms(self.u1)[repo_name] == new_perm_h
288
281
289 # grant perm for group this should NOT override permission from user
282 # grant perm for group this should NOT override permission from user
290 # since it's lower than granted
283 # since it's lower than granted
291 new_perm_l = 'repository.read'
284 new_perm_l = 'repository.read'
292 RepoModel().grant_user_group_permission(
285 RepoModel().grant_user_group_permission(
293 repo=repo_name, group_name=self.ug1, perm=new_perm_l)
286 repo=repo_name, group_name=self.ug1, perm=new_perm_l)
294 Session().commit()
287 Session().commit()
295
288
296 assert repo_perms(self.u1)[repo_name] == new_perm_h
289 assert repo_perms(self.u1)[repo_name] == new_perm_h
297 assert group_perms(self.u1) == {}
290 assert group_perms(self.u1) == {}
298
291
299 def test_repo_in_group_permissions(self):
292 def test_repo_in_group_permissions(self):
300 self.g1 = fixture.create_repo_group('group1', skip_if_exists=True)
293 self.g1 = fixture.create_repo_group('group1', skip_if_exists=True)
301 self.g2 = fixture.create_repo_group('group2', skip_if_exists=True)
294 self.g2 = fixture.create_repo_group('group2', skip_if_exists=True)
302 # both perms should be read !
295 # both perms should be read !
303 assert group_perms(self.u1) == \
296 assert group_perms(self.u1) == \
304 {u'group1': u'group.read', u'group2': u'group.read'}
297 {'group1': 'group.read', 'group2': 'group.read'}
305
298
306 assert group_perms(self.anon) == \
299 assert group_perms(self.anon) == \
307 {u'group1': u'group.read', u'group2': u'group.read'}
300 {'group1': 'group.read', 'group2': 'group.read'}
308
301
309 # Change perms to none for both groups
302 # Change perms to none for both groups
310 RepoGroupModel().grant_user_permission(
303 RepoGroupModel().grant_user_permission(
311 repo_group=self.g1, user=self.anon, perm='group.none')
304 repo_group=self.g1, user=self.anon, perm='group.none')
312 RepoGroupModel().grant_user_permission(
305 RepoGroupModel().grant_user_permission(
313 repo_group=self.g2, user=self.anon, perm='group.none')
306 repo_group=self.g2, user=self.anon, perm='group.none')
314
307
315 assert group_perms(self.u1) == \
308 assert group_perms(self.u1) == \
316 {u'group1': u'group.none', u'group2': u'group.none'}
309 {'group1': 'group.none', 'group2': 'group.none'}
317 assert group_perms(self.anon) == \
310 assert group_perms(self.anon) == \
318 {u'group1': u'group.none', u'group2': u'group.none'}
311 {'group1': 'group.none', 'group2': 'group.none'}
319
312
320 # add repo to group
313 # add repo to group
321 name = RepoGroup.url_sep().join([self.g1.group_name, 'test_perm'])
314 name = RepoGroup.url_sep().join([self.g1.group_name, 'test_perm'])
322 self.test_repo = fixture.create_repo(name=name,
315 self.test_repo = fixture.create_repo(name=name,
323 repo_type='hg',
316 repo_type='hg',
324 repo_group=self.g1,
317 repo_group=self.g1,
325 cur_user=self.u1,)
318 cur_user=self.u1,)
326
319
327 assert group_perms(self.u1) == \
320 assert group_perms(self.u1) == \
328 {u'group1': u'group.none', u'group2': u'group.none'}
321 {'group1': 'group.none', 'group2': 'group.none'}
329 assert group_perms(self.anon) == \
322 assert group_perms(self.anon) == \
330 {u'group1': u'group.none', u'group2': u'group.none'}
323 {'group1': 'group.none', 'group2': 'group.none'}
331
324
332 # grant permission for u2 !
325 # grant permission for u2 !
333 RepoGroupModel().grant_user_permission(
326 RepoGroupModel().grant_user_permission(
334 repo_group=self.g1, user=self.u2, perm='group.read')
327 repo_group=self.g1, user=self.u2, perm='group.read')
335 RepoGroupModel().grant_user_permission(
328 RepoGroupModel().grant_user_permission(
336 repo_group=self.g2, user=self.u2, perm='group.read')
329 repo_group=self.g2, user=self.u2, perm='group.read')
337 Session().commit()
330 Session().commit()
338 assert self.u1 != self.u2
331 assert self.u1 != self.u2
339
332
340 # u1 and anon should have not change perms while u2 should !
333 # u1 and anon should have not change perms while u2 should !
341 assert group_perms(self.u1) == \
334 assert group_perms(self.u1) == \
342 {u'group1': u'group.none', u'group2': u'group.none'}
335 {'group1': 'group.none', 'group2': 'group.none'}
343 assert group_perms(self.u2) == \
336 assert group_perms(self.u2) == \
344 {u'group1': u'group.read', u'group2': u'group.read'}
337 {'group1': 'group.read', 'group2': 'group.read'}
345 assert group_perms(self.anon) == \
338 assert group_perms(self.anon) == \
346 {u'group1': u'group.none', u'group2': u'group.none'}
339 {'group1': 'group.none', 'group2': 'group.none'}
347
340
348 def test_repo_group_user_as_user_group_member(self):
341 def test_repo_group_user_as_user_group_member(self):
349 # create Group1
342 # create Group1
350 self.g1 = fixture.create_repo_group('group1', skip_if_exists=True)
343 self.g1 = fixture.create_repo_group('group1', skip_if_exists=True)
351 assert group_perms(self.anon) == {u'group1': u'group.read'}
344 assert group_perms(self.anon) == {'group1': 'group.read'}
352
345
353 # set default permission to none
346 # set default permission to none
354 RepoGroupModel().grant_user_permission(
347 RepoGroupModel().grant_user_permission(
355 repo_group=self.g1, user=self.anon, perm='group.none')
348 repo_group=self.g1, user=self.anon, perm='group.none')
356 Session().commit()
349 Session().commit()
357
350
358 # make group
351 # make group
359 self.ug1 = fixture.create_user_group('G1')
352 self.ug1 = fixture.create_user_group('G1')
360 # add user to group
353 # add user to group
361 UserGroupModel().add_user_to_group(self.ug1, self.u1)
354 UserGroupModel().add_user_to_group(self.ug1, self.u1)
362 Session().commit()
355 Session().commit()
363
356
364 # check if user is in the group
357 # check if user is in the group
365 ug1 = UserGroupModel().get(self.ug1.users_group_id)
358 ug1 = UserGroupModel().get(self.ug1.users_group_id)
366 members = [x.user_id for x in ug1.members]
359 members = [x.user_id for x in ug1.members]
367 assert members == [self.u1.user_id]
360 assert members == [self.u1.user_id]
368 # add some user to that group
361 # add some user to that group
369
362
370 # check his permissions
363 # check his permissions
371 assert group_perms(self.anon) == {u'group1': u'group.none'}
364 assert group_perms(self.anon) == {'group1': 'group.none'}
372 assert group_perms(self.u1) == {u'group1': u'group.none'}
365 assert group_perms(self.u1) == {'group1': 'group.none'}
373
366
374 # grant ug1 read permissions for
367 # grant ug1 read permissions for
375 RepoGroupModel().grant_user_group_permission(
368 RepoGroupModel().grant_user_group_permission(
376 repo_group=self.g1, group_name=self.ug1, perm='group.read')
369 repo_group=self.g1, group_name=self.ug1, perm='group.read')
377 Session().commit()
370 Session().commit()
378
371
379 # check if the
372 # check if the
380 obj = Session().query(UserGroupRepoGroupToPerm)\
373 obj = Session().query(UserGroupRepoGroupToPerm)\
381 .filter(UserGroupRepoGroupToPerm.group == self.g1)\
374 .filter(UserGroupRepoGroupToPerm.group == self.g1)\
382 .filter(UserGroupRepoGroupToPerm.users_group == self.ug1)\
375 .filter(UserGroupRepoGroupToPerm.users_group == self.ug1)\
383 .scalar()
376 .scalar()
384 assert obj.permission.permission_name == 'group.read'
377 assert obj.permission.permission_name == 'group.read'
385
378
386 assert group_perms(self.anon) == {u'group1': u'group.none'}
379 assert group_perms(self.anon) == {'group1': 'group.none'}
387 assert group_perms(self.u1) == {u'group1': u'group.read'}
380 assert group_perms(self.u1) == {'group1': 'group.read'}
388
381
389 def test_inherited_permissions_from_default_on_user_enabled(self):
382 def test_inherited_permissions_from_default_on_user_enabled(self):
390 # enable fork and create on default user
383 # enable fork and create on default user
391 _form_result = {
384 _form_result = {
392 'default_repo_create': 'hg.create.repository',
385 'default_repo_create': 'hg.create.repository',
393 'default_fork_create': 'hg.fork.repository'
386 'default_fork_create': 'hg.fork.repository'
394 }
387 }
395 PermissionModel().set_new_user_perms(
388 PermissionModel().set_new_user_perms(
396 User.get_default_user(), _form_result)
389 User.get_default_user(), _form_result)
397 Session().commit()
390 Session().commit()
398
391
399 # make sure inherit flag is turned on
392 # make sure inherit flag is turned on
400 self.u1.inherit_default_permissions = True
393 self.u1.inherit_default_permissions = True
401 Session().commit()
394 Session().commit()
402
395
403 # this user will have inherited permissions from default user
396 # this user will have inherited permissions from default user
404 assert global_perms(self.u1) == default_perms()
397 assert global_perms(self.u1) == default_perms()
405
398
406 def test_inherited_permissions_from_default_on_user_disabled(self):
399 def test_inherited_permissions_from_default_on_user_disabled(self):
407 # disable fork and create on default user
400 # disable fork and create on default user
408 _form_result = {
401 _form_result = {
409 'default_repo_create': 'hg.create.none',
402 'default_repo_create': 'hg.create.none',
410 'default_fork_create': 'hg.fork.none'
403 'default_fork_create': 'hg.fork.none'
411 }
404 }
412 PermissionModel().set_new_user_perms(
405 PermissionModel().set_new_user_perms(
413 User.get_default_user(), _form_result)
406 User.get_default_user(), _form_result)
414 Session().commit()
407 Session().commit()
415
408
416 # make sure inherit flag is turned on
409 # make sure inherit flag is turned on
417 self.u1.inherit_default_permissions = True
410 self.u1.inherit_default_permissions = True
418 Session().commit()
411 Session().commit()
419
412
420 # this user will have inherited permissions from default user
413 # this user will have inherited permissions from default user
421 expected_perms = default_perms(
414 expected_perms = default_perms(
422 added=['hg.create.none', 'hg.fork.none'],
415 added=['hg.create.none', 'hg.fork.none'],
423 removed=['hg.create.repository', 'hg.fork.repository'])
416 removed=['hg.create.repository', 'hg.fork.repository'])
424 assert global_perms(self.u1) == expected_perms
417 assert global_perms(self.u1) == expected_perms
425
418
426 def test_non_inherited_permissions_from_default_on_user_enabled(self):
419 def test_non_inherited_permissions_from_default_on_user_enabled(self):
427 user_model = UserModel()
420 user_model = UserModel()
428 # enable fork and create on default user
421 # enable fork and create on default user
429 usr = User.DEFAULT_USER
422 usr = User.DEFAULT_USER
430 user_model.revoke_perm(usr, 'hg.create.none')
423 user_model.revoke_perm(usr, 'hg.create.none')
431 user_model.grant_perm(usr, 'hg.create.repository')
424 user_model.grant_perm(usr, 'hg.create.repository')
432 user_model.revoke_perm(usr, 'hg.fork.none')
425 user_model.revoke_perm(usr, 'hg.fork.none')
433 user_model.grant_perm(usr, 'hg.fork.repository')
426 user_model.grant_perm(usr, 'hg.fork.repository')
434
427
435 # disable global perms on specific user
428 # disable global perms on specific user
436 user_model.revoke_perm(self.u1, 'hg.create.repository')
429 user_model.revoke_perm(self.u1, 'hg.create.repository')
437 user_model.grant_perm(self.u1, 'hg.create.none')
430 user_model.grant_perm(self.u1, 'hg.create.none')
438 user_model.revoke_perm(self.u1, 'hg.fork.repository')
431 user_model.revoke_perm(self.u1, 'hg.fork.repository')
439 user_model.grant_perm(self.u1, 'hg.fork.none')
432 user_model.grant_perm(self.u1, 'hg.fork.none')
440
433
441 # TODO(marcink): check branch permissions now ?
434 # TODO(marcink): check branch permissions now ?
442
435
443 # make sure inherit flag is turned off
436 # make sure inherit flag is turned off
444 self.u1.inherit_default_permissions = False
437 self.u1.inherit_default_permissions = False
445 Session().commit()
438 Session().commit()
446
439
447 # this user will have non inherited permissions from he's
440 # this user will have non inherited permissions from he's
448 # explicitly set permissions
441 # explicitly set permissions
449 assert global_perms(self.u1) == {
442 assert global_perms(self.u1) == {
450 'hg.create.none',
443 'hg.create.none',
451 'hg.fork.none',
444 'hg.fork.none',
452 'hg.register.manual_activate',
445 'hg.register.manual_activate',
453 'hg.password_reset.enabled',
446 'hg.password_reset.enabled',
454 'hg.extern_activate.auto',
447 'hg.extern_activate.auto',
455 'repository.read',
448 'repository.read',
456 'group.read',
449 'group.read',
457 'usergroup.read',
450 'usergroup.read',
458 'branch.push_force',
451 'branch.push_force',
459 }
452 }
460
453
461 def test_non_inherited_permissions_from_default_on_user_disabled(self):
454 def test_non_inherited_permissions_from_default_on_user_disabled(self):
462 user_model = UserModel()
455 user_model = UserModel()
463 # disable fork and create on default user
456 # disable fork and create on default user
464 usr = User.DEFAULT_USER
457 usr = User.DEFAULT_USER
465 user_model.revoke_perm(usr, 'hg.create.repository')
458 user_model.revoke_perm(usr, 'hg.create.repository')
466 user_model.grant_perm(usr, 'hg.create.none')
459 user_model.grant_perm(usr, 'hg.create.none')
467 user_model.revoke_perm(usr, 'hg.fork.repository')
460 user_model.revoke_perm(usr, 'hg.fork.repository')
468 user_model.grant_perm(usr, 'hg.fork.none')
461 user_model.grant_perm(usr, 'hg.fork.none')
469
462
470 # enable global perms on specific user
463 # enable global perms on specific user
471 user_model.revoke_perm(self.u1, 'hg.create.none')
464 user_model.revoke_perm(self.u1, 'hg.create.none')
472 user_model.grant_perm(self.u1, 'hg.create.repository')
465 user_model.grant_perm(self.u1, 'hg.create.repository')
473 user_model.revoke_perm(self.u1, 'hg.fork.none')
466 user_model.revoke_perm(self.u1, 'hg.fork.none')
474 user_model.grant_perm(self.u1, 'hg.fork.repository')
467 user_model.grant_perm(self.u1, 'hg.fork.repository')
475
468
476 # make sure inherit flag is turned off
469 # make sure inherit flag is turned off
477 self.u1.inherit_default_permissions = False
470 self.u1.inherit_default_permissions = False
478 Session().commit()
471 Session().commit()
479
472
480 # TODO(marcink): check branch perms
473 # TODO(marcink): check branch perms
481
474
482 # this user will have non inherited permissions from he's
475 # this user will have non inherited permissions from he's
483 # explicitly set permissions
476 # explicitly set permissions
484 assert global_perms(self.u1) == {
477 assert global_perms(self.u1) == {
485 'hg.create.repository',
478 'hg.create.repository',
486 'hg.fork.repository',
479 'hg.fork.repository',
487 'hg.register.manual_activate',
480 'hg.register.manual_activate',
488 'hg.password_reset.enabled',
481 'hg.password_reset.enabled',
489 'hg.extern_activate.auto',
482 'hg.extern_activate.auto',
490 'repository.read',
483 'repository.read',
491 'group.read',
484 'group.read',
492 'usergroup.read',
485 'usergroup.read',
493 'branch.push_force',
486 'branch.push_force',
494 }
487 }
495
488
496 @pytest.mark.parametrize('perm, expected_perm', [
489 @pytest.mark.parametrize('perm, expected_perm', [
497 ('hg.inherit_default_perms.false', 'repository.none', ),
490 ('hg.inherit_default_perms.false', 'repository.none', ),
498 ('hg.inherit_default_perms.true', 'repository.read', ),
491 ('hg.inherit_default_perms.true', 'repository.read', ),
499 ])
492 ])
500 def test_inherited_permissions_on_objects(self, perm, expected_perm):
493 def test_inherited_permissions_on_objects(self, perm, expected_perm):
501 _form_result = {
494 _form_result = {
502 'default_inherit_default_permissions': perm,
495 'default_inherit_default_permissions': perm,
503 }
496 }
504 PermissionModel().set_new_user_perms(
497 PermissionModel().set_new_user_perms(
505 User.get_default_user(), _form_result)
498 User.get_default_user(), _form_result)
506 Session().commit()
499 Session().commit()
507
500
508 # make sure inherit flag is turned on
501 # make sure inherit flag is turned on
509 self.u1.inherit_default_permissions = True
502 self.u1.inherit_default_permissions = True
510 Session().commit()
503 Session().commit()
511
504
512 # TODO(marcink): check branch perms
505 # TODO(marcink): check branch perms
513
506
514 # this user will have inherited permissions from default user
507 # this user will have inherited permissions from default user
515 assert global_perms(self.u1) == {
508 assert global_perms(self.u1) == {
516 'hg.create.none',
509 'hg.create.none',
517 'hg.fork.none',
510 'hg.fork.none',
518 'hg.register.manual_activate',
511 'hg.register.manual_activate',
519 'hg.password_reset.enabled',
512 'hg.password_reset.enabled',
520 'hg.extern_activate.auto',
513 'hg.extern_activate.auto',
521 'repository.read',
514 'repository.read',
522 'group.read',
515 'group.read',
523 'usergroup.read',
516 'usergroup.read',
524 'branch.push_force',
517 'branch.push_force',
525 'hg.create.write_on_repogroup.true',
518 'hg.create.write_on_repogroup.true',
526 'hg.usergroup.create.false',
519 'hg.usergroup.create.false',
527 'hg.repogroup.create.false',
520 'hg.repogroup.create.false',
528 perm
521 perm
529 }
522 }
530
523
531 assert set(repo_perms(self.u1).values()) == set([expected_perm])
524 assert set(repo_perms(self.u1).values()) == set([expected_perm])
532
525
533 def test_repo_owner_permissions_not_overwritten_by_group(self):
526 def test_repo_owner_permissions_not_overwritten_by_group(self):
534 # create repo as USER,
527 # create repo as USER,
535 self.test_repo = fixture.create_repo(name='myownrepo',
528 self.test_repo = fixture.create_repo(name='myownrepo',
536 repo_type='hg',
529 repo_type='hg',
537 cur_user=self.u1)
530 cur_user=self.u1)
538
531
539 # he has permissions of admin as owner
532 # he has permissions of admin as owner
540 assert repo_perms(self.u1)['myownrepo'] == 'repository.admin'
533 assert repo_perms(self.u1)['myownrepo'] == 'repository.admin'
541
534
542 # set his permission as user group, he should still be admin
535 # set his permission as user group, he should still be admin
543 self.ug1 = fixture.create_user_group('G1')
536 self.ug1 = fixture.create_user_group('G1')
544 UserGroupModel().add_user_to_group(self.ug1, self.u1)
537 UserGroupModel().add_user_to_group(self.ug1, self.u1)
545 RepoModel().grant_user_group_permission(
538 RepoModel().grant_user_group_permission(
546 self.test_repo,
539 self.test_repo,
547 group_name=self.ug1,
540 group_name=self.ug1,
548 perm='repository.none')
541 perm='repository.none')
549 Session().commit()
542 Session().commit()
550
543
551 assert repo_perms(self.u1)['myownrepo'] == 'repository.admin'
544 assert repo_perms(self.u1)['myownrepo'] == 'repository.admin'
552
545
553 def test_repo_owner_permissions_not_overwritten_by_others(self):
546 def test_repo_owner_permissions_not_overwritten_by_others(self):
554 # create repo as USER,
547 # create repo as USER,
555 self.test_repo = fixture.create_repo(name='myownrepo',
548 self.test_repo = fixture.create_repo(name='myownrepo',
556 repo_type='hg',
549 repo_type='hg',
557 cur_user=self.u1)
550 cur_user=self.u1)
558
551
559 # he has permissions of admin as owner
552 # he has permissions of admin as owner
560 assert repo_perms(self.u1)['myownrepo'] == 'repository.admin'
553 assert repo_perms(self.u1)['myownrepo'] == 'repository.admin'
561
554
562 # set his permission as user, he should still be admin
555 # set his permission as user, he should still be admin
563 RepoModel().grant_user_permission(
556 RepoModel().grant_user_permission(
564 self.test_repo, user=self.u1, perm='repository.none')
557 self.test_repo, user=self.u1, perm='repository.none')
565 Session().commit()
558 Session().commit()
566
559
567 assert repo_perms(self.u1)['myownrepo'] == 'repository.admin'
560 assert repo_perms(self.u1)['myownrepo'] == 'repository.admin'
568
561
569 def test_repo_group_owner_permissions_not_overwritten_by_group(self):
562 def test_repo_group_owner_permissions_not_overwritten_by_group(self):
570 # "u1" shall be owner without any special permission assigned
563 # "u1" shall be owner without any special permission assigned
571 self.g1 = fixture.create_repo_group('test1')
564 self.g1 = fixture.create_repo_group('test1')
572
565
573 # Make user group and grant a permission to user group
566 # Make user group and grant a permission to user group
574 self.ug1 = fixture.create_user_group('G1')
567 self.ug1 = fixture.create_user_group('G1')
575 UserGroupModel().add_user_to_group(self.ug1, self.u1)
568 UserGroupModel().add_user_to_group(self.ug1, self.u1)
576 RepoGroupModel().grant_user_group_permission(
569 RepoGroupModel().grant_user_group_permission(
577 repo_group=self.g1, group_name=self.ug1, perm='group.write')
570 repo_group=self.g1, group_name=self.ug1, perm='group.write')
578 Session().commit()
571 Session().commit()
579
572
580 # Verify that user does not get any special permission if he is not
573 # Verify that user does not get any special permission if he is not
581 # owner
574 # owner
582 assert group_perms(self.u1) == {'test1': 'group.write'}
575 assert group_perms(self.u1) == {'test1': 'group.write'}
583
576
584 # Make him owner of the repo group
577 # Make him owner of the repo group
585 self.g1.user = self.u1
578 self.g1.user = self.u1
586 assert group_perms(self.u1) == {'test1': 'group.admin'}
579 assert group_perms(self.u1) == {'test1': 'group.admin'}
587
580
588 def test_repo_group_owner_permissions_not_overwritten_by_others(self):
581 def test_repo_group_owner_permissions_not_overwritten_by_others(self):
589 # "u1" shall be owner without any special permission assigned
582 # "u1" shall be owner without any special permission assigned
590 self.g1 = fixture.create_repo_group('test1')
583 self.g1 = fixture.create_repo_group('test1')
591 RepoGroupModel().grant_user_permission(
584 RepoGroupModel().grant_user_permission(
592 repo_group=self.g1, user=self.u1, perm='group.write')
585 repo_group=self.g1, user=self.u1, perm='group.write')
593 Session().commit()
586 Session().commit()
594
587
595 # Verify that user does not get any special permission if he is not
588 # Verify that user does not get any special permission if he is not
596 # owner
589 # owner
597 assert group_perms(self.u1) == {'test1': 'group.write'}
590 assert group_perms(self.u1) == {'test1': 'group.write'}
598
591
599 # Make him owner of the repo group
592 # Make him owner of the repo group
600 self.g1.user = self.u1
593 self.g1.user = self.u1
601 assert group_perms(self.u1) == {u'test1': 'group.admin'}
594 assert group_perms(self.u1) == {'test1': 'group.admin'}
602
595
603 def assert_user_perm_equal(
596 def assert_user_perm_equal(
604 self, user, change_factor=0, compare_keys=None):
597 self, user, change_factor=0, compare_keys=None):
605 perms = UserToPerm.query().filter(UserToPerm.user == user).all()
598 perms = UserToPerm.query().filter(UserToPerm.user == user).all()
606 assert len(perms) == \
599 assert len(perms) == \
607 len(Permission.DEFAULT_USER_PERMISSIONS) + change_factor
600 len(Permission.DEFAULT_USER_PERMISSIONS) + change_factor
608 if compare_keys:
601 if compare_keys:
609 assert set(
602 assert set(
610 x.permissions.permission_name for x in perms) == compare_keys
603 x.permissions.permission_name for x in perms) == compare_keys
611
604
612 def assert_def_user_group_perm_equal(
605 def assert_def_user_group_perm_equal(
613 self, user_group, change_factor=0, compare_keys=None):
606 self, user_group, change_factor=0, compare_keys=None):
614 perms = UserGroupToPerm.query().filter(
607 perms = UserGroupToPerm.query().filter(
615 UserGroupToPerm.users_group == user_group).all()
608 UserGroupToPerm.users_group == user_group).all()
616 assert len(perms) == \
609 assert len(perms) == \
617 len(Permission.DEFAULT_USER_PERMISSIONS) + change_factor
610 len(Permission.DEFAULT_USER_PERMISSIONS) + change_factor
618 if compare_keys:
611 if compare_keys:
619 assert set(
612 assert set(
620 x.permissions.permission_name for x in perms) == compare_keys
613 x.permissions.permission_name for x in perms) == compare_keys
621
614
622 def test_set_default_permissions(self):
615 def test_set_default_permissions(self):
623 PermissionModel().create_default_user_permissions(user=self.u1)
616 PermissionModel().create_default_user_permissions(user=self.u1)
624 self.assert_user_perm_equal(user=self.u1)
617 self.assert_user_perm_equal(user=self.u1)
625
618
626 def test_set_default_permissions_after_one_is_missing(self):
619 def test_set_default_permissions_after_one_is_missing(self):
627 PermissionModel().create_default_user_permissions(user=self.u1)
620 PermissionModel().create_default_user_permissions(user=self.u1)
628 self.assert_user_perm_equal(user=self.u1)
621 self.assert_user_perm_equal(user=self.u1)
629 # now we delete one, it should be re-created after another call
622 # now we delete one, it should be re-created after another call
630 perms = UserToPerm.query().filter(UserToPerm.user == self.u1).all()
623 perms = UserToPerm.query().filter(UserToPerm.user == self.u1).all()
631 Session().delete(perms[0])
624 Session().delete(perms[0])
632 Session().commit()
625 Session().commit()
633
626
634 self.assert_user_perm_equal(user=self.u1, change_factor=-1)
627 self.assert_user_perm_equal(user=self.u1, change_factor=-1)
635
628
636 # create missing one !
629 # create missing one !
637 PermissionModel().create_default_user_permissions(user=self.u1)
630 PermissionModel().create_default_user_permissions(user=self.u1)
638 self.assert_user_perm_equal(user=self.u1)
631 self.assert_user_perm_equal(user=self.u1)
639
632
640 @pytest.mark.parametrize("perm, modify_to", [
633 @pytest.mark.parametrize("perm, modify_to", [
641 ('repository.read', 'repository.none'),
634 ('repository.read', 'repository.none'),
642 ('group.read', 'group.none'),
635 ('group.read', 'group.none'),
643 ('usergroup.read', 'usergroup.none'),
636 ('usergroup.read', 'usergroup.none'),
644 ('hg.create.repository', 'hg.create.none'),
637 ('hg.create.repository', 'hg.create.none'),
645 ('hg.fork.repository', 'hg.fork.none'),
638 ('hg.fork.repository', 'hg.fork.none'),
646 ('hg.register.manual_activate', 'hg.register.auto_activate',)
639 ('hg.register.manual_activate', 'hg.register.auto_activate',)
647 ])
640 ])
648 def test_set_default_permissions_after_modification(self, perm, modify_to):
641 def test_set_default_permissions_after_modification(self, perm, modify_to):
649 PermissionModel().create_default_user_permissions(user=self.u1)
642 PermissionModel().create_default_user_permissions(user=self.u1)
650 self.assert_user_perm_equal(user=self.u1)
643 self.assert_user_perm_equal(user=self.u1)
651
644
652 old = Permission.get_by_key(perm)
645 old = Permission.get_by_key(perm)
653 new = Permission.get_by_key(modify_to)
646 new = Permission.get_by_key(modify_to)
654 assert old is not None
647 assert old is not None
655 assert new is not None
648 assert new is not None
656
649
657 # now modify permissions
650 # now modify permissions
658 p = UserToPerm.query().filter(
651 p = UserToPerm.query().filter(
659 UserToPerm.user == self.u1).filter(
652 UserToPerm.user == self.u1).filter(
660 UserToPerm.permission == old).one()
653 UserToPerm.permission == old).one()
661 p.permission = new
654 p.permission = new
662 Session().add(p)
655 Session().add(p)
663 Session().commit()
656 Session().commit()
664
657
665 PermissionModel().create_default_user_permissions(user=self.u1)
658 PermissionModel().create_default_user_permissions(user=self.u1)
666 self.assert_user_perm_equal(user=self.u1)
659 self.assert_user_perm_equal(user=self.u1)
667
660
668 def test_clear_user_perms(self):
661 def test_clear_user_perms(self):
669 PermissionModel().create_default_user_permissions(user=self.u1)
662 PermissionModel().create_default_user_permissions(user=self.u1)
670 self.assert_user_perm_equal(user=self.u1)
663 self.assert_user_perm_equal(user=self.u1)
671
664
672 # now clear permissions
665 # now clear permissions
673 cleared = PermissionModel()._clear_user_perms(self.u1.user_id)
666 cleared = PermissionModel()._clear_user_perms(self.u1.user_id)
674 self.assert_user_perm_equal(user=self.u1,
667 self.assert_user_perm_equal(user=self.u1,
675 change_factor=len(cleared)*-1)
668 change_factor=len(cleared)*-1)
676
669
677 def test_clear_user_group_perms(self):
670 def test_clear_user_group_perms(self):
678 self.ug1 = fixture.create_user_group('G1')
671 self.ug1 = fixture.create_user_group('G1')
679 PermissionModel().create_default_user_group_permissions(
672 PermissionModel().create_default_user_group_permissions(
680 user_group=self.ug1)
673 user_group=self.ug1)
681 self.assert_def_user_group_perm_equal(user_group=self.ug1)
674 self.assert_def_user_group_perm_equal(user_group=self.ug1)
682
675
683 # now clear permissions
676 # now clear permissions
684 cleared = PermissionModel()._clear_user_group_perms(
677 cleared = PermissionModel()._clear_user_group_perms(
685 self.ug1.users_group_id)
678 self.ug1.users_group_id)
686 self.assert_def_user_group_perm_equal(user_group=self.ug1,
679 self.assert_def_user_group_perm_equal(user_group=self.ug1,
687 change_factor=len(cleared)*-1)
680 change_factor=len(cleared)*-1)
688
681
689 @pytest.mark.parametrize("form_result", [
682 @pytest.mark.parametrize("form_result", [
690 {},
683 {},
691 {'default_repo_create': 'hg.create.repository'},
684 {'default_repo_create': 'hg.create.repository'},
692 {'default_repo_create': 'hg.create.repository',
685 {'default_repo_create': 'hg.create.repository',
693 'default_repo_perm': 'repository.read'},
686 'default_repo_perm': 'repository.read'},
694 {'default_repo_create': 'hg.create.none',
687 {'default_repo_create': 'hg.create.none',
695 'default_repo_perm': 'repository.write',
688 'default_repo_perm': 'repository.write',
696 'default_fork_create': 'hg.fork.none'},
689 'default_fork_create': 'hg.fork.none'},
697 ])
690 ])
698 def test_set_new_user_permissions(self, form_result):
691 def test_set_new_user_permissions(self, form_result):
699 _form_result = {}
692 _form_result = {}
700 _form_result.update(form_result)
693 _form_result.update(form_result)
701 PermissionModel().set_new_user_perms(self.u1, _form_result)
694 PermissionModel().set_new_user_perms(self.u1, _form_result)
702 Session().commit()
695 Session().commit()
703 change_factor = -1 * (len(Permission.DEFAULT_USER_PERMISSIONS)
696 change_factor = -1 * (len(Permission.DEFAULT_USER_PERMISSIONS)
704 - len(form_result.keys()))
697 - len(form_result.keys()))
705 self.assert_user_perm_equal(
698 self.assert_user_perm_equal(
706 self.u1, change_factor=change_factor)
699 self.u1, change_factor=change_factor)
707
700
708 @pytest.mark.parametrize("form_result", [
701 @pytest.mark.parametrize("form_result", [
709 {},
702 {},
710 {'default_repo_create': 'hg.create.repository'},
703 {'default_repo_create': 'hg.create.repository'},
711 {'default_repo_create': 'hg.create.repository',
704 {'default_repo_create': 'hg.create.repository',
712 'default_repo_perm': 'repository.read'},
705 'default_repo_perm': 'repository.read'},
713 {'default_repo_create': 'hg.create.none',
706 {'default_repo_create': 'hg.create.none',
714 'default_repo_perm': 'repository.write',
707 'default_repo_perm': 'repository.write',
715 'default_fork_create': 'hg.fork.none'},
708 'default_fork_create': 'hg.fork.none'},
716 ])
709 ])
717 def test_set_new_user_group_permissions(self, form_result):
710 def test_set_new_user_group_permissions(self, form_result):
718 _form_result = {}
711 _form_result = {}
719 _form_result.update(form_result)
712 _form_result.update(form_result)
720 self.ug1 = fixture.create_user_group('G1')
713 self.ug1 = fixture.create_user_group('G1')
721 PermissionModel().set_new_user_group_perms(self.ug1, _form_result)
714 PermissionModel().set_new_user_group_perms(self.ug1, _form_result)
722 Session().commit()
715 Session().commit()
723 change_factor = -1 * (len(Permission.DEFAULT_USER_PERMISSIONS)
716 change_factor = -1 * (len(Permission.DEFAULT_USER_PERMISSIONS)
724 - len(form_result.keys()))
717 - len(form_result.keys()))
725 self.assert_def_user_group_perm_equal(
718 self.assert_def_user_group_perm_equal(
726 self.ug1, change_factor=change_factor)
719 self.ug1, change_factor=change_factor)
727
720
728 @pytest.mark.parametrize("group_active, expected_perm", [
721 @pytest.mark.parametrize("group_active, expected_perm", [
729 (True, 'repository.admin'),
722 (True, 'repository.admin'),
730 (False, 'repository.read'),
723 (False, 'repository.read'),
731 ])
724 ])
732 def test_get_default_repo_perms_from_user_group_with_active_group(
725 def test_get_default_repo_perms_from_user_group_with_active_group(
733 self, backend, user_util, group_active, expected_perm):
726 self, backend, user_util, group_active, expected_perm):
734 repo = backend.create_repo()
727 repo = backend.create_repo()
735 user = user_util.create_user()
728 user = user_util.create_user()
736 user_group = user_util.create_user_group(
729 user_group = user_util.create_user_group(
737 members=[user], users_group_active=group_active)
730 members=[user], users_group_active=group_active)
738
731
739 user_util.grant_user_group_permission_to_repo(
732 user_util.grant_user_group_permission_to_repo(
740 repo, user_group, 'repository.admin')
733 repo, user_group, 'repository.admin')
741 permissions = repo_perms(user)
734 permissions = repo_perms(user)
742 repo_permission = permissions.get(repo.repo_name)
735 repo_permission = permissions.get(repo.repo_name)
743 assert repo_permission == expected_perm
736 assert repo_permission == expected_perm
744
737
745 @pytest.mark.parametrize("group_active, expected_perm", [
738 @pytest.mark.parametrize("group_active, expected_perm", [
746 (True, 'group.admin'),
739 (True, 'group.admin'),
747 (False, 'group.read')
740 (False, 'group.read')
748 ])
741 ])
749 def test_get_default_group_perms_from_user_group_with_active_group(
742 def test_get_default_group_perms_from_user_group_with_active_group(
750 self, user_util, group_active, expected_perm):
743 self, user_util, group_active, expected_perm):
751 user = user_util.create_user()
744 user = user_util.create_user()
752 repo_group = user_util.create_repo_group()
745 repo_group = user_util.create_repo_group()
753 user_group = user_util.create_user_group(
746 user_group = user_util.create_user_group(
754 members=[user], users_group_active=group_active)
747 members=[user], users_group_active=group_active)
755
748
756 user_util.grant_user_group_permission_to_repo_group(
749 user_util.grant_user_group_permission_to_repo_group(
757 repo_group, user_group, 'group.admin')
750 repo_group, user_group, 'group.admin')
758 permissions = group_perms(user)
751 permissions = group_perms(user)
759 group_permission = permissions.get(repo_group.name)
752 group_permission = permissions.get(repo_group.name)
760 assert group_permission == expected_perm
753 assert group_permission == expected_perm
761
754
762 @pytest.mark.parametrize("group_active, expected_perm", [
755 @pytest.mark.parametrize("group_active, expected_perm", [
763 (True, 'usergroup.admin'),
756 (True, 'usergroup.admin'),
764 (False, 'usergroup.read')
757 (False, 'usergroup.read')
765 ])
758 ])
766 def test_get_default_user_group_perms_from_user_group_with_active_group(
759 def test_get_default_user_group_perms_from_user_group_with_active_group(
767 self, user_util, group_active, expected_perm):
760 self, user_util, group_active, expected_perm):
768 user = user_util.create_user()
761 user = user_util.create_user()
769 user_group = user_util.create_user_group(
762 user_group = user_util.create_user_group(
770 members=[user], users_group_active=group_active)
763 members=[user], users_group_active=group_active)
771 target_user_group = user_util.create_user_group()
764 target_user_group = user_util.create_user_group()
772
765
773 user_util.grant_user_group_permission_to_user_group(
766 user_util.grant_user_group_permission_to_user_group(
774 target_user_group, user_group, 'usergroup.admin')
767 target_user_group, user_group, 'usergroup.admin')
775 permissions = user_group_perms(user)
768 permissions = user_group_perms(user)
776 group_permission = permissions.get(target_user_group.users_group_name)
769 group_permission = permissions.get(target_user_group.users_group_name)
777 assert group_permission == expected_perm
770 assert group_permission == expected_perm
778
771
779
772
780 def repo_perms(user):
773 def repo_perms(user):
781 auth_user = AuthUser(user_id=user.user_id)
774 auth_user = AuthUser(user_id=user.user_id)
782 return auth_user.permissions['repositories']
775 return auth_user.permissions['repositories']
783
776
784
777
785 def branch_perms(user):
778 def branch_perms(user):
786 auth_user = AuthUser(user_id=user.user_id)
779 auth_user = AuthUser(user_id=user.user_id)
787 return auth_user.permissions['repository_branches']
780 return auth_user.permissions['repository_branches']
788
781
789
782
790 def group_perms(user):
783 def group_perms(user):
791 auth_user = AuthUser(user_id=user.user_id)
784 auth_user = AuthUser(user_id=user.user_id)
792 return auth_user.permissions['repositories_groups']
785 return auth_user.permissions['repositories_groups']
793
786
794
787
795 def user_group_perms(user):
788 def user_group_perms(user):
796 auth_user = AuthUser(user_id=user.user_id)
789 auth_user = AuthUser(user_id=user.user_id)
797 return auth_user.permissions['user_groups']
790 return auth_user.permissions['user_groups']
798
791
799
792
800 def global_perms(user):
793 def global_perms(user):
801 auth_user = AuthUser(user_id=user.user_id)
794 auth_user = AuthUser(user_id=user.user_id)
802 return auth_user.permissions['global']
795 return auth_user.permissions['global']
803
796
804
797
805 def default_perms(added=None, removed=None):
798 def default_perms(added=None, removed=None):
806 expected_perms = set(Permission.DEFAULT_USER_PERMISSIONS)
799 expected_perms = set(Permission.DEFAULT_USER_PERMISSIONS)
807 if removed:
800 if removed:
808 expected_perms.difference_update(removed)
801 expected_perms.difference_update(removed)
809 if added:
802 if added:
810 expected_perms.update(added)
803 expected_perms.update(added)
811 return expected_perms
804 return expected_perms
@@ -1,897 +1,897 b''
1
1
2 ; #########################################
2 ; #########################################
3 ; RHODECODE COMMUNITY EDITION CONFIGURATION
3 ; RHODECODE COMMUNITY EDITION CONFIGURATION
4 ; #########################################
4 ; #########################################
5
5
6 [DEFAULT]
6 [DEFAULT]
7 ; Debug flag sets all loggers to debug, and enables request tracking
7 ; Debug flag sets all loggers to debug, and enables request tracking
8 debug = true
8 debug = true
9
9
10 ; ########################################################################
10 ; ########################################################################
11 ; EMAIL CONFIGURATION
11 ; EMAIL CONFIGURATION
12 ; These settings will be used by the RhodeCode mailing system
12 ; These settings will be used by the RhodeCode mailing system
13 ; ########################################################################
13 ; ########################################################################
14
14
15 ; prefix all emails subjects with given prefix, helps filtering out emails
15 ; prefix all emails subjects with given prefix, helps filtering out emails
16 #email_prefix = [RhodeCode]
16 #email_prefix = [RhodeCode]
17
17
18 ; email FROM address all mails will be sent
18 ; email FROM address all mails will be sent
19 #app_email_from = rhodecode-noreply@localhost
19 #app_email_from = rhodecode-noreply@localhost
20
20
21 #smtp_server = mail.server.com
21 #smtp_server = mail.server.com
22 #smtp_username =
22 #smtp_username =
23 #smtp_password =
23 #smtp_password =
24 #smtp_port =
24 #smtp_port =
25 #smtp_use_tls = false
25 #smtp_use_tls = false
26 #smtp_use_ssl = true
26 #smtp_use_ssl = true
27
27
28 [server:main]
28 [server:main]
29 ; COMMON HOST/IP CONFIG, This applies mostly to develop setup,
29 ; COMMON HOST/IP CONFIG, This applies mostly to develop setup,
30 ; Host port for gunicorn are controlled by gunicorn_conf.py
30 ; Host port for gunicorn are controlled by gunicorn_conf.py
31 host = 127.0.0.1
31 host = 127.0.0.1
32 port = 10020
32 port = 10020
33
33
34
34
35 ; ###########################
35 ; ###########################
36 ; GUNICORN APPLICATION SERVER
36 ; GUNICORN APPLICATION SERVER
37 ; ###########################
37 ; ###########################
38
38
39 ; run with gunicorn --config gunicorn_conf.py --paste rhodecode.ini
39 ; run with gunicorn --config gunicorn_conf.py --paste rhodecode.ini
40
40
41 ; Module to use, this setting shouldn't be changed
41 ; Module to use, this setting shouldn't be changed
42 use = egg:gunicorn#main
42 use = egg:gunicorn#main
43
43
44 ; Prefix middleware for RhodeCode.
44 ; Prefix middleware for RhodeCode.
45 ; recommended when using proxy setup.
45 ; recommended when using proxy setup.
46 ; allows to set RhodeCode under a prefix in server.
46 ; allows to set RhodeCode under a prefix in server.
47 ; eg https://server.com/custom_prefix. Enable `filter-with =` option below as well.
47 ; eg https://server.com/custom_prefix. Enable `filter-with =` option below as well.
48 ; And set your prefix like: `prefix = /custom_prefix`
48 ; And set your prefix like: `prefix = /custom_prefix`
49 ; be sure to also set beaker.session.cookie_path = /custom_prefix if you need
49 ; be sure to also set beaker.session.cookie_path = /custom_prefix if you need
50 ; to make your cookies only work on prefix url
50 ; to make your cookies only work on prefix url
51 [filter:proxy-prefix]
51 [filter:proxy-prefix]
52 use = egg:PasteDeploy#prefix
52 use = egg:PasteDeploy#prefix
53 prefix = /
53 prefix = /
54
54
55 [app:main]
55 [app:main]
56 ; The %(here)s variable will be replaced with the absolute path of parent directory
56 ; The %(here)s variable will be replaced with the absolute path of parent directory
57 ; of this file
57 ; of this file
58 ; Each option in the app:main can be override by an environmental variable
58 ; Each option in the app:main can be override by an environmental variable
59 ;
59 ;
60 ;To override an option:
60 ;To override an option:
61 ;
61 ;
62 ;RC_<KeyName>
62 ;RC_<KeyName>
63 ;Everything should be uppercase, . and - should be replaced by _.
63 ;Everything should be uppercase, . and - should be replaced by _.
64 ;For example, if you have these configuration settings:
64 ;For example, if you have these configuration settings:
65 ;rc_cache.repo_object.backend = foo
65 ;rc_cache.repo_object.backend = foo
66 ;can be overridden by
66 ;can be overridden by
67 ;export RC_CACHE_REPO_OBJECT_BACKEND=foo
67 ;export RC_CACHE_REPO_OBJECT_BACKEND=foo
68
68
69 use = egg:rhodecode-enterprise-ce
69 use = egg:rhodecode-enterprise-ce
70
70
71 ; enable proxy prefix middleware, defined above
71 ; enable proxy prefix middleware, defined above
72 #filter-with = proxy-prefix
72 #filter-with = proxy-prefix
73
73
74 ; control if environmental variables to be expanded into the .ini settings
74 ; control if environmental variables to be expanded into the .ini settings
75 rhodecode.env_expand = false
75 rhodecode.env_expand = false
76
76
77 ; encryption key used to encrypt social plugin tokens,
77 ; encryption key used to encrypt social plugin tokens,
78 ; remote_urls with credentials etc, if not set it defaults to
78 ; remote_urls with credentials etc, if not set it defaults to
79 ; `beaker.session.secret`
79 ; `beaker.session.secret`
80 #rhodecode.encrypted_values.secret =
80 #rhodecode.encrypted_values.secret =
81
81
82 ; decryption strict mode (enabled by default). It controls if decryption raises
82 ; decryption strict mode (enabled by default). It controls if decryption raises
83 ; `SignatureVerificationError` in case of wrong key, or damaged encryption data.
83 ; `SignatureVerificationError` in case of wrong key, or damaged encryption data.
84 #rhodecode.encrypted_values.strict = false
84 #rhodecode.encrypted_values.strict = false
85
85
86 ; Pick algorithm for encryption. Either fernet (more secure) or aes (default)
86 ; Pick algorithm for encryption. Either fernet (more secure) or aes (default)
87 ; fernet is safer, and we strongly recommend switching to it.
87 ; fernet is safer, and we strongly recommend switching to it.
88 ; Due to backward compatibility aes is used as default.
88 ; Due to backward compatibility aes is used as default.
89 #rhodecode.encrypted_values.algorithm = fernet
89 #rhodecode.encrypted_values.algorithm = fernet
90
90
91 ; Return gzipped responses from RhodeCode (static files/application)
91 ; Return gzipped responses from RhodeCode (static files/application)
92 gzip_responses = false
92 gzip_responses = false
93
93
94 ; Auto-generate javascript routes file on startup
94 ; Auto-generate javascript routes file on startup
95 generate_js_files = false
95 generate_js_files = false
96
96
97 ; System global default language.
97 ; System global default language.
98 ; All available languages: en (default), be, de, es, fr, it, ja, pl, pt, ru, zh
98 ; All available languages: en (default), be, de, es, fr, it, ja, pl, pt, ru, zh
99 lang = en
99 lang = en
100
100
101 ; Perform a full repository scan and import on each server start.
101 ; Perform a full repository scan and import on each server start.
102 ; Settings this to true could lead to very long startup time.
102 ; Settings this to true could lead to very long startup time.
103 startup.import_repos = true
103 startup.import_repos = true
104
104
105 ; URL at which the application is running. This is used for Bootstrapping
105 ; URL at which the application is running. This is used for Bootstrapping
106 ; requests in context when no web request is available. Used in ishell, or
106 ; requests in context when no web request is available. Used in ishell, or
107 ; SSH calls. Set this for events to receive proper url for SSH calls.
107 ; SSH calls. Set this for events to receive proper url for SSH calls.
108 app.base_url = http://rhodecode.local
108 app.base_url = http://rhodecode.local
109
109
110 ; Host at which the Service API is running.
110 ; Host at which the Service API is running.
111 app.service_api.host = http://rhodecode.local:10020
111 app.service_api.host = http://rhodecode.local:10020
112
112
113 ; Secret for Service API authentication.
113 ; Secret for Service API authentication.
114 app.service_api.token =
114 app.service_api.token =
115
115
116 ; Unique application ID. Should be a random unique string for security.
116 ; Unique application ID. Should be a random unique string for security.
117 app_instance_uuid = rc-production
117 app_instance_uuid = rc-production
118
118
119 ; Cut off limit for large diffs (size in bytes). If overall diff size on
119 ; Cut off limit for large diffs (size in bytes). If overall diff size on
120 ; commit, or pull request exceeds this limit this diff will be displayed
120 ; commit, or pull request exceeds this limit this diff will be displayed
121 ; partially. E.g 512000 == 512Kb
121 ; partially. E.g 512000 == 512Kb
122 cut_off_limit_diff = 1024000
122 cut_off_limit_diff = 1024000
123
123
124 ; Cut off limit for large files inside diffs (size in bytes). Each individual
124 ; Cut off limit for large files inside diffs (size in bytes). Each individual
125 ; file inside diff which exceeds this limit will be displayed partially.
125 ; file inside diff which exceeds this limit will be displayed partially.
126 ; E.g 128000 == 128Kb
126 ; E.g 128000 == 128Kb
127 cut_off_limit_file = 256000
127 cut_off_limit_file = 256000
128
128
129 ; Use cached version of vcs repositories everywhere. Recommended to be `true`
129 ; Use cached version of vcs repositories everywhere. Recommended to be `true`
130 vcs_full_cache = false
130 vcs_full_cache = false
131
131
132 ; Force https in RhodeCode, fixes https redirects, assumes it's always https.
132 ; Force https in RhodeCode, fixes https redirects, assumes it's always https.
133 ; Normally this is controlled by proper flags sent from http server such as Nginx or Apache
133 ; Normally this is controlled by proper flags sent from http server such as Nginx or Apache
134 force_https = false
134 force_https = false
135
135
136 ; use Strict-Transport-Security headers
136 ; use Strict-Transport-Security headers
137 use_htsts = false
137 use_htsts = false
138
138
139 ; Set to true if your repos are exposed using the dumb protocol
139 ; Set to true if your repos are exposed using the dumb protocol
140 git_update_server_info = false
140 git_update_server_info = false
141
141
142 ; RSS/ATOM feed options
142 ; RSS/ATOM feed options
143 rss_cut_off_limit = 256000
143 rss_cut_off_limit = 256000
144 rss_items_per_page = 10
144 rss_items_per_page = 10
145 rss_include_diff = false
145 rss_include_diff = false
146
146
147 ; gist URL alias, used to create nicer urls for gist. This should be an
147 ; gist URL alias, used to create nicer urls for gist. This should be an
148 ; url that does rewrites to _admin/gists/{gistid}.
148 ; url that does rewrites to _admin/gists/{gistid}.
149 ; example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
149 ; example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
150 ; RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/{gistid}
150 ; RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/{gistid}
151 gist_alias_url =
151 gist_alias_url =
152
152
153 ; List of views (using glob pattern syntax) that AUTH TOKENS could be
153 ; List of views (using glob pattern syntax) that AUTH TOKENS could be
154 ; used for access.
154 ; used for access.
155 ; Adding ?auth_token=TOKEN_HASH to the url authenticates this request as if it
155 ; Adding ?auth_token=TOKEN_HASH to the url authenticates this request as if it
156 ; came from the the logged in user who own this authentication token.
156 ; came from the the logged in user who own this authentication token.
157 ; Additionally @TOKEN syntax can be used to bound the view to specific
157 ; Additionally @TOKEN syntax can be used to bound the view to specific
158 ; authentication token. Such view would be only accessible when used together
158 ; authentication token. Such view would be only accessible when used together
159 ; with this authentication token
159 ; with this authentication token
160 ; list of all views can be found under `/_admin/permissions/auth_token_access`
160 ; list of all views can be found under `/_admin/permissions/auth_token_access`
161 ; The list should be "," separated and on a single line.
161 ; The list should be "," separated and on a single line.
162 ; Most common views to enable:
162 ; Most common views to enable:
163
163
164 # RepoCommitsView:repo_commit_download
164 # RepoCommitsView:repo_commit_download
165 # RepoCommitsView:repo_commit_patch
165 # RepoCommitsView:repo_commit_patch
166 # RepoCommitsView:repo_commit_raw
166 # RepoCommitsView:repo_commit_raw
167 # RepoCommitsView:repo_commit_raw@TOKEN
167 # RepoCommitsView:repo_commit_raw@TOKEN
168 # RepoFilesView:repo_files_diff
168 # RepoFilesView:repo_files_diff
169 # RepoFilesView:repo_archivefile
169 # RepoFilesView:repo_archivefile
170 # RepoFilesView:repo_file_raw
170 # RepoFilesView:repo_file_raw
171 # GistView:*
171 # GistView:*
172 api_access_controllers_whitelist =
172 api_access_controllers_whitelist =
173
173
174 ; Default encoding used to convert from and to unicode
174 ; Default encoding used to convert from and to unicode
175 ; can be also a comma separated list of encoding in case of mixed encodings
175 ; can be also a comma separated list of encoding in case of mixed encodings
176 default_encoding = UTF-8
176 default_encoding = UTF-8
177
177
178 ; instance-id prefix
178 ; instance-id prefix
179 ; a prefix key for this instance used for cache invalidation when running
179 ; a prefix key for this instance used for cache invalidation when running
180 ; multiple instances of RhodeCode, make sure it's globally unique for
180 ; multiple instances of RhodeCode, make sure it's globally unique for
181 ; all running RhodeCode instances. Leave empty if you don't use it
181 ; all running RhodeCode instances. Leave empty if you don't use it
182 instance_id =
182 instance_id =
183
183
184 ; Fallback authentication plugin. Set this to a plugin ID to force the usage
184 ; Fallback authentication plugin. Set this to a plugin ID to force the usage
185 ; of an authentication plugin also if it is disabled by it's settings.
185 ; of an authentication plugin also if it is disabled by it's settings.
186 ; This could be useful if you are unable to log in to the system due to broken
186 ; This could be useful if you are unable to log in to the system due to broken
187 ; authentication settings. Then you can enable e.g. the internal RhodeCode auth
187 ; authentication settings. Then you can enable e.g. the internal RhodeCode auth
188 ; module to log in again and fix the settings.
188 ; module to log in again and fix the settings.
189 ; Available builtin plugin IDs (hash is part of the ID):
189 ; Available builtin plugin IDs (hash is part of the ID):
190 ; egg:rhodecode-enterprise-ce#rhodecode
190 ; egg:rhodecode-enterprise-ce#rhodecode
191 ; egg:rhodecode-enterprise-ce#pam
191 ; egg:rhodecode-enterprise-ce#pam
192 ; egg:rhodecode-enterprise-ce#ldap
192 ; egg:rhodecode-enterprise-ce#ldap
193 ; egg:rhodecode-enterprise-ce#jasig_cas
193 ; egg:rhodecode-enterprise-ce#jasig_cas
194 ; egg:rhodecode-enterprise-ce#headers
194 ; egg:rhodecode-enterprise-ce#headers
195 ; egg:rhodecode-enterprise-ce#crowd
195 ; egg:rhodecode-enterprise-ce#crowd
196
196
197 #rhodecode.auth_plugin_fallback = egg:rhodecode-enterprise-ce#rhodecode
197 #rhodecode.auth_plugin_fallback = egg:rhodecode-enterprise-ce#rhodecode
198
198
199 ; Flag to control loading of legacy plugins in py:/path format
199 ; Flag to control loading of legacy plugins in py:/path format
200 auth_plugin.import_legacy_plugins = true
200 auth_plugin.import_legacy_plugins = true
201
201
202 ; alternative return HTTP header for failed authentication. Default HTTP
202 ; alternative return HTTP header for failed authentication. Default HTTP
203 ; response is 401 HTTPUnauthorized. Currently HG clients have troubles with
203 ; response is 401 HTTPUnauthorized. Currently HG clients have troubles with
204 ; handling that causing a series of failed authentication calls.
204 ; handling that causing a series of failed authentication calls.
205 ; Set this variable to 403 to return HTTPForbidden, or any other HTTP code
205 ; Set this variable to 403 to return HTTPForbidden, or any other HTTP code
206 ; This will be served instead of default 401 on bad authentication
206 ; This will be served instead of default 401 on bad authentication
207 auth_ret_code =
207 auth_ret_code =
208
208
209 ; use special detection method when serving auth_ret_code, instead of serving
209 ; use special detection method when serving auth_ret_code, instead of serving
210 ; ret_code directly, use 401 initially (Which triggers credentials prompt)
210 ; ret_code directly, use 401 initially (Which triggers credentials prompt)
211 ; and then serve auth_ret_code to clients
211 ; and then serve auth_ret_code to clients
212 auth_ret_code_detection = false
212 auth_ret_code_detection = false
213
213
214 ; locking return code. When repository is locked return this HTTP code. 2XX
214 ; locking return code. When repository is locked return this HTTP code. 2XX
215 ; codes don't break the transactions while 4XX codes do
215 ; codes don't break the transactions while 4XX codes do
216 lock_ret_code = 423
216 lock_ret_code = 423
217
217
218 ; Filesystem location were repositories should be stored
218 ; Filesystem location were repositories should be stored
219 repo_store.path = /var/opt/rhodecode_repo_store
219 repo_store.path = /var/opt/rhodecode_repo_store
220
220
221 ; allows to setup custom hooks in settings page
221 ; allows to setup custom hooks in settings page
222 allow_custom_hooks_settings = true
222 allow_custom_hooks_settings = true
223
223
224 ; Generated license token required for EE edition license.
224 ; Generated license token required for EE edition license.
225 ; New generated token value can be found in Admin > settings > license page.
225 ; New generated token value can be found in Admin > settings > license page.
226 license_token = abra-cada-bra1-rce3
226 license_token = abra-cada-bra1-rce3
227
227
228 ; This flag hides sensitive information on the license page such as token, and license data
228 ; This flag hides sensitive information on the license page such as token, and license data
229 license.hide_license_info = false
229 license.hide_license_info = false
230
230
231 ; Import EE license from this license path
231 ; Import EE license from this license path
232 #license.import_path = %(here)s/rhodecode_enterprise.license
232 license.import_path = %(here)s/rhodecode_enterprise.license
233
233
234 ; import license 'if-missing' or 'force' (always override)
234 ; import license 'if-missing' or 'force' (always override)
235 ; if-missing means apply license if it doesn't exist. 'force' option always overrides it
235 ; if-missing means apply license if it doesn't exist. 'force' option always overrides it
236 license.import_path_mode = if-missing
236 license.import_path_mode = if-missing
237
237
238 ; supervisor connection uri, for managing supervisor and logs.
238 ; supervisor connection uri, for managing supervisor and logs.
239 supervisor.uri =
239 supervisor.uri =
240
240
241 ; supervisord group name/id we only want this RC instance to handle
241 ; supervisord group name/id we only want this RC instance to handle
242 supervisor.group_id = dev
242 supervisor.group_id = dev
243
243
244 ; Display extended labs settings
244 ; Display extended labs settings
245 labs_settings_active = true
245 labs_settings_active = true
246
246
247 ; Custom exception store path, defaults to TMPDIR
247 ; Custom exception store path, defaults to TMPDIR
248 ; This is used to store exception from RhodeCode in shared directory
248 ; This is used to store exception from RhodeCode in shared directory
249 #exception_tracker.store_path =
249 #exception_tracker.store_path =
250
250
251 ; Send email with exception details when it happens
251 ; Send email with exception details when it happens
252 #exception_tracker.send_email = false
252 #exception_tracker.send_email = false
253
253
254 ; Comma separated list of recipients for exception emails,
254 ; Comma separated list of recipients for exception emails,
255 ; e.g admin@rhodecode.com,devops@rhodecode.com
255 ; e.g admin@rhodecode.com,devops@rhodecode.com
256 ; Can be left empty, then emails will be sent to ALL super-admins
256 ; Can be left empty, then emails will be sent to ALL super-admins
257 #exception_tracker.send_email_recipients =
257 #exception_tracker.send_email_recipients =
258
258
259 ; optional prefix to Add to email Subject
259 ; optional prefix to Add to email Subject
260 #exception_tracker.email_prefix = [RHODECODE ERROR]
260 #exception_tracker.email_prefix = [RHODECODE ERROR]
261
261
262 ; NOTE: this setting IS DEPRECATED:
262 ; NOTE: this setting IS DEPRECATED:
263 ; file_store backend is always enabled
263 ; file_store backend is always enabled
264 #file_store.enabled = true
264 #file_store.enabled = true
265
265
266 ; NOTE: this setting IS DEPRECATED:
266 ; NOTE: this setting IS DEPRECATED:
267 ; file_store.backend = X -> use `file_store.backend.type = filesystem_v2` instead
267 ; file_store.backend = X -> use `file_store.backend.type = filesystem_v2` instead
268 ; Storage backend, available options are: local
268 ; Storage backend, available options are: local
269 #file_store.backend = local
269 #file_store.backend = local
270
270
271 ; NOTE: this setting IS DEPRECATED:
271 ; NOTE: this setting IS DEPRECATED:
272 ; file_store.storage_path = X -> use `file_store.filesystem_v2.storage_path = X` instead
272 ; file_store.storage_path = X -> use `file_store.filesystem_v2.storage_path = X` instead
273 ; path to store the uploaded binaries and artifacts
273 ; path to store the uploaded binaries and artifacts
274 #file_store.storage_path = /var/opt/rhodecode_data/file_store
274 #file_store.storage_path = /var/opt/rhodecode_data/file_store
275
275
276 ; Artifacts file-store, is used to store comment attachments and artifacts uploads.
276 ; Artifacts file-store, is used to store comment attachments and artifacts uploads.
277 ; file_store backend type: filesystem_v1, filesystem_v2 or objectstore (s3-based) are available as options
277 ; file_store backend type: filesystem_v1, filesystem_v2 or objectstore (s3-based) are available as options
278 ; filesystem_v1 is backwards compat with pre 5.1 storage changes
278 ; filesystem_v1 is backwards compat with pre 5.1 storage changes
279 ; new installations should choose filesystem_v2 or objectstore (s3-based), pick filesystem when migrating from
279 ; new installations should choose filesystem_v2 or objectstore (s3-based), pick filesystem when migrating from
280 ; previous installations to keep the artifacts without a need of migration
280 ; previous installations to keep the artifacts without a need of migration
281 file_store.backend.type = filesystem_v1
281 file_store.backend.type = filesystem_v1
282
282
283 ; filesystem options...
283 ; filesystem options...
284 file_store.filesystem_v1.storage_path = /var/opt/rhodecode_data/test_artifacts_file_store
284 file_store.filesystem_v1.storage_path = /var/opt/rhodecode_data/test_artifacts_file_store
285
285
286 ; filesystem_v2 options...
286 ; filesystem_v2 options...
287 file_store.filesystem_v2.storage_path = /var/opt/rhodecode_data/test_artifacts_file_store_2
287 file_store.filesystem_v2.storage_path = /var/opt/rhodecode_data/test_artifacts_file_store_2
288 file_store.filesystem_v2.shards = 8
288 file_store.filesystem_v2.shards = 8
289
289
290 ; objectstore options...
290 ; objectstore options...
291 ; url for s3 compatible storage that allows to upload artifacts
291 ; url for s3 compatible storage that allows to upload artifacts
292 ; e.g http://minio:9000
292 ; e.g http://minio:9000
293 #file_store.backend.type = objectstore
293 #file_store.backend.type = objectstore
294 file_store.objectstore.url = http://s3-minio:9000
294 file_store.objectstore.url = http://s3-minio:9000
295
295
296 ; a top-level bucket to put all other shards in
296 ; a top-level bucket to put all other shards in
297 ; objects will be stored in rhodecode-file-store/shard-N based on the bucket_shards number
297 ; objects will be stored in rhodecode-file-store/shard-N based on the bucket_shards number
298 file_store.objectstore.bucket = rhodecode-file-store-tests
298 file_store.objectstore.bucket = rhodecode-file-store-tests
299
299
300 ; number of sharded buckets to create to distribute archives across
300 ; number of sharded buckets to create to distribute archives across
301 ; default is 8 shards
301 ; default is 8 shards
302 file_store.objectstore.bucket_shards = 8
302 file_store.objectstore.bucket_shards = 8
303
303
304 ; key for s3 auth
304 ; key for s3 auth
305 file_store.objectstore.key = s3admin
305 file_store.objectstore.key = s3admin
306
306
307 ; secret for s3 auth
307 ; secret for s3 auth
308 file_store.objectstore.secret = s3secret4
308 file_store.objectstore.secret = s3secret4
309
309
310 ;region for s3 storage
310 ;region for s3 storage
311 file_store.objectstore.region = eu-central-1
311 file_store.objectstore.region = eu-central-1
312
312
313 ; Redis url to acquire/check generation of archives locks
313 ; Redis url to acquire/check generation of archives locks
314 archive_cache.locking.url = redis://redis:6379/1
314 archive_cache.locking.url = redis://redis:6379/1
315
315
316 ; Storage backend, only 'filesystem' and 'objectstore' are available now
316 ; Storage backend, only 'filesystem' and 'objectstore' are available now
317 archive_cache.backend.type = filesystem
317 archive_cache.backend.type = filesystem
318
318
319 ; url for s3 compatible storage that allows to upload artifacts
319 ; url for s3 compatible storage that allows to upload artifacts
320 ; e.g http://minio:9000
320 ; e.g http://minio:9000
321 archive_cache.objectstore.url = http://s3-minio:9000
321 archive_cache.objectstore.url = http://s3-minio:9000
322
322
323 ; key for s3 auth
323 ; key for s3 auth
324 archive_cache.objectstore.key = key
324 archive_cache.objectstore.key = key
325
325
326 ; secret for s3 auth
326 ; secret for s3 auth
327 archive_cache.objectstore.secret = secret
327 archive_cache.objectstore.secret = secret
328
328
329 ;region for s3 storage
329 ;region for s3 storage
330 archive_cache.objectstore.region = eu-central-1
330 archive_cache.objectstore.region = eu-central-1
331
331
332 ; number of sharded buckets to create to distribute archives across
332 ; number of sharded buckets to create to distribute archives across
333 ; default is 8 shards
333 ; default is 8 shards
334 archive_cache.objectstore.bucket_shards = 8
334 archive_cache.objectstore.bucket_shards = 8
335
335
336 ; a top-level bucket to put all other shards in
336 ; a top-level bucket to put all other shards in
337 ; objects will be stored in rhodecode-archive-cache/shard-N based on the bucket_shards number
337 ; objects will be stored in rhodecode-archive-cache/shard-N based on the bucket_shards number
338 archive_cache.objectstore.bucket = rhodecode-archive-cache
338 archive_cache.objectstore.bucket = rhodecode-archive-cache
339
339
340 ; if true, this cache will try to retry with retry_attempts=N times waiting retry_backoff time
340 ; if true, this cache will try to retry with retry_attempts=N times waiting retry_backoff time
341 archive_cache.objectstore.retry = false
341 archive_cache.objectstore.retry = false
342
342
343 ; number of seconds to wait for next try using retry
343 ; number of seconds to wait for next try using retry
344 archive_cache.objectstore.retry_backoff = 1
344 archive_cache.objectstore.retry_backoff = 1
345
345
346 ; how many tries do do a retry fetch from this backend
346 ; how many tries do do a retry fetch from this backend
347 archive_cache.objectstore.retry_attempts = 10
347 archive_cache.objectstore.retry_attempts = 10
348
348
349 ; Default is $cache_dir/archive_cache if not set
349 ; Default is $cache_dir/archive_cache if not set
350 ; Generated repo archives will be cached at this location
350 ; Generated repo archives will be cached at this location
351 ; and served from the cache during subsequent requests for the same archive of
351 ; and served from the cache during subsequent requests for the same archive of
352 ; the repository. This path is important to be shared across filesystems and with
352 ; the repository. This path is important to be shared across filesystems and with
353 ; RhodeCode and vcsserver
353 ; RhodeCode and vcsserver
354 archive_cache.filesystem.store_dir = %(here)s/rc-tests/archive_cache
354 archive_cache.filesystem.store_dir = %(here)s/rc-tests/archive_cache
355
355
356 ; The limit in GB sets how much data we cache before recycling last used, defaults to 10 gb
356 ; The limit in GB sets how much data we cache before recycling last used, defaults to 10 gb
357 archive_cache.filesystem.cache_size_gb = 2
357 archive_cache.filesystem.cache_size_gb = 2
358
358
359 ; Eviction policy used to clear out after cache_size_gb limit is reached
359 ; Eviction policy used to clear out after cache_size_gb limit is reached
360 archive_cache.filesystem.eviction_policy = least-recently-stored
360 archive_cache.filesystem.eviction_policy = least-recently-stored
361
361
362 ; By default cache uses sharding technique, this specifies how many shards are there
362 ; By default cache uses sharding technique, this specifies how many shards are there
363 ; default is 8 shards
363 ; default is 8 shards
364 archive_cache.filesystem.cache_shards = 8
364 archive_cache.filesystem.cache_shards = 8
365
365
366 ; if true, this cache will try to retry with retry_attempts=N times waiting retry_backoff time
366 ; if true, this cache will try to retry with retry_attempts=N times waiting retry_backoff time
367 archive_cache.filesystem.retry = false
367 archive_cache.filesystem.retry = false
368
368
369 ; number of seconds to wait for next try using retry
369 ; number of seconds to wait for next try using retry
370 archive_cache.filesystem.retry_backoff = 1
370 archive_cache.filesystem.retry_backoff = 1
371
371
372 ; how many tries do do a retry fetch from this backend
372 ; how many tries do do a retry fetch from this backend
373 archive_cache.filesystem.retry_attempts = 10
373 archive_cache.filesystem.retry_attempts = 10
374
374
375
375
376 ; #############
376 ; #############
377 ; CELERY CONFIG
377 ; CELERY CONFIG
378 ; #############
378 ; #############
379
379
380 ; manually run celery: /path/to/celery worker --task-events --beat --app rhodecode.lib.celerylib.loader --scheduler rhodecode.lib.celerylib.scheduler.RcScheduler --loglevel DEBUG --ini /path/to/rhodecode.ini
380 ; manually run celery: /path/to/celery worker --task-events --beat --app rhodecode.lib.celerylib.loader --scheduler rhodecode.lib.celerylib.scheduler.RcScheduler --loglevel DEBUG --ini /path/to/rhodecode.ini
381
381
382 use_celery = false
382 use_celery = false
383
383
384 ; path to store schedule database
384 ; path to store schedule database
385 #celerybeat-schedule.path =
385 #celerybeat-schedule.path =
386
386
387 ; connection url to the message broker (default redis)
387 ; connection url to the message broker (default redis)
388 celery.broker_url = redis://redis:6379/8
388 celery.broker_url = redis://redis:6379/8
389
389
390 ; results backend to get results for (default redis)
390 ; results backend to get results for (default redis)
391 celery.result_backend = redis://redis:6379/8
391 celery.result_backend = redis://redis:6379/8
392
392
393 ; rabbitmq example
393 ; rabbitmq example
394 #celery.broker_url = amqp://rabbitmq:qweqwe@localhost:5672/rabbitmqhost
394 #celery.broker_url = amqp://rabbitmq:qweqwe@localhost:5672/rabbitmqhost
395
395
396 ; maximum tasks to execute before worker restart
396 ; maximum tasks to execute before worker restart
397 celery.max_tasks_per_child = 20
397 celery.max_tasks_per_child = 20
398
398
399 ; tasks will never be sent to the queue, but executed locally instead.
399 ; tasks will never be sent to the queue, but executed locally instead.
400 celery.task_always_eager = true
400 celery.task_always_eager = true
401 celery.task_store_eager_result = true
401 celery.task_store_eager_result = true
402
402
403 ; #############
403 ; #############
404 ; DOGPILE CACHE
404 ; DOGPILE CACHE
405 ; #############
405 ; #############
406
406
407 ; Default cache dir for caches. Putting this into a ramdisk can boost performance.
407 ; Default cache dir for caches. Putting this into a ramdisk can boost performance.
408 ; eg. /tmpfs/data_ramdisk, however this directory might require large amount of space
408 ; eg. /tmpfs/data_ramdisk, however this directory might require large amount of space
409 cache_dir = %(here)s/rc-test-data
409 cache_dir = %(here)s/rc-test-data
410
410
411 ; *********************************************
411 ; *********************************************
412 ; `sql_cache_short` cache for heavy SQL queries
412 ; `sql_cache_short` cache for heavy SQL queries
413 ; Only supported backend is `memory_lru`
413 ; Only supported backend is `memory_lru`
414 ; *********************************************
414 ; *********************************************
415 rc_cache.sql_cache_short.backend = dogpile.cache.rc.memory_lru
415 rc_cache.sql_cache_short.backend = dogpile.cache.rc.memory_lru
416 rc_cache.sql_cache_short.expiration_time = 0
416 rc_cache.sql_cache_short.expiration_time = 0
417
417
418
418
419 ; *****************************************************
419 ; *****************************************************
420 ; `cache_repo_longterm` cache for repo object instances
420 ; `cache_repo_longterm` cache for repo object instances
421 ; Only supported backend is `memory_lru`
421 ; Only supported backend is `memory_lru`
422 ; *****************************************************
422 ; *****************************************************
423 rc_cache.cache_repo_longterm.backend = dogpile.cache.rc.memory_lru
423 rc_cache.cache_repo_longterm.backend = dogpile.cache.rc.memory_lru
424 ; by default we use 30 Days, cache is still invalidated on push
424 ; by default we use 30 Days, cache is still invalidated on push
425 rc_cache.cache_repo_longterm.expiration_time = 2592000
425 rc_cache.cache_repo_longterm.expiration_time = 2592000
426 ; max items in LRU cache, set to smaller number to save memory, and expire last used caches
426 ; max items in LRU cache, set to smaller number to save memory, and expire last used caches
427 rc_cache.cache_repo_longterm.max_size = 10000
427 rc_cache.cache_repo_longterm.max_size = 10000
428
428
429
429
430 ; *********************************************
430 ; *********************************************
431 ; `cache_general` cache for general purpose use
431 ; `cache_general` cache for general purpose use
432 ; for simplicity use rc.file_namespace backend,
432 ; for simplicity use rc.file_namespace backend,
433 ; for performance and scale use rc.redis
433 ; for performance and scale use rc.redis
434 ; *********************************************
434 ; *********************************************
435 rc_cache.cache_general.backend = dogpile.cache.rc.file_namespace
435 rc_cache.cache_general.backend = dogpile.cache.rc.file_namespace
436 rc_cache.cache_general.expiration_time = 43200
436 rc_cache.cache_general.expiration_time = 43200
437 ; file cache store path. Defaults to `cache_dir =` value or tempdir if both values are not set
437 ; file cache store path. Defaults to `cache_dir =` value or tempdir if both values are not set
438 rc_cache.cache_general.arguments.filename = %(here)s/rc-tests/cache-backend/cache_general_db
438 rc_cache.cache_general.arguments.filename = %(here)s/rc-tests/cache-backend/cache_general_db
439
439
440 ; alternative `cache_general` redis backend with distributed lock
440 ; alternative `cache_general` redis backend with distributed lock
441 #rc_cache.cache_general.backend = dogpile.cache.rc.redis
441 #rc_cache.cache_general.backend = dogpile.cache.rc.redis
442 #rc_cache.cache_general.expiration_time = 300
442 #rc_cache.cache_general.expiration_time = 300
443
443
444 ; redis_expiration_time needs to be greater then expiration_time
444 ; redis_expiration_time needs to be greater then expiration_time
445 #rc_cache.cache_general.arguments.redis_expiration_time = 7200
445 #rc_cache.cache_general.arguments.redis_expiration_time = 7200
446
446
447 #rc_cache.cache_general.arguments.host = localhost
447 #rc_cache.cache_general.arguments.host = localhost
448 #rc_cache.cache_general.arguments.port = 6379
448 #rc_cache.cache_general.arguments.port = 6379
449 #rc_cache.cache_general.arguments.db = 0
449 #rc_cache.cache_general.arguments.db = 0
450 #rc_cache.cache_general.arguments.socket_timeout = 30
450 #rc_cache.cache_general.arguments.socket_timeout = 30
451 ; more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends
451 ; more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends
452 #rc_cache.cache_general.arguments.distributed_lock = true
452 #rc_cache.cache_general.arguments.distributed_lock = true
453
453
454 ; auto-renew lock to prevent stale locks, slower but safer. Use only if problems happen
454 ; auto-renew lock to prevent stale locks, slower but safer. Use only if problems happen
455 #rc_cache.cache_general.arguments.lock_auto_renewal = true
455 #rc_cache.cache_general.arguments.lock_auto_renewal = true
456
456
457 ; *************************************************
457 ; *************************************************
458 ; `cache_perms` cache for permission tree, auth TTL
458 ; `cache_perms` cache for permission tree, auth TTL
459 ; for simplicity use rc.file_namespace backend,
459 ; for simplicity use rc.file_namespace backend,
460 ; for performance and scale use rc.redis
460 ; for performance and scale use rc.redis
461 ; *************************************************
461 ; *************************************************
462 rc_cache.cache_perms.backend = dogpile.cache.rc.file_namespace
462 rc_cache.cache_perms.backend = dogpile.cache.rc.file_namespace
463 rc_cache.cache_perms.expiration_time = 0
463 rc_cache.cache_perms.expiration_time = 0
464 ; file cache store path. Defaults to `cache_dir =` value or tempdir if both values are not set
464 ; file cache store path. Defaults to `cache_dir =` value or tempdir if both values are not set
465 rc_cache.cache_perms.arguments.filename = %(here)s/rc-tests/cache-backend/cache_perms_db
465 rc_cache.cache_perms.arguments.filename = %(here)s/rc-tests/cache-backend/cache_perms_db
466
466
467 ; alternative `cache_perms` redis backend with distributed lock
467 ; alternative `cache_perms` redis backend with distributed lock
468 #rc_cache.cache_perms.backend = dogpile.cache.rc.redis
468 #rc_cache.cache_perms.backend = dogpile.cache.rc.redis
469 #rc_cache.cache_perms.expiration_time = 300
469 #rc_cache.cache_perms.expiration_time = 300
470
470
471 ; redis_expiration_time needs to be greater then expiration_time
471 ; redis_expiration_time needs to be greater then expiration_time
472 #rc_cache.cache_perms.arguments.redis_expiration_time = 7200
472 #rc_cache.cache_perms.arguments.redis_expiration_time = 7200
473
473
474 #rc_cache.cache_perms.arguments.host = localhost
474 #rc_cache.cache_perms.arguments.host = localhost
475 #rc_cache.cache_perms.arguments.port = 6379
475 #rc_cache.cache_perms.arguments.port = 6379
476 #rc_cache.cache_perms.arguments.db = 0
476 #rc_cache.cache_perms.arguments.db = 0
477 #rc_cache.cache_perms.arguments.socket_timeout = 30
477 #rc_cache.cache_perms.arguments.socket_timeout = 30
478 ; more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends
478 ; more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends
479 #rc_cache.cache_perms.arguments.distributed_lock = true
479 #rc_cache.cache_perms.arguments.distributed_lock = true
480
480
481 ; auto-renew lock to prevent stale locks, slower but safer. Use only if problems happen
481 ; auto-renew lock to prevent stale locks, slower but safer. Use only if problems happen
482 #rc_cache.cache_perms.arguments.lock_auto_renewal = true
482 #rc_cache.cache_perms.arguments.lock_auto_renewal = true
483
483
484 ; ***************************************************
484 ; ***************************************************
485 ; `cache_repo` cache for file tree, Readme, RSS FEEDS
485 ; `cache_repo` cache for file tree, Readme, RSS FEEDS
486 ; for simplicity use rc.file_namespace backend,
486 ; for simplicity use rc.file_namespace backend,
487 ; for performance and scale use rc.redis
487 ; for performance and scale use rc.redis
488 ; ***************************************************
488 ; ***************************************************
489 rc_cache.cache_repo.backend = dogpile.cache.rc.file_namespace
489 rc_cache.cache_repo.backend = dogpile.cache.rc.file_namespace
490 rc_cache.cache_repo.expiration_time = 2592000
490 rc_cache.cache_repo.expiration_time = 2592000
491 ; file cache store path. Defaults to `cache_dir =` value or tempdir if both values are not set
491 ; file cache store path. Defaults to `cache_dir =` value or tempdir if both values are not set
492 rc_cache.cache_repo.arguments.filename = %(here)s/rc-tests/cache-backend/cache_repo_db
492 rc_cache.cache_repo.arguments.filename = %(here)s/rc-tests/cache-backend/cache_repo_db
493
493
494 ; alternative `cache_repo` redis backend with distributed lock
494 ; alternative `cache_repo` redis backend with distributed lock
495 #rc_cache.cache_repo.backend = dogpile.cache.rc.redis
495 #rc_cache.cache_repo.backend = dogpile.cache.rc.redis
496 #rc_cache.cache_repo.expiration_time = 2592000
496 #rc_cache.cache_repo.expiration_time = 2592000
497
497
498 ; redis_expiration_time needs to be greater then expiration_time
498 ; redis_expiration_time needs to be greater then expiration_time
499 #rc_cache.cache_repo.arguments.redis_expiration_time = 2678400
499 #rc_cache.cache_repo.arguments.redis_expiration_time = 2678400
500
500
501 #rc_cache.cache_repo.arguments.host = localhost
501 #rc_cache.cache_repo.arguments.host = localhost
502 #rc_cache.cache_repo.arguments.port = 6379
502 #rc_cache.cache_repo.arguments.port = 6379
503 #rc_cache.cache_repo.arguments.db = 1
503 #rc_cache.cache_repo.arguments.db = 1
504 #rc_cache.cache_repo.arguments.socket_timeout = 30
504 #rc_cache.cache_repo.arguments.socket_timeout = 30
505 ; more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends
505 ; more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends
506 #rc_cache.cache_repo.arguments.distributed_lock = true
506 #rc_cache.cache_repo.arguments.distributed_lock = true
507
507
508 ; auto-renew lock to prevent stale locks, slower but safer. Use only if problems happen
508 ; auto-renew lock to prevent stale locks, slower but safer. Use only if problems happen
509 #rc_cache.cache_repo.arguments.lock_auto_renewal = true
509 #rc_cache.cache_repo.arguments.lock_auto_renewal = true
510
510
511 ; ##############
511 ; ##############
512 ; BEAKER SESSION
512 ; BEAKER SESSION
513 ; ##############
513 ; ##############
514
514
515 ; beaker.session.type is type of storage options for the logged users sessions. Current allowed
515 ; beaker.session.type is type of storage options for the logged users sessions. Current allowed
516 ; types are file, ext:redis, ext:database, ext:memcached
516 ; types are file, ext:redis, ext:database, ext:memcached
517 ; Fastest ones are ext:redis and ext:database, DO NOT use memory type for session
517 ; Fastest ones are ext:redis and ext:database, DO NOT use memory type for session
518 beaker.session.type = file
518 beaker.session.type = file
519 beaker.session.data_dir = %(here)s/rc-tests/data/sessions
519 beaker.session.data_dir = %(here)s/rc-tests/data/sessions
520
520
521 ; Redis based sessions
521 ; Redis based sessions
522 #beaker.session.type = ext:redis
522 #beaker.session.type = ext:redis
523 #beaker.session.url = redis://redis:6379/2
523 #beaker.session.url = redis://redis:6379/2
524
524
525 ; DB based session, fast, and allows easy management over logged in users
525 ; DB based session, fast, and allows easy management over logged in users
526 #beaker.session.type = ext:database
526 #beaker.session.type = ext:database
527 #beaker.session.table_name = db_session
527 #beaker.session.table_name = db_session
528 #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
528 #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
529 #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode
529 #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode
530 #beaker.session.sa.pool_recycle = 3600
530 #beaker.session.sa.pool_recycle = 3600
531 #beaker.session.sa.echo = false
531 #beaker.session.sa.echo = false
532
532
533 beaker.session.key = rhodecode
533 beaker.session.key = rhodecode
534 beaker.session.secret = test-rc-uytcxaz
534 beaker.session.secret = test-rc-uytcxaz
535 beaker.session.lock_dir = %(here)s/rc-tests/data/sessions/lock
535 beaker.session.lock_dir = %(here)s/rc-tests/data/sessions/lock
536
536
537 ; Secure encrypted cookie. Requires AES and AES python libraries
537 ; Secure encrypted cookie. Requires AES and AES python libraries
538 ; you must disable beaker.session.secret to use this
538 ; you must disable beaker.session.secret to use this
539 #beaker.session.encrypt_key = key_for_encryption
539 #beaker.session.encrypt_key = key_for_encryption
540 #beaker.session.validate_key = validation_key
540 #beaker.session.validate_key = validation_key
541
541
542 ; Sets session as invalid (also logging out user) if it haven not been
542 ; Sets session as invalid (also logging out user) if it haven not been
543 ; accessed for given amount of time in seconds
543 ; accessed for given amount of time in seconds
544 beaker.session.timeout = 2592000
544 beaker.session.timeout = 2592000
545 beaker.session.httponly = true
545 beaker.session.httponly = true
546
546
547 ; Path to use for the cookie. Set to prefix if you use prefix middleware
547 ; Path to use for the cookie. Set to prefix if you use prefix middleware
548 #beaker.session.cookie_path = /custom_prefix
548 #beaker.session.cookie_path = /custom_prefix
549
549
550 ; Set https secure cookie
550 ; Set https secure cookie
551 beaker.session.secure = false
551 beaker.session.secure = false
552
552
553 ; default cookie expiration time in seconds, set to `true` to set expire
553 ; default cookie expiration time in seconds, set to `true` to set expire
554 ; at browser close
554 ; at browser close
555 #beaker.session.cookie_expires = 3600
555 #beaker.session.cookie_expires = 3600
556
556
557 ; #############################
557 ; #############################
558 ; SEARCH INDEXING CONFIGURATION
558 ; SEARCH INDEXING CONFIGURATION
559 ; #############################
559 ; #############################
560
560
561 ; Full text search indexer is available in rhodecode-tools under
561 ; Full text search indexer is available in rhodecode-tools under
562 ; `rhodecode-tools index` command
562 ; `rhodecode-tools index` command
563
563
564 ; WHOOSH Backend, doesn't require additional services to run
564 ; WHOOSH Backend, doesn't require additional services to run
565 ; it works good with few dozen repos
565 ; it works good with few dozen repos
566 search.module = rhodecode.lib.index.whoosh
566 search.module = rhodecode.lib.index.whoosh
567 search.location = %(here)s/rc-tests/data/index
567 search.location = %(here)s/rc-tests/data/index
568
568
569 ; ####################
569 ; ####################
570 ; CHANNELSTREAM CONFIG
570 ; CHANNELSTREAM CONFIG
571 ; ####################
571 ; ####################
572
572
573 ; channelstream enables persistent connections and live notification
573 ; channelstream enables persistent connections and live notification
574 ; in the system. It's also used by the chat system
574 ; in the system. It's also used by the chat system
575
575
576 channelstream.enabled = false
576 channelstream.enabled = false
577
577
578 ; server address for channelstream server on the backend
578 ; server address for channelstream server on the backend
579 channelstream.server = channelstream:9800
579 channelstream.server = channelstream:9800
580
580
581 ; location of the channelstream server from outside world
581 ; location of the channelstream server from outside world
582 ; use ws:// for http or wss:// for https. This address needs to be handled
582 ; use ws:// for http or wss:// for https. This address needs to be handled
583 ; by external HTTP server such as Nginx or Apache
583 ; by external HTTP server such as Nginx or Apache
584 ; see Nginx/Apache configuration examples in our docs
584 ; see Nginx/Apache configuration examples in our docs
585 channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
585 channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
586 channelstream.secret = ENV_GENERATED
586 channelstream.secret = ENV_GENERATED
587 channelstream.history.location = %(here)s/rc-tests/channelstream_history
587 channelstream.history.location = %(here)s/rc-tests/channelstream_history
588
588
589 ; Internal application path that Javascript uses to connect into.
589 ; Internal application path that Javascript uses to connect into.
590 ; If you use proxy-prefix the prefix should be added before /_channelstream
590 ; If you use proxy-prefix the prefix should be added before /_channelstream
591 channelstream.proxy_path = /_channelstream
591 channelstream.proxy_path = /_channelstream
592
592
593
593
594 ; ##############################
594 ; ##############################
595 ; MAIN RHODECODE DATABASE CONFIG
595 ; MAIN RHODECODE DATABASE CONFIG
596 ; ##############################
596 ; ##############################
597
597
598 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
598 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
599 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
599 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
600 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode?charset=utf8
600 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode?charset=utf8
601 ; pymysql is an alternative driver for MySQL, use in case of problems with default one
601 ; pymysql is an alternative driver for MySQL, use in case of problems with default one
602 #sqlalchemy.db1.url = mysql+pymysql://root:qweqwe@localhost/rhodecode
602 #sqlalchemy.db1.url = mysql+pymysql://root:qweqwe@localhost/rhodecode
603
603
604 sqlalchemy.db1.url = sqlite:///%(here)s/rc-tests/rhodecode_test.db?timeout=30
604 sqlalchemy.db1.url = sqlite:///%(here)s/rc-tests/rhodecode_test.db?timeout=30
605
605
606 ; see sqlalchemy docs for other advanced settings
606 ; see sqlalchemy docs for other advanced settings
607 ; print the sql statements to output
607 ; print the sql statements to output
608 sqlalchemy.db1.echo = false
608 sqlalchemy.db1.echo = false
609
609
610 ; recycle the connections after this amount of seconds
610 ; recycle the connections after this amount of seconds
611 sqlalchemy.db1.pool_recycle = 3600
611 sqlalchemy.db1.pool_recycle = 3600
612
612
613 ; the number of connections to keep open inside the connection pool.
613 ; the number of connections to keep open inside the connection pool.
614 ; 0 indicates no limit
614 ; 0 indicates no limit
615 ; the general calculus with gevent is:
615 ; the general calculus with gevent is:
616 ; if your system allows 500 concurrent greenlets (max_connections) that all do database access,
616 ; if your system allows 500 concurrent greenlets (max_connections) that all do database access,
617 ; then increase pool size + max overflow so that they add up to 500.
617 ; then increase pool size + max overflow so that they add up to 500.
618 #sqlalchemy.db1.pool_size = 5
618 #sqlalchemy.db1.pool_size = 5
619
619
620 ; The number of connections to allow in connection pool "overflow", that is
620 ; The number of connections to allow in connection pool "overflow", that is
621 ; connections that can be opened above and beyond the pool_size setting,
621 ; connections that can be opened above and beyond the pool_size setting,
622 ; which defaults to five.
622 ; which defaults to five.
623 #sqlalchemy.db1.max_overflow = 10
623 #sqlalchemy.db1.max_overflow = 10
624
624
625 ; Connection check ping, used to detect broken database connections
625 ; Connection check ping, used to detect broken database connections
626 ; could be enabled to better handle cases if MySQL has gone away errors
626 ; could be enabled to better handle cases if MySQL has gone away errors
627 #sqlalchemy.db1.ping_connection = true
627 #sqlalchemy.db1.ping_connection = true
628
628
629 ; ##########
629 ; ##########
630 ; VCS CONFIG
630 ; VCS CONFIG
631 ; ##########
631 ; ##########
632 vcs.server.enable = true
632 vcs.server.enable = true
633 vcs.server = vcsserver:10010
633 vcs.server = vcsserver:10010
634
634
635 ; Web server connectivity protocol, responsible for web based VCS operations
635 ; Web server connectivity protocol, responsible for web based VCS operations
636 ; Available protocols are:
636 ; Available protocols are:
637 ; `http` - use http-rpc backend (default)
637 ; `http` - use http-rpc backend (default)
638 vcs.server.protocol = http
638 vcs.server.protocol = http
639
639
640 ; Push/Pull operations protocol, available options are:
640 ; Push/Pull operations protocol, available options are:
641 ; `http` - use http-rpc backend (default)
641 ; `http` - use http-rpc backend (default)
642 vcs.scm_app_implementation = http
642 vcs.scm_app_implementation = http
643
643
644 ; Push/Pull operations hooks protocol, available options are:
644 ; Push/Pull operations hooks protocol, available options are:
645 ; `http` - use http-rpc backend (default)
645 ; `http` - use http-rpc backend (default)
646 ; `celery` - use celery based hooks
646 ; `celery` - use celery based hooks
647 #DEPRECATED:vcs.hooks.protocol = http
647 #DEPRECATED:vcs.hooks.protocol = http
648 vcs.hooks.protocol = http
648 vcs.hooks.protocol.v2 = celery
649
649
650 ; Host on which this instance is listening for hooks. vcsserver will call this host to pull/push hooks so it should be
650 ; Host on which this instance is listening for hooks. vcsserver will call this host to pull/push hooks so it should be
651 ; accessible via network.
651 ; accessible via network.
652 ; Use vcs.hooks.host = "*" to bind to current hostname (for Docker)
652 ; Use vcs.hooks.host = "*" to bind to current hostname (for Docker)
653 vcs.hooks.host = *
653 vcs.hooks.host = *
654
654
655 ; Start VCSServer with this instance as a subprocess, useful for development
655 ; Start VCSServer with this instance as a subprocess, useful for development
656 vcs.start_server = false
656 vcs.start_server = false
657
657
658 ; List of enabled VCS backends, available options are:
658 ; List of enabled VCS backends, available options are:
659 ; `hg` - mercurial
659 ; `hg` - mercurial
660 ; `git` - git
660 ; `git` - git
661 ; `svn` - subversion
661 ; `svn` - subversion
662 vcs.backends = hg, git, svn
662 vcs.backends = hg, git, svn
663
663
664 ; Wait this number of seconds before killing connection to the vcsserver
664 ; Wait this number of seconds before killing connection to the vcsserver
665 vcs.connection_timeout = 3600
665 vcs.connection_timeout = 3600
666
666
667 ; Cache flag to cache vcsserver remote calls locally
667 ; Cache flag to cache vcsserver remote calls locally
668 ; It uses cache_region `cache_repo`
668 ; It uses cache_region `cache_repo`
669 vcs.methods.cache = false
669 vcs.methods.cache = false
670
670
671 ; Filesystem location where Git lfs objects should be stored
671 ; Filesystem location where Git lfs objects should be stored
672 vcs.git.lfs.storage_location = /var/opt/rhodecode_repo_store/.cache/git_lfs_store
672 vcs.git.lfs.storage_location = /var/opt/rhodecode_repo_store/.cache/git_lfs_store
673
673
674 ; Filesystem location where Mercurial largefile objects should be stored
674 ; Filesystem location where Mercurial largefile objects should be stored
675 vcs.hg.largefiles.storage_location = /var/opt/rhodecode_repo_store/.cache/hg_largefiles_store
675 vcs.hg.largefiles.storage_location = /var/opt/rhodecode_repo_store/.cache/hg_largefiles_store
676
676
677 ; ####################################################
677 ; ####################################################
678 ; Subversion proxy support (mod_dav_svn)
678 ; Subversion proxy support (mod_dav_svn)
679 ; Maps RhodeCode repo groups into SVN paths for Apache
679 ; Maps RhodeCode repo groups into SVN paths for Apache
680 ; ####################################################
680 ; ####################################################
681
681
682 ; Compatibility version when creating SVN repositories. Defaults to newest version when commented out.
682 ; Compatibility version when creating SVN repositories. Defaults to newest version when commented out.
683 ; Set a numeric version for your current SVN e.g 1.8, or 1.12
683 ; Set a numeric version for your current SVN e.g 1.8, or 1.12
684 ; Legacy available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible, pre-1.9-compatible
684 ; Legacy available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible, pre-1.9-compatible
685 #vcs.svn.compatible_version = 1.8
685 #vcs.svn.compatible_version = 1.8
686
686
687 ; Redis connection settings for svn integrations logic
687 ; Redis connection settings for svn integrations logic
688 ; This connection string needs to be the same on ce and vcsserver
688 ; This connection string needs to be the same on ce and vcsserver
689 vcs.svn.redis_conn = redis://redis:6379/0
689 vcs.svn.redis_conn = redis://redis:6379/0
690
690
691 ; Enable SVN proxy of requests over HTTP
691 ; Enable SVN proxy of requests over HTTP
692 vcs.svn.proxy.enabled = true
692 vcs.svn.proxy.enabled = true
693
693
694 ; host to connect to running SVN subsystem
694 ; host to connect to running SVN subsystem
695 vcs.svn.proxy.host = http://svn:8090
695 vcs.svn.proxy.host = http://svn:8090
696
696
697 ; Enable or disable the config file generation.
697 ; Enable or disable the config file generation.
698 svn.proxy.generate_config = false
698 svn.proxy.generate_config = false
699
699
700 ; Generate config file with `SVNListParentPath` set to `On`.
700 ; Generate config file with `SVNListParentPath` set to `On`.
701 svn.proxy.list_parent_path = true
701 svn.proxy.list_parent_path = true
702
702
703 ; Set location and file name of generated config file.
703 ; Set location and file name of generated config file.
704 svn.proxy.config_file_path = %(here)s/rc-tests/mod_dav_svn.conf
704 svn.proxy.config_file_path = %(here)s/rc-tests/mod_dav_svn.conf
705
705
706 ; alternative mod_dav config template. This needs to be a valid mako template
706 ; alternative mod_dav config template. This needs to be a valid mako template
707 ; Example template can be found in the source code:
707 ; Example template can be found in the source code:
708 ; rhodecode/apps/svn_support/templates/mod-dav-svn.conf.mako
708 ; rhodecode/apps/svn_support/templates/mod-dav-svn.conf.mako
709 #svn.proxy.config_template = ~/.rccontrol/enterprise-1/custom_svn_conf.mako
709 #svn.proxy.config_template = ~/.rccontrol/enterprise-1/custom_svn_conf.mako
710
710
711 ; Used as a prefix to the `Location` block in the generated config file.
711 ; Used as a prefix to the `Location` block in the generated config file.
712 ; In most cases it should be set to `/`.
712 ; In most cases it should be set to `/`.
713 svn.proxy.location_root = /
713 svn.proxy.location_root = /
714
714
715 ; Command to reload the mod dav svn configuration on change.
715 ; Command to reload the mod dav svn configuration on change.
716 ; Example: `/etc/init.d/apache2 reload` or /home/USER/apache_reload.sh
716 ; Example: `/etc/init.d/apache2 reload` or /home/USER/apache_reload.sh
717 ; Make sure user who runs RhodeCode process is allowed to reload Apache
717 ; Make sure user who runs RhodeCode process is allowed to reload Apache
718 #svn.proxy.reload_cmd = /etc/init.d/apache2 reload
718 #svn.proxy.reload_cmd = /etc/init.d/apache2 reload
719
719
720 ; If the timeout expires before the reload command finishes, the command will
720 ; If the timeout expires before the reload command finishes, the command will
721 ; be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
721 ; be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
722 #svn.proxy.reload_timeout = 10
722 #svn.proxy.reload_timeout = 10
723
723
724 ; ####################
724 ; ####################
725 ; SSH Support Settings
725 ; SSH Support Settings
726 ; ####################
726 ; ####################
727
727
728 ; Defines if a custom authorized_keys file should be created and written on
728 ; Defines if a custom authorized_keys file should be created and written on
729 ; any change user ssh keys. Setting this to false also disables possibility
729 ; any change user ssh keys. Setting this to false also disables possibility
730 ; of adding SSH keys by users from web interface. Super admins can still
730 ; of adding SSH keys by users from web interface. Super admins can still
731 ; manage SSH Keys.
731 ; manage SSH Keys.
732 ssh.generate_authorized_keyfile = true
732 ssh.generate_authorized_keyfile = true
733
733
734 ; Options for ssh, default is `no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding`
734 ; Options for ssh, default is `no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding`
735 # ssh.authorized_keys_ssh_opts =
735 # ssh.authorized_keys_ssh_opts =
736
736
737 ; Path to the authorized_keys file where the generate entries are placed.
737 ; Path to the authorized_keys file where the generate entries are placed.
738 ; It is possible to have multiple key files specified in `sshd_config` e.g.
738 ; It is possible to have multiple key files specified in `sshd_config` e.g.
739 ; AuthorizedKeysFile %h/.ssh/authorized_keys %h/.ssh/authorized_keys_rhodecode
739 ; AuthorizedKeysFile %h/.ssh/authorized_keys %h/.ssh/authorized_keys_rhodecode
740 ssh.authorized_keys_file_path = %(here)s/rc-tests/authorized_keys_rhodecode
740 ssh.authorized_keys_file_path = %(here)s/rc-tests/authorized_keys_rhodecode
741
741
742 ; Command to execute the SSH wrapper. The binary is available in the
742 ; Command to execute the SSH wrapper. The binary is available in the
743 ; RhodeCode installation directory.
743 ; RhodeCode installation directory.
744 ; legacy: /usr/local/bin/rhodecode_bin/bin/rc-ssh-wrapper
744 ; legacy: /usr/local/bin/rhodecode_bin/bin/rc-ssh-wrapper
745 ; new rewrite: /usr/local/bin/rhodecode_bin/bin/rc-ssh-wrapper-v2
745 ; new rewrite: /usr/local/bin/rhodecode_bin/bin/rc-ssh-wrapper-v2
746 #DEPRECATED: ssh.wrapper_cmd = /usr/local/bin/rhodecode_bin/bin/rc-ssh-wrapper
746 #DEPRECATED: ssh.wrapper_cmd = /usr/local/bin/rhodecode_bin/bin/rc-ssh-wrapper
747 ssh.wrapper_cmd.v2 = /usr/local/bin/rhodecode_bin/bin/rc-ssh-wrapper-v2
747 ssh.wrapper_cmd.v2 = /usr/local/bin/rhodecode_bin/bin/rc-ssh-wrapper-v2
748
748
749 ; Allow shell when executing the ssh-wrapper command
749 ; Allow shell when executing the ssh-wrapper command
750 ssh.wrapper_cmd_allow_shell = false
750 ssh.wrapper_cmd_allow_shell = false
751
751
752 ; Enables logging, and detailed output send back to the client during SSH
752 ; Enables logging, and detailed output send back to the client during SSH
753 ; operations. Useful for debugging, shouldn't be used in production.
753 ; operations. Useful for debugging, shouldn't be used in production.
754 ssh.enable_debug_logging = true
754 ssh.enable_debug_logging = true
755
755
756 ; Paths to binary executable, by default they are the names, but we can
756 ; Paths to binary executable, by default they are the names, but we can
757 ; override them if we want to use a custom one
757 ; override them if we want to use a custom one
758 ssh.executable.hg = /usr/local/bin/rhodecode_bin/vcs_bin/hg
758 ssh.executable.hg = /usr/local/bin/rhodecode_bin/vcs_bin/hg
759 ssh.executable.git = /usr/local/bin/rhodecode_bin/vcs_bin/git
759 ssh.executable.git = /usr/local/bin/rhodecode_bin/vcs_bin/git
760 ssh.executable.svn = /usr/local/bin/rhodecode_bin/vcs_bin/svnserve
760 ssh.executable.svn = /usr/local/bin/rhodecode_bin/vcs_bin/svnserve
761
761
762 ; Enables SSH key generator web interface. Disabling this still allows users
762 ; Enables SSH key generator web interface. Disabling this still allows users
763 ; to add their own keys.
763 ; to add their own keys.
764 ssh.enable_ui_key_generator = true
764 ssh.enable_ui_key_generator = true
765
765
766 ; Statsd client config, this is used to send metrics to statsd
766 ; Statsd client config, this is used to send metrics to statsd
767 ; We recommend setting statsd_exported and scrape them using Prometheus
767 ; We recommend setting statsd_exported and scrape them using Prometheus
768 #statsd.enabled = false
768 #statsd.enabled = false
769 #statsd.statsd_host = 0.0.0.0
769 #statsd.statsd_host = 0.0.0.0
770 #statsd.statsd_port = 8125
770 #statsd.statsd_port = 8125
771 #statsd.statsd_prefix =
771 #statsd.statsd_prefix =
772 #statsd.statsd_ipv6 = false
772 #statsd.statsd_ipv6 = false
773
773
774 ; configure logging automatically at server startup set to false
774 ; configure logging automatically at server startup set to false
775 ; to use the below custom logging config.
775 ; to use the below custom logging config.
776 ; RC_LOGGING_FORMATTER
776 ; RC_LOGGING_FORMATTER
777 ; RC_LOGGING_LEVEL
777 ; RC_LOGGING_LEVEL
778 ; env variables can control the settings for logging in case of autoconfigure
778 ; env variables can control the settings for logging in case of autoconfigure
779
779
780 logging.autoconfigure = false
780 logging.autoconfigure = false
781
781
782 ; specify your own custom logging config file to configure logging
782 ; specify your own custom logging config file to configure logging
783 #logging.logging_conf_file = /path/to/custom_logging.ini
783 #logging.logging_conf_file = /path/to/custom_logging.ini
784
784
785 ; Dummy marker to add new entries after.
785 ; Dummy marker to add new entries after.
786 ; Add any custom entries below. Please don't remove this marker.
786 ; Add any custom entries below. Please don't remove this marker.
787 custom.conf = 1
787 custom.conf = 1
788
788
789
789
790 ; #####################
790 ; #####################
791 ; LOGGING CONFIGURATION
791 ; LOGGING CONFIGURATION
792 ; #####################
792 ; #####################
793
793
794 [loggers]
794 [loggers]
795 keys = root, sqlalchemy, beaker, celery, rhodecode, ssh_wrapper, dogpile
795 keys = root, sqlalchemy, beaker, celery, rhodecode, ssh_wrapper, dogpile
796
796
797 [handlers]
797 [handlers]
798 keys = console, console_sql
798 keys = console, console_sql
799
799
800 [formatters]
800 [formatters]
801 keys = generic, json, color_formatter, color_formatter_sql
801 keys = generic, json, color_formatter, color_formatter_sql
802
802
803 ; #######
803 ; #######
804 ; LOGGERS
804 ; LOGGERS
805 ; #######
805 ; #######
806 [logger_root]
806 [logger_root]
807 level = NOTSET
807 level = NOTSET
808 handlers = console
808 handlers = console
809
809
810 [logger_routes]
810 [logger_routes]
811 level = DEBUG
811 level = DEBUG
812 handlers =
812 handlers =
813 qualname = routes.middleware
813 qualname = routes.middleware
814 ## "level = DEBUG" logs the route matched and routing variables.
814 ## "level = DEBUG" logs the route matched and routing variables.
815 propagate = 1
815 propagate = 1
816
816
817 [logger_sqlalchemy]
817 [logger_sqlalchemy]
818 level = INFO
818 level = INFO
819 handlers = console_sql
819 handlers = console_sql
820 qualname = sqlalchemy.engine
820 qualname = sqlalchemy.engine
821 propagate = 0
821 propagate = 0
822
822
823 [logger_beaker]
823 [logger_beaker]
824 level = DEBUG
824 level = DEBUG
825 handlers =
825 handlers =
826 qualname = beaker.container
826 qualname = beaker.container
827 propagate = 1
827 propagate = 1
828
828
829 [logger_dogpile]
829 [logger_dogpile]
830 level = INFO
830 level = INFO
831 handlers = console
831 handlers = console
832 qualname = dogpile
832 qualname = dogpile
833 propagate = 1
833 propagate = 1
834
834
835 [logger_rhodecode]
835 [logger_rhodecode]
836 level = DEBUG
836 level = DEBUG
837 handlers =
837 handlers =
838 qualname = rhodecode
838 qualname = rhodecode
839 propagate = 1
839 propagate = 1
840
840
841 [logger_ssh_wrapper]
841 [logger_ssh_wrapper]
842 level = DEBUG
842 level = DEBUG
843 handlers =
843 handlers =
844 qualname = ssh_wrapper
844 qualname = ssh_wrapper
845 propagate = 1
845 propagate = 1
846
846
847 [logger_celery]
847 [logger_celery]
848 level = DEBUG
848 level = DEBUG
849 handlers =
849 handlers =
850 qualname = celery
850 qualname = celery
851
851
852
852
853 ; ########
853 ; ########
854 ; HANDLERS
854 ; HANDLERS
855 ; ########
855 ; ########
856
856
857 [handler_console]
857 [handler_console]
858 class = StreamHandler
858 class = StreamHandler
859 args = (sys.stderr, )
859 args = (sys.stderr, )
860 level = DEBUG
860 level = DEBUG
861 ; To enable JSON formatted logs replace 'generic/color_formatter' with 'json'
861 ; To enable JSON formatted logs replace 'generic/color_formatter' with 'json'
862 ; This allows sending properly formatted logs to grafana loki or elasticsearch
862 ; This allows sending properly formatted logs to grafana loki or elasticsearch
863 formatter = generic
863 formatter = generic
864
864
865 [handler_console_sql]
865 [handler_console_sql]
866 ; "level = DEBUG" logs SQL queries and results.
866 ; "level = DEBUG" logs SQL queries and results.
867 ; "level = INFO" logs SQL queries.
867 ; "level = INFO" logs SQL queries.
868 ; "level = WARN" logs neither. (Recommended for production systems.)
868 ; "level = WARN" logs neither. (Recommended for production systems.)
869 class = StreamHandler
869 class = StreamHandler
870 args = (sys.stderr, )
870 args = (sys.stderr, )
871 level = WARN
871 level = WARN
872 ; To enable JSON formatted logs replace 'generic/color_formatter_sql' with 'json'
872 ; To enable JSON formatted logs replace 'generic/color_formatter_sql' with 'json'
873 ; This allows sending properly formatted logs to grafana loki or elasticsearch
873 ; This allows sending properly formatted logs to grafana loki or elasticsearch
874 formatter = generic
874 formatter = generic
875
875
876 ; ##########
876 ; ##########
877 ; FORMATTERS
877 ; FORMATTERS
878 ; ##########
878 ; ##########
879
879
880 [formatter_generic]
880 [formatter_generic]
881 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
881 class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter
882 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
882 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
883 datefmt = %Y-%m-%d %H:%M:%S
883 datefmt = %Y-%m-%d %H:%M:%S
884
884
885 [formatter_color_formatter]
885 [formatter_color_formatter]
886 class = rhodecode.lib.logging_formatter.ColorFormatter
886 class = rhodecode.lib.logging_formatter.ColorFormatter
887 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
887 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
888 datefmt = %Y-%m-%d %H:%M:%S
888 datefmt = %Y-%m-%d %H:%M:%S
889
889
890 [formatter_color_formatter_sql]
890 [formatter_color_formatter_sql]
891 class = rhodecode.lib.logging_formatter.ColorFormatterSql
891 class = rhodecode.lib.logging_formatter.ColorFormatterSql
892 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
892 format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s
893 datefmt = %Y-%m-%d %H:%M:%S
893 datefmt = %Y-%m-%d %H:%M:%S
894
894
895 [formatter_json]
895 [formatter_json]
896 format = %(timestamp)s %(levelname)s %(name)s %(message)s %(req_id)s
896 format = %(timestamp)s %(levelname)s %(name)s %(message)s %(req_id)s
897 class = rhodecode.lib._vendor.jsonlogger.JsonFormatter
897 class = rhodecode.lib._vendor.jsonlogger.JsonFormatter
General Comments 0
You need to be logged in to leave comments. Login now