Exemplo n.º 1
0
def test_init_user_attributes_from_ldap(monkeypatch, arrange_ldap_auth):
    """Authenticate unknown user with mocked LDAP, verify user is created.
    """

    # Arrange test user.
    uniqifier = uuid.uuid4()
    username = '******'.format(uniqifier)
    assert User.get_by_username(username) is None

    # Arrange LDAP auth.
    monkeypatch.setattr(auth_ldap, 'AuthLdap', _AuthLdapMock)

    # Authenticate with LDAP.
    user_data = authenticate(username, 'password')

    # Verify that authenication succeeded and retrieved correct attributes
    # from LDAP.
    assert user_data is not None
    assert user_data.get('firstname') == u'spam ldap first name'
    assert user_data.get('lastname') == u'spam ldap last name'
    assert user_data.get('email') == 'spam ldap email'

    # Verify that authentication created new user with attributes
    # retrieved from LDAP.
    new_user = User.get_by_username(username)
    assert new_user is not None
    assert new_user.firstname == u'spam ldap first name'
    assert new_user.lastname == u'spam ldap last name'
    assert new_user.email == 'spam ldap email'
Exemplo n.º 2
0
 def validate_python(self, value, state):
     from kallithea.lib import auth_modules
     if auth_modules.authenticate(username, value, '') is None:
         msg = M(self, 'invalid_password', state)
         raise formencode.Invalid(msg, value, state,
             error_dict=dict(current_password=msg)
         )
Exemplo n.º 3
0
def test_init_user_attributes_from_ldap(monkeypatch, arrange_ldap_auth):
    """Authenticate unknown user with mocked LDAP, verify user is created.
    """

    # Arrange test user.
    uniqifier = uuid.uuid4()
    username = '******'.format(uniqifier)
    assert User.get_by_username(username) is None

    # Arrange LDAP auth.
    monkeypatch.setattr(auth_ldap, 'AuthLdap', _AuthLdapMock)

    # Authenticate with LDAP.
    user_data = authenticate(username, 'password')

    # Verify that authenication succeeded and retrieved correct attributes
    # from LDAP.
    assert user_data is not None
    assert user_data.get('firstname') == u'spam ldap first name'
    assert user_data.get('lastname') == u'spam ldap last name'
    assert user_data.get('email') == 'spam ldap email'

    # Verify that authentication created new user with attributes
    # retrieved from LDAP.
    new_user = User.get_by_username(username)
    assert new_user is not None
    assert new_user.firstname == u'spam ldap first name'
    assert new_user.lastname == u'spam ldap last name'
    assert new_user.email == 'spam ldap email'
Exemplo n.º 4
0
        def validate_python(self, value, state):
            from kallithea.lib import auth_modules

            password = value['password']
            username = value['username']

            # authenticate returns unused dict but has called
            # plugin._authenticate which has create_or_update'ed the username user in db
            if auth_modules.authenticate(username, password) is None:
                user = User.get_by_username_or_email(username)
                if user and not user.active:
                    log.warning('user %s is disabled', username)
                    msg = self.message('invalid_auth', state)
                    raise formencode.Invalid(msg,
                                             value,
                                             state,
                                             error_dict=dict(username='******',
                                                             password=msg))
                else:
                    log.warning('user %s failed to authenticate', username)
                    msg = self.message('invalid_auth', state)
                    raise formencode.Invalid(msg,
                                             value,
                                             state,
                                             error_dict=dict(username='******',
                                                             password=msg))
Exemplo n.º 5
0
 def validate_python(self, value, state):
     from kallithea.lib import auth_modules
     if auth_modules.authenticate(username, value, '') is None:
         msg = self.message('invalid_password', state)
         raise formencode.Invalid(msg,
                                  value,
                                  state,
                                  error_dict=dict(current_password=msg))
