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
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')