コード例 #1
0
    def auth(self, userobj, username, password, settings, **kwargs):
        if not userobj:
            log.debug('userobj was:%s skipping' % (userobj, ))
            return None

        user_attrs = {
            "username": userobj.username,
            "firstname": userobj.firstname,
            "lastname": userobj.lastname,
            "groups": [],
            "email": userobj.email,
            "admin": userobj.admin,
            "active": userobj.active,
            "active_from_extern": userobj.active,
            "extern_name": userobj.user_id,
            "extern_type": userobj.extern_type,
        }

        log.debug('Authenticating user with args %s', user_attrs)
        if userobj.active:
            role = UserApiKeys.ROLE_VCS
            active_tokens = [x.api_key for x in
                             User.extra_valid_auth_tokens(userobj, role=role)]
            if userobj.username == username and password in active_tokens:
                log.info(
                    'user `%s` successfully authenticated via %s',
                    user_attrs['username'], self.name)
                return user_attrs
            log.error(
                'user `%s` failed to authenticate via %s, reason: bad or '
                'inactive token.', username, self.name)
        else:
            log.warning(
                'user `%s` failed to authenticate via %s, reason: account not '
                'active.', username, self.name)
        return None
コード例 #2
0
def request_view(request):
    """
    Main request handling method. It handles all logic to call a specific
    exposed method
    """

    # check if we can find this session using api_key, get_by_auth_token
    # search not expired tokens only

    try:
        u = User.get_by_auth_token(request.rpc_api_key)

        if u is None:
            return jsonrpc_error(request,
                                 retid=request.rpc_id,
                                 message='Invalid API KEY')

        if not u.active:
            return jsonrpc_error(request,
                                 retid=request.rpc_id,
                                 message='Request from this user not allowed')

        # check if we are allowed to use this IP
        auth_u = AuthUser(u.user_id,
                          request.rpc_api_key,
                          ip_addr=request.rpc_ip_addr)
        if not auth_u.ip_allowed:
            return jsonrpc_error(request,
                                 retid=request.rpc_id,
                                 message='Request from IP:%s not allowed' %
                                 (request.rpc_ip_addr, ))
        else:
            log.info('Access for IP:%s allowed' % (request.rpc_ip_addr, ))

        # now check if token is valid for API
        role = UserApiKeys.ROLE_API
        extra_auth_tokens = [
            x.api_key for x in User.extra_valid_auth_tokens(u, role=role)
        ]
        active_tokens = [u.api_key] + extra_auth_tokens

        log.debug('Checking if API key has proper role')
        if request.rpc_api_key not in active_tokens:
            return jsonrpc_error(
                request,
                retid=request.rpc_id,
                message='API KEY has bad role for an API call')

    except Exception as e:
        log.exception('Error on API AUTH')
        return jsonrpc_error(request,
                             retid=request.rpc_id,
                             message='Invalid API KEY')

    method = request.rpc_method
    func = request.registry.jsonrpc_methods[method]

    # now that we have a method, add request._req_params to
    # self.kargs and dispatch control to WGIController
    argspec = inspect.getargspec(func)
    arglist = argspec[0]
    defaults = map(type, argspec[3] or [])
    default_empty = types.NotImplementedType

    # kw arguments required by this method
    func_kwargs = dict(
        itertools.izip_longest(reversed(arglist),
                               reversed(defaults),
                               fillvalue=default_empty))

    # This attribute will need to be first param of a method that uses
    # api_key, which is translated to instance of user at that name
    user_var = 'apiuser'
    request_var = 'request'

    for arg in [user_var, request_var]:
        if arg not in arglist:
            return jsonrpc_error(request,
                                 retid=request.rpc_id,
                                 message='This method [%s] does not support '
                                 'required parameter `%s`' %
                                 (func.__name__, arg))

    # get our arglist and check if we provided them as args
    for arg, default in func_kwargs.items():
        if arg in [user_var, request_var]:
            # user_var and request_var are pre-hardcoded parameters and we
            # don't need to do any translation
            continue

        # skip the required param check if it's default value is
        # NotImplementedType (default_empty)
        if default == default_empty and arg not in request.rpc_params:
            return jsonrpc_error(
                request,
                retid=request.rpc_id,
                message=('Missing non optional `%s` arg in JSON DATA' % arg))

    # sanitze extra passed arguments
    for k in request.rpc_params.keys()[:]:
        if k not in func_kwargs:
            del request.rpc_params[k]

    call_params = request.rpc_params
    call_params.update({'request': request, 'apiuser': auth_u})
    try:
        ret_value = func(**call_params)
        return jsonrpc_response(request, ret_value)
    except JSONRPCBaseError:
        raise
    except Exception:
        log.exception('Unhandled exception occured on api call: %s', func)
        return jsonrpc_error(request,
                             retid=request.rpc_id,
                             message='Internal server error')