Exemplo n.º 6
0
    def _determine_auth_user(api_key, bearer_token, session_authuser):
        """
        Create an `AuthUser` object given the API key/bearer token
        (if any) and the value of the authuser session cookie.
        """

        # Authenticate by bearer token
        if bearer_token is not None:
            api_key = bearer_token

        # Authenticate by API key
        if api_key is not None:
            au = AuthUser(dbuser=User.get_by_api_key(api_key),
                authenticating_api_key=api_key, is_external_auth=True)
            if au.is_anonymous:
                log.warning('API key ****%s is NOT valid', api_key[-4:])
                raise webob.exc.HTTPForbidden(_('Invalid API key'))
            return au

        # Authenticate by session cookie
        # In ancient login sessions, 'authuser' may not be a dict.
        # In that case, the user will have to log in again.
        # v0.3 and earlier included an 'is_authenticated' key; if present,
        # this must be True.
        if isinstance(session_authuser, dict) and session_authuser.get('is_authenticated', True):
            try:
                return AuthUser.from_cookie(session_authuser)
            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(
            plugin.is_container_auth
            for plugin in auth_modules.get_auth_plugins()
        ):
            try:
                user_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 user_info is not None:
                    username = user_info['username']
                    user = User.get_by_username(username, case_insensitive=True)
                    return log_in_user(user, remember=False,
                                       is_external_auth=True)

        # User is anonymous
        return AuthUser()
Exemplo n.º 7
0
    def _determine_auth_user(api_key, session_authuser):
        """
        Create an `AuthUser` object given the API key (if any) and the
        value of the authuser session cookie.
        """

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

        # Authenticate by session cookie
        # In ancient login sessions, 'authuser' may not be a dict.
        # In that case, the user will have to log in again.
        # v0.3 and earlier included an 'is_authenticated' key; if present,
        # this must be True.
        if isinstance(session_authuser, dict) and session_authuser.get('is_authenticated', True):
            try:
                return AuthUser.from_cookie(session_authuser)
            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:
                user_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 user_info is not None:
                    username = user_info['username']
                    user = User.get_by_username(username, case_insensitive=True)
                    return log_in_user(user, remember=False,
                                       is_external_auth=True)

        # User is anonymous
        return AuthUser()
Exemplo n.º 8
0
    def _determine_auth_user(session_authuser, ip_addr):
        """
        Create an `AuthUser` object given the API key/bearer token
        (if any) and the value of the authuser session cookie.
        Returns None if no valid user is found (like not active or no access for IP).
        """

        # Authenticate by session cookie
        # In ancient login sessions, 'authuser' may not be a dict.
        # In that case, the user will have to log in again.
        # v0.3 and earlier included an 'is_authenticated' key; if present,
        # this must be True.
        if isinstance(session_authuser, dict) and session_authuser.get(
                'is_authenticated', True):
            return AuthUser.from_cookie(session_authuser, ip_addr=ip_addr)

        # Authenticate by auth_container plugin (if enabled)
        if any(plugin.is_container_auth
               for plugin in auth_modules.get_auth_plugins()):
            try:
                user_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 user_info is not None:
                    username = user_info['username']
                    user = User.get_by_username(username,
                                                case_insensitive=True)
                    return log_in_user(user,
                                       remember=False,
                                       is_external_auth=True,
                                       ip_addr=ip_addr)

        # User is default user (if active) or anonymous
        default_user = User.get_default_user()
        authuser = AuthUser.make(dbuser=default_user, ip_addr=ip_addr)
        if authuser is None:  # fall back to anonymous
            authuser = AuthUser(
                dbuser=default_user)  # TODO: somehow use .make?
        return authuser
Exemplo n.º 9
0
        def validate_python(self, value, state):
            from kallithea.lib import auth_modules

            password = value['password']
            username = value['username']

            if not auth_modules.authenticate(username, password):
                user = User.get_by_username(username)
                if user and not user.active:
                    log.warning('user %s is disabled' % username)
                    msg = M(self, 'disabled_account', state)
                    raise formencode.Invalid(msg, value, state,
                        error_dict=dict(username=msg)
                    )
                else:
                    log.warning('user %s failed to authenticate' % username)
                    msg = M(self, 'invalid_username', state)
                    msg2 = M(self, 'invalid_password', state)
                    raise formencode.Invalid(msg, value, state,
                        error_dict=dict(username=msg, password=msg2)
                    )
Exemplo n.º 10
0
        def validate_python(self, value, state):
            from kallithea.lib import auth_modules

            password = value['password']
            username = value['username']

            # authenticate returns unused dict but has called
            # plugin._authenticate which has create_or_update'ed the username user in db
            if auth_modules.authenticate(username, password) is None:
                user = User.get_by_username_or_email(username)
                if user and not user.active:
                    log.warning('user %s is disabled', username)
                    msg = M(self, 'invalid_auth', state)
                    raise formencode.Invalid(msg, value, state,
                        error_dict=dict(username='******', password=msg)
                    )
                else:
                    log.warning('user %s failed to authenticate', username)
                    msg = M(self, 'invalid_auth', state)
                    raise formencode.Invalid(msg, value, state,
                        error_dict=dict(username='******', password=msg)
                    )
