def _record_api_access_for_authenticated_user(self, api_method_wrapper, request_time, usage_statistics): oauth_server = oauth2.Server(signature_methods={'HMAC-SHA1': oauth2.SignatureMethod_HMAC_SHA1()}) #oauth_server.timestamp_threshold = 500000 auth_header = {} key = None if 'Authorization' in self._request.headers: auth_header = {'Authorization':self._request.headers['Authorization']} key = extract_oauth_consumer_key_from_auth_header_string(auth_header['Authorization']) req = oauth2.Request.from_request( self._request.method, self._request.url.split('?')[0], headers=auth_header, parameters=dict([(k,v) for k,v in self._request.values.iteritems()])) #If key not present in the auth header try form the params if not key: key = self._request.values.get('oauth_consumer_key') #if still no key then quit if not key: return_data = RecordAPIAccessReturn() return_data.access_status = 'denied' return_data.access_message = "Sorry, we didn't find an oauth_consumer_key in the Authorization header of your request" return return_data user = get_authenticated_user_app_by_key(key) if user is None: return_data = RecordAPIAccessReturn() return_data.access_status = 'denied' return_data.access_message = "Sorry, we didn't find a user account that matches the Oauth customer key %s, are you sure you have it correct?" % key return return_data user_app = filter(lambda x: x.key == key, user.apps)[0] usage_statistics['app_id'] = user_app.key try: oauth_server.verify_request(req, user_app, None) except oauth2.Error, e: return_data = RecordAPIAccessReturn() return_data.access_status = 'denied' return_data.access_message = "%s" % e baselogger.error("OAUTH REQUEST DENIED, |%s|" % return_data.access_message) return return_data
def run_submit_image_adapter(request, api_method_wrapper): view = getattr(views, api_method_wrapper.view); file = request.files.get('image') filename = int(time.time()) file.save("/tmp/%s.tif" % filename) image = Image.open("/tmp/%s.tif" % filename) text = image_to_string(image) text = re.sub('\\n', ' ', text) image = None os.unlink("/tmp/%s.tif" % filename) is_text = len(text.strip(' \t\n\r')) != 0 if(is_text): return_data = view('success', {"message":"Text was extracted from your image and has been submitted for processing"}) else: return_data = view('failure', {"message":"No text could be extracted from the image"}) yield return_data core_api_request = "%sapi/channelservices/pushtochannel.php" % config.get('services', 'core') core_api_parameters = { "deviceid":request.form.get('deviceid'), "imageid":request.form.get('imageid'), "key":request.form.get('deviceid'), "origin":"MetalensImageText", "text":text } request = Request(url=core_api_request, data=urlencode(core_api_parameters)) try: urlopen(request) except HTTPError, e: baselogger.error("%s" % e)
def run_search_for_image_adapter(request, api_method_wrapper): view = getattr(views, api_method_wrapper.view); core_api_request = "%sapi/contentservices/getcontent.php" % config.get('services', 'core') core_api_parameters = { "json":'{"id":"%s"}' % request.form.get('imageid'), "key":request.form.get('deviceid'), } request = Request(url=core_api_request, data=urlencode(core_api_parameters)) try: response = urlopen(request) response_data = response.read() return view('success', response_data) except HTTPError, e: baselogger.error("%s" % e) return view('failure')
def __call__(self, environ, start_response): local.application = self request = Request(environ) usage_statistics = APIUsageStatistics({ "remote_ip":request.remote_addr, "start_time": time.time()}) #Check for XSS atacks that contain none word chars xss_atack_rule = re.compile("^[\w\d\=\%/.]+$", re.IGNORECASE) if not bool(xss_atack_rule.match(request.path)): usage_statistics['state'] = 'XSS' safe_save_usage_statistics_stage_two(usage_statistics) response = generic_error_handler(request, '400', 'Humm, it looks like you are trying a XSS attack? If not, make sure you are encoding your request url.') return ClosingIterator(response(environ, start_response), [local_manager.cleanup]) #Check for malformed query strings in the request mal_formed_query_rule = re.compile(r'.+(=\?|=&).+') if bool(mal_formed_query_rule.match(request.query_string)): usage_statistics['state'] = 'QUERYERROR' safe_save_usage_statistics_stage_two(usage_statistics) response = generic_error_handler(request, '400', 'Humm, it looks like your request contains some illegal character sequances (something like "=&" or "=?").') return ClosingIterator(response(environ, start_response), [local_manager.cleanup]) #extract the service identifier from the path service_identifier = map_path_to_api_wrapper_identifier(request.path) #Disallow access to the root if service_identifier is None: usage_statistics['state'] = 'NOSERVICE' safe_save_usage_statistics_stage_two(usage_statistics) response = generic_error_handler(request, '403', 'Access to the root is not permitted') return ClosingIterator(response(environ, start_response), [local_manager.cleanup]) #Get the API Wrapper from the datastore api_wrapper = get_api_wrapper_by_identifier(service_identifier) #If the extracted service_identifier does not match if api_wrapper is None: usage_statistics['state'] = 'SERVICEUNKNOWN' safe_save_usage_statistics_stage_two(usage_statistics) response = generic_error_handler(request, '404', 'Sorry, we could not find a service that matches "%s". Please check our documentation.' % (service_identifier)) return ClosingIterator(response(environ, start_response), [local_manager.cleanup]) #Now we know the service they are trying to hit, update the usage_stats usage_statistics['service_id'] = unicode(api_wrapper._id) usage_statistics['service_name'] = api_wrapper.display_name #use the util function to extract the correct APIMethodWrapper for the request path api_method_wrapper = get_api_method_wrapper_by_url_pattern(request.path, api_wrapper) #if no element found then retutn bad request if api_method_wrapper is None: usage_statistics['state'] = 'METHODUNKNOWN' safe_save_usage_statistics_stage_two(usage_statistics) response = generic_error_handler(request, "400", 'Sorry, we could not find the method you wanted on the service "%s". Please check our documentation.' % (service_identifier)) return ClosingIterator(response(environ, start_response), [local_manager.cleanup]) #check that the request method is supported by this api_method if not bool(re.match(r'^[\w|]*%s[\w|]*$' % (request.method), api_method_wrapper.accepted_http_methods)): usage_statistics['state'] = 'METHODTYPENOTACCEPTED' safe_save_usage_statistics_stage_two(usage_statistics) response = generic_error_handler(request, "405", 'Sorry, the service you are trying to access doesn not support the request type "%s".' % (request.method)) response.headers.add("Allow", re.sub(r'\|', ', ', api_method_wrapper.accepted_http_methods)) return ClosingIterator(response(environ, start_response), [local_manager.cleanup]) #Now we know the method they are trying to hit, update the usage_stats usage_statistics['method_id'] = api_method_wrapper.method_identifier #build a new request user object user = RequestUser(request, api_wrapper) #assert that api access is ok and record it access_data = user.record_api_access(api_method_wrapper, usage_statistics) #if the request user can not be granted access then return a 401 if access_data.access_status is 'denied': usage_statistics['state'] = 'DENIED' safe_save_usage_statistics_stage_two(usage_statistics) response = generic_error_handler(request, '401', access_data.access_message) return ClosingIterator(response(environ, start_response), [local_manager.cleanup]) #Try to match build the mapper handler = getattr(handlers, api_wrapper.request_handler) #Save the usage statatistcs inces there is an error from the remote call #safe_save_usage_statistics_stage_one(usage_statistics) try: response = handler(request, api_method_wrapper) except URLError, e: #TODO this needs to be handled as this means there is an error in our endpoint mapping or a service is down! response = generic_error_handler(request, '503', 'The service you request is temporarily unavailable.') baselogger.error('SERVICE URL ERROR - URL:%s | ERROR: %s' % (request.url, e)) usage_statistics['state'] = 'ERROR'