def get_managed_fields(self): fields = ['username', 'password'] if(Setting.get_by_name('auth_container_email_header').app_settings_value): fields.append('email') if(Setting.get_by_name('auth_container_firstname_header').app_settings_value): fields.append('firstname') if(Setting.get_by_name('auth_container_lastname_header').app_settings_value): fields.append('lastname') return fields
def _set_settings(*kvtseq): session = Session() for kvt in kvtseq: assert len(kvt) in (2, 3) k = kvt[0] v = kvt[1] t = kvt[2] if len(kvt) == 3 else 'unicode' Setting.create_or_update(k, v, t) session.commit()
def test_list_valued_setting_creation_requires_manual_value_formatting(): assert Setting.get_by_name(name) is None # Quirk: need manual formatting of list setting value. setting = Setting.create_or_update(name, 'spam,eggs', type='list') Session().flush() # must flush so we can delete it below try: assert setting.app_settings_value == ['spam', 'eggs'] finally: Session().delete(setting)
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 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 test_passing_list_setting_value_results_in_string_valued_setting(): assert Setting.get_by_name(name) is None setting = Setting.create_or_update(name, ['spam', 'eggs']) Session().flush() # must flush so we can delete it below try: assert Setting.get_by_name(name) is not None # Quirk: list value is stringified. assert Setting.get_by_name(name).app_settings_value \ == "['spam', 'eggs']" assert Setting.get_by_name(name).app_settings_type == 'unicode' finally: Session().delete(setting)
def get_managed_fields(self): fields = ['username', 'password'] if (Setting.get_by_name( 'auth_container_email_header').app_settings_value): fields.append('email') if (Setting.get_by_name( 'auth_container_firstname_header').app_settings_value): fields.append('firstname') if (Setting.get_by_name( 'auth_container_lastname_header').app_settings_value): fields.append('lastname') return fields
def create_default_options(self, skip_existing=False): """Creates default settings""" for k, v, t in [('default_repo_enable_locking', False, 'bool'), ('default_repo_enable_downloads', False, 'bool'), ('default_repo_enable_statistics', False, 'bool'), ('default_repo_private', False, 'bool'), ('default_repo_type', 'hg', 'unicode')]: if skip_existing and Setting.get_by_name(k) is not None: log.debug('Skipping option %s', k) continue setting = Setting(k, v, t) self.sa.add(setting)
def test_list_valued_setting_update(): assert Setting.get_by_name(name) is None setting = Setting.create_or_update(name, 'spam', type='list') Session().flush() # must flush so we can delete it below try: assert setting.app_settings_value == ['spam'] # Assign back setting value. setting.app_settings_value = setting.app_settings_value # Quirk: value is stringified on write and listified on read. assert setting.app_settings_value == ["['spam']"] setting.app_settings_value = setting.app_settings_value assert setting.app_settings_value == ["[\"['spam']\"]"] finally: Session().delete(setting)
def create_auth_plugin_options(self, skip_existing=False): """ Create default auth plugin settings, and make it active :param skip_existing: """ for k, v, t in [('auth_plugins', 'kallithea.lib.auth_modules.auth_internal', 'list'), ('auth_internal_enabled', 'True', 'bool')]: if skip_existing and Setting.get_by_name(k) is not None: log.debug('Skipping option %s', k) continue setting = Setting(k, v, t) self.sa.add(setting)
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, 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 during updating ' 'application settings'), category='error') return redirect(url('admin_settings_global'))
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 __render(self, defaults, errors): c.defaults = {} c.plugin_settings = {} c.plugin_shortnames = {} for plugin in self.enabled_plugins: module = plugin.__class__.__module__ c.plugin_shortnames[module] = plugin.name c.plugin_settings[module] = plugin.plugin_settings() for v in c.plugin_settings[module]: fullname = "auth_%s_%s" % (plugin.name, v["name"]) if "default" in v: c.defaults[fullname] = v["default"] # Current values will be the default on the form, if there are any setting = Setting.get_by_name(fullname) if setting is not None: c.defaults[fullname] = setting.app_settings_value # we want to show , separated list of enabled plugins c.defaults['auth_plugins'] = ','.join(c.enabled_plugin_names) if defaults: c.defaults.update(defaults) log.debug(formatted_json(defaults)) return formencode.htmlfill.render( render('admin/auth/auth_settings.html'), defaults=c.defaults, errors=errors, prefix_error=False, encoding="UTF-8", force_defaults=False)
def auth_settings(self): """POST create and store auth settings""" self.__load_defaults() _form = AuthSettingsForm(c.enabled_plugins)() log.debug("POST Result: %s" % formatted_json(dict(request.POST))) try: form_result = _form.to_python(dict(request.POST)) for k, v in form_result.items(): if k == 'auth_plugins': # we want to store it comma separated inside our settings v = ','.join(v) log.debug("%s = %s" % (k, str(v))) setting = Setting.create_or_update(k, v) Session().add(setting) Session().commit() h.flash(_('Auth settings updated successfully'), category='success') except formencode.Invalid, errors: log.error(traceback.format_exc()) e = errors.error_dict or {} return self.index( defaults=errors.value, errors=e, prefix_error=False)
def update(self, id): _form = DefaultsForm()() try: form_result = _form.to_python(dict(request.POST)) for k, v in form_result.items(): setting = Setting.create_or_update(k, v) Session().commit() h.flash(_('Default settings updated successfully'), category='success') except formencode.Invalid as errors: defaults = errors.value return htmlfill.render( render('admin/defaults/defaults.html'), defaults=defaults, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during update of defaults'), category='error') raise HTTPFound(location=url('defaults'))
def update(self, id): _form = DefaultsForm()() try: form_result = _form.to_python(dict(request.POST)) for k, v in form_result.iteritems(): setting = Setting.create_or_update(k, v) Session().commit() h.flash(_('Default settings updated successfully'), category='success') except formencode.Invalid as errors: defaults = errors.value return htmlfill.render( render('admin/defaults/defaults.html'), defaults=defaults, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during update of defaults'), category='error') raise HTTPFound(location=url('defaults'))
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 test_ldap_save_settings(self): self.log_user() params = self._enable_plugins('kallithea.lib.auth_modules.auth_internal,kallithea.lib.auth_modules.auth_ldap') params.update({'auth_ldap_host': u'dc.example.com', 'auth_ldap_port': '999', 'auth_ldap_tls_kind': 'PLAIN', 'auth_ldap_tls_reqcert': 'NEVER', 'auth_ldap_cacertdir': '', 'auth_ldap_dn_user': '******', 'auth_ldap_dn_pass': '******', 'auth_ldap_base_dn': 'test_base_dn', 'auth_ldap_filter': 'test_filter', 'auth_ldap_search_scope': 'BASE', 'auth_ldap_attr_login': '******', 'auth_ldap_attr_firstname': 'ima', 'auth_ldap_attr_lastname': 'tester', 'auth_ldap_attr_email': '*****@*****.**'}) test_url = url(controller='admin/auth_settings', action='auth_settings') response = self.app.post(url=test_url, params=params) self.checkSessionFlash(response, 'Auth settings updated successfully') new_settings = Setting.get_auth_settings() assert new_settings['auth_ldap_host'] == u'dc.example.com', 'fail db write compare'
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_ldap_save_settings(self): self.log_user() params = self._enable_plugins( 'kallithea.lib.auth_modules.auth_internal,kallithea.lib.auth_modules.auth_ldap' ) params.update({ 'auth_ldap_host': u'dc.example.com', 'auth_ldap_port': '999', 'auth_ldap_tls_kind': 'PLAIN', 'auth_ldap_tls_reqcert': 'NEVER', 'auth_ldap_cacertdir': '', 'auth_ldap_dn_user': '******', 'auth_ldap_dn_pass': '******', 'auth_ldap_base_dn': 'test_base_dn', 'auth_ldap_filter': 'test_filter', 'auth_ldap_search_scope': 'BASE', 'auth_ldap_attr_login': '******', 'auth_ldap_attr_firstname': 'ima', 'auth_ldap_attr_lastname': 'tester', 'auth_ldap_attr_email': '*****@*****.**' }) test_url = url(controller='admin/auth_settings', action='auth_settings') response = self.app.post(url=test_url, params=params) self.checkSessionFlash(response, 'Auth settings updated successfully') new_settings = Setting.get_auth_settings() assert new_settings[ 'auth_ldap_host'] == u'dc.example.com', 'fail db write compare'
def get_settings(self): """Get plugin settings values.""" plugin_settings = {} for v in self.plugin_settings(): conf_key = "auth_%s_%s" % (self.name, v["name"]) setting = Setting.get_by_name(conf_key) plugin_settings[v["name"]] = setting.app_settings_value if setting else None return plugin_settings
def set_test_settings(): """Restore settings after test is over.""" # Save settings. settings_snapshot = [(s.app_settings_name, s.app_settings_value, s.app_settings_type) for s in Setting.query().all()] yield _set_settings # Restore settings. session = Session() keys = frozenset(k for (k, v, t) in settings_snapshot) for s in Setting.query().all(): if s.app_settings_name not in keys: session.delete(s) for k, v, t in settings_snapshot: if t == 'list' and hasattr(v, '__iter__'): v = ','.join(v) # Quirk: must format list value manually. Setting.create_or_update(k, v, t) session.commit()
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 __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 fix_settings(self): """ Fixes kallithea settings adds ga_code key for google analytics """ hgsettings3 = Setting('ga_code', '') self.sa.add(hgsettings3) self.sa.commit()
def set_test_settings(): """Restore settings after test is over.""" # Save settings. settings_snapshot = [ (s.app_settings_name, s.app_settings_value, s.app_settings_type) for s in Setting.query().all()] yield _set_settings # Restore settings. session = Session() keys = frozenset(k for (k, v, t) in settings_snapshot) for s in Setting.query().all(): if s.app_settings_name not in keys: session.delete(s) for k, v, t in settings_snapshot: if t == 'list' and hasattr(v, '__iter__'): v = ','.join(v) # Quirk: must format list value manually. Setting.create_or_update(k, v, t) session.commit()
def __load_defaults(self): c.available_plugins = [ 'kallithea.lib.auth_modules.auth_internal', 'kallithea.lib.auth_modules.auth_container', 'kallithea.lib.auth_modules.auth_ldap', 'kallithea.lib.auth_modules.auth_crowd', 'kallithea.lib.auth_modules.auth_pam' ] c.enabled_plugins = Setting.get_auth_plugins()
def index(self, format='html'): defaults = Setting.get_default_repo_settings() return htmlfill.render( render('admin/defaults/defaults.html'), defaults=defaults, encoding="UTF-8", force_defaults=False )
def index(self, defaults=None, errors=None, prefix_error=False): self.__load_defaults() _defaults = {} # default plugins loaded formglobals = { "auth_plugins": ["kallithea.lib.auth_modules.auth_internal"] } formglobals.update(Setting.get_auth_settings()) formglobals["plugin_settings"] = {} formglobals["auth_plugins_shortnames"] = {} _defaults["auth_plugins"] = formglobals["auth_plugins"] for module in formglobals["auth_plugins"]: plugin = auth_modules.loadplugin(module) plugin_name = plugin.name formglobals["auth_plugins_shortnames"][module] = plugin_name formglobals["plugin_settings"][module] = plugin.plugin_settings() for v in formglobals["plugin_settings"][module]: fullname = ("auth_" + plugin_name + "_" + v["name"]) if "default" in v: _defaults[fullname] = v["default"] # Current values will be the default on the form, if there are any setting = Setting.get_by_name(fullname) if setting: _defaults[fullname] = setting.app_settings_value # we want to show , separated list of enabled plugins _defaults['auth_plugins'] = ','.join(_defaults['auth_plugins']) if defaults: _defaults.update(defaults) formglobals["defaults"] = _defaults # set template context variables for k, v in formglobals.iteritems(): setattr(c, k, v) log.debug(pprint.pformat(formglobals, indent=4)) log.debug(formatted_json(defaults)) return formencode.htmlfill.render( render('admin/auth/auth_settings.html'), defaults=_defaults, errors=errors, prefix_error=prefix_error, 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 index(self, format='html'): c.backends = BACKENDS.keys() defaults = Setting.get_default_repo_settings() return htmlfill.render( render('admin/defaults/defaults.html'), defaults=defaults, encoding="UTF-8", force_defaults=False )
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 index(self, format='html'): """GET /defaults: All items in the collection""" # url('defaults') c.backends = BACKENDS.keys() defaults = Setting.get_default_repo_settings() return htmlfill.render( render('admin/defaults/defaults.html'), defaults=defaults, encoding="UTF-8", force_defaults=False )
def get_auth_plugins(): """Return a list of instances of plugins that are available and enabled""" auth_plugins = [] for plugin_name in Setting.get_by_name("auth_plugins").app_settings_value: try: plugin = loadplugin(plugin_name) except Exception: log.exception('Failed to load authentication module %s' % (plugin_name)) else: auth_plugins.append(plugin) return auth_plugins
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 get_managed_fields(user): """return list of fields that are managed by the user's auth source, usually some of 'username', 'firstname', 'lastname', 'email', 'active', 'password' """ auth_plugins = Setting.get_auth_plugins() for module in auth_plugins: log.debug('testing %s (%s) with auth plugin %s', user, user.extern_type, module) plugin = loadplugin(module) if plugin.name == user.extern_type: return plugin.get_managed_fields() log.error('no auth plugin %s found for %s', user.extern_type, user) return [] # TODO: Fail badly instead of allowing everything to be edited?
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 auth_settings(self): """POST create and store auth settings""" self.__load_defaults() log.debug("POST Result: %s", formatted_json(dict(request.POST))) # First, parse only the plugin list (not the plugin settings). _auth_plugins_validator = AuthSettingsForm([]).fields['auth_plugins'] try: new_enabled_plugins = _auth_plugins_validator.to_python( request.POST.get('auth_plugins')) except formencode.Invalid: # User provided an invalid plugin list. Just fall back to # the list of currently enabled plugins. (We'll re-validate # and show an error message to the user, below.) pass else: # Hide plugins that the user has asked to be disabled, but # do not show plugins that the user has asked to be enabled # (yet), since that'll cause validation errors and/or wrong # settings being applied (e.g. checkboxes being cleared), # since the plugin settings will not be in the POST data. c.enabled_plugin_names = [ p for p in c.enabled_plugin_names if p in new_enabled_plugins ] # Next, parse everything including plugin settings. _form = AuthSettingsForm(c.enabled_plugin_names)() try: form_result = _form.to_python(dict(request.POST)) for k, v in form_result.items(): if k == 'auth_plugins': # we want to store it comma separated inside our settings v = ','.join(v) log.debug("%s = %s", k, str(v)) setting = Setting.create_or_update(k, v) Session().commit() h.flash(_('Auth settings updated successfully'), category='success') except formencode.Invalid as errors: log.error(traceback.format_exc()) e = errors.error_dict or {} return self.__render( defaults=errors.value, errors=e, ) except Exception: log.error(traceback.format_exc()) h.flash(_('error occurred during update of auth settings'), category='error') raise HTTPFound(location=url('auth_home'))
def test_update_params_false_git(self): self.log_user() params = { 'default_repo_enable_locking': False, 'default_repo_enable_downloads': False, 'default_repo_enable_statistics': False, 'default_repo_private': False, 'default_repo_type': 'git', } response = self.app.put(url('default', id='default'), params=params) self.checkSessionFlash(response, 'Default settings updated successfully') defs = Setting.get_default_repo_settings() self.assertEqual(params, defs)
def create_auth_plugin_options(self, skip_existing=False): """ Create default auth plugin settings, and make it active :param skip_existing: """ for k, v, t in [('auth_plugins', 'kallithea.lib.auth_modules.auth_internal', 'list'), ('auth_internal_enabled', 'True', 'bool')]: if skip_existing and Setting.get_by_name(k) != None: log.debug('Skipping option %s' % k) continue setting = Setting(k, v, t) self.sa.add(setting)
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 auth_settings(self): """POST create and store auth settings""" self.__load_defaults() log.debug("POST Result: %s", formatted_json(dict(request.POST))) # First, parse only the plugin list (not the plugin settings). _auth_plugins_validator = AuthSettingsForm([]).fields['auth_plugins'] try: new_enabled_plugins = _auth_plugins_validator.to_python(request.POST.get('auth_plugins')) except formencode.Invalid: # User provided an invalid plugin list. Just fall back to # the list of currently enabled plugins. (We'll re-validate # and show an error message to the user, below.) pass else: # Hide plugins that the user has asked to be disabled, but # do not show plugins that the user has asked to be enabled # (yet), since that'll cause validation errors and/or wrong # settings being applied (e.g. checkboxes being cleared), # since the plugin settings will not be in the POST data. c.enabled_plugins = [ p for p in c.enabled_plugins if p in new_enabled_plugins ] # Next, parse everything including plugin settings. _form = AuthSettingsForm(c.enabled_plugins)() try: form_result = _form.to_python(dict(request.POST)) for k, v in form_result.items(): if k == 'auth_plugins': # we want to store it comma separated inside our settings v = ','.join(v) log.debug("%s = %s", k, str(v)) setting = Setting.create_or_update(k, v) Session().add(setting) Session().commit() h.flash(_('Auth settings updated successfully'), category='success') except formencode.Invalid as errors: log.error(traceback.format_exc()) e = errors.error_dict or {} return self.__render( defaults=errors.value, errors=e, ) except Exception: log.error(traceback.format_exc()) h.flash(_('error occurred during update of auth settings'), category='error') raise HTTPFound(location=url('auth_home'))
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 create_default_options(self, skip_existing=False): """Creates default settings""" for k, v, t in [ ('default_repo_enable_locking', False, 'bool'), ('default_repo_enable_downloads', False, 'bool'), ('default_repo_enable_statistics', False, 'bool'), ('default_repo_private', False, 'bool'), ('default_repo_type', 'hg', 'unicode')]: if skip_existing and Setting.get_by_name(k) is not None: log.debug('Skipping option %s' % k) continue setting = Setting(k, v, t) self.sa.add(setting)
def test_pam_save_settings(self): self.log_user() params = self._enable_plugins('kallithea.lib.auth_modules.auth_internal,kallithea.lib.auth_modules.auth_pam') params.update({'auth_pam_service': 'kallithea', 'auth_pam_gecos': '^foo-.*'}) test_url = url(controller='admin/auth_settings', action='auth_settings') response = self.app.post(url=test_url, params=params) self.checkSessionFlash(response, 'Auth settings updated successfully') new_settings = Setting.get_auth_settings() assert new_settings['auth_pam_service'] == u'kallithea', 'fail db write compare'
def test_update_params_true_hg(self): self.log_user() params = { 'default_repo_enable_locking': True, 'default_repo_enable_downloads': True, 'default_repo_enable_statistics': True, 'default_repo_private': True, 'default_repo_type': 'hg', '_authentication_token': self.authentication_token(), } response = self.app.put(url('default', id='default'), params=params) self.checkSessionFlash(response, 'Default settings updated successfully') params.pop('_authentication_token') defs = Setting.get_default_repo_settings() self.assertEqual(params, defs)
def test_update_params_false_git(self): self.log_user() params = { 'default_repo_enable_downloads': False, 'default_repo_enable_statistics': False, 'default_repo_private': False, 'default_repo_type': 'git', '_session_csrf_secret_token': self.session_csrf_secret_token(), } response = self.app.post(base.url('defaults_update', id='default'), params=params) self.checkSessionFlash(response, 'Default settings updated successfully') params.pop('_session_csrf_secret_token') defs = Setting.get_default_repo_settings() assert params == defs
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)