Exemplo n.º 11
0
def test_update_user_attributes_from_ldap(monkeypatch, create_test_user,
                                          arrange_ldap_auth):
    """Authenticate user with mocked LDAP, verify attributes are updated.
    """

    # Arrange test user.
    uniqifier = uuid.uuid4()
    username = '******'.format(uniqifier)
    assert User.get_by_username(username) is None
    user_input = dict(username='******'.format(uniqifier),
                      password='******',
                      email='spam-email-{0}'.format(uniqifier),
                      firstname=u'spam first name',
                      lastname=u'spam last name',
                      active=True,
                      admin=False)
    user = create_test_user(user_input)

    # Arrange LDAP auth.
    monkeypatch.setattr(auth_ldap, 'AuthLdap', _AuthLdapMock)

    # Authenticate with LDAP.
    user_data = authenticate(username, 'password')

    # Verify that authenication succeeded and retrieved correct attributes
    # from LDAP.
    assert user_data is not None
    assert user_data.get('firstname') == u'spam ldap first name'
    assert user_data.get('lastname') == u'spam ldap last name'
    assert user_data.get('email') == 'spam ldap email'

    # Verify that authentication overwrote user attributes with the ones
    # retrieved from LDAP.
    assert user.firstname == u'spam ldap first name'
    assert user.lastname == u'spam ldap last name'
    assert user.email == 'spam ldap email'
Exemplo n.º 12
0
def test_update_user_attributes_from_ldap(monkeypatch, create_test_user,
                                          arrange_ldap_auth):
    """Authenticate user with mocked LDAP, verify attributes are updated.
    """

    # Arrange test user.
    uniqifier = uuid.uuid4()
    username = '******'.format(uniqifier)
    assert User.get_by_username(username) is None
    user_input = dict(username='******'.format(uniqifier),
                      password='******',
                      email='spam-email-{0}'.format(uniqifier),
                      firstname=u'spam first name',
                      lastname=u'spam last name',
                      active=True,
                      admin=False)
    user = create_test_user(user_input)

    # Arrange LDAP auth.
    monkeypatch.setattr(auth_ldap, 'AuthLdap', _AuthLdapMock)

    # Authenticate with LDAP.
    user_data = authenticate(username, 'password')

    # Verify that authenication succeeded and retrieved correct attributes
    # from LDAP.
    assert user_data is not None
    assert user_data.get('firstname') == u'spam ldap first name'
    assert user_data.get('lastname') == u'spam ldap last name'
    assert user_data.get('email') == 'spam ldap email'

    # Verify that authentication overwrote user attributes with the ones
    # retrieved from LDAP.
    assert user.firstname == u'spam ldap first name'
    assert user.lastname == u'spam ldap last name'
    assert user.email == 'spam ldap email'
Exemplo n.º 13
0
        def validate_python(self, value, state):
            from kallithea.lib import auth_modules

            password = value['password']
            username = value['username']

            if not auth_modules.authenticate(username, password):
                user = User.get_by_username(username)
                if user and not user.active:
                    log.warning('user %s is disabled' % username)
                    msg = M(self, 'disabled_account', state)
                    raise formencode.Invalid(msg,
                                             value,
                                             state,
                                             error_dict=dict(username=msg))
                else:
                    log.warning('user %s failed to authenticate' % username)
                    msg = M(self, 'invalid_username', state)
                    msg2 = M(self, 'invalid_password', state)
                    raise formencode.Invalid(msg,
                                             value,
                                             state,
                                             error_dict=dict(username=msg,
                                                             password=msg2))
Exemplo n.º 14
0
                                       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')

        # check if we use container plugin, and try to login using it.
        auth_plugins = Setting.get_auth_plugins()
        if any(
            (importplugin(name).is_container_auth for name in auth_plugins)):
            from kallithea.lib import auth_modules
            try:
                auth_info = auth_modules.authenticate('', '', request.environ)
            except UserCreationError, e:
                log.error(e)
                h.flash(e, 'error')
                # render login, with flash message about limit
                return render('/login.html')

            if auth_info:
                headers = self._store_user_in_session(
                    auth_info.get('username'))
                raise HTTPFound(location=c.came_from, headers=headers)
        return render('/login.html')

    @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
                               'hg.register.manual_activate')
    def register(self):
