Changeset - f103b1a2383b
[Not reviewed]
default
0 5 0
Søren Løvborg - 10 years ago 2015-07-14 14:00:17
kwi@kwi.dk
BaseController: hide "Log out" link for external login sessions

If user is authorized by external means (API key or container auth),
Kallithea is not actually able to log the user out and should not show
the "Log out" link.
5 files changed with 29 insertions and 7 deletions:
0 comments (0 inline, 0 general)
kallithea/controllers/login.py
Show inline comments
 
@@ -71,97 +71,98 @@ class LoginController(BaseController):
 
            log.error('Suspicious NETLOC detected %s for url %s server url '
 
                      'is: %s' % (parsed.netloc, parsed, server_parsed))
 
            return False
 
        return True
 

	
 
    def _redirect_to_origin(self, origin):
 
        '''redirect to the original page, preserving any get arguments given'''
 
        request.GET.pop('came_from', None)
 
        raise HTTPFound(location=url(origin, **request.GET))
 

	
 
    def index(self):
 
        c.came_from = safe_str(request.GET.get('came_from', ''))
 
        if not self._validate_came_from(c.came_from):
 
            c.came_from = url('home')
 

	
 
        not_default = self.authuser.username != User.DEFAULT_USER
 
        ip_allowed = AuthUser.check_ip_allowed(self.authuser, self.ip_addr)
 

	
 
        # redirect if already logged in
 
        if self.authuser.is_authenticated and not_default and ip_allowed:
 
            return self._redirect_to_origin(c.came_from)
 

	
 
        if request.POST:
 
            # import Login Form validator class
 
            login_form = LoginForm()
 
            try:
 
                c.form_result = login_form.to_python(dict(request.POST))
 
                # form checks for username/password, now we're authenticated
 
                username = c.form_result['username']
 
                user = User.get_by_username(username, case_insensitive=True)
 
            except formencode.Invalid, errors:
 
                defaults = errors.value
 
                # remove password from filling in form again
 
                del defaults['password']
 
                return htmlfill.render(
 
                    render('/login.html'),
 
                    defaults=errors.value,
 
                    errors=errors.error_dict or {},
 
                    prefix_error=False,
 
                    encoding="UTF-8",
 
                    force_defaults=False)
 
            except UserCreationError, 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')
 
            else:
 
                log_in_user(user, c.form_result['remember'])
 
                log_in_user(user, c.form_result['remember'],
 
                    is_external_auth=False)
 
                return self._redirect_to_origin(c.came_from)
 

	
 
        return render('/login.html')
 

	
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
 
                               'hg.register.manual_activate')
 
    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()
 
                return redirect(url('login_home'))
 

	
 
            except formencode.Invalid, errors:
 
                return htmlfill.render(
 
                    render('/register.html'),
 
                    defaults=errors.value,
 
                    errors=errors.error_dict or {},
 
                    prefix_error=False,
 
                    encoding="UTF-8",
 
                    force_defaults=False)
kallithea/lib/auth.py
Show inline comments
 
