##// END OF EJS Templates
automation: add EE feature placeholder
marcink -
r2637:96836581 default
parent child Browse files
Show More
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -0,0 +1,9 b''
1 <div class="panel panel-default">
2 <div class="panel-heading">
3 <h3 class="panel-title">${_('Admin Automation')}</h3>
4 </div>
5 <div class="panel-body">
6 <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4>
7 <img style="width: 100%; height: 100%" src="${h.asset('images/ee_features/admin_automation.png')}"/>
8 </div>
9 </div>
@@ -1,409 +1,414 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2018 RhodeCode GmbH
3 # Copyright (C) 2016-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 from rhodecode.apps._base import ADMIN_PREFIX
22 from rhodecode.apps._base import ADMIN_PREFIX
23
23
24
24
25 def admin_routes(config):
25 def admin_routes(config):
26 """
26 """
27 Admin prefixed routes
27 Admin prefixed routes
28 """
28 """
29
29
30 config.add_route(
30 config.add_route(
31 name='admin_audit_logs',
31 name='admin_audit_logs',
32 pattern='/audit_logs')
32 pattern='/audit_logs')
33
33
34 config.add_route(
34 config.add_route(
35 name='admin_audit_log_entry',
35 name='admin_audit_log_entry',
36 pattern='/audit_logs/{audit_log_id}')
36 pattern='/audit_logs/{audit_log_id}')
37
37
38 config.add_route(
38 config.add_route(
39 name='pull_requests_global_0', # backward compat
39 name='pull_requests_global_0', # backward compat
40 pattern='/pull_requests/{pull_request_id:\d+}')
40 pattern='/pull_requests/{pull_request_id:\d+}')
41 config.add_route(
41 config.add_route(
42 name='pull_requests_global_1', # backward compat
42 name='pull_requests_global_1', # backward compat
43 pattern='/pull-requests/{pull_request_id:\d+}')
43 pattern='/pull-requests/{pull_request_id:\d+}')
44 config.add_route(
44 config.add_route(
45 name='pull_requests_global',
45 name='pull_requests_global',
46 pattern='/pull-request/{pull_request_id:\d+}')
46 pattern='/pull-request/{pull_request_id:\d+}')
47
47
48 config.add_route(
48 config.add_route(
49 name='admin_settings_open_source',
49 name='admin_settings_open_source',
50 pattern='/settings/open_source')
50 pattern='/settings/open_source')
51 config.add_route(
51 config.add_route(
52 name='admin_settings_vcs_svn_generate_cfg',
52 name='admin_settings_vcs_svn_generate_cfg',
53 pattern='/settings/vcs/svn_generate_cfg')
53 pattern='/settings/vcs/svn_generate_cfg')
54
54
55 config.add_route(
55 config.add_route(
56 name='admin_settings_system',
56 name='admin_settings_system',
57 pattern='/settings/system')
57 pattern='/settings/system')
58 config.add_route(
58 config.add_route(
59 name='admin_settings_system_update',
59 name='admin_settings_system_update',
60 pattern='/settings/system/updates')
60 pattern='/settings/system/updates')
61
61
62 config.add_route(
62 config.add_route(
63 name='admin_settings_sessions',
63 name='admin_settings_sessions',
64 pattern='/settings/sessions')
64 pattern='/settings/sessions')
65 config.add_route(
65 config.add_route(
66 name='admin_settings_sessions_cleanup',
66 name='admin_settings_sessions_cleanup',
67 pattern='/settings/sessions/cleanup')
67 pattern='/settings/sessions/cleanup')
68
68
69 config.add_route(
69 config.add_route(
70 name='admin_settings_process_management',
70 name='admin_settings_process_management',
71 pattern='/settings/process_management')
71 pattern='/settings/process_management')
72 config.add_route(
72 config.add_route(
73 name='admin_settings_process_management_data',
73 name='admin_settings_process_management_data',
74 pattern='/settings/process_management/data')
74 pattern='/settings/process_management/data')
75 config.add_route(
75 config.add_route(
76 name='admin_settings_process_management_signal',
76 name='admin_settings_process_management_signal',
77 pattern='/settings/process_management/signal')
77 pattern='/settings/process_management/signal')
78 config.add_route(
78 config.add_route(
79 name='admin_settings_process_management_master_signal',
79 name='admin_settings_process_management_master_signal',
80 pattern='/settings/process_management/master_signal')
80 pattern='/settings/process_management/master_signal')
81
81
82 # default settings
82 # default settings
83 config.add_route(
83 config.add_route(
84 name='admin_defaults_repositories',
84 name='admin_defaults_repositories',
85 pattern='/defaults/repositories')
85 pattern='/defaults/repositories')
86 config.add_route(
86 config.add_route(
87 name='admin_defaults_repositories_update',
87 name='admin_defaults_repositories_update',
88 pattern='/defaults/repositories/update')
88 pattern='/defaults/repositories/update')
89
89
90 # admin settings
90 # admin settings
91
91
92 config.add_route(
92 config.add_route(
93 name='admin_settings',
93 name='admin_settings',
94 pattern='/settings')
94 pattern='/settings')
95 config.add_route(
95 config.add_route(
96 name='admin_settings_update',
96 name='admin_settings_update',
97 pattern='/settings/update')
97 pattern='/settings/update')
98
98
99 config.add_route(
99 config.add_route(
100 name='admin_settings_global',
100 name='admin_settings_global',
101 pattern='/settings/global')
101 pattern='/settings/global')
102 config.add_route(
102 config.add_route(
103 name='admin_settings_global_update',
103 name='admin_settings_global_update',
104 pattern='/settings/global/update')
104 pattern='/settings/global/update')
105
105
106 config.add_route(
106 config.add_route(
107 name='admin_settings_vcs',
107 name='admin_settings_vcs',
108 pattern='/settings/vcs')
108 pattern='/settings/vcs')
109 config.add_route(
109 config.add_route(
110 name='admin_settings_vcs_update',
110 name='admin_settings_vcs_update',
111 pattern='/settings/vcs/update')
111 pattern='/settings/vcs/update')
112 config.add_route(
112 config.add_route(
113 name='admin_settings_vcs_svn_pattern_delete',
113 name='admin_settings_vcs_svn_pattern_delete',
114 pattern='/settings/vcs/svn_pattern_delete')
114 pattern='/settings/vcs/svn_pattern_delete')
115
115
116 config.add_route(
116 config.add_route(
117 name='admin_settings_mapping',
117 name='admin_settings_mapping',
118 pattern='/settings/mapping')
118 pattern='/settings/mapping')
119 config.add_route(
119 config.add_route(
120 name='admin_settings_mapping_update',
120 name='admin_settings_mapping_update',
121 pattern='/settings/mapping/update')
121 pattern='/settings/mapping/update')
122
122
123 config.add_route(
123 config.add_route(
124 name='admin_settings_visual',
124 name='admin_settings_visual',
125 pattern='/settings/visual')
125 pattern='/settings/visual')
126 config.add_route(
126 config.add_route(
127 name='admin_settings_visual_update',
127 name='admin_settings_visual_update',
128 pattern='/settings/visual/update')
128 pattern='/settings/visual/update')
129
129
130
130
131 config.add_route(
131 config.add_route(
132 name='admin_settings_issuetracker',
132 name='admin_settings_issuetracker',
133 pattern='/settings/issue-tracker')
133 pattern='/settings/issue-tracker')
134 config.add_route(
134 config.add_route(
135 name='admin_settings_issuetracker_update',
135 name='admin_settings_issuetracker_update',
136 pattern='/settings/issue-tracker/update')
136 pattern='/settings/issue-tracker/update')
137 config.add_route(
137 config.add_route(
138 name='admin_settings_issuetracker_test',
138 name='admin_settings_issuetracker_test',
139 pattern='/settings/issue-tracker/test')
139 pattern='/settings/issue-tracker/test')
140 config.add_route(
140 config.add_route(
141 name='admin_settings_issuetracker_delete',
141 name='admin_settings_issuetracker_delete',
142 pattern='/settings/issue-tracker/delete')
142 pattern='/settings/issue-tracker/delete')
143
143
144 config.add_route(
144 config.add_route(
145 name='admin_settings_email',
145 name='admin_settings_email',
146 pattern='/settings/email')
146 pattern='/settings/email')
147 config.add_route(
147 config.add_route(
148 name='admin_settings_email_update',
148 name='admin_settings_email_update',
149 pattern='/settings/email/update')
149 pattern='/settings/email/update')
150
150
151 config.add_route(
151 config.add_route(
152 name='admin_settings_hooks',
152 name='admin_settings_hooks',
153 pattern='/settings/hooks')
153 pattern='/settings/hooks')
154 config.add_route(
154 config.add_route(
155 name='admin_settings_hooks_update',
155 name='admin_settings_hooks_update',
156 pattern='/settings/hooks/update')
156 pattern='/settings/hooks/update')
157 config.add_route(
157 config.add_route(
158 name='admin_settings_hooks_delete',
158 name='admin_settings_hooks_delete',
159 pattern='/settings/hooks/delete')
159 pattern='/settings/hooks/delete')
160
160
161 config.add_route(
161 config.add_route(
162 name='admin_settings_search',
162 name='admin_settings_search',
163 pattern='/settings/search')
163 pattern='/settings/search')
164
164
165 config.add_route(
165 config.add_route(
166 name='admin_settings_labs',
166 name='admin_settings_labs',
167 pattern='/settings/labs')
167 pattern='/settings/labs')
168 config.add_route(
168 config.add_route(
169 name='admin_settings_labs_update',
169 name='admin_settings_labs_update',
170 pattern='/settings/labs/update')
170 pattern='/settings/labs/update')
171
171
172 # Automation EE feature
173 config.add_route(
174 'admin_settings_automation',
175 pattern=ADMIN_PREFIX + '/settings/automation')
176
172 # global permissions
177 # global permissions
173
178
174 config.add_route(
179 config.add_route(
175 name='admin_permissions_application',
180 name='admin_permissions_application',
176 pattern='/permissions/application')
181 pattern='/permissions/application')
177 config.add_route(
182 config.add_route(
178 name='admin_permissions_application_update',
183 name='admin_permissions_application_update',
179 pattern='/permissions/application/update')
184 pattern='/permissions/application/update')
180
185
181 config.add_route(
186 config.add_route(
182 name='admin_permissions_global',
187 name='admin_permissions_global',
183 pattern='/permissions/global')
188 pattern='/permissions/global')
184 config.add_route(
189 config.add_route(
185 name='admin_permissions_global_update',
190 name='admin_permissions_global_update',
186 pattern='/permissions/global/update')
191 pattern='/permissions/global/update')
187
192
188 config.add_route(
193 config.add_route(
189 name='admin_permissions_object',
194 name='admin_permissions_object',
190 pattern='/permissions/object')
195 pattern='/permissions/object')
191 config.add_route(
196 config.add_route(
192 name='admin_permissions_object_update',
197 name='admin_permissions_object_update',
193 pattern='/permissions/object/update')
198 pattern='/permissions/object/update')
194
199
195 config.add_route(
200 config.add_route(
196 name='admin_permissions_ips',
201 name='admin_permissions_ips',
197 pattern='/permissions/ips')
202 pattern='/permissions/ips')
198
203
199 config.add_route(
204 config.add_route(
200 name='admin_permissions_overview',
205 name='admin_permissions_overview',
201 pattern='/permissions/overview')
206 pattern='/permissions/overview')
202
207
203 config.add_route(
208 config.add_route(
204 name='admin_permissions_auth_token_access',
209 name='admin_permissions_auth_token_access',
205 pattern='/permissions/auth_token_access')
210 pattern='/permissions/auth_token_access')
206
211
207 config.add_route(
212 config.add_route(
208 name='admin_permissions_ssh_keys',
213 name='admin_permissions_ssh_keys',
209 pattern='/permissions/ssh_keys')
214 pattern='/permissions/ssh_keys')
210 config.add_route(
215 config.add_route(
211 name='admin_permissions_ssh_keys_data',
216 name='admin_permissions_ssh_keys_data',
212 pattern='/permissions/ssh_keys/data')
217 pattern='/permissions/ssh_keys/data')
213 config.add_route(
218 config.add_route(
214 name='admin_permissions_ssh_keys_update',
219 name='admin_permissions_ssh_keys_update',
215 pattern='/permissions/ssh_keys/update')
220 pattern='/permissions/ssh_keys/update')
216
221
217 # users admin
222 # users admin
218 config.add_route(
223 config.add_route(
219 name='users',
224 name='users',
220 pattern='/users')
225 pattern='/users')
221
226
222 config.add_route(
227 config.add_route(
223 name='users_data',
228 name='users_data',
224 pattern='/users_data')
229 pattern='/users_data')
225
230
226 config.add_route(
231 config.add_route(
227 name='users_create',
232 name='users_create',
228 pattern='/users/create')
233 pattern='/users/create')
229
234
230 config.add_route(
235 config.add_route(
231 name='users_new',
236 name='users_new',
232 pattern='/users/new')
237 pattern='/users/new')
233
238
234 # user management
239 # user management
235 config.add_route(
240 config.add_route(
236 name='user_edit',
241 name='user_edit',
237 pattern='/users/{user_id:\d+}/edit',
242 pattern='/users/{user_id:\d+}/edit',
238 user_route=True)
243 user_route=True)
239 config.add_route(
244 config.add_route(
240 name='user_edit_advanced',
245 name='user_edit_advanced',
241 pattern='/users/{user_id:\d+}/edit/advanced',
246 pattern='/users/{user_id:\d+}/edit/advanced',
242 user_route=True)
247 user_route=True)
243 config.add_route(
248 config.add_route(
244 name='user_edit_global_perms',
249 name='user_edit_global_perms',
245 pattern='/users/{user_id:\d+}/edit/global_permissions',
250 pattern='/users/{user_id:\d+}/edit/global_permissions',
246 user_route=True)
251 user_route=True)
247 config.add_route(
252 config.add_route(
248 name='user_edit_global_perms_update',
253 name='user_edit_global_perms_update',
249 pattern='/users/{user_id:\d+}/edit/global_permissions/update',
254 pattern='/users/{user_id:\d+}/edit/global_permissions/update',
250 user_route=True)
255 user_route=True)
251 config.add_route(
256 config.add_route(
252 name='user_update',
257 name='user_update',
253 pattern='/users/{user_id:\d+}/update',
258 pattern='/users/{user_id:\d+}/update',
254 user_route=True)
259 user_route=True)
255 config.add_route(
260 config.add_route(
256 name='user_delete',
261 name='user_delete',
257 pattern='/users/{user_id:\d+}/delete',
262 pattern='/users/{user_id:\d+}/delete',
258 user_route=True)
263 user_route=True)
259 config.add_route(
264 config.add_route(
260 name='user_force_password_reset',
265 name='user_force_password_reset',
261 pattern='/users/{user_id:\d+}/password_reset',
266 pattern='/users/{user_id:\d+}/password_reset',
262 user_route=True)
267 user_route=True)
263 config.add_route(
268 config.add_route(
264 name='user_create_personal_repo_group',
269 name='user_create_personal_repo_group',
265 pattern='/users/{user_id:\d+}/create_repo_group',
270 pattern='/users/{user_id:\d+}/create_repo_group',
266 user_route=True)
271 user_route=True)
267
272
268 # user auth tokens
273 # user auth tokens
269 config.add_route(
274 config.add_route(
270 name='edit_user_auth_tokens',
275 name='edit_user_auth_tokens',
271 pattern='/users/{user_id:\d+}/edit/auth_tokens',
276 pattern='/users/{user_id:\d+}/edit/auth_tokens',
272 user_route=True)
277 user_route=True)
273 config.add_route(
278 config.add_route(
274 name='edit_user_auth_tokens_add',
279 name='edit_user_auth_tokens_add',
275 pattern='/users/{user_id:\d+}/edit/auth_tokens/new',
280 pattern='/users/{user_id:\d+}/edit/auth_tokens/new',
276 user_route=True)
281 user_route=True)
277 config.add_route(
282 config.add_route(
278 name='edit_user_auth_tokens_delete',
283 name='edit_user_auth_tokens_delete',
279 pattern='/users/{user_id:\d+}/edit/auth_tokens/delete',
284 pattern='/users/{user_id:\d+}/edit/auth_tokens/delete',
280 user_route=True)
285 user_route=True)
281
286
282 # user ssh keys
287 # user ssh keys
283 config.add_route(
288 config.add_route(
284 name='edit_user_ssh_keys',
289 name='edit_user_ssh_keys',
285 pattern='/users/{user_id:\d+}/edit/ssh_keys',
290 pattern='/users/{user_id:\d+}/edit/ssh_keys',
286 user_route=True)
291 user_route=True)
287 config.add_route(
292 config.add_route(
288 name='edit_user_ssh_keys_generate_keypair',
293 name='edit_user_ssh_keys_generate_keypair',
289 pattern='/users/{user_id:\d+}/edit/ssh_keys/generate',
294 pattern='/users/{user_id:\d+}/edit/ssh_keys/generate',
290 user_route=True)
295 user_route=True)
291 config.add_route(
296 config.add_route(
292 name='edit_user_ssh_keys_add',
297 name='edit_user_ssh_keys_add',
293 pattern='/users/{user_id:\d+}/edit/ssh_keys/new',
298 pattern='/users/{user_id:\d+}/edit/ssh_keys/new',
294 user_route=True)
299 user_route=True)
295 config.add_route(
300 config.add_route(
296 name='edit_user_ssh_keys_delete',
301 name='edit_user_ssh_keys_delete',
297 pattern='/users/{user_id:\d+}/edit/ssh_keys/delete',
302 pattern='/users/{user_id:\d+}/edit/ssh_keys/delete',
298 user_route=True)
303 user_route=True)
299
304
300 # user emails
305 # user emails
301 config.add_route(
306 config.add_route(
302 name='edit_user_emails',
307 name='edit_user_emails',
303 pattern='/users/{user_id:\d+}/edit/emails',
308 pattern='/users/{user_id:\d+}/edit/emails',
304 user_route=True)
309 user_route=True)
305 config.add_route(
310 config.add_route(
306 name='edit_user_emails_add',
311 name='edit_user_emails_add',
307 pattern='/users/{user_id:\d+}/edit/emails/new',
312 pattern='/users/{user_id:\d+}/edit/emails/new',
308 user_route=True)
313 user_route=True)
309 config.add_route(
314 config.add_route(
310 name='edit_user_emails_delete',
315 name='edit_user_emails_delete',
311 pattern='/users/{user_id:\d+}/edit/emails/delete',
316 pattern='/users/{user_id:\d+}/edit/emails/delete',
312 user_route=True)
317 user_route=True)
313
318
314 # user IPs
319 # user IPs
315 config.add_route(
320 config.add_route(
316 name='edit_user_ips',
321 name='edit_user_ips',
317 pattern='/users/{user_id:\d+}/edit/ips',
322 pattern='/users/{user_id:\d+}/edit/ips',
318 user_route=True)
323 user_route=True)
319 config.add_route(
324 config.add_route(
320 name='edit_user_ips_add',
325 name='edit_user_ips_add',
321 pattern='/users/{user_id:\d+}/edit/ips/new',
326 pattern='/users/{user_id:\d+}/edit/ips/new',
322 user_route_with_default=True) # enabled for default user too
327 user_route_with_default=True) # enabled for default user too
323 config.add_route(
328 config.add_route(
324 name='edit_user_ips_delete',
329 name='edit_user_ips_delete',
325 pattern='/users/{user_id:\d+}/edit/ips/delete',
330 pattern='/users/{user_id:\d+}/edit/ips/delete',
326 user_route_with_default=True) # enabled for default user too
331 user_route_with_default=True) # enabled for default user too
327
332
328 # user perms
333 # user perms
329 config.add_route(
334 config.add_route(
330 name='edit_user_perms_summary',
335 name='edit_user_perms_summary',
331 pattern='/users/{user_id:\d+}/edit/permissions_summary',
336 pattern='/users/{user_id:\d+}/edit/permissions_summary',
332 user_route=True)
337 user_route=True)
333 config.add_route(
338 config.add_route(
334 name='edit_user_perms_summary_json',
339 name='edit_user_perms_summary_json',
335 pattern='/users/{user_id:\d+}/edit/permissions_summary/json',
340 pattern='/users/{user_id:\d+}/edit/permissions_summary/json',
336 user_route=True)
341 user_route=True)
337
342
338 # user user groups management
343 # user user groups management
339 config.add_route(
344 config.add_route(
340 name='edit_user_groups_management',
345 name='edit_user_groups_management',
341 pattern='/users/{user_id:\d+}/edit/groups_management',
346 pattern='/users/{user_id:\d+}/edit/groups_management',
342 user_route=True)
347 user_route=True)
343
348
344 config.add_route(
349 config.add_route(
345 name='edit_user_groups_management_updates',
350 name='edit_user_groups_management_updates',
346 pattern='/users/{user_id:\d+}/edit/edit_user_groups_management/updates',
351 pattern='/users/{user_id:\d+}/edit/edit_user_groups_management/updates',
347 user_route=True)
352 user_route=True)
348
353
349 # user audit logs
354 # user audit logs
350 config.add_route(
355 config.add_route(
351 name='edit_user_audit_logs',
356 name='edit_user_audit_logs',
352 pattern='/users/{user_id:\d+}/edit/audit', user_route=True)
357 pattern='/users/{user_id:\d+}/edit/audit', user_route=True)
353
358
354 # user-groups admin
359 # user-groups admin
355 config.add_route(
360 config.add_route(
356 name='user_groups',
361 name='user_groups',
357 pattern='/user_groups')
362 pattern='/user_groups')
358
363
359 config.add_route(
364 config.add_route(
360 name='user_groups_data',
365 name='user_groups_data',
361 pattern='/user_groups_data')
366 pattern='/user_groups_data')
362
367
363 config.add_route(
368 config.add_route(
364 name='user_groups_new',
369 name='user_groups_new',
365 pattern='/user_groups/new')
370 pattern='/user_groups/new')
366
371
367 config.add_route(
372 config.add_route(
368 name='user_groups_create',
373 name='user_groups_create',
369 pattern='/user_groups/create')
374 pattern='/user_groups/create')
370
375
371 # repos admin
376 # repos admin
372 config.add_route(
377 config.add_route(
373 name='repos',
378 name='repos',
374 pattern='/repos')
379 pattern='/repos')
375
380
376 config.add_route(
381 config.add_route(
377 name='repo_new',
382 name='repo_new',
378 pattern='/repos/new')
383 pattern='/repos/new')
379
384
380 config.add_route(
385 config.add_route(
381 name='repo_create',
386 name='repo_create',
382 pattern='/repos/create')
387 pattern='/repos/create')
383
388
384 # repo groups admin
389 # repo groups admin
385 config.add_route(
390 config.add_route(
386 name='repo_groups',
391 name='repo_groups',
387 pattern='/repo_groups')
392 pattern='/repo_groups')
388
393
389 config.add_route(
394 config.add_route(
390 name='repo_group_new',
395 name='repo_group_new',
391 pattern='/repo_group/new')
396 pattern='/repo_group/new')
392
397
393 config.add_route(
398 config.add_route(
394 name='repo_group_create',
399 name='repo_group_create',
395 pattern='/repo_group/create')
400 pattern='/repo_group/create')
396
401
397
402
398 def includeme(config):
403 def includeme(config):
399 from rhodecode.apps.admin.navigation import includeme as nav_includeme
404 from rhodecode.apps.admin.navigation import includeme as nav_includeme
400
405
401 # Create admin navigation registry and add it to the pyramid registry.
406 # Create admin navigation registry and add it to the pyramid registry.
402 nav_includeme(config)
407 nav_includeme(config)
403
408
404 # main admin routes
409 # main admin routes
405 config.add_route(name='admin_home', pattern=ADMIN_PREFIX)
410 config.add_route(name='admin_home', pattern=ADMIN_PREFIX)
406 config.include(admin_routes, route_prefix=ADMIN_PREFIX)
411 config.include(admin_routes, route_prefix=ADMIN_PREFIX)
407
412
408 # Scan module for configuration decorators.
413 # Scan module for configuration decorators.
409 config.scan('.views', ignore='.tests')
414 config.scan('.views', ignore='.tests')
@@ -1,143 +1,144 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2018 RhodeCode GmbH
3 # Copyright (C) 2016-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 import logging
22 import logging
23 import collections
23 import collections
24
24
25 from zope.interface import implementer
25 from zope.interface import implementer
26
26
27 from rhodecode.apps.admin.interfaces import IAdminNavigationRegistry
27 from rhodecode.apps.admin.interfaces import IAdminNavigationRegistry
28 from rhodecode.lib.utils2 import str2bool
28 from rhodecode.lib.utils2 import str2bool
29 from rhodecode.translation import _
29 from rhodecode.translation import _
30
30
31
31
32 log = logging.getLogger(__name__)
32 log = logging.getLogger(__name__)
33
33
34 NavListEntry = collections.namedtuple(
34 NavListEntry = collections.namedtuple(
35 'NavListEntry', ['key', 'name', 'url', 'active_list'])
35 'NavListEntry', ['key', 'name', 'url', 'active_list'])
36
36
37
37
38 class NavEntry(object):
38 class NavEntry(object):
39 """
39 """
40 Represents an entry in the admin navigation.
40 Represents an entry in the admin navigation.
41
41
42 :param key: Unique identifier used to store reference in an OrderedDict.
42 :param key: Unique identifier used to store reference in an OrderedDict.
43 :param name: Display name, usually a translation string.
43 :param name: Display name, usually a translation string.
44 :param view_name: Name of the view, used generate the URL.
44 :param view_name: Name of the view, used generate the URL.
45 :param active_list: list of urls that we select active for this element
45 :param active_list: list of urls that we select active for this element
46 """
46 """
47
47
48 def __init__(self, key, name, view_name, active_list=None):
48 def __init__(self, key, name, view_name, active_list=None):
49 self.key = key
49 self.key = key
50 self.name = name
50 self.name = name
51 self.view_name = view_name
51 self.view_name = view_name
52 self._active_list = active_list or []
52 self._active_list = active_list or []
53
53
54 def generate_url(self, request):
54 def generate_url(self, request):
55 return request.route_path(self.view_name)
55 return request.route_path(self.view_name)
56
56
57 def get_localized_name(self, request):
57 def get_localized_name(self, request):
58 return request.translate(self.name)
58 return request.translate(self.name)
59
59
60 @property
60 @property
61 def active_list(self):
61 def active_list(self):
62 active_list = [self.key]
62 active_list = [self.key]
63 if self._active_list:
63 if self._active_list:
64 active_list = self._active_list
64 active_list = self._active_list
65 return active_list
65 return active_list
66
66
67
67
68 @implementer(IAdminNavigationRegistry)
68 @implementer(IAdminNavigationRegistry)
69 class NavigationRegistry(object):
69 class NavigationRegistry(object):
70
70
71 _base_entries = [
71 _base_entries = [
72 NavEntry('global', _('Global'),
72 NavEntry('global', _('Global'),
73 'admin_settings_global'),
73 'admin_settings_global'),
74 NavEntry('vcs', _('VCS'),
74 NavEntry('vcs', _('VCS'),
75 'admin_settings_vcs'),
75 'admin_settings_vcs'),
76 NavEntry('visual', _('Visual'),
76 NavEntry('visual', _('Visual'),
77 'admin_settings_visual'),
77 'admin_settings_visual'),
78 NavEntry('mapping', _('Remap and Rescan'),
78 NavEntry('mapping', _('Remap and Rescan'),
79 'admin_settings_mapping'),
79 'admin_settings_mapping'),
80 NavEntry('issuetracker', _('Issue Tracker'),
80 NavEntry('issuetracker', _('Issue Tracker'),
81 'admin_settings_issuetracker'),
81 'admin_settings_issuetracker'),
82 NavEntry('email', _('Email'),
82 NavEntry('email', _('Email'),
83 'admin_settings_email'),
83 'admin_settings_email'),
84 NavEntry('hooks', _('Hooks'),
84 NavEntry('hooks', _('Hooks'),
85 'admin_settings_hooks'),
85 'admin_settings_hooks'),
86 NavEntry('search', _('Full Text Search'),
86 NavEntry('search', _('Full Text Search'),
87 'admin_settings_search'),
87 'admin_settings_search'),
88 NavEntry('integrations', _('Integrations'),
88 NavEntry('integrations', _('Integrations'),
89 'global_integrations_home'),
89 'global_integrations_home'),
90 NavEntry('system', _('System Info'),
90 NavEntry('system', _('System Info'),
91 'admin_settings_system'),
91 'admin_settings_system'),
92 NavEntry('process_management', _('Processes'),
92 NavEntry('process_management', _('Processes'),
93 'admin_settings_process_management'),
93 'admin_settings_process_management'),
94 NavEntry('sessions', _('User Sessions'),
94 NavEntry('sessions', _('User Sessions'),
95 'admin_settings_sessions'),
95 'admin_settings_sessions'),
96 NavEntry('open_source', _('Open Source Licenses'),
96 NavEntry('open_source', _('Open Source Licenses'),
97 'admin_settings_open_source'),
97 'admin_settings_open_source'),
98
98 NavEntry('automation', _('Automation'),
99 'admin_settings_automation')
99 ]
100 ]
100
101
101 _labs_entry = NavEntry('labs', _('Labs'),
102 _labs_entry = NavEntry('labs', _('Labs'),
102 'admin_settings_labs')
103 'admin_settings_labs')
103
104
104 def __init__(self, labs_active=False):
105 def __init__(self, labs_active=False):
105 self._registered_entries = collections.OrderedDict()
106 self._registered_entries = collections.OrderedDict()
106 for item in self.__class__._base_entries:
107 for item in self.__class__._base_entries:
107 self._registered_entries[item.key] = item
108 self._registered_entries[item.key] = item
108
109
109 if labs_active:
110 if labs_active:
110 self.add_entry(self._labs_entry)
111 self.add_entry(self._labs_entry)
111
112
112 def add_entry(self, entry):
113 def add_entry(self, entry):
113 self._registered_entries[entry.key] = entry
114 self._registered_entries[entry.key] = entry
114
115
115 def get_navlist(self, request):
116 def get_navlist(self, request):
116 navlist = [NavListEntry(i.key, i.get_localized_name(request),
117 navlist = [NavListEntry(i.key, i.get_localized_name(request),
117 i.generate_url(request), i.active_list)
118 i.generate_url(request), i.active_list)
118 for i in self._registered_entries.values()]
119 for i in self._registered_entries.values()]
119 return navlist
120 return navlist
120
121
121
122
122 def navigation_registry(request, registry=None):
123 def navigation_registry(request, registry=None):
123 """
124 """
124 Helper that returns the admin navigation registry.
125 Helper that returns the admin navigation registry.
125 """
126 """
126 pyramid_registry = registry or request.registry
127 pyramid_registry = registry or request.registry
127 nav_registry = pyramid_registry.queryUtility(IAdminNavigationRegistry)
128 nav_registry = pyramid_registry.queryUtility(IAdminNavigationRegistry)
128 return nav_registry
129 return nav_registry
129
130
130
131
131 def navigation_list(request):
132 def navigation_list(request):
132 """
133 """
133 Helper that returns the admin navigation as list of NavListEntry objects.
134 Helper that returns the admin navigation as list of NavListEntry objects.
134 """
135 """
135 return navigation_registry(request).get_navlist(request)
136 return navigation_registry(request).get_navlist(request)
136
137
137
138
138 def includeme(config):
139 def includeme(config):
139 # Create admin navigation registry and add it to the pyramid registry.
140 # Create admin navigation registry and add it to the pyramid registry.
140 settings = config.get_settings()
141 settings = config.get_settings()
141 labs_active = str2bool(settings.get('labs_settings_active', False))
142 labs_active = str2bool(settings.get('labs_settings_active', False))
142 navigation_registry = NavigationRegistry(labs_active=labs_active)
143 navigation_registry = NavigationRegistry(labs_active=labs_active)
143 config.registry.registerUtility(navigation_registry) No newline at end of file
144 config.registry.registerUtility(navigation_registry)
@@ -1,770 +1,781 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2018 RhodeCode GmbH
3 # Copyright (C) 2010-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 import logging
22 import logging
23 import collections
23 import collections
24
24
25 import datetime
25 import datetime
26 import formencode
26 import formencode
27 import formencode.htmlfill
27 import formencode.htmlfill
28
28
29 import rhodecode
29 import rhodecode
30 from pyramid.view import view_config
30 from pyramid.view import view_config
31 from pyramid.httpexceptions import HTTPFound, HTTPNotFound
31 from pyramid.httpexceptions import HTTPFound, HTTPNotFound
32 from pyramid.renderers import render
32 from pyramid.renderers import render
33 from pyramid.response import Response
33 from pyramid.response import Response
34
34
35 from rhodecode.apps._base import BaseAppView
35 from rhodecode.apps._base import BaseAppView
36 from rhodecode.apps.admin.navigation import navigation_list
36 from rhodecode.apps.admin.navigation import navigation_list
37 from rhodecode.apps.svn_support.config_keys import generate_config
37 from rhodecode.apps.svn_support.config_keys import generate_config
38 from rhodecode.lib import helpers as h
38 from rhodecode.lib import helpers as h
39 from rhodecode.lib.auth import (
39 from rhodecode.lib.auth import (
40 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
40 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
41 from rhodecode.lib.celerylib import tasks, run_task
41 from rhodecode.lib.celerylib import tasks, run_task
42 from rhodecode.lib.utils import repo2db_mapper
42 from rhodecode.lib.utils import repo2db_mapper
43 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict
43 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict
44 from rhodecode.lib.index import searcher_from_config
44 from rhodecode.lib.index import searcher_from_config
45
45
46 from rhodecode.model.db import RhodeCodeUi, Repository
46 from rhodecode.model.db import RhodeCodeUi, Repository
47 from rhodecode.model.forms import (ApplicationSettingsForm,
47 from rhodecode.model.forms import (ApplicationSettingsForm,
48 ApplicationUiSettingsForm, ApplicationVisualisationForm,
48 ApplicationUiSettingsForm, ApplicationVisualisationForm,
49 LabsSettingsForm, IssueTrackerPatternsForm)
49 LabsSettingsForm, IssueTrackerPatternsForm)
50 from rhodecode.model.repo_group import RepoGroupModel
50 from rhodecode.model.repo_group import RepoGroupModel
51
51
52 from rhodecode.model.scm import ScmModel
52 from rhodecode.model.scm import ScmModel
53 from rhodecode.model.notification import EmailNotificationModel
53 from rhodecode.model.notification import EmailNotificationModel
54 from rhodecode.model.meta import Session
54 from rhodecode.model.meta import Session
55 from rhodecode.model.settings import (
55 from rhodecode.model.settings import (
56 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
56 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
57 SettingsModel)
57 SettingsModel)
58
58
59
59
60 log = logging.getLogger(__name__)
60 log = logging.getLogger(__name__)
61
61
62
62
63 class AdminSettingsView(BaseAppView):
63 class AdminSettingsView(BaseAppView):
64
64
65 def load_default_context(self):
65 def load_default_context(self):
66 c = self._get_local_tmpl_context()
66 c = self._get_local_tmpl_context()
67 c.labs_active = str2bool(
67 c.labs_active = str2bool(
68 rhodecode.CONFIG.get('labs_settings_active', 'true'))
68 rhodecode.CONFIG.get('labs_settings_active', 'true'))
69 c.navlist = navigation_list(self.request)
69 c.navlist = navigation_list(self.request)
70
70
71 return c
71 return c
72
72
73 @classmethod
73 @classmethod
74 def _get_ui_settings(cls):
74 def _get_ui_settings(cls):
75 ret = RhodeCodeUi.query().all()
75 ret = RhodeCodeUi.query().all()
76
76
77 if not ret:
77 if not ret:
78 raise Exception('Could not get application ui settings !')
78 raise Exception('Could not get application ui settings !')
79 settings = {}
79 settings = {}
80 for each in ret:
80 for each in ret:
81 k = each.ui_key
81 k = each.ui_key
82 v = each.ui_value
82 v = each.ui_value
83 if k == '/':
83 if k == '/':
84 k = 'root_path'
84 k = 'root_path'
85
85
86 if k in ['push_ssl', 'publish', 'enabled']:
86 if k in ['push_ssl', 'publish', 'enabled']:
87 v = str2bool(v)
87 v = str2bool(v)
88
88
89 if k.find('.') != -1:
89 if k.find('.') != -1:
90 k = k.replace('.', '_')
90 k = k.replace('.', '_')
91
91
92 if each.ui_section in ['hooks', 'extensions']:
92 if each.ui_section in ['hooks', 'extensions']:
93 v = each.ui_active
93 v = each.ui_active
94
94
95 settings[each.ui_section + '_' + k] = v
95 settings[each.ui_section + '_' + k] = v
96 return settings
96 return settings
97
97
98 @classmethod
98 @classmethod
99 def _form_defaults(cls):
99 def _form_defaults(cls):
100 defaults = SettingsModel().get_all_settings()
100 defaults = SettingsModel().get_all_settings()
101 defaults.update(cls._get_ui_settings())
101 defaults.update(cls._get_ui_settings())
102
102
103 defaults.update({
103 defaults.update({
104 'new_svn_branch': '',
104 'new_svn_branch': '',
105 'new_svn_tag': '',
105 'new_svn_tag': '',
106 })
106 })
107 return defaults
107 return defaults
108
108
109 @LoginRequired()
109 @LoginRequired()
110 @HasPermissionAllDecorator('hg.admin')
110 @HasPermissionAllDecorator('hg.admin')
111 @view_config(
111 @view_config(
112 route_name='admin_settings_vcs', request_method='GET',
112 route_name='admin_settings_vcs', request_method='GET',
113 renderer='rhodecode:templates/admin/settings/settings.mako')
113 renderer='rhodecode:templates/admin/settings/settings.mako')
114 def settings_vcs(self):
114 def settings_vcs(self):
115 c = self.load_default_context()
115 c = self.load_default_context()
116 c.active = 'vcs'
116 c.active = 'vcs'
117 model = VcsSettingsModel()
117 model = VcsSettingsModel()
118 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
118 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
119 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
119 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
120
120
121 settings = self.request.registry.settings
121 settings = self.request.registry.settings
122 c.svn_proxy_generate_config = settings[generate_config]
122 c.svn_proxy_generate_config = settings[generate_config]
123
123
124 defaults = self._form_defaults()
124 defaults = self._form_defaults()
125
125
126 model.create_largeobjects_dirs_if_needed(defaults['paths_root_path'])
126 model.create_largeobjects_dirs_if_needed(defaults['paths_root_path'])
127
127
128 data = render('rhodecode:templates/admin/settings/settings.mako',
128 data = render('rhodecode:templates/admin/settings/settings.mako',
129 self._get_template_context(c), self.request)
129 self._get_template_context(c), self.request)
130 html = formencode.htmlfill.render(
130 html = formencode.htmlfill.render(
131 data,
131 data,
132 defaults=defaults,
132 defaults=defaults,
133 encoding="UTF-8",
133 encoding="UTF-8",
134 force_defaults=False
134 force_defaults=False
135 )
135 )
136 return Response(html)
136 return Response(html)
137
137
138 @LoginRequired()
138 @LoginRequired()
139 @HasPermissionAllDecorator('hg.admin')
139 @HasPermissionAllDecorator('hg.admin')
140 @CSRFRequired()
140 @CSRFRequired()
141 @view_config(
141 @view_config(
142 route_name='admin_settings_vcs_update', request_method='POST',
142 route_name='admin_settings_vcs_update', request_method='POST',
143 renderer='rhodecode:templates/admin/settings/settings.mako')
143 renderer='rhodecode:templates/admin/settings/settings.mako')
144 def settings_vcs_update(self):
144 def settings_vcs_update(self):
145 _ = self.request.translate
145 _ = self.request.translate
146 c = self.load_default_context()
146 c = self.load_default_context()
147 c.active = 'vcs'
147 c.active = 'vcs'
148
148
149 model = VcsSettingsModel()
149 model = VcsSettingsModel()
150 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
150 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
151 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
151 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
152
152
153 settings = self.request.registry.settings
153 settings = self.request.registry.settings
154 c.svn_proxy_generate_config = settings[generate_config]
154 c.svn_proxy_generate_config = settings[generate_config]
155
155
156 application_form = ApplicationUiSettingsForm(self.request.translate)()
156 application_form = ApplicationUiSettingsForm(self.request.translate)()
157
157
158 try:
158 try:
159 form_result = application_form.to_python(dict(self.request.POST))
159 form_result = application_form.to_python(dict(self.request.POST))
160 except formencode.Invalid as errors:
160 except formencode.Invalid as errors:
161 h.flash(
161 h.flash(
162 _("Some form inputs contain invalid data."),
162 _("Some form inputs contain invalid data."),
163 category='error')
163 category='error')
164 data = render('rhodecode:templates/admin/settings/settings.mako',
164 data = render('rhodecode:templates/admin/settings/settings.mako',
165 self._get_template_context(c), self.request)
165 self._get_template_context(c), self.request)
166 html = formencode.htmlfill.render(
166 html = formencode.htmlfill.render(
167 data,
167 data,
168 defaults=errors.value,
168 defaults=errors.value,
169 errors=errors.error_dict or {},
169 errors=errors.error_dict or {},
170 prefix_error=False,
170 prefix_error=False,
171 encoding="UTF-8",
171 encoding="UTF-8",
172 force_defaults=False
172 force_defaults=False
173 )
173 )
174 return Response(html)
174 return Response(html)
175
175
176 try:
176 try:
177 if c.visual.allow_repo_location_change:
177 if c.visual.allow_repo_location_change:
178 model.update_global_path_setting(
178 model.update_global_path_setting(
179 form_result['paths_root_path'])
179 form_result['paths_root_path'])
180
180
181 model.update_global_ssl_setting(form_result['web_push_ssl'])
181 model.update_global_ssl_setting(form_result['web_push_ssl'])
182 model.update_global_hook_settings(form_result)
182 model.update_global_hook_settings(form_result)
183
183
184 model.create_or_update_global_svn_settings(form_result)
184 model.create_or_update_global_svn_settings(form_result)
185 model.create_or_update_global_hg_settings(form_result)
185 model.create_or_update_global_hg_settings(form_result)
186 model.create_or_update_global_git_settings(form_result)
186 model.create_or_update_global_git_settings(form_result)
187 model.create_or_update_global_pr_settings(form_result)
187 model.create_or_update_global_pr_settings(form_result)
188 except Exception:
188 except Exception:
189 log.exception("Exception while updating settings")
189 log.exception("Exception while updating settings")
190 h.flash(_('Error occurred during updating '
190 h.flash(_('Error occurred during updating '
191 'application settings'), category='error')
191 'application settings'), category='error')
192 else:
192 else:
193 Session().commit()
193 Session().commit()
194 h.flash(_('Updated VCS settings'), category='success')
194 h.flash(_('Updated VCS settings'), category='success')
195 raise HTTPFound(h.route_path('admin_settings_vcs'))
195 raise HTTPFound(h.route_path('admin_settings_vcs'))
196
196
197 data = render('rhodecode:templates/admin/settings/settings.mako',
197 data = render('rhodecode:templates/admin/settings/settings.mako',
198 self._get_template_context(c), self.request)
198 self._get_template_context(c), self.request)
199 html = formencode.htmlfill.render(
199 html = formencode.htmlfill.render(
200 data,
200 data,
201 defaults=self._form_defaults(),
201 defaults=self._form_defaults(),
202 encoding="UTF-8",
202 encoding="UTF-8",
203 force_defaults=False
203 force_defaults=False
204 )
204 )
205 return Response(html)
205 return Response(html)
206
206
207 @LoginRequired()
207 @LoginRequired()
208 @HasPermissionAllDecorator('hg.admin')
208 @HasPermissionAllDecorator('hg.admin')
209 @CSRFRequired()
209 @CSRFRequired()
210 @view_config(
210 @view_config(
211 route_name='admin_settings_vcs_svn_pattern_delete', request_method='POST',
211 route_name='admin_settings_vcs_svn_pattern_delete', request_method='POST',
212 renderer='json_ext', xhr=True)
212 renderer='json_ext', xhr=True)
213 def settings_vcs_delete_svn_pattern(self):
213 def settings_vcs_delete_svn_pattern(self):
214 delete_pattern_id = self.request.POST.get('delete_svn_pattern')
214 delete_pattern_id = self.request.POST.get('delete_svn_pattern')
215 model = VcsSettingsModel()
215 model = VcsSettingsModel()
216 try:
216 try:
217 model.delete_global_svn_pattern(delete_pattern_id)
217 model.delete_global_svn_pattern(delete_pattern_id)
218 except SettingNotFound:
218 except SettingNotFound:
219 log.exception(
219 log.exception(
220 'Failed to delete svn_pattern with id %s', delete_pattern_id)
220 'Failed to delete svn_pattern with id %s', delete_pattern_id)
221 raise HTTPNotFound()
221 raise HTTPNotFound()
222
222
223 Session().commit()
223 Session().commit()
224 return True
224 return True
225
225
226 @LoginRequired()
226 @LoginRequired()
227 @HasPermissionAllDecorator('hg.admin')
227 @HasPermissionAllDecorator('hg.admin')
228 @view_config(
228 @view_config(
229 route_name='admin_settings_mapping', request_method='GET',
229 route_name='admin_settings_mapping', request_method='GET',
230 renderer='rhodecode:templates/admin/settings/settings.mako')
230 renderer='rhodecode:templates/admin/settings/settings.mako')
231 def settings_mapping(self):
231 def settings_mapping(self):
232 c = self.load_default_context()
232 c = self.load_default_context()
233 c.active = 'mapping'
233 c.active = 'mapping'
234
234
235 data = render('rhodecode:templates/admin/settings/settings.mako',
235 data = render('rhodecode:templates/admin/settings/settings.mako',
236 self._get_template_context(c), self.request)
236 self._get_template_context(c), self.request)
237 html = formencode.htmlfill.render(
237 html = formencode.htmlfill.render(
238 data,
238 data,
239 defaults=self._form_defaults(),
239 defaults=self._form_defaults(),
240 encoding="UTF-8",
240 encoding="UTF-8",
241 force_defaults=False
241 force_defaults=False
242 )
242 )
243 return Response(html)
243 return Response(html)
244
244
245 @LoginRequired()
245 @LoginRequired()
246 @HasPermissionAllDecorator('hg.admin')
246 @HasPermissionAllDecorator('hg.admin')
247 @CSRFRequired()
247 @CSRFRequired()
248 @view_config(
248 @view_config(
249 route_name='admin_settings_mapping_update', request_method='POST',
249 route_name='admin_settings_mapping_update', request_method='POST',
250 renderer='rhodecode:templates/admin/settings/settings.mako')
250 renderer='rhodecode:templates/admin/settings/settings.mako')
251 def settings_mapping_update(self):
251 def settings_mapping_update(self):
252 _ = self.request.translate
252 _ = self.request.translate
253 c = self.load_default_context()
253 c = self.load_default_context()
254 c.active = 'mapping'
254 c.active = 'mapping'
255 rm_obsolete = self.request.POST.get('destroy', False)
255 rm_obsolete = self.request.POST.get('destroy', False)
256 invalidate_cache = self.request.POST.get('invalidate', False)
256 invalidate_cache = self.request.POST.get('invalidate', False)
257 log.debug(
257 log.debug(
258 'rescanning repo location with destroy obsolete=%s', rm_obsolete)
258 'rescanning repo location with destroy obsolete=%s', rm_obsolete)
259
259
260 if invalidate_cache:
260 if invalidate_cache:
261 log.debug('invalidating all repositories cache')
261 log.debug('invalidating all repositories cache')
262 for repo in Repository.get_all():
262 for repo in Repository.get_all():
263 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
263 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
264
264
265 filesystem_repos = ScmModel().repo_scan()
265 filesystem_repos = ScmModel().repo_scan()
266 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
266 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
267 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
267 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
268 h.flash(_('Repositories successfully '
268 h.flash(_('Repositories successfully '
269 'rescanned added: %s ; removed: %s') %
269 'rescanned added: %s ; removed: %s') %
270 (_repr(added), _repr(removed)),
270 (_repr(added), _repr(removed)),
271 category='success')
271 category='success')
272 raise HTTPFound(h.route_path('admin_settings_mapping'))
272 raise HTTPFound(h.route_path('admin_settings_mapping'))
273
273
274 @LoginRequired()
274 @LoginRequired()
275 @HasPermissionAllDecorator('hg.admin')
275 @HasPermissionAllDecorator('hg.admin')
276 @view_config(
276 @view_config(
277 route_name='admin_settings', request_method='GET',
277 route_name='admin_settings', request_method='GET',
278 renderer='rhodecode:templates/admin/settings/settings.mako')
278 renderer='rhodecode:templates/admin/settings/settings.mako')
279 @view_config(
279 @view_config(
280 route_name='admin_settings_global', request_method='GET',
280 route_name='admin_settings_global', request_method='GET',
281 renderer='rhodecode:templates/admin/settings/settings.mako')
281 renderer='rhodecode:templates/admin/settings/settings.mako')
282 def settings_global(self):
282 def settings_global(self):
283 c = self.load_default_context()
283 c = self.load_default_context()
284 c.active = 'global'
284 c.active = 'global'
285 c.personal_repo_group_default_pattern = RepoGroupModel()\
285 c.personal_repo_group_default_pattern = RepoGroupModel()\
286 .get_personal_group_name_pattern()
286 .get_personal_group_name_pattern()
287
287
288 data = render('rhodecode:templates/admin/settings/settings.mako',
288 data = render('rhodecode:templates/admin/settings/settings.mako',
289 self._get_template_context(c), self.request)
289 self._get_template_context(c), self.request)
290 html = formencode.htmlfill.render(
290 html = formencode.htmlfill.render(
291 data,
291 data,
292 defaults=self._form_defaults(),
292 defaults=self._form_defaults(),
293 encoding="UTF-8",
293 encoding="UTF-8",
294 force_defaults=False
294 force_defaults=False
295 )
295 )
296 return Response(html)
296 return Response(html)
297
297
298 @LoginRequired()
298 @LoginRequired()
299 @HasPermissionAllDecorator('hg.admin')
299 @HasPermissionAllDecorator('hg.admin')
300 @CSRFRequired()
300 @CSRFRequired()
301 @view_config(
301 @view_config(
302 route_name='admin_settings_update', request_method='POST',
302 route_name='admin_settings_update', request_method='POST',
303 renderer='rhodecode:templates/admin/settings/settings.mako')
303 renderer='rhodecode:templates/admin/settings/settings.mako')
304 @view_config(
304 @view_config(
305 route_name='admin_settings_global_update', request_method='POST',
305 route_name='admin_settings_global_update', request_method='POST',
306 renderer='rhodecode:templates/admin/settings/settings.mako')
306 renderer='rhodecode:templates/admin/settings/settings.mako')
307 def settings_global_update(self):
307 def settings_global_update(self):
308 _ = self.request.translate
308 _ = self.request.translate
309 c = self.load_default_context()
309 c = self.load_default_context()
310 c.active = 'global'
310 c.active = 'global'
311 c.personal_repo_group_default_pattern = RepoGroupModel()\
311 c.personal_repo_group_default_pattern = RepoGroupModel()\
312 .get_personal_group_name_pattern()
312 .get_personal_group_name_pattern()
313 application_form = ApplicationSettingsForm(self.request.translate)()
313 application_form = ApplicationSettingsForm(self.request.translate)()
314 try:
314 try:
315 form_result = application_form.to_python(dict(self.request.POST))
315 form_result = application_form.to_python(dict(self.request.POST))
316 except formencode.Invalid as errors:
316 except formencode.Invalid as errors:
317 h.flash(
317 h.flash(
318 _("Some form inputs contain invalid data."),
318 _("Some form inputs contain invalid data."),
319 category='error')
319 category='error')
320 data = render('rhodecode:templates/admin/settings/settings.mako',
320 data = render('rhodecode:templates/admin/settings/settings.mako',
321 self._get_template_context(c), self.request)
321 self._get_template_context(c), self.request)
322 html = formencode.htmlfill.render(
322 html = formencode.htmlfill.render(
323 data,
323 data,
324 defaults=errors.value,
324 defaults=errors.value,
325 errors=errors.error_dict or {},
325 errors=errors.error_dict or {},
326 prefix_error=False,
326 prefix_error=False,
327 encoding="UTF-8",
327 encoding="UTF-8",
328 force_defaults=False
328 force_defaults=False
329 )
329 )
330 return Response(html)
330 return Response(html)
331
331
332 settings = [
332 settings = [
333 ('title', 'rhodecode_title', 'unicode'),
333 ('title', 'rhodecode_title', 'unicode'),
334 ('realm', 'rhodecode_realm', 'unicode'),
334 ('realm', 'rhodecode_realm', 'unicode'),
335 ('pre_code', 'rhodecode_pre_code', 'unicode'),
335 ('pre_code', 'rhodecode_pre_code', 'unicode'),
336 ('post_code', 'rhodecode_post_code', 'unicode'),
336 ('post_code', 'rhodecode_post_code', 'unicode'),
337 ('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'),
337 ('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'),
338 ('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'),
338 ('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'),
339 ('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'),
339 ('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'),
340 ('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'),
340 ('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'),
341 ]
341 ]
342 try:
342 try:
343 for setting, form_key, type_ in settings:
343 for setting, form_key, type_ in settings:
344 sett = SettingsModel().create_or_update_setting(
344 sett = SettingsModel().create_or_update_setting(
345 setting, form_result[form_key], type_)
345 setting, form_result[form_key], type_)
346 Session().add(sett)
346 Session().add(sett)
347
347
348 Session().commit()
348 Session().commit()
349 SettingsModel().invalidate_settings_cache()
349 SettingsModel().invalidate_settings_cache()
350 h.flash(_('Updated application settings'), category='success')
350 h.flash(_('Updated application settings'), category='success')
351 except Exception:
351 except Exception:
352 log.exception("Exception while updating application settings")
352 log.exception("Exception while updating application settings")
353 h.flash(
353 h.flash(
354 _('Error occurred during updating application settings'),
354 _('Error occurred during updating application settings'),
355 category='error')
355 category='error')
356
356
357 raise HTTPFound(h.route_path('admin_settings_global'))
357 raise HTTPFound(h.route_path('admin_settings_global'))
358
358
359 @LoginRequired()
359 @LoginRequired()
360 @HasPermissionAllDecorator('hg.admin')
360 @HasPermissionAllDecorator('hg.admin')
361 @view_config(
361 @view_config(
362 route_name='admin_settings_visual', request_method='GET',
362 route_name='admin_settings_visual', request_method='GET',
363 renderer='rhodecode:templates/admin/settings/settings.mako')
363 renderer='rhodecode:templates/admin/settings/settings.mako')
364 def settings_visual(self):
364 def settings_visual(self):
365 c = self.load_default_context()
365 c = self.load_default_context()
366 c.active = 'visual'
366 c.active = 'visual'
367
367
368 data = render('rhodecode:templates/admin/settings/settings.mako',
368 data = render('rhodecode:templates/admin/settings/settings.mako',
369 self._get_template_context(c), self.request)
369 self._get_template_context(c), self.request)
370 html = formencode.htmlfill.render(
370 html = formencode.htmlfill.render(
371 data,
371 data,
372 defaults=self._form_defaults(),
372 defaults=self._form_defaults(),
373 encoding="UTF-8",
373 encoding="UTF-8",
374 force_defaults=False
374 force_defaults=False
375 )
375 )
376 return Response(html)
376 return Response(html)
377
377
378 @LoginRequired()
378 @LoginRequired()
379 @HasPermissionAllDecorator('hg.admin')
379 @HasPermissionAllDecorator('hg.admin')
380 @CSRFRequired()
380 @CSRFRequired()
381 @view_config(
381 @view_config(
382 route_name='admin_settings_visual_update', request_method='POST',
382 route_name='admin_settings_visual_update', request_method='POST',
383 renderer='rhodecode:templates/admin/settings/settings.mako')
383 renderer='rhodecode:templates/admin/settings/settings.mako')
384 def settings_visual_update(self):
384 def settings_visual_update(self):
385 _ = self.request.translate
385 _ = self.request.translate
386 c = self.load_default_context()
386 c = self.load_default_context()
387 c.active = 'visual'
387 c.active = 'visual'
388 application_form = ApplicationVisualisationForm(self.request.translate)()
388 application_form = ApplicationVisualisationForm(self.request.translate)()
389 try:
389 try:
390 form_result = application_form.to_python(dict(self.request.POST))
390 form_result = application_form.to_python(dict(self.request.POST))
391 except formencode.Invalid as errors:
391 except formencode.Invalid as errors:
392 h.flash(
392 h.flash(
393 _("Some form inputs contain invalid data."),
393 _("Some form inputs contain invalid data."),
394 category='error')
394 category='error')
395 data = render('rhodecode:templates/admin/settings/settings.mako',
395 data = render('rhodecode:templates/admin/settings/settings.mako',
396 self._get_template_context(c), self.request)
396 self._get_template_context(c), self.request)
397 html = formencode.htmlfill.render(
397 html = formencode.htmlfill.render(
398 data,
398 data,
399 defaults=errors.value,
399 defaults=errors.value,
400 errors=errors.error_dict or {},
400 errors=errors.error_dict or {},
401 prefix_error=False,
401 prefix_error=False,
402 encoding="UTF-8",
402 encoding="UTF-8",
403 force_defaults=False
403 force_defaults=False
404 )
404 )
405 return Response(html)
405 return Response(html)
406
406
407 try:
407 try:
408 settings = [
408 settings = [
409 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
409 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
410 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
410 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
411 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
411 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
412 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
412 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
413 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
413 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
414 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
414 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
415 ('show_version', 'rhodecode_show_version', 'bool'),
415 ('show_version', 'rhodecode_show_version', 'bool'),
416 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
416 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
417 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
417 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
418 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
418 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
419 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
419 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
420 ('clone_uri_ssh_tmpl', 'rhodecode_clone_uri_ssh_tmpl', 'unicode'),
420 ('clone_uri_ssh_tmpl', 'rhodecode_clone_uri_ssh_tmpl', 'unicode'),
421 ('support_url', 'rhodecode_support_url', 'unicode'),
421 ('support_url', 'rhodecode_support_url', 'unicode'),
422 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
422 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
423 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
423 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
424 ]
424 ]
425 for setting, form_key, type_ in settings:
425 for setting, form_key, type_ in settings:
426 sett = SettingsModel().create_or_update_setting(
426 sett = SettingsModel().create_or_update_setting(
427 setting, form_result[form_key], type_)
427 setting, form_result[form_key], type_)
428 Session().add(sett)
428 Session().add(sett)
429
429
430 Session().commit()
430 Session().commit()
431 SettingsModel().invalidate_settings_cache()
431 SettingsModel().invalidate_settings_cache()
432 h.flash(_('Updated visualisation settings'), category='success')
432 h.flash(_('Updated visualisation settings'), category='success')
433 except Exception:
433 except Exception:
434 log.exception("Exception updating visualization settings")
434 log.exception("Exception updating visualization settings")
435 h.flash(_('Error occurred during updating '
435 h.flash(_('Error occurred during updating '
436 'visualisation settings'),
436 'visualisation settings'),
437 category='error')
437 category='error')
438
438
439 raise HTTPFound(h.route_path('admin_settings_visual'))
439 raise HTTPFound(h.route_path('admin_settings_visual'))
440
440
441 @LoginRequired()
441 @LoginRequired()
442 @HasPermissionAllDecorator('hg.admin')
442 @HasPermissionAllDecorator('hg.admin')
443 @view_config(
443 @view_config(
444 route_name='admin_settings_issuetracker', request_method='GET',
444 route_name='admin_settings_issuetracker', request_method='GET',
445 renderer='rhodecode:templates/admin/settings/settings.mako')
445 renderer='rhodecode:templates/admin/settings/settings.mako')
446 def settings_issuetracker(self):
446 def settings_issuetracker(self):
447 c = self.load_default_context()
447 c = self.load_default_context()
448 c.active = 'issuetracker'
448 c.active = 'issuetracker'
449 defaults = SettingsModel().get_all_settings()
449 defaults = SettingsModel().get_all_settings()
450
450
451 entry_key = 'rhodecode_issuetracker_pat_'
451 entry_key = 'rhodecode_issuetracker_pat_'
452
452
453 c.issuetracker_entries = {}
453 c.issuetracker_entries = {}
454 for k, v in defaults.items():
454 for k, v in defaults.items():
455 if k.startswith(entry_key):
455 if k.startswith(entry_key):
456 uid = k[len(entry_key):]
456 uid = k[len(entry_key):]
457 c.issuetracker_entries[uid] = None
457 c.issuetracker_entries[uid] = None
458
458
459 for uid in c.issuetracker_entries:
459 for uid in c.issuetracker_entries:
460 c.issuetracker_entries[uid] = AttributeDict({
460 c.issuetracker_entries[uid] = AttributeDict({
461 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
461 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
462 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
462 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
463 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
463 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
464 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
464 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
465 })
465 })
466
466
467 return self._get_template_context(c)
467 return self._get_template_context(c)
468
468
469 @LoginRequired()
469 @LoginRequired()
470 @HasPermissionAllDecorator('hg.admin')
470 @HasPermissionAllDecorator('hg.admin')
471 @CSRFRequired()
471 @CSRFRequired()
472 @view_config(
472 @view_config(
473 route_name='admin_settings_issuetracker_test', request_method='POST',
473 route_name='admin_settings_issuetracker_test', request_method='POST',
474 renderer='string', xhr=True)
474 renderer='string', xhr=True)
475 def settings_issuetracker_test(self):
475 def settings_issuetracker_test(self):
476 return h.urlify_commit_message(
476 return h.urlify_commit_message(
477 self.request.POST.get('test_text', ''),
477 self.request.POST.get('test_text', ''),
478 'repo_group/test_repo1')
478 'repo_group/test_repo1')
479
479
480 @LoginRequired()
480 @LoginRequired()
481 @HasPermissionAllDecorator('hg.admin')
481 @HasPermissionAllDecorator('hg.admin')
482 @CSRFRequired()
482 @CSRFRequired()
483 @view_config(
483 @view_config(
484 route_name='admin_settings_issuetracker_update', request_method='POST',
484 route_name='admin_settings_issuetracker_update', request_method='POST',
485 renderer='rhodecode:templates/admin/settings/settings.mako')
485 renderer='rhodecode:templates/admin/settings/settings.mako')
486 def settings_issuetracker_update(self):
486 def settings_issuetracker_update(self):
487 _ = self.request.translate
487 _ = self.request.translate
488 self.load_default_context()
488 self.load_default_context()
489 settings_model = IssueTrackerSettingsModel()
489 settings_model = IssueTrackerSettingsModel()
490
490
491 try:
491 try:
492 form = IssueTrackerPatternsForm(self.request.translate)()
492 form = IssueTrackerPatternsForm(self.request.translate)()
493 data = form.to_python(self.request.POST)
493 data = form.to_python(self.request.POST)
494 except formencode.Invalid as errors:
494 except formencode.Invalid as errors:
495 log.exception('Failed to add new pattern')
495 log.exception('Failed to add new pattern')
496 error = errors
496 error = errors
497 h.flash(_('Invalid issue tracker pattern: {}'.format(error)),
497 h.flash(_('Invalid issue tracker pattern: {}'.format(error)),
498 category='error')
498 category='error')
499 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
499 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
500
500
501 if data:
501 if data:
502 for uid in data.get('delete_patterns', []):
502 for uid in data.get('delete_patterns', []):
503 settings_model.delete_entries(uid)
503 settings_model.delete_entries(uid)
504
504
505 for pattern in data.get('patterns', []):
505 for pattern in data.get('patterns', []):
506 for setting, value, type_ in pattern:
506 for setting, value, type_ in pattern:
507 sett = settings_model.create_or_update_setting(
507 sett = settings_model.create_or_update_setting(
508 setting, value, type_)
508 setting, value, type_)
509 Session().add(sett)
509 Session().add(sett)
510
510
511 Session().commit()
511 Session().commit()
512
512
513 SettingsModel().invalidate_settings_cache()
513 SettingsModel().invalidate_settings_cache()
514 h.flash(_('Updated issue tracker entries'), category='success')
514 h.flash(_('Updated issue tracker entries'), category='success')
515 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
515 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
516
516
517 @LoginRequired()
517 @LoginRequired()
518 @HasPermissionAllDecorator('hg.admin')
518 @HasPermissionAllDecorator('hg.admin')
519 @CSRFRequired()
519 @CSRFRequired()
520 @view_config(
520 @view_config(
521 route_name='admin_settings_issuetracker_delete', request_method='POST',
521 route_name='admin_settings_issuetracker_delete', request_method='POST',
522 renderer='rhodecode:templates/admin/settings/settings.mako')
522 renderer='rhodecode:templates/admin/settings/settings.mako')
523 def settings_issuetracker_delete(self):
523 def settings_issuetracker_delete(self):
524 _ = self.request.translate
524 _ = self.request.translate
525 self.load_default_context()
525 self.load_default_context()
526 uid = self.request.POST.get('uid')
526 uid = self.request.POST.get('uid')
527 try:
527 try:
528 IssueTrackerSettingsModel().delete_entries(uid)
528 IssueTrackerSettingsModel().delete_entries(uid)
529 except Exception:
529 except Exception:
530 log.exception('Failed to delete issue tracker setting %s', uid)
530 log.exception('Failed to delete issue tracker setting %s', uid)
531 raise HTTPNotFound()
531 raise HTTPNotFound()
532 h.flash(_('Removed issue tracker entry'), category='success')
532 h.flash(_('Removed issue tracker entry'), category='success')
533 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
533 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
534
534
535 @LoginRequired()
535 @LoginRequired()
536 @HasPermissionAllDecorator('hg.admin')
536 @HasPermissionAllDecorator('hg.admin')
537 @view_config(
537 @view_config(
538 route_name='admin_settings_email', request_method='GET',
538 route_name='admin_settings_email', request_method='GET',
539 renderer='rhodecode:templates/admin/settings/settings.mako')
539 renderer='rhodecode:templates/admin/settings/settings.mako')
540 def settings_email(self):
540 def settings_email(self):
541 c = self.load_default_context()
541 c = self.load_default_context()
542 c.active = 'email'
542 c.active = 'email'
543 c.rhodecode_ini = rhodecode.CONFIG
543 c.rhodecode_ini = rhodecode.CONFIG
544
544
545 data = render('rhodecode:templates/admin/settings/settings.mako',
545 data = render('rhodecode:templates/admin/settings/settings.mako',
546 self._get_template_context(c), self.request)
546 self._get_template_context(c), self.request)
547 html = formencode.htmlfill.render(
547 html = formencode.htmlfill.render(
548 data,
548 data,
549 defaults=self._form_defaults(),
549 defaults=self._form_defaults(),
550 encoding="UTF-8",
550 encoding="UTF-8",
551 force_defaults=False
551 force_defaults=False
552 )
552 )
553 return Response(html)
553 return Response(html)
554
554
555 @LoginRequired()
555 @LoginRequired()
556 @HasPermissionAllDecorator('hg.admin')
556 @HasPermissionAllDecorator('hg.admin')
557 @CSRFRequired()
557 @CSRFRequired()
558 @view_config(
558 @view_config(
559 route_name='admin_settings_email_update', request_method='POST',
559 route_name='admin_settings_email_update', request_method='POST',
560 renderer='rhodecode:templates/admin/settings/settings.mako')
560 renderer='rhodecode:templates/admin/settings/settings.mako')
561 def settings_email_update(self):
561 def settings_email_update(self):
562 _ = self.request.translate
562 _ = self.request.translate
563 c = self.load_default_context()
563 c = self.load_default_context()
564 c.active = 'email'
564 c.active = 'email'
565
565
566 test_email = self.request.POST.get('test_email')
566 test_email = self.request.POST.get('test_email')
567
567
568 if not test_email:
568 if not test_email:
569 h.flash(_('Please enter email address'), category='error')
569 h.flash(_('Please enter email address'), category='error')
570 raise HTTPFound(h.route_path('admin_settings_email'))
570 raise HTTPFound(h.route_path('admin_settings_email'))
571
571
572 email_kwargs = {
572 email_kwargs = {
573 'date': datetime.datetime.now(),
573 'date': datetime.datetime.now(),
574 'user': c.rhodecode_user,
574 'user': c.rhodecode_user,
575 'rhodecode_version': c.rhodecode_version
575 'rhodecode_version': c.rhodecode_version
576 }
576 }
577
577
578 (subject, headers, email_body,
578 (subject, headers, email_body,
579 email_body_plaintext) = EmailNotificationModel().render_email(
579 email_body_plaintext) = EmailNotificationModel().render_email(
580 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
580 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
581
581
582 recipients = [test_email] if test_email else None
582 recipients = [test_email] if test_email else None
583
583
584 run_task(tasks.send_email, recipients, subject,
584 run_task(tasks.send_email, recipients, subject,
585 email_body_plaintext, email_body)
585 email_body_plaintext, email_body)
586
586
587 h.flash(_('Send email task created'), category='success')
587 h.flash(_('Send email task created'), category='success')
588 raise HTTPFound(h.route_path('admin_settings_email'))
588 raise HTTPFound(h.route_path('admin_settings_email'))
589
589
590 @LoginRequired()
590 @LoginRequired()
591 @HasPermissionAllDecorator('hg.admin')
591 @HasPermissionAllDecorator('hg.admin')
592 @view_config(
592 @view_config(
593 route_name='admin_settings_hooks', request_method='GET',
593 route_name='admin_settings_hooks', request_method='GET',
594 renderer='rhodecode:templates/admin/settings/settings.mako')
594 renderer='rhodecode:templates/admin/settings/settings.mako')
595 def settings_hooks(self):
595 def settings_hooks(self):
596 c = self.load_default_context()
596 c = self.load_default_context()
597 c.active = 'hooks'
597 c.active = 'hooks'
598
598
599 model = SettingsModel()
599 model = SettingsModel()
600 c.hooks = model.get_builtin_hooks()
600 c.hooks = model.get_builtin_hooks()
601 c.custom_hooks = model.get_custom_hooks()
601 c.custom_hooks = model.get_custom_hooks()
602
602
603 data = render('rhodecode:templates/admin/settings/settings.mako',
603 data = render('rhodecode:templates/admin/settings/settings.mako',
604 self._get_template_context(c), self.request)
604 self._get_template_context(c), self.request)
605 html = formencode.htmlfill.render(
605 html = formencode.htmlfill.render(
606 data,
606 data,
607 defaults=self._form_defaults(),
607 defaults=self._form_defaults(),
608 encoding="UTF-8",
608 encoding="UTF-8",
609 force_defaults=False
609 force_defaults=False
610 )
610 )
611 return Response(html)
611 return Response(html)
612
612
613 @LoginRequired()
613 @LoginRequired()
614 @HasPermissionAllDecorator('hg.admin')
614 @HasPermissionAllDecorator('hg.admin')
615 @CSRFRequired()
615 @CSRFRequired()
616 @view_config(
616 @view_config(
617 route_name='admin_settings_hooks_update', request_method='POST',
617 route_name='admin_settings_hooks_update', request_method='POST',
618 renderer='rhodecode:templates/admin/settings/settings.mako')
618 renderer='rhodecode:templates/admin/settings/settings.mako')
619 @view_config(
619 @view_config(
620 route_name='admin_settings_hooks_delete', request_method='POST',
620 route_name='admin_settings_hooks_delete', request_method='POST',
621 renderer='rhodecode:templates/admin/settings/settings.mako')
621 renderer='rhodecode:templates/admin/settings/settings.mako')
622 def settings_hooks_update(self):
622 def settings_hooks_update(self):
623 _ = self.request.translate
623 _ = self.request.translate
624 c = self.load_default_context()
624 c = self.load_default_context()
625 c.active = 'hooks'
625 c.active = 'hooks'
626 if c.visual.allow_custom_hooks_settings:
626 if c.visual.allow_custom_hooks_settings:
627 ui_key = self.request.POST.get('new_hook_ui_key')
627 ui_key = self.request.POST.get('new_hook_ui_key')
628 ui_value = self.request.POST.get('new_hook_ui_value')
628 ui_value = self.request.POST.get('new_hook_ui_value')
629
629
630 hook_id = self.request.POST.get('hook_id')
630 hook_id = self.request.POST.get('hook_id')
631 new_hook = False
631 new_hook = False
632
632
633 model = SettingsModel()
633 model = SettingsModel()
634 try:
634 try:
635 if ui_value and ui_key:
635 if ui_value and ui_key:
636 model.create_or_update_hook(ui_key, ui_value)
636 model.create_or_update_hook(ui_key, ui_value)
637 h.flash(_('Added new hook'), category='success')
637 h.flash(_('Added new hook'), category='success')
638 new_hook = True
638 new_hook = True
639 elif hook_id:
639 elif hook_id:
640 RhodeCodeUi.delete(hook_id)
640 RhodeCodeUi.delete(hook_id)
641 Session().commit()
641 Session().commit()
642
642
643 # check for edits
643 # check for edits
644 update = False
644 update = False
645 _d = self.request.POST.dict_of_lists()
645 _d = self.request.POST.dict_of_lists()
646 for k, v in zip(_d.get('hook_ui_key', []),
646 for k, v in zip(_d.get('hook_ui_key', []),
647 _d.get('hook_ui_value_new', [])):
647 _d.get('hook_ui_value_new', [])):
648 model.create_or_update_hook(k, v)
648 model.create_or_update_hook(k, v)
649 update = True
649 update = True
650
650
651 if update and not new_hook:
651 if update and not new_hook:
652 h.flash(_('Updated hooks'), category='success')
652 h.flash(_('Updated hooks'), category='success')
653 Session().commit()
653 Session().commit()
654 except Exception:
654 except Exception:
655 log.exception("Exception during hook creation")
655 log.exception("Exception during hook creation")
656 h.flash(_('Error occurred during hook creation'),
656 h.flash(_('Error occurred during hook creation'),
657 category='error')
657 category='error')
658
658
659 raise HTTPFound(h.route_path('admin_settings_hooks'))
659 raise HTTPFound(h.route_path('admin_settings_hooks'))
660
660
661 @LoginRequired()
661 @LoginRequired()
662 @HasPermissionAllDecorator('hg.admin')
662 @HasPermissionAllDecorator('hg.admin')
663 @view_config(
663 @view_config(
664 route_name='admin_settings_search', request_method='GET',
664 route_name='admin_settings_search', request_method='GET',
665 renderer='rhodecode:templates/admin/settings/settings.mako')
665 renderer='rhodecode:templates/admin/settings/settings.mako')
666 def settings_search(self):
666 def settings_search(self):
667 c = self.load_default_context()
667 c = self.load_default_context()
668 c.active = 'search'
668 c.active = 'search'
669
669
670 searcher = searcher_from_config(self.request.registry.settings)
670 searcher = searcher_from_config(self.request.registry.settings)
671 c.statistics = searcher.statistics(self.request.translate)
671 c.statistics = searcher.statistics(self.request.translate)
672
672
673 return self._get_template_context(c)
673 return self._get_template_context(c)
674
674
675 @LoginRequired()
675 @LoginRequired()
676 @HasPermissionAllDecorator('hg.admin')
676 @HasPermissionAllDecorator('hg.admin')
677 @view_config(
677 @view_config(
678 route_name='admin_settings_automation', request_method='GET',
679 renderer='rhodecode:templates/admin/settings/settings.mako')
680 def settings_automation(self):
681 c = self.load_default_context()
682 c.active = 'automation'
683
684 return self._get_template_context(c)
685
686 @LoginRequired()
687 @HasPermissionAllDecorator('hg.admin')
688 @view_config(
678 route_name='admin_settings_labs', request_method='GET',
689 route_name='admin_settings_labs', request_method='GET',
679 renderer='rhodecode:templates/admin/settings/settings.mako')
690 renderer='rhodecode:templates/admin/settings/settings.mako')
680 def settings_labs(self):
691 def settings_labs(self):
681 c = self.load_default_context()
692 c = self.load_default_context()
682 if not c.labs_active:
693 if not c.labs_active:
683 raise HTTPFound(h.route_path('admin_settings'))
694 raise HTTPFound(h.route_path('admin_settings'))
684
695
685 c.active = 'labs'
696 c.active = 'labs'
686 c.lab_settings = _LAB_SETTINGS
697 c.lab_settings = _LAB_SETTINGS
687
698
688 data = render('rhodecode:templates/admin/settings/settings.mako',
699 data = render('rhodecode:templates/admin/settings/settings.mako',
689 self._get_template_context(c), self.request)
700 self._get_template_context(c), self.request)
690 html = formencode.htmlfill.render(
701 html = formencode.htmlfill.render(
691 data,
702 data,
692 defaults=self._form_defaults(),
703 defaults=self._form_defaults(),
693 encoding="UTF-8",
704 encoding="UTF-8",
694 force_defaults=False
705 force_defaults=False
695 )
706 )
696 return Response(html)
707 return Response(html)
697
708
698 @LoginRequired()
709 @LoginRequired()
699 @HasPermissionAllDecorator('hg.admin')
710 @HasPermissionAllDecorator('hg.admin')
700 @CSRFRequired()
711 @CSRFRequired()
701 @view_config(
712 @view_config(
702 route_name='admin_settings_labs_update', request_method='POST',
713 route_name='admin_settings_labs_update', request_method='POST',
703 renderer='rhodecode:templates/admin/settings/settings.mako')
714 renderer='rhodecode:templates/admin/settings/settings.mako')
704 def settings_labs_update(self):
715 def settings_labs_update(self):
705 _ = self.request.translate
716 _ = self.request.translate
706 c = self.load_default_context()
717 c = self.load_default_context()
707 c.active = 'labs'
718 c.active = 'labs'
708
719
709 application_form = LabsSettingsForm(self.request.translate)()
720 application_form = LabsSettingsForm(self.request.translate)()
710 try:
721 try:
711 form_result = application_form.to_python(dict(self.request.POST))
722 form_result = application_form.to_python(dict(self.request.POST))
712 except formencode.Invalid as errors:
723 except formencode.Invalid as errors:
713 h.flash(
724 h.flash(
714 _("Some form inputs contain invalid data."),
725 _("Some form inputs contain invalid data."),
715 category='error')
726 category='error')
716 data = render('rhodecode:templates/admin/settings/settings.mako',
727 data = render('rhodecode:templates/admin/settings/settings.mako',
717 self._get_template_context(c), self.request)
728 self._get_template_context(c), self.request)
718 html = formencode.htmlfill.render(
729 html = formencode.htmlfill.render(
719 data,
730 data,
720 defaults=errors.value,
731 defaults=errors.value,
721 errors=errors.error_dict or {},
732 errors=errors.error_dict or {},
722 prefix_error=False,
733 prefix_error=False,
723 encoding="UTF-8",
734 encoding="UTF-8",
724 force_defaults=False
735 force_defaults=False
725 )
736 )
726 return Response(html)
737 return Response(html)
727
738
728 try:
739 try:
729 session = Session()
740 session = Session()
730 for setting in _LAB_SETTINGS:
741 for setting in _LAB_SETTINGS:
731 setting_name = setting.key[len('rhodecode_'):]
742 setting_name = setting.key[len('rhodecode_'):]
732 sett = SettingsModel().create_or_update_setting(
743 sett = SettingsModel().create_or_update_setting(
733 setting_name, form_result[setting.key], setting.type)
744 setting_name, form_result[setting.key], setting.type)
734 session.add(sett)
745 session.add(sett)
735
746
736 except Exception:
747 except Exception:
737 log.exception('Exception while updating lab settings')
748 log.exception('Exception while updating lab settings')
738 h.flash(_('Error occurred during updating labs settings'),
749 h.flash(_('Error occurred during updating labs settings'),
739 category='error')
750 category='error')
740 else:
751 else:
741 Session().commit()
752 Session().commit()
742 SettingsModel().invalidate_settings_cache()
753 SettingsModel().invalidate_settings_cache()
743 h.flash(_('Updated Labs settings'), category='success')
754 h.flash(_('Updated Labs settings'), category='success')
744 raise HTTPFound(h.route_path('admin_settings_labs'))
755 raise HTTPFound(h.route_path('admin_settings_labs'))
745
756
746 data = render('rhodecode:templates/admin/settings/settings.mako',
757 data = render('rhodecode:templates/admin/settings/settings.mako',
747 self._get_template_context(c), self.request)
758 self._get_template_context(c), self.request)
748 html = formencode.htmlfill.render(
759 html = formencode.htmlfill.render(
749 data,
760 data,
750 defaults=self._form_defaults(),
761 defaults=self._form_defaults(),
751 encoding="UTF-8",
762 encoding="UTF-8",
752 force_defaults=False
763 force_defaults=False
753 )
764 )
754 return Response(html)
765 return Response(html)
755
766
756
767
757 # :param key: name of the setting including the 'rhodecode_' prefix
768 # :param key: name of the setting including the 'rhodecode_' prefix
758 # :param type: the RhodeCodeSetting type to use.
769 # :param type: the RhodeCodeSetting type to use.
759 # :param group: the i18ned group in which we should dispaly this setting
770 # :param group: the i18ned group in which we should dispaly this setting
760 # :param label: the i18ned label we should display for this setting
771 # :param label: the i18ned label we should display for this setting
761 # :param help: the i18ned help we should dispaly for this setting
772 # :param help: the i18ned help we should dispaly for this setting
762 LabSetting = collections.namedtuple(
773 LabSetting = collections.namedtuple(
763 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
774 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
764
775
765
776
766 # This list has to be kept in sync with the form
777 # This list has to be kept in sync with the form
767 # rhodecode.model.forms.LabsSettingsForm.
778 # rhodecode.model.forms.LabsSettingsForm.
768 _LAB_SETTINGS = [
779 _LAB_SETTINGS = [
769
780
770 ]
781 ]
General Comments 0
You need to be logged in to leave comments. Login now