Exemplo n.º 15
0
    def _handle_request(self, environ, start_response):
        if not is_git(environ):
            return self.application(environ, start_response)
        if not self._check_ssl(environ):
            return HTTPNotAcceptable('SSL REQUIRED !')(environ, start_response)

        ip_addr = self._get_ip_addr(environ)
        username = None
        self._git_first_op = False
        # skip passing error to error controller
        environ['pylons.status_code_redirect'] = True

        #======================================================================
        # EXTRACT REPOSITORY NAME FROM ENV
        #======================================================================
        try:
            repo_name = self.__get_repository(environ)
            log.debug('Extracted repo name is %s' % repo_name)
        except Exception:
            return HTTPInternalServerError()(environ, start_response)

        # quick check if that dir exists...
        if not is_valid_repo(repo_name, self.basepath, 'git'):
            return HTTPNotFound()(environ, start_response)

        #======================================================================
        # GET ACTION PULL or PUSH
        #======================================================================
        action = self.__get_action(environ)

        #======================================================================
        # CHECK ANONYMOUS PERMISSION
        #======================================================================
        if action in ['pull', 'push']:
            anonymous_user = self.__get_user('default')
            username = anonymous_user.username
            if anonymous_user.active:
                # ONLY check permissions if the user is activated
                anonymous_perm = self._check_permission(
                    action, anonymous_user, repo_name, ip_addr)
            else:
                anonymous_perm = False

            if not anonymous_user.active or not anonymous_perm:
                if not anonymous_user.active:
                    log.debug('Anonymous access is disabled, running '
                              'authentication')

                if not anonymous_perm:
                    log.debug('Not enough credentials to access this '
                              'repository as anonymous user')

                username = None
                #==============================================================
                # DEFAULT PERM FAILED OR ANONYMOUS ACCESS IS DISABLED SO WE
                # NEED TO AUTHENTICATE AND ASK FOR AUTH USER PERMISSIONS
                #==============================================================

                # try to auth based on environ, container auth methods
                log.debug(
                    'Running PRE-AUTH for container based authentication')
                pre_auth = auth_modules.authenticate('', '', environ)
                if pre_auth and pre_auth.get('username'):
                    username = pre_auth['username']
                log.debug('PRE-AUTH got %s as username' % username)

                # If not authenticated by the container, running basic auth
                if not username:
                    self.authenticate.realm = \
                        safe_str(self.config['realm'])
                    result = self.authenticate(environ)
                    if isinstance(result, str):
                        AUTH_TYPE.update(environ, 'basic')
                        REMOTE_USER.update(environ, result)
                        username = result
                    else:
                        return result.wsgi_application(environ, start_response)

                #==============================================================
                # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME
                #==============================================================
                try:
                    user = self.__get_user(username)
                    if user is None or not user.active:
                        return HTTPForbidden()(environ, start_response)
                    username = user.username
                except Exception:
                    log.error(traceback.format_exc())
                    return HTTPInternalServerError()(environ, start_response)

                #check permissions for this repository
                perm = self._check_permission(action, user, repo_name, ip_addr)
                if not perm:
                    return HTTPForbidden()(environ, start_response)

        # extras are injected into UI object and later available
        # in hooks executed by kallithea
        from kallithea import CONFIG
        server_url = get_server_url(environ)
        extras = {
            'ip': ip_addr,
            'username': username,
            'action': action,
            'repository': repo_name,
            'scm': 'git',
            'config': CONFIG['__file__'],
            'server_url': server_url,
            'make_lock': None,
            'locked_by': [None, None]
        }

        #===================================================================
        # GIT REQUEST HANDLING
        #===================================================================
        str_repo_name = safe_str(repo_name)
        repo_path = os.path.join(safe_str(self.basepath), str_repo_name)
        log.debug('Repository path is %s' % repo_path)

        # CHECK LOCKING only if it's not ANONYMOUS USER
        if username != User.DEFAULT_USER:
            log.debug('Checking locking on repository')
            (make_lock, locked,
             locked_by) = self._check_locking_state(environ=environ,
                                                    action=action,
                                                    repo=repo_name,
                                                    user_id=user.user_id)
            # store the make_lock for later evaluation in hooks
            extras.update({'make_lock': make_lock, 'locked_by': locked_by})

        fix_PATH()
        log.debug('HOOKS extras is %s' % extras)
        baseui = make_ui('db')
        self.__inject_extras(repo_path, baseui, extras)

        try:
            self._handle_githooks(repo_name, action, baseui, environ)
            log.info('%s action on Git repo "%s" by "%s" from %s' %
                     (action, str_repo_name, safe_str(username), ip_addr))
            app = self.__make_app(repo_name, repo_path, extras)
            return app(environ, start_response)
        except HTTPLockedRC, e:
            _code = CONFIG.get('lock_ret_code')
            log.debug('Repository LOCKED ret code %s!' % (_code))
            return e(environ, start_response)