@@ -431,109 +431,111 @@ def _cached_perms_data(user_id, user_is_
 
        if not explicit:
 
            p = _choose_perm(p, cur_perm)
 
        permissions[UK][u_k] = p
 

	
 
    return permissions
 

	
 

	
 
def allowed_api_access(controller_name, whitelist=None, api_key=None):
 
    """
 
    Check if given controller_name is in whitelist API access
 
    """
 
    if not whitelist:
 
        from kallithea import CONFIG
 
        whitelist = aslist(CONFIG.get('api_access_controllers_whitelist'),
 
                           sep=',')
 
        log.debug('whitelist of API access is: %s' % (whitelist))
 
    api_access_valid = controller_name in whitelist
 
    if api_access_valid:
 
        log.debug('controller:%s is in API whitelist' % (controller_name))
 
    else:
 
        msg = 'controller: %s is *NOT* in API whitelist' % (controller_name)
 
        if api_key:
 
            #if we use API key and don't have access it's a warning
 
            log.warning(msg)
 
        else:
 
            log.debug(msg)
 
    return api_access_valid
 

	
 

	
 
class AuthUser(object):
 
    """
 
    Represents a Kallithea user, including various authentication and
 
    authorization information. Typically used to store the current user,
 
    but is also used as a generic user information data structure in
 
    parts of the code, e.g. user management.
 

	
 
    Constructed from user ID, username, API key or cookie dict, it looks
 
    up the matching database `User` and copies all attributes to itself,
 
    adding various non-persistent data. If lookup fails but anonymous
 
    access to Kallithea is enabled, the default user is loaded instead.
 

	
 
    `AuthUser` does not by itself authenticate users and the constructor
 
    sets the `is_authenticated` field to False, except when falling back
 
    to the default anonymous user (if enabled). It's up to other parts
 
    of the code to check e.g. if a supplied password is correct, and if
 
    so, set `is_authenticated` to True.
 
    """
 

	
 
    def __init__(self, user_id=None, api_key=None, username=None):
 
    def __init__(self, user_id=None, api_key=None, username=None,
 
            is_external_auth=False):
 

	
 
        self.user_id = user_id
 
        self._api_key = api_key
 

	
 
        self.api_key = None
 
        self.username = username
 
        self.name = ''
 
        self.lastname = ''
 
        self.email = ''
 
        self.is_authenticated = False
 
        self.admin = False
 
        self.inherit_default_permissions = False
 
        self.is_external_auth = is_external_auth
 

	
 
        self.propagate_data()
 
        self._instance = None
 

	
 
    @LazyProperty
 
    def permissions(self):
 
        return self.__get_perms(user=self, cache=False)
 

	
 
    @property
 
    def api_keys(self):
 
        return self.get_api_keys()
 

	
 
    def propagate_data(self):
 
        user_model = UserModel()
 
        self.anonymous_user = User.get_default_user(cache=True)
 
        is_user_loaded = False
 

	
 
        # lookup by userid
 
        if self.user_id is not None and self.user_id != self.anonymous_user.user_id:
 
            log.debug('Auth User lookup by USER ID %s' % self.user_id)
 
            is_user_loaded = user_model.fill_data(self, user_id=self.user_id)
 

	
 
        # try go get user by API key
 
        elif self._api_key and self._api_key != self.anonymous_user.api_key:
 
            log.debug('Auth User lookup by API key %s' % self._api_key)
 
            is_user_loaded = user_model.fill_data(self, api_key=self._api_key)
 

	
 
        # lookup by username
 
        elif self.username:
 
            log.debug('Auth User lookup by USER NAME %s' % self.username)
 
            is_user_loaded = user_model.fill_data(self, username=self.username)
 
        else:
 
            log.debug('No data in %s that could been used to log in' % self)
 

	
 
        if not is_user_loaded:
 
            # if we cannot authenticate user try anonymous
 
            if self.anonymous_user.active:
 
                user_model.fill_data(self, user_id=self.anonymous_user.user_id)
 
                # then we set this user is logged in
 
                self.is_authenticated = True
 
            else:
 
                self.user_id = None
 
                self.username = None
 
                self.is_authenticated = False
 

	
 
        if not self.username:
 
            self.username = 'None'
 

	
 
@@ -588,107 +590,109 @@ class AuthUser(object):
 
                if x[1] == 'repository.admin']
 

	
 
    @property
 
    def repository_groups_admin(self):
 
        """
 
        Returns list of repository groups you're an admin of
 
        """
 
        return [x[0] for x in self.permissions['repositories_groups'].iteritems()
 
                if x[1] == 'group.admin']
 

	
 
    @property
 
    def user_groups_admin(self):
 
        """
 
        Returns list of user groups you're an admin of
 
        """
 
        return [x[0] for x in self.permissions['user_groups'].iteritems()
 
                if x[1] == 'usergroup.admin']
 

	
 
    @staticmethod
 
    def check_ip_allowed(user, ip_addr):
 
        """
 
        Check if the given IP address (a `str`) is allowed for the given
 
        user (an `AuthUser` or `db.User`).
 
        """
 
        allowed_ips = AuthUser.get_allowed_ips(user.user_id, cache=True,
 
            inherit_from_default=user.inherit_default_permissions)
 
        if check_ip_access(source_ip=ip_addr, allowed_ips=allowed_ips):
 
            log.debug('IP:%s is in range of %s' % (ip_addr, allowed_ips))
 
            return True
 
        else:
 
            log.info('Access for IP:%s forbidden, '
 
                     'not in %s' % (ip_addr, allowed_ips))
 
            return False
 

	
 
    def __repr__(self):
 
        return "<AuthUser('id:%s[%s] auth:%s')>"\
 
            % (self.user_id, self.username, self.is_authenticated)
 

	
 
    def set_authenticated(self, authenticated=True):
 
        if self.user_id != self.anonymous_user.user_id:
 
            self.is_authenticated = authenticated
 

	
 
    def to_cookie(self):
 
        """ Serializes this login session to a cookie `dict`. """
 
        return {
 
            'user_id': self.user_id,
 
            'username': self.username,
 
            'is_authenticated': self.is_authenticated,
 
            'is_external_auth': self.is_external_auth,
 
        }
 

	
 
    @staticmethod
 
    def from_cookie(cookie):
 
        """
 
        Deserializes an `AuthUser` from a cookie `dict`.
 
        """
 

	
 
        au = AuthUser(
 
            user_id=cookie.get('user_id'),
 
            username=cookie.get('username'),
 
            is_external_auth=cookie.get('is_external_auth', False),
 
        )
 
        if not au.is_authenticated and au.user_id is not None:
 
            # user is not authenticated and not empty
 
            au.set_authenticated(cookie.get('is_authenticated'))
 
        return au
 

	
 
    @classmethod
 
    def get_allowed_ips(cls, user_id, cache=False, inherit_from_default=False):
 
        _set = set()
 

	
 
        if inherit_from_default:
 
            default_ips = UserIpMap.query().filter(UserIpMap.user ==
 
                                            User.get_default_user(cache=True))
 
            if cache:
 
                default_ips = default_ips.options(FromCache("sql_cache_short",
 
                                                  "get_user_ips_default"))
 

	
 
            # populate from default user
 
            for ip in default_ips:
 
                try:
 
                    _set.add(ip.ip_addr)
 
                except ObjectDeletedError:
 
                    # since we use heavy caching sometimes it happens that we get
 
                    # deleted objects here, we just skip them
 
                    pass
 

	
 
        user_ips = UserIpMap.query().filter(UserIpMap.user_id == user_id)
 
        if cache:
 
            user_ips = user_ips.options(FromCache("sql_cache_short",
 
                                                  "get_user_ips_%s" % user_id))
 

	
 
        for ip in user_ips:
 
            try:
 
                _set.add(ip.ip_addr)
 
            except ObjectDeletedError:
 
                # since we use heavy caching sometimes it happens that we get
 
                # deleted objects here, we just skip them
 
                pass
 
        return _set or set(['0.0.0.0/0', '::/0'])
 

	
 

	
 
