def test_title_change(self): self.log_user() old_title = 'Kallithea' new_title = old_title + '_changed' old_realm = 'Kallithea authentication' for new_title in ['Changed', 'Żółwik', old_title]: response = self.app.post( url('admin_settings_global'), params=dict( title=new_title, realm=old_realm, ga_code='', captcha_private_key='', captcha_public_key='', _authentication_token=self.authentication_token(), )) self.checkSessionFlash(response, 'Updated application settings') assert Setting.get_app_settings()['title'] == new_title.decode( 'utf-8') response = response.follow() response.mustcontain("""<span class="branding">%s</span>""" % new_title)
def settings_system_update(self): """GET /admin/settings/system/updates: All items in the collection""" # url('admin_settings_system_update') import json import urllib2 from kallithea.lib.verlib import NormalizedVersion from kallithea import __version__ defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) _update_url = defaults.get('update_url', '') _update_url = "" # FIXME: disabled _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">%s</div>' % (s) try: import kallithea ver = kallithea.__version__ log.debug('Checking for upgrade on `%s` server' % _update_url) opener = urllib2.build_opener() opener.addheaders = [('User-agent', 'Kallithea-SCM/%s' % ver)] response = opener.open(_update_url) response_data = response.read() data = json.loads(response_data) except urllib2.URLError, e: log.error(traceback.format_exc()) return _err('Failed to contact upgrade server: %r' % e)
def settings_mapping(self): """GET /admin/settings/mapping: All items in the collection""" # url('admin_settings_mapping') c.active = 'mapping' if request.POST: rm_obsolete = request.POST.get('destroy', False) install_git_hooks = request.POST.get('hooks', False) invalidate_cache = request.POST.get('invalidate', False) log.debug('rescanning repo location with destroy obsolete=%s and ' 'install git hooks=%s' % (rm_obsolete,install_git_hooks)) if invalidate_cache: log.debug('invalidating all repositories cache') for repo in Repository.get_all(): ScmModel().mark_for_invalidation(repo.repo_name, delete=True) filesystem_repos = ScmModel().repo_scan() added, removed = repo2db_mapper(filesystem_repos, rm_obsolete, install_git_hook=install_git_hooks, user=c.authuser.username) h.flash(h.literal(_('Repositories successfully rescanned. Added: %s. Removed: %s.') % (', '.join(h.link_to(safe_unicode(repo_name), h.url('summary_home', repo_name=repo_name)) for repo_name in added) or '-', ', '.join(h.escape(safe_unicode(repo_name)) for repo_name in removed) or '-')), category='success') return redirect(url('admin_settings_mapping')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def password_reset(self): settings = Setting.get_app_settings() captcha_private_key = settings.get('captcha_private_key') c.captcha_active = bool(captcha_private_key) c.captcha_public_key = settings.get('captcha_public_key') if request.POST: password_reset_form = PasswordResetForm()() try: form_result = password_reset_form.to_python(dict(request.POST)) if c.captcha_active: from kallithea.lib.recaptcha import submit response = submit(request.POST.get('recaptcha_challenge_field'), request.POST.get('recaptcha_response_field'), private_key=captcha_private_key, remoteip=self.ip_addr) if c.captcha_active and not response.is_valid: _value = form_result _msg = _('bad captcha') error_dict = {'recaptcha_field': _msg} raise formencode.Invalid(_msg, _value, None, error_dict=error_dict) UserModel().reset_password_link(form_result) h.flash(_('Your password reset link was sent'), category='success') return redirect(url('login_home')) except formencode.Invalid, errors: return htmlfill.render( render('/password_reset.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False)
def settings_global(self): """GET /admin/settings/global: All items in the collection""" # url('admin_settings_global') c.active = 'global' if request.POST: application_form = ApplicationSettingsForm()() try: form_result = application_form.to_python(dict(request.POST)) except formencode.Invalid as errors: return htmlfill.render( render('admin/settings/settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) try: sett1 = Setting.create_or_update('title', form_result['title']) Session().add(sett1) sett2 = Setting.create_or_update('realm', form_result['realm']) Session().add(sett2) sett3 = Setting.create_or_update('ga_code', form_result['ga_code']) Session().add(sett3) sett4 = Setting.create_or_update('captcha_public_key', form_result['captcha_public_key']) Session().add(sett4) sett5 = Setting.create_or_update('captcha_private_key', form_result['captcha_private_key']) Session().add(sett5) Session().commit() set_app_settings(config) h.flash(_('Updated application settings'), category='success') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred while updating ' 'application settings'), category='error') raise HTTPFound(location=url('admin_settings_global')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def __before__(self): """ __before__ is called before controller methods and after __call__ """ c.kallithea_version = __version__ rc_config = Setting.get_app_settings() # Visual options c.visual = AttributeDict({}) ## DB stored c.visual.show_public_icon = str2bool(rc_config.get('show_public_icon')) c.visual.show_private_icon = str2bool(rc_config.get('show_private_icon')) c.visual.stylify_metatags = str2bool(rc_config.get('stylify_metatags')) c.visual.dashboard_items = safe_int(rc_config.get('dashboard_items', 100)) c.visual.admin_grid_items = safe_int(rc_config.get('admin_grid_items', 100)) c.visual.repository_fields = str2bool(rc_config.get('repository_fields')) c.visual.show_version = str2bool(rc_config.get('show_version')) c.visual.use_gravatar = str2bool(rc_config.get('use_gravatar')) c.visual.gravatar_url = rc_config.get('gravatar_url') c.ga_code = rc_config.get('ga_code') # TODO: replace undocumented backwards compatibility hack with db upgrade and rename ga_code if c.ga_code and '<' not in c.ga_code: c.ga_code = '''<script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', '%s']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script>''' % c.ga_code c.site_name = rc_config.get('title') c.clone_uri_tmpl = rc_config.get('clone_uri_tmpl') ## INI stored c.visual.allow_repo_location_change = str2bool(config.get('allow_repo_location_change', True)) c.visual.allow_custom_hooks_settings = str2bool(config.get('allow_custom_hooks_settings', True)) c.instance_id = config.get('instance_id') c.issues_url = config.get('bugtracker', url('issues_url')) # END CONFIG VARS c.repo_name = get_repo_slug(request) # can be empty c.backends = BACKENDS.keys() c.unread_notifications = NotificationModel() \ .get_unread_cnt_for_user(c.authuser.user_id) self.cut_off_limit = safe_int(config.get('cut_off_limit')) c.my_pr_count = PullRequestModel().get_pullrequest_cnt_for_user(c.authuser.user_id) self.sa = meta.Session self.scm_model = ScmModel(self.sa)
def settings_visual(self): """GET /admin/settings/visual: All items in the collection""" # url('admin_settings_visual') c.active = 'visual' if request.POST: application_form = ApplicationVisualisationForm()() try: form_result = application_form.to_python(dict(request.POST)) except formencode.Invalid as errors: return htmlfill.render( render('admin/settings/settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) try: settings = [ ('show_public_icon', 'show_public_icon', 'bool'), ('show_private_icon', 'show_private_icon', 'bool'), ('stylify_metatags', 'stylify_metatags', 'bool'), ('repository_fields', 'repository_fields', 'bool'), ('dashboard_items', 'dashboard_items', 'int'), ('admin_grid_items', 'admin_grid_items', 'int'), ('show_version', 'show_version', 'bool'), ('use_gravatar', 'use_gravatar', 'bool'), ('gravatar_url', 'gravatar_url', 'unicode'), ('clone_uri_tmpl', 'clone_uri_tmpl', 'unicode'), ] for setting, form_key, type_ in settings: sett = Setting.create_or_update(setting, form_result[form_key], type_) Session().add(sett) Session().commit() set_app_settings(config) h.flash(_('Updated visualisation settings'), category='success') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during updating ' 'visualisation settings'), category='error') raise HTTPFound(location=url('admin_settings_visual')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def _before(self, *args, **kwargs): """ _before is called before controller methods and after __call__ """ c.kallithea_version = __version__ rc_config = Setting.get_app_settings() # Visual options c.visual = AttributeDict({}) ## DB stored c.visual.show_public_icon = str2bool(rc_config.get('show_public_icon')) c.visual.show_private_icon = str2bool(rc_config.get('show_private_icon')) c.visual.stylify_metatags = str2bool(rc_config.get('stylify_metatags')) c.visual.page_size = safe_int(rc_config.get('dashboard_items', 100)) c.visual.admin_grid_items = safe_int(rc_config.get('admin_grid_items', 100)) c.visual.repository_fields = str2bool(rc_config.get('repository_fields')) c.visual.show_version = str2bool(rc_config.get('show_version')) c.visual.use_gravatar = str2bool(rc_config.get('use_gravatar')) c.visual.gravatar_url = rc_config.get('gravatar_url') c.ga_code = rc_config.get('ga_code') # TODO: replace undocumented backwards compatibility hack with db upgrade and rename ga_code if c.ga_code and '<' not in c.ga_code: c.ga_code = '''<script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', '%s']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script>''' % c.ga_code c.site_name = rc_config.get('title') c.clone_uri_tmpl = rc_config.get('clone_uri_tmpl') ## INI stored c.visual.allow_repo_location_change = str2bool(config.get('allow_repo_location_change', True)) c.visual.allow_custom_hooks_settings = str2bool(config.get('allow_custom_hooks_settings', True)) c.instance_id = config.get('instance_id') c.issues_url = config.get('bugtracker', url('issues_url')) # END CONFIG VARS c.repo_name = get_repo_slug(request) # can be empty c.backends = BACKENDS.keys() c.unread_notifications = NotificationModel() \ .get_unread_cnt_for_user(request.authuser.user_id) self.cut_off_limit = safe_int(config.get('cut_off_limit')) c.my_pr_count = PullRequest.query(reviewer_id=request.authuser.user_id, include_closed=False).count() self.scm_model = ScmModel()
def set_app_settings(config): """ Updates pylons config with new settings from database :param config: """ hgsettings = Setting.get_app_settings() for k, v in hgsettings.items(): config[k] = v
def set_app_settings(config): """ Updates app config with new settings from database :param config: """ hgsettings = Setting.get_app_settings() for k, v in hgsettings.items(): config[k] = v config['base_path'] = Ui.get_repos_location()
def settings_hooks(self): c.active = 'hooks' if request.POST: if c.visual.allow_custom_hooks_settings: ui_key = request.POST.get('new_hook_ui_key') ui_value = request.POST.get('new_hook_ui_value') hook_id = request.POST.get('hook_id') try: ui_key = ui_key and ui_key.strip() if ui_key in (x.ui_key for x in Ui.get_custom_hooks()): h.flash(_('Hook already exists'), category='error') elif ui_key in (x.ui_key for x in Ui.get_builtin_hooks()): h.flash(_('Builtin hooks are read-only. Please use another hook name.'), category='error') elif ui_value and ui_key: Ui.create_or_update_hook(ui_key, ui_value) h.flash(_('Added new hook'), category='success') elif hook_id: Ui.delete(hook_id) Session().commit() # check for edits update = False _d = request.POST.dict_of_lists() for k, v, ov in zip(_d.get('hook_ui_key', []), _d.get('hook_ui_value_new', []), _d.get('hook_ui_value', [])): if v != ov: Ui.create_or_update_hook(k, v) update = True if update: h.flash(_('Updated hooks'), category='success') Session().commit() except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during hook creation'), category='error') raise HTTPFound(location=url('admin_settings_hooks')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) c.hooks = Ui.get_builtin_hooks() c.custom_hooks = Ui.get_custom_hooks() return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def settings_visual(self): c.active = 'visual' if request.POST: application_form = ApplicationVisualisationForm()() try: form_result = application_form.to_python(dict(request.POST)) except formencode.Invalid as errors: return htmlfill.render( render('admin/settings/settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) try: settings = [ ('show_public_icon', 'show_public_icon', 'bool'), ('show_private_icon', 'show_private_icon', 'bool'), ('stylify_metalabels', 'stylify_metalabels', 'bool'), ('repository_fields', 'repository_fields', 'bool'), ('dashboard_items', 'dashboard_items', 'int'), ('admin_grid_items', 'admin_grid_items', 'int'), ('show_version', 'show_version', 'bool'), ('use_gravatar', 'use_gravatar', 'bool'), ('gravatar_url', 'gravatar_url', 'unicode'), ('clone_uri_tmpl', 'clone_uri_tmpl', 'unicode'), ('clone_ssh_tmpl', 'clone_ssh_tmpl', 'unicode'), ] for setting, form_key, type_ in settings: Setting.create_or_update(setting, form_result[form_key], type_) Session().commit() set_app_settings(config) h.flash(_('Updated visualisation settings'), category='success') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during updating ' 'visualisation settings'), category='error') raise HTTPFound(location=url('admin_settings_visual')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def register(self): def_user_perms = AuthUser( dbuser=User.get_default_user()).permissions['global'] c.auto_active = 'hg.register.auto_activate' in def_user_perms settings = Setting.get_app_settings() captcha_private_key = settings.get('captcha_private_key') c.captcha_active = bool(captcha_private_key) c.captcha_public_key = settings.get('captcha_public_key') if request.POST: register_form = RegisterForm()() try: form_result = register_form.to_python(dict(request.POST)) form_result['active'] = c.auto_active if c.captcha_active: from kallithea.lib.recaptcha import submit response = submit(request.POST.get('g-recaptcha-response'), private_key=captcha_private_key, remoteip=request.ip_addr) if not response.is_valid: _value = form_result _msg = _('Bad captcha') error_dict = {'recaptcha_field': _msg} raise formencode.Invalid(_msg, _value, None, error_dict=error_dict) UserModel().create_registration(form_result) h.flash(_('You have successfully registered with %s') % (c.site_name or 'Kallithea'), category='success') Session().commit() raise HTTPFound(location=url('login_home')) except formencode.Invalid as errors: return htmlfill.render(render('/register.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except UserCreationError as e: # container auth or other auth functions that create users on # the fly can throw this exception signaling that there's issue # with user creation, explanation should be provided in # Exception itself h.flash(e, 'error') return render('/register.html')
def register(self): c.auto_active = 'hg.register.auto_activate' in User.get_default_user() \ .AuthUser.permissions['global'] settings = Setting.get_app_settings() captcha_private_key = settings.get('captcha_private_key') c.captcha_active = bool(captcha_private_key) c.captcha_public_key = settings.get('captcha_public_key') if request.POST: register_form = RegisterForm()() try: form_result = register_form.to_python(dict(request.POST)) form_result['active'] = c.auto_active if c.captcha_active: from kallithea.lib.recaptcha import submit response = submit(request.POST.get('recaptcha_challenge_field'), request.POST.get('recaptcha_response_field'), private_key=captcha_private_key, remoteip=self.ip_addr) if c.captcha_active and not response.is_valid: _value = form_result _msg = _('Bad captcha') error_dict = {'recaptcha_field': _msg} raise formencode.Invalid(_msg, _value, None, error_dict=error_dict) UserModel().create_registration(form_result) h.flash(_('You have successfully registered into Kallithea'), category='success') Session().commit() raise HTTPFound(location=url('login_home')) except formencode.Invalid as errors: return htmlfill.render( render('/register.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except UserCreationError as e: # container auth or other auth functions that create users on # the fly can throw this exception signaling that there's issue # with user creation, explanation should be provided in # Exception itself h.flash(e, 'error') return render('/register.html')
def settings_hooks(self): """GET /admin/settings/hooks: All items in the collection""" # url('admin_settings_hooks') c.active = 'hooks' if request.POST: if c.visual.allow_custom_hooks_settings: ui_key = request.POST.get('new_hook_ui_key') ui_value = request.POST.get('new_hook_ui_value') hook_id = request.POST.get('hook_id') try: ui_key = ui_key and ui_key.strip() if ui_value and ui_key: Ui.create_or_update_hook(ui_key, ui_value) h.flash(_('Added new hook'), category='success') elif hook_id: Ui.delete(hook_id) Session().commit() # check for edits update = False _d = request.POST.dict_of_lists() for k, v in zip(_d.get('hook_ui_key', []), _d.get('hook_ui_value_new', [])): Ui.create_or_update_hook(k, v) update = True if update: h.flash(_('Updated hooks'), category='success') Session().commit() except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during hook creation'), category='error') raise HTTPFound(location=url('admin_settings_hooks')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) c.hooks = Ui.get_builtin_hooks() c.custom_hooks = Ui.get_custom_hooks() return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def settings_search(self): c.active = 'search' if request.POST: repo_location = self._get_hg_ui_settings()['paths_root_path'] full_index = request.POST.get('full_index', False) tasks.whoosh_index(repo_location, full_index) h.flash(_('Whoosh reindex task scheduled'), category='success') raise HTTPFound(location=url('admin_settings_search')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def settings_mapping(self): c.active = 'mapping' if request.POST: rm_obsolete = request.POST.get('destroy', False) install_git_hooks = request.POST.get('hooks', False) overwrite_git_hooks = request.POST.get('hooks_overwrite', False) invalidate_cache = request.POST.get('invalidate', False) log.debug('rescanning repo location with destroy obsolete=%s, ' 'install git hooks=%s and ' 'overwrite git hooks=%s' % (rm_obsolete, install_git_hooks, overwrite_git_hooks)) filesystem_repos = ScmModel().repo_scan() added, removed = repo2db_mapper(filesystem_repos, rm_obsolete, install_git_hooks=install_git_hooks, user=request.authuser.username, overwrite_git_hooks=overwrite_git_hooks) added_msg = h.HTML(', ').join( h.link_to(safe_str(repo_name), h.url('summary_home', repo_name=repo_name)) for repo_name in added ) or '-' removed_msg = h.HTML(', ').join( safe_str(repo_name) for repo_name in removed ) or '-' h.flash(h.HTML(_('Repositories successfully rescanned. Added: %s. Removed: %s.')) % (added_msg, removed_msg), category='success') if invalidate_cache: log.debug('invalidating all repositories cache') i = 0 for repo in Repository.query(): try: ScmModel().mark_for_invalidation(repo.repo_name) i += 1 except VCSError as e: log.warning('VCS error invalidating %s: %s', repo.repo_name, e) h.flash(_('Invalidated %s repositories') % i, category='success') raise HTTPFound(location=url('admin_settings_mapping')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def settings_system(self): c.active = 'system' defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) import kallithea c.ini = kallithea.CONFIG server_info = Setting.get_server_info() for key, val in server_info.items(): setattr(c, key, val) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def settings_global(self): c.active = 'global' if request.POST: application_form = ApplicationSettingsForm()() try: form_result = application_form.to_python(dict(request.POST)) except formencode.Invalid as errors: return htmlfill.render( render('admin/settings/settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) try: for setting in ( 'title', 'realm', 'ga_code', 'captcha_public_key', 'captcha_private_key', ): Setting.create_or_update(setting, form_result[setting]) Session().commit() set_app_settings(config) h.flash(_('Updated application settings'), category='success') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred while updating ' 'application settings'), category='error') raise HTTPFound(location=url('admin_settings_global')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def settings_system(self): c.active = 'system' defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) import kallithea c.ini = kallithea.CONFIG c.update_url = defaults.get('update_url') server_info = Setting.get_server_info() for key, val in server_info.iteritems(): setattr(c, key, val) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def test_ga_code_inactive(self): self.log_user() old_title = 'Kallithea' old_realm = 'Kallithea authentication' new_ga_code = '' response = self.app.post(base.url('admin_settings_global'), params=dict(title=old_title, realm=old_realm, ga_code=new_ga_code, captcha_private_key='', captcha_public_key='', _session_csrf_secret_token=self.session_csrf_secret_token(), )) self.checkSessionFlash(response, 'Updated application settings') assert Setting.get_app_settings()['ga_code'] == new_ga_code response = response.follow() response.mustcontain(no=["_gaq.push(['_setAccount', '%s']);" % new_ga_code])
def test_captcha_activate(self): self.log_user() old_title = 'Kallithea' old_realm = 'Kallithea authentication' new_ga_code = '' response = self.app.post(base.url('admin_settings_global'), params=dict(title=old_title, realm=old_realm, ga_code=new_ga_code, captcha_private_key='1234567890', captcha_public_key='1234567890', _session_csrf_secret_token=self.session_csrf_secret_token(), )) self.checkSessionFlash(response, 'Updated application settings') assert Setting.get_app_settings()['captcha_private_key'] == '1234567890' response = self.app.get(base.url('register')) response.mustcontain('captcha')
def settings_search(self): """GET /admin/settings/search: All items in the collection""" # url('admin_settings_search') c.active = 'search' if request.POST: repo_location = self._get_hg_ui_settings()['paths_root_path'] full_index = request.POST.get('full_index', False) run_task(tasks.whoosh_index, repo_location, full_index) h.flash(_('Whoosh reindex task scheduled'), category='success') return redirect(url('admin_settings_search')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def settings_system_update(self): """GET /admin/settings/system/updates: All items in the collection""" # url('admin_settings_system_update') import json import urllib2 from kallithea.lib.verlib import NormalizedVersion from kallithea import __version__ defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) _update_url = defaults.get('update_url', '') _update_url = "" # FIXME: disabled _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">%s</div>' % (s) try: import kallithea ver = kallithea.__version__ log.debug('Checking for upgrade on `%s` server', _update_url) opener = urllib2.build_opener() opener.addheaders = [('User-agent', 'Kallithea-SCM/%s' % ver)] response = opener.open(_update_url) response_data = response.read() data = json.loads(response_data) except urllib2.URLError as e: log.error(traceback.format_exc()) return _err('Failed to contact upgrade server: %r' % e) except ValueError as e: log.error(traceback.format_exc()) return _err('Bad data sent from update server') latest = data['versions'][0] c.update_url = _update_url c.latest_data = latest c.latest_ver = latest['version'] c.cur_ver = __version__ c.should_upgrade = False if NormalizedVersion(c.latest_ver) > NormalizedVersion(c.cur_ver): c.should_upgrade = True c.important_notices = latest['general'] return render('admin/settings/settings_system_update.html'),
def test_ga_code_inactive(self): self.log_user() old_title = 'Kallithea' old_realm = 'Kallithea authentication' new_ga_code = '' response = self.app.post(url('admin_settings_global'), params=dict(title=old_title, realm=old_realm, ga_code=new_ga_code, captcha_private_key='', captcha_public_key='', _authentication_token=self.authentication_token(), )) self.checkSessionFlash(response, 'Updated application settings') assert Setting.get_app_settings()['ga_code'] == new_ga_code response = response.follow() response.mustcontain(no=["_gaq.push(['_setAccount', '%s']);" % new_ga_code])
def test_captcha_deactivate(self): self.log_user() old_title = 'Kallithea' old_realm = 'Kallithea authentication' new_ga_code = '' response = self.app.post(url('admin_settings_global'), params=dict(title=old_title, realm=old_realm, ga_code=new_ga_code, captcha_private_key='', captcha_public_key='1234567890', _authentication_token=self.authentication_token(), )) self.checkSessionFlash(response, 'Updated application settings') assert Setting.get_app_settings()['captcha_private_key'] == '' response = self.app.get(url('register')) response.mustcontain(no=['captcha'])
def settings_mapping(self): c.active = 'mapping' if request.POST: rm_obsolete = request.POST.get('destroy', False) install_git_hooks = request.POST.get('hooks', False) overwrite_git_hooks = request.POST.get('hooks_overwrite', False); invalidate_cache = request.POST.get('invalidate', False) log.debug('rescanning repo location with destroy obsolete=%s, ' 'install git hooks=%s and ' 'overwrite git hooks=%s' % (rm_obsolete, install_git_hooks, overwrite_git_hooks)) filesystem_repos = ScmModel().repo_scan() added, removed = repo2db_mapper(filesystem_repos, rm_obsolete, install_git_hooks=install_git_hooks, user=request.authuser.username, overwrite_git_hooks=overwrite_git_hooks) h.flash(h.literal(_('Repositories successfully rescanned. Added: %s. Removed: %s.') % (', '.join(h.link_to(safe_unicode(repo_name), h.url('summary_home', repo_name=repo_name)) for repo_name in added) or '-', ', '.join(h.escape(safe_unicode(repo_name)) for repo_name in removed) or '-')), category='success') if invalidate_cache: log.debug('invalidating all repositories cache') i = 0 for repo in Repository.query(): try: ScmModel().mark_for_invalidation(repo.repo_name) i += 1 except VCSError as e: log.warning('VCS error invalidating %s: %s', repo.repo_name, e) h.flash(_('Invalidated %s repositories') % i, category='success') raise HTTPFound(location=url('admin_settings_mapping')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def test_captcha_deactivate(self): self.log_user() old_title = 'Kallithea' old_realm = 'Kallithea authentication' new_ga_code = '' response = self.app.post(url('admin_settings_global'), params=dict( title=old_title, realm=old_realm, ga_code=new_ga_code, captcha_private_key='', captcha_public_key='1234567890', )) self.checkSessionFlash(response, 'Updated application settings') self.assertEqual(Setting.get_app_settings()['captcha_private_key'], '') response = self.app.get(url('register')) response.mustcontain(no=['captcha'])
def test_title_change(self): self.log_user() old_title = 'Kallithea' new_title = old_title + '_changed' old_realm = 'Kallithea authentication' for new_title in ['Changed', 'Żółwik', old_title]: response = self.app.post(url('admin_settings_global'), params=dict(title=new_title, realm=old_realm, ga_code='', captcha_private_key='', captcha_public_key='', _authentication_token=self.authentication_token(), )) self.checkSessionFlash(response, 'Updated application settings') assert Setting.get_app_settings()['title'] == new_title.decode('utf-8') response = response.follow() response.mustcontain("""<span class="branding">%s</span>""" % new_title)
def test_ga_code_active(self): self.log_user() old_title = 'Kallithea' old_realm = 'Kallithea authentication' new_ga_code = 'ga-test-123456789' response = self.app.post(url('admin_settings_global'), params=dict( title=old_title, realm=old_realm, ga_code=new_ga_code, captcha_private_key='', captcha_public_key='', )) self.checkSessionFlash(response, 'Updated application settings') self.assertEqual(Setting.get_app_settings()['ga_code'], new_ga_code) response = response.follow() response.mustcontain("""_gaq.push(['_setAccount', '%s']);""" % new_ga_code)
def settings_email(self): """GET /admin/settings/email: All items in the collection""" # url('admin_settings_email') c.active = 'email' if request.POST: test_email = request.POST.get('test_email') test_email_subj = 'Kallithea test email' test_body = ('Kallithea Email test, ' 'Kallithea version: %s' % c.kallithea_version) if not test_email: h.flash(_('Please enter email address'), category='error') raise HTTPFound(location=url('admin_settings_email')) test_email_txt_body = EmailNotificationModel() \ .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT, 'txt', body=test_body) test_email_html_body = EmailNotificationModel() \ .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT, 'html', body=test_body) recipients = [test_email] if test_email else None run_task(tasks.send_email, recipients, test_email_subj, test_email_txt_body, test_email_html_body) h.flash(_('Send email task created'), category='success') raise HTTPFound(location=url('admin_settings_email')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) import kallithea c.ini = kallithea.CONFIG return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def password_reset(self): settings = Setting.get_app_settings() captcha_private_key = settings.get('captcha_private_key') c.captcha_active = bool(captcha_private_key) c.captcha_public_key = settings.get('captcha_public_key') if request.POST: password_reset_form = PasswordResetRequestForm()() try: form_result = password_reset_form.to_python(dict(request.POST)) if c.captcha_active: from kallithea.lib.recaptcha import submit response = submit(request.POST.get('g-recaptcha-response'), private_key=captcha_private_key, remoteip=request.ip_addr) if not response.is_valid: _value = form_result _msg = _('Bad captcha') error_dict = {'recaptcha_field': _msg} raise formencode.Invalid(_msg, _value, None, error_dict=error_dict) redirect_link = UserModel().send_reset_password_email( form_result) h.flash(_('A password reset confirmation code has been sent'), category='success') raise HTTPFound(location=redirect_link) except formencode.Invalid as errors: return htmlfill.render(render('/password_reset.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) return render('/password_reset.html')
def password_reset(self): settings = Setting.get_app_settings() captcha_private_key = settings.get('captcha_private_key') c.captcha_active = bool(captcha_private_key) c.captcha_public_key = settings.get('captcha_public_key') if request.POST: password_reset_form = PasswordResetForm()() try: form_result = password_reset_form.to_python(dict(request.POST)) if c.captcha_active: from kallithea.lib.recaptcha import submit response = submit( request.POST.get('recaptcha_challenge_field'), request.POST.get('recaptcha_response_field'), private_key=captcha_private_key, remoteip=self.ip_addr) if c.captcha_active and not response.is_valid: _value = form_result _msg = _('bad captcha') error_dict = {'recaptcha_field': _msg} raise formencode.Invalid(_msg, _value, None, error_dict=error_dict) UserModel().reset_password_link(form_result) h.flash(_('Your password reset link was sent'), category='success') return redirect(url('login_home')) except formencode.Invalid, errors: return htmlfill.render(render('/password_reset.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False)
def settings_email(self): c.active = 'email' if request.POST: test_email = request.POST.get('test_email') test_email_subj = 'Kallithea test email' test_body = ('Kallithea Email test, ' 'Kallithea version: %s' % c.kallithea_version) if not test_email: h.flash(_('Please enter email address'), category='error') raise HTTPFound(location=url('admin_settings_email')) test_email_txt_body = EmailNotificationModel() \ .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT, 'txt', body=test_body) test_email_html_body = EmailNotificationModel() \ .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT, 'html', body=test_body) recipients = [test_email] if test_email else None tasks.send_email(recipients, test_email_subj, test_email_txt_body, test_email_html_body) h.flash(_('Send email task created'), category='success') raise HTTPFound(location=url('admin_settings_email')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) import kallithea c.ini = kallithea.CONFIG return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
form_result['captcha_private_key']) Session().add(sett5) Session().commit() set_app_settings(config) h.flash(_('Updated application settings'), category='success') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during updating ' 'application settings'), category='error') return redirect(url('admin_settings_global')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False) @HasPermissionAllDecorator('hg.admin') def settings_visual(self): """GET /admin/settings/visual: All items in the collection""" # url('admin_settings_visual') c.active = 'visual' if request.POST: application_form = ApplicationVisualisationForm()()
def settings_vcs(self): """GET /admin/settings: All items in the collection""" # url('admin_settings') c.active = 'vcs' if request.POST: application_form = ApplicationUiSettingsForm()() try: form_result = application_form.to_python(dict(request.POST)) except formencode.Invalid as errors: return htmlfill.render( render('admin/settings/settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) try: sett = Ui.get_by_key('web', 'push_ssl') sett.ui_value = form_result['web_push_ssl'] if c.visual.allow_repo_location_change: sett = Ui.get_by_key('paths', '/') sett.ui_value = form_result['paths_root_path'] #HOOKS sett = Ui.get_by_key('hooks', Ui.HOOK_UPDATE) sett.ui_active = form_result['hooks_changegroup_update'] sett = Ui.get_by_key('hooks', Ui.HOOK_REPO_SIZE) sett.ui_active = form_result['hooks_changegroup_repo_size'] sett = Ui.get_by_key('hooks', Ui.HOOK_PUSH) sett.ui_active = form_result['hooks_changegroup_push_logger'] sett = Ui.get_by_key('hooks', Ui.HOOK_PULL) sett.ui_active = form_result['hooks_outgoing_pull_logger'] ## EXTENSIONS sett = Ui.get_or_create('extensions', 'largefiles') sett.ui_active = form_result['extensions_largefiles'] sett = Ui.get_or_create('extensions', 'hgsubversion') sett.ui_active = form_result['extensions_hgsubversion'] if sett.ui_active: try: import hgsubversion # pragma: no cover except ImportError: raise HgsubversionImportError # sett = Ui.get_or_create('extensions', 'hggit') # sett.ui_active = form_result['extensions_hggit'] Session().commit() h.flash(_('Updated VCS settings'), category='success') except HgsubversionImportError: log.error(traceback.format_exc()) h.flash(_('Unable to activate hgsubversion support. ' 'The "hgsubversion" library is missing'), category='error') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred while updating ' 'application settings'), category='error') defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def settings_vcs(self): c.active = 'vcs' if request.POST: application_form = ApplicationUiSettingsForm()() try: form_result = application_form.to_python(dict(request.POST)) except formencode.Invalid as errors: return htmlfill.render( render('admin/settings/settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) try: if c.visual.allow_repo_location_change: sett = Ui.get_by_key('paths', '/') sett.ui_value = form_result['paths_root_path'] # HOOKS sett = Ui.get_by_key('hooks', Ui.HOOK_UPDATE) sett.ui_active = form_result['hooks_changegroup_update'] sett = Ui.get_by_key('hooks', Ui.HOOK_REPO_SIZE) sett.ui_active = form_result['hooks_changegroup_repo_size'] ## EXTENSIONS sett = Ui.get_or_create('extensions', 'largefiles') sett.ui_active = form_result['extensions_largefiles'] sett = Ui.get_or_create('extensions', 'hgsubversion') sett.ui_active = form_result['extensions_hgsubversion'] if sett.ui_active: try: import hgsubversion # pragma: no cover assert hgsubversion except ImportError: raise HgsubversionImportError # sett = Ui.get_or_create('extensions', 'hggit') # sett.ui_active = form_result['extensions_hggit'] Session().commit() h.flash(_('Updated VCS settings'), category='success') except HgsubversionImportError: log.error(traceback.format_exc()) h.flash(_('Unable to activate hgsubversion support. ' 'The "hgsubversion" library is missing'), category='error') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred while updating ' 'application settings'), category='error') defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def _before(self, *args, **kwargs): """ _before is called before controller methods and after __call__ """ if request.needs_csrf_check: # CSRF protection: Whenever a request has ambient authority (whether # through a session cookie or its origin IP address), it must include # the correct token, unless the HTTP method is GET or HEAD (and thus # guaranteed to be side effect free. In practice, the only situation # where we allow side effects without ambient authority is when the # authority comes from an API key; and that is handled above. from kallithea.lib import helpers as h token = request.POST.get(h.session_csrf_secret_name) if not token or token != h.session_csrf_secret_token(): log.error('CSRF check failed') raise webob.exc.HTTPForbidden() c.kallithea_version = __version__ rc_config = Setting.get_app_settings() # Visual options c.visual = AttributeDict({}) ## DB stored c.visual.show_public_icon = str2bool(rc_config.get('show_public_icon')) c.visual.show_private_icon = str2bool( rc_config.get('show_private_icon')) c.visual.stylify_metalabels = str2bool( rc_config.get('stylify_metalabels')) c.visual.page_size = safe_int(rc_config.get('dashboard_items', 100)) c.visual.admin_grid_items = safe_int( rc_config.get('admin_grid_items', 100)) c.visual.repository_fields = str2bool( rc_config.get('repository_fields')) c.visual.show_version = str2bool(rc_config.get('show_version')) c.visual.use_gravatar = str2bool(rc_config.get('use_gravatar')) c.visual.gravatar_url = rc_config.get('gravatar_url') c.ga_code = rc_config.get('ga_code') # TODO: replace undocumented backwards compatibility hack with db upgrade and rename ga_code if c.ga_code and '<' not in c.ga_code: c.ga_code = '''<script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', '%s']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script>''' % c.ga_code c.site_name = rc_config.get('title') c.clone_uri_tmpl = rc_config.get( 'clone_uri_tmpl') or Repository.DEFAULT_CLONE_URI c.clone_ssh_tmpl = rc_config.get( 'clone_ssh_tmpl') or Repository.DEFAULT_CLONE_SSH ## INI stored c.visual.allow_repo_location_change = str2bool( config.get('allow_repo_location_change', True)) c.visual.allow_custom_hooks_settings = str2bool( config.get('allow_custom_hooks_settings', True)) c.ssh_enabled = str2bool(config.get('ssh_enabled', False)) c.instance_id = config.get('instance_id') c.issues_url = config.get('bugtracker', url('issues_url')) # END CONFIG VARS c.repo_name = get_repo_slug(request) # can be empty c.backends = list(BACKENDS) self.cut_off_limit = safe_int(config.get('cut_off_limit')) c.my_pr_count = PullRequest.query(reviewer_id=request.authuser.user_id, include_closed=False).count() self.scm_model = ScmModel()