Exemplo n.º 16
0
    def _authorize(self, environ, start_response, action, repo_name, ip_addr):
        """Authenticate and authorize user.

        Since we're dealing with a VCS client and not a browser, we only
        support HTTP basic authentication, either directly via raw header
        inspection, or by using container authentication to delegate the
        authentication to the web server.

        Returns (user, None) on successful authentication and authorization.
        Returns (None, wsgi_app) to send the wsgi_app response to the client.
        """
        # Check if anonymous access is allowed.
        default_user = User.get_default_user(cache=True)
        is_default_user_allowed = (default_user.active and
            self._check_permission(action, default_user, repo_name, ip_addr))
        if is_default_user_allowed:
            return default_user, None

        if not default_user.active:
            log.debug('Anonymous access is disabled')
        else:
            log.debug('Not authorized to access this '
                      'repository as anonymous user')

        username = None
        #==============================================================
        # DEFAULT PERM FAILED OR ANONYMOUS ACCESS IS DISABLED SO WE
        # NEED TO AUTHENTICATE AND ASK FOR AUTH USER PERMISSIONS
        #==============================================================

        # try to auth based on environ, container auth methods
        log.debug('Running PRE-AUTH for container based authentication')
        pre_auth = auth_modules.authenticate('', '', environ)
        if pre_auth is not None and pre_auth.get('username'):
            username = pre_auth['username']
        log.debug('PRE-AUTH got %s as username', username)

        # If not authenticated by the container, running basic auth
        if not username:
            self.authenticate.realm = safe_str(self.config['realm'])
            result = self.authenticate(environ)
            if isinstance(result, str):
                paste.httpheaders.AUTH_TYPE.update(environ, 'basic')
                paste.httpheaders.REMOTE_USER.update(environ, result)
                username = result
            else:
                return None, result.wsgi_application

        #==============================================================
        # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME
        #==============================================================
        try:
            user = User.get_by_username_or_email(username)
            if user is None or not user.active:
                return None, webob.exc.HTTPForbidden()
        except Exception:
            log.error(traceback.format_exc())
            return None, webob.exc.HTTPInternalServerError()

        #check permissions for this repository
        perm = self._check_permission(action, user, repo_name, ip_addr)
        if not perm:
            return None, webob.exc.HTTPForbidden()

        return user, None
