示例#1
0
    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)
示例#2
0
    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)
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
    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)
示例#7
0
    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)
示例#8
0
    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()
示例#9
0
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
示例#10
0
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()
示例#11
0
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
示例#12
0
    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)
示例#13
0
    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)
示例#14
0
    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')
示例#15
0
    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')
示例#16
0
    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)
示例#17
0
    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)
示例#18
0
    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)
示例#19
0
    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)
示例#20
0
    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)
示例#21
0
    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)
示例#22
0
    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)
示例#23
0
    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])
示例#24
0
    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')
示例#25
0
    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)
示例#26
0
    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'])
示例#29
0
    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)
示例#30
0
    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)
示例#32
0
    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)
示例#33
0
    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)
示例#34
0
    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')
示例#35
0
    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)
示例#36
0
    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)
示例#37
0
                                    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()()
示例#38
0
    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)
示例#39
0
    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)
示例#40
0
    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()