def set_available_permissions(config):
 
    """
 
    This function will propagate pylons globals with all available defined
 
    permission given in db. We don't want to check each time from db for new
 
    permissions since adding a new permission also requires application restart
 
    ie. to decorate new views with the newly created permission
 

	
kallithea/lib/base.py
Show inline comments
 
@@ -59,108 +59,109 @@ from kallithea.model.db import Repositor
 
from kallithea.model.notification import NotificationModel
 
from kallithea.model.scm import ScmModel
 
from kallithea.model.pull_request import PullRequestModel
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def _filter_proxy(ip):
 
    """
 
    HEADERS can have multiple ips inside the left-most being the original
 
    client, and each successive proxy that passed the request adding the IP
 
    address where it received the request from.
 

	
 
    :param ip:
 
    """
 
    if ',' in ip:
 
        _ips = ip.split(',')
 
        _first_ip = _ips[0].strip()
 
        log.debug('Got multiple IPs %s, using %s' % (','.join(_ips), _first_ip))
 
        return _first_ip
 
    return ip
 

	
 

	
 
def _get_ip_addr(environ):
 
    proxy_key = 'HTTP_X_REAL_IP'
 
    proxy_key2 = 'HTTP_X_FORWARDED_FOR'
 
    def_key = 'REMOTE_ADDR'
 

	
 
    ip = environ.get(proxy_key)
 
    if ip:
 
        return _filter_proxy(ip)
 

	
 
    ip = environ.get(proxy_key2)
 
    if ip:
 
        return _filter_proxy(ip)
 

	
 
    ip = environ.get(def_key, '0.0.0.0')
 
    return _filter_proxy(ip)
 

	
 

	
 
def _get_access_path(environ):
 
    path = environ.get('PATH_INFO')
 
    org_req = environ.get('pylons.original_request')
 
    if org_req:
 
        path = org_req.environ.get('PATH_INFO')
 
    return path
 

	
 

	
 
def log_in_user(user, remember):
 
def log_in_user(user, remember, is_external_auth):
 
    """
 
    Log a `User` in and update session and cookies. If `remember` is True,
 
    the session cookie is set to expire in a year; otherwise, it expires at
 
    the end of the browser session.
 

	
 
    Returns populated `AuthUser` object.
 
    """
 
    user.update_lastlogin()
 
    meta.Session().commit()
 

	
 
    auth_user = AuthUser(user_id=user.user_id)
 
    auth_user = AuthUser(user_id=user.user_id,
 
                         is_external_auth=is_external_auth)
 
    auth_user.set_authenticated()
 

	
 
    # Start new session to prevent session fixation attacks.
 
    session.invalidate()
 
    session['authuser'] = cookie = auth_user.to_cookie()
 

	
 
    # If they want to be remembered, update the cookie
 
    if remember:
 
        t = datetime.datetime.now() + datetime.timedelta(days=365)
 
        session._set_cookie_expires(t)
 

	
 
    session.save()
 

	
 
    log.info('user %s is now authenticated and stored in '
 
             'session, session attrs %s', user.username, cookie)
 

	
 
    # dumps session attrs back to cookie
 
    session._update_cookie_out()
 

	
 
    return auth_user
 

	
 

	
 
class BasicAuth(paste.auth.basic.AuthBasicAuthenticator):
 

	
 
    def __init__(self, realm, authfunc, auth_http_code=None):
 
        self.realm = realm
 
        self.authfunc = authfunc
 
        self._rc_auth_http_code = auth_http_code
 

	
 
    def build_authentication(self):
 
        head = paste.httpheaders.WWW_AUTHENTICATE.tuples('Basic realm="%s"' % self.realm)
 
        if self._rc_auth_http_code and self._rc_auth_http_code == '403':
 
            # return 403 if alternative http return code is specified in
 
            # Kallithea config
 
            return paste.httpexceptions.HTTPForbidden(headers=head)
 
        return paste.httpexceptions.HTTPUnauthorized(headers=head)
 

	
 
    def authenticate(self, environ):
 
        authorization = paste.httpheaders.AUTHORIZATION(environ)
 
        if not authorization:
 
            return self.build_authentication()
 
        (authmeth, auth) = authorization.split(' ', 1)
 
        if 'basic' != authmeth.lower():
 
            return self.build_authentication()
 
        auth = auth.strip().decode('base64')
 
        _parts = auth.split(':', 1)
 
        if len(_parts) == 2:
 
            username, password = _parts
 
@@ -339,128 +340,129 @@ class BaseController(WSGIController):
 

	
 
        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)
 

	
 
    @staticmethod
 
    def _determine_auth_user(api_key, session_authuser):
 
        """
 
        Create an `AuthUser` object given the IP address of the request, the
 
        API key (if any), and the authuser from the session.
 
        """
 

	
 
        # Authenticate by API key
 
        if api_key:
 
            # when using API_KEY we are sure user exists.
 
            return AuthUser(api_key=api_key)
 
            return AuthUser(api_key=api_key, is_external_auth=True)
 

	
 
        # Authenticate by session cookie
 
        cookie = session.get('authuser')
 
        # In ancient login sessions, 'authuser' may not be a dict.
 
        # In that case, the user will have to log in again.
 
        if isinstance(cookie, dict):
 
            try:
 
                return AuthUser.from_cookie(cookie)
 
            except UserCreationError as e:
 
                # container auth or other auth functions that create users on
 
                # the fly can throw UserCreationError to signal issues with
 
                # user creation. Explanation should be provided in the
 
                # exception object.
 
                from kallithea.lib import helpers as h
 
                h.flash(e, 'error', logf=log.error)
 

	
 
        # Authenticate by auth_container plugin (if enabled)
 
        if any(
 
            auth_modules.importplugin(name).is_container_auth
 
            for name in Setting.get_auth_plugins()
 
        ):
 
            try:
 
                auth_info = auth_modules.authenticate('', '', request.environ)
 
            except UserCreationError as e:
 
                from kallithea.lib import helpers as h
 
                h.flash(e, 'error', logf=log.error)
 
            else:
 
                if auth_info:
 
                    username = auth_info['username']
 
                    user = User.get_by_username(username, case_insensitive=True)
 
                    return log_in_user(user, remember=False)
 
                    return log_in_user(user, remember=False,
 
                                       is_external_auth=True)
 

	
 
        # User is anonymous
 
        return AuthUser()
 

	
 
    def __call__(self, environ, start_response):
 
        """Invoke the Controller"""
 

	
 
        # WSGIController.__call__ dispatches to the Controller method
 
        # the request is routed to. This routing information is
 
        # available in environ['pylons.routes_dict']
 
        try:
 
            self.ip_addr = _get_ip_addr(environ)
 
            # make sure that we update permissions each time we call controller
 

	
 
            #set globals for auth user
 
            self.authuser = c.authuser = request.user = self._determine_auth_user(
 
                request.GET.get('api_key'),
 
                session.get('authuser'),
 
            )
 

	
 
            log.info('IP: %s User: %s accessed %s',
 
                self.ip_addr, self.authuser,
 
                safe_unicode(_get_access_path(environ)),
 
            )
 
            return WSGIController.__call__(self, environ, start_response)
 
        finally:
 
            meta.Session.remove()
 

	
 

	
 
class BaseRepoController(BaseController):
 
    """
 
    Base class for controllers responsible for loading all needed data for
 
    repository loaded items are
 

	
 
    c.db_repo_scm_instance: instance of scm repository
 
    c.db_repo: instance of db
 
    c.repository_followers: number of followers
 
    c.repository_forks: number of forks
 
    c.repository_following: weather the current user is following the current repo
 
    """
 

	
 
    def __before__(self):
 
        super(BaseRepoController, self).__before__()
 
        if c.repo_name:  # extracted from routes
 
            _dbr = Repository.get_by_repo_name(c.repo_name)
 
            if not _dbr:
 
                return
 

	
kallithea/templates/base/base.html
Show inline comments
 
@@ -303,97 +303,100 @@
 
            <h4>${_('Login to Your Account')}</h4>
 
            ${h.form(h.url('login_home',came_from=h.url.current()))}
 
            <div class="form">
 
                <div class="fields">
 
                    <div class="field">
 
                        <div class="label">
 
                            <label for="username">${_('Username')}:</label>
 
                        </div>
 
                        <div class="input">
 
                            ${h.text('username',class_='focus')}
 
                        </div>
 

	
 
                    </div>
 
                    <div class="field">
 
                        <div class="label">
 
                            <label for="password">${_('Password')}:</label>
 
                        </div>
 
                        <div class="input">
 
                            ${h.password('password',class_='focus')}
 
                        </div>
 

	
 
                    </div>
 
                    <div class="buttons">
 
                        <div class="password_forgoten">${h.link_to(_('Forgot password ?'),h.url('reset_password'))}</div>
 
                        <div class="register">
 
                        %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')():
 
                         ${h.link_to(_("Don't have an account ?"),h.url('register'))}
 
                        %endif
 
                        </div>
 
                        <div class="submit">
 
                            ${h.submit('sign_in',_('Log In'),class_="btn btn-mini")}
 
                        </div>
 
                    </div>
 
                </div>
 
            </div>
 
            ${h.end_form()}
 
          %else:
 
            <div class="links_left">
 
                <div class="big_gravatar">
 
                  ${h.gravatar(c.authuser.email, size=48)}
 
                </div>
 
                <div class="full_name">${c.authuser.full_name_or_username}</div>
 
                <div class="email">${c.authuser.email}</div>
 
            </div>
 
            <div class="links_right">
 
            <ol class="links">
 
              <li><a href="${h.url('notifications')}">${_('Notifications')}: ${c.unread_notifications}</a></li>
 
              <li>${h.link_to(_(u'My Account'),h.url('my_account'))}</li>
 
              <li class="logout">${h.link_to(_(u'Log Out'),h.url('logout_home'))}</li>
 
              %if not c.authuser.is_external_auth:
 
                ## Cannot log out if using external (container) authentication.
 
                <li class="logout">${h.link_to(_(u'Log Out'), h.url('logout_home'))}</li>
 
              %endif
 
            </ol>
 
            </div>
 
          %endif
 
        </div>
 
      </div>
 
    </li>
 

	
 
    <script type="text/javascript">
 
        var visual_show_public_icon = "${c.visual.show_public_icon}" == "True";
 
        var cache = {}
 
        /*format the look of items in the list*/
 
        var format = function(state){
 
            if (!state.id){
 
              return state.text; // optgroup
 
            }
 
            var obj_dict = state.obj;
 
            var tmpl = '';
 

	
 
            if(obj_dict && state.type == 'repo'){
 
                tmpl += '<span class="repo-icons">';
 
                if(obj_dict['repo_type'] === 'hg'){
 
                    tmpl += '<span class="repotag">hg</span> ';
 
                }
 
                else if(obj_dict['repo_type'] === 'git'){
 
                    tmpl += '<span class="repotag">git</span> ';
 
                }
 
                if(obj_dict['private']){
 
                    tmpl += '<i class="icon-keyhole-circled"></i> ';
 
                }
 
                else if(visual_show_public_icon){
 
                    tmpl += '<i class="icon-globe"></i> ';
 
                }
 
                tmpl += '</span>';
 
            }
 
            if(obj_dict && state.type == 'group'){
 
                    tmpl += '<i class="icon-folder"></i> ';
 
            }
 
            tmpl += state.text;
 
            return tmpl;
 
        }
 

	
 
        $("#repo_switcher").select2({
 
            placeholder: '<i class="icon-database"></i> ${_('Repositories')}',
 
            dropdownAutoWidth: true,
 
            formatResult: format,
 
            formatSelection: format,
 
            formatNoMatches: function(term){
 
                return "${_('No matches found')}";
kallithea/tests/functional/test_admin_auth_settings.py
Show inline comments
 
@@ -130,48 +130,60 @@ class TestAuthSettingsController(TestCon
 
            url=url(controller='admin/my_account', action='my_account'),
 
            **get_kwargs
 
        )
 
        response.mustcontain('My Account %s' % resulting_username)
 

	
 
    def test_container_auth_login_header(self):
 
        self._container_auth_setup(
 
            auth_container_header='THE_USER_NAME',
 
            auth_container_fallback_header='',
 
            auth_container_clean_username='False',
 
        )
 
        self._container_auth_verify_login(
 
            extra_environ={'THE_USER_NAME': 'john@example.org'},
 
            resulting_username='john@example.org',
 
        )
 

	
 
    def test_container_auth_login_fallback_header(self):
 
        self._container_auth_setup(
 
            auth_container_header='THE_USER_NAME',
 
            auth_container_fallback_header='HTTP_X_YZZY',
 
            auth_container_clean_username='False',
 
        )
 
        self._container_auth_verify_login(
 
            headers={'X-Yzzy': r'foo\bar'},
 
            resulting_username=r'foo\bar',
 
        )
 

	
 
    def test_container_auth_clean_username_at(self):
 
        self._container_auth_setup(
 
            auth_container_header='REMOTE_USER',
 
            auth_container_fallback_header='',
 
            auth_container_clean_username='True',
 
        )
 
        self._container_auth_verify_login(
 
            extra_environ={'REMOTE_USER': 'john@example.org'},
 
            resulting_username='john',
 
        )
 

	
 
    def test_container_auth_clean_username_backslash(self):
 
        self._container_auth_setup(
 
            auth_container_header='REMOTE_USER',
 
            auth_container_fallback_header='',
 
            auth_container_clean_username='True',
 
        )
 
        self._container_auth_verify_login(
 
            extra_environ={'REMOTE_USER': r'example\jane'},
 
            resulting_username=r'jane',
 
        )
 

	
 
    def test_container_auth_no_logout(self):
 
        self._container_auth_setup(
 
            auth_container_header='REMOTE_USER',
 
            auth_container_fallback_header='',
 
            auth_container_clean_username='True',
 
        )
 
        response = self.app.get(
 
            url=url(controller='admin/my_account', action='my_account'),
 
            extra_environ={'REMOTE_USER': 'john'},
 
        )
 
        self.assertNotIn('Log Out', response.normal_body)
0 comments (0 inline, 0 general)