Exemplo n.º 17
0
    def _handle_request(self, environ, start_response):
        if not is_git(environ):
            return self.application(environ, start_response)
        if not self._check_ssl(environ):
            return HTTPNotAcceptable('SSL REQUIRED !')(environ, start_response)

        ip_addr = self._get_ip_addr(environ)
        username = None
        self._git_first_op = False
        # skip passing error to error controller
        environ['pylons.status_code_redirect'] = True

        #======================================================================
        # EXTRACT REPOSITORY NAME FROM ENV
        #======================================================================
        try:
            str_repo_name = self.__get_repository(environ)
            repo_name = safe_unicode(str_repo_name)
            log.debug('Extracted repo name is %s', repo_name)
        except Exception as e:
            log.error('error extracting repo_name: %r', e)
            return HTTPInternalServerError()(environ, start_response)

        # quick check if that dir exists...
        if not is_valid_repo(repo_name, self.basepath, 'git'):
            return HTTPNotFound()(environ, start_response)

        #======================================================================
        # GET ACTION PULL or PUSH
        #======================================================================
        action = self.__get_action(environ)

        #======================================================================
        # CHECK ANONYMOUS PERMISSION
        #======================================================================
        if action in ['pull', 'push']:
            anonymous_user = User.get_default_user(cache=True)
            username = anonymous_user.username
            if anonymous_user.active:
                # ONLY check permissions if the user is activated
                anonymous_perm = self._check_permission(action, anonymous_user,
                                                        repo_name, ip_addr)
            else:
                anonymous_perm = False

            if not anonymous_user.active or not anonymous_perm:
                if not anonymous_user.active:
                    log.debug('Anonymous access is disabled, running '
                              'authentication')

                if not anonymous_perm:
                    log.debug('Not enough credentials to access this '
                              'repository as anonymous user')

                username = None
                #==============================================================
                # DEFAULT PERM FAILED OR ANONYMOUS ACCESS IS DISABLED SO WE
                # NEED TO AUTHENTICATE AND ASK FOR AUTH USER PERMISSIONS
                #==============================================================

                # try to auth based on environ, container auth methods
                log.debug('Running PRE-AUTH for container based authentication')
                pre_auth = auth_modules.authenticate('', '', environ)
                if pre_auth is not None and pre_auth.get('username'):
                    username = pre_auth['username']
                log.debug('PRE-AUTH got %s as username', username)

                # If not authenticated by the container, running basic auth
                if not username:
                    self.authenticate.realm = \
                        safe_str(self.config['realm'])
                    result = self.authenticate(environ)
                    if isinstance(result, str):
                        AUTH_TYPE.update(environ, 'basic')
                        REMOTE_USER.update(environ, result)
                        username = result
                    else:
                        return result.wsgi_application(environ, start_response)

                #==============================================================
                # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME
                #==============================================================
                try:
                    user = User.get_by_username_or_email(username)
                    if user is None or not user.active:
                        return HTTPForbidden()(environ, start_response)
                    username = user.username
                except Exception:
                    log.error(traceback.format_exc())
                    return HTTPInternalServerError()(environ, start_response)

                #check permissions for this repository
                perm = self._check_permission(action, user, repo_name, ip_addr)
                if not perm:
                    return HTTPForbidden()(environ, start_response)

        # extras are injected into UI object and later available
        # in hooks executed by kallithea
        from kallithea import CONFIG
        server_url = get_server_url(environ)
        extras = {
            'ip': ip_addr,
            'username': username,
            'action': action,
            'repository': repo_name,
            'scm': 'git',
            'config': CONFIG['__file__'],
            'server_url': server_url,
            'make_lock': None,
            'locked_by': [None, None]
        }

        #===================================================================
        # GIT REQUEST HANDLING
        #===================================================================
        repo_path = os.path.join(safe_str(self.basepath),str_repo_name)
        log.debug('Repository path is %s', repo_path)

        # CHECK LOCKING only if it's not ANONYMOUS USER
        if username != User.DEFAULT_USER:
            log.debug('Checking locking on repository')
            (make_lock,
             locked,
             locked_by) = self._check_locking_state(
                            environ=environ, action=action,
                            repo=repo_name, user_id=user.user_id
                       )
            # store the make_lock for later evaluation in hooks
            extras.update({'make_lock': make_lock,
                           'locked_by': locked_by})

        fix_PATH()
        log.debug('HOOKS extras is %s', extras)
        baseui = make_ui('db')
        self.__inject_extras(repo_path, baseui, extras)

        try:
            self._handle_githooks(repo_name, action, baseui, environ)
            log.info('%s action on Git repo "%s" by "%s" from %s',
                     action, str_repo_name, safe_str(username), ip_addr)
            app = self.__make_app(repo_name, repo_path, extras)
            result = app(environ, start_response)
            if action == 'push':
                result = WSGIResultCloseCallback(result,
                    lambda: self._invalidate_cache(repo_name))
            return result
        except HTTPLockedRC as e:
            _code = CONFIG.get('lock_ret_code')
            log.debug('Repository LOCKED ret code %s!', _code)
            return e(environ, start_response)
        except Exception:
            log.error(traceback.format_exc())
            return HTTPInternalServerError()(environ, start_response)
Exemplo n.º 18
0
                    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')

        # check if we use container plugin, and try to login using it.
        auth_plugins = Setting.get_auth_plugins()
        if any((importplugin(name).is_container_auth for name in auth_plugins)):
            from kallithea.lib import auth_modules
            try:
                auth_info = auth_modules.authenticate('', '', request.environ)
            except UserCreationError, e:
                log.error(e)
                h.flash(e, 'error')
                # render login, with flash message about limit
                return render('/login.html')

            if auth_info:
                headers = self._store_user_in_session(auth_info.get('username'))
                raise HTTPFound(location=c.came_from, headers=headers)
        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()\