def failprocess(self, ip, request, logFailure, errorStmt, logUsage, errType): """ If logFailure is not None, Update the failureDict when the request does something wrong If logUsage is not None, log the usage track info. Arguments: ip : IP of client request : the request we received logFailure : If none, we do not log this failure to failure dict. Otherwise it is a tuple of key : the key to use in the failureDict failureDict : the dict record the failure attempt history errorStmt : A string to return to the user, looks like 'Malformed Body: %s' so that we can add things like "Number of attempts remaining: 2" to the response logUsage : A tuple of (tictoc and devid) used for usage tracker errorResponse: The error code to set response code Returns: String to respond to the client """ time = timeflt() # Set the response error code if(errType == pdapi.ERR_BADPARAM): request.setResponseCode(*pdapi.getResponse(errType, "")) else: request.setResponseCode(*pdapi.getResponse(errType)) headers = request.received_headers if(logUsage is not None): tictoc, devid = logUsage if(devid is None): devid = "Null" duration = 0 # self.perf.toc(tictoc) # Log the info of this call # TODO self.usageTracker.addTrackInfo(ip, devid , request.path, self.usageTracker.FAIL_AUTH, duration, request.content.getvalue()) if(logFailure is not None): key, failureDict = logFailure # update the accessInfo if(key in failureDict): failureDict[key].update(ip, headers, time) else: failureDict[key] = AccessInfo(ip, headers, time) attempts = failureDict[key].attempts out.warn('Failure access recorded: %s Attempts: %d\n' % (key, attempts)) remaining = str(max(0, settings.DBAPI_FAILURE_THRESH - attempts)) if(errorStmt): return errorStmt % ("%s attempts remaining" % remaining) if(errorStmt): return errorStmt % ("Null")
def GET_test(self, request): """ A Simple test method to ping if the API server is working properly. """ request.setHeader('Access-Control-Allow-Origin', settings.PDFCD_HEADER_VALUE) ip = apiutils.getIP(request) out.info('Test called (%s)\n' % (ip)) request.setResponseCode(*pdapi.getResponse(pdapi.OK)) return "SUCCESS\n"
def preprocess(self, request, checkThresh, tictoc): """ Check if failure attempts for the user name has met the threshold. Arguments: request : checkThresh : If None, no checking. Tuple of arguments for checking thresholds ip: IP of client in string format token: sessionToken if found, or None username: username if signin, or None failureDict: the dict for failure history ticktoc: If none, do not track the usage. The start time of the API call Return: str: if threshold is met None: if ok """ if(checkThresh): ip, token, key, failureDict = checkThresh # Check if IP is in whitelist ipaddr = apiutils.unpackIPAddr(ip) for ipnet in self.WHITELIST_IP: net = apiutils.unpackIPAddrWithSlash(ipnet) if(apiutils.addressInNetwork(ipaddr, net)): out.verbose('Request from white list: %s\n' % (ip)) return None if(key in failureDict): if(failureDict[key].attempts >= settings.DBAPI_FAILURE_THRESH): out.err('Threshold met: %s %s!\n' % (ip, key)) if(tictoc is None): usage = None else: usage = (tictoc, None) self.failprocess(ip, request, (ip, failureDict), None, usage, pdapi.getResponse(pdapi.ERR_THRESHOLD)) duration = 0 # self.perf.toc(tictoc) # Log the info of this call # TODO self.usageTracker.addTrackInfo(ip, 'Null', request.path, self.usageTracker.FAIL_THRESH, duration, request.content.getvalue()) return "Threshold Met!" # Otherwise everything is ok return None
def postprocess(self, request, key, failureDict, logUsage): """ If the client is successful in their request, we should: * reset their failure attempts if failureDict is not none. * set success response code * If usage is not none, add usage track info of the api call """ request.setResponseCode(*pdapi.getResponse(pdapi.OK)) if(logUsage): tictoc, ip, devid = logUsage duration = 0 # self.perf.toc(tictoc) # when devid is none, we log "Null" into the database if(devid is None): devid = "Null" # Log the info of this call # TODO self.usageTracker.addTrackInfo(ip, devid, request.path, self.usageTracker.SUCCESS, duration, request.content.getvalue()) if(failureDict is not None): if(key in failureDict): out.info('Clearing %s from failure list\n' % (key)) del failureDict[key]