def __call__(self): """Execute the view and return a response.""" api_key = None api_key_text = self.parse_apikey() skip_check = False if api_key_text is None: self.log_count("none") if self.error_on_invalidkey: raise self.prepare_exception(InvalidAPIKey()) if api_key_text is not None: try: api_key = get_key(self.request.db_session, api_key_text) except (DatabaseError, DBAPIError): # if we cannot connect to backend DB, skip api key check skip_check = True self.raven_client.captureException() bind_threadlocal( api_key=api_key_text, api_path=self.metric_path, api_type=self.view_type, api_key_db_fail=True, ) if api_key is not None: valid_key = api_key.valid_key if api_key.allowed(self.view_type): self.log_count(valid_key) # Potentially avoid overhead of Redis connection. if self.ip_log_and_rate_limit: if self.log_ip_and_rate_limited(valid_key, api_key.maxreq): raise self.prepare_exception(DailyLimitExceeded()) else: self.log_count("invalid") # Switch "invalid" with real key, add "api_key_allowed" bind_threadlocal(api_key=valid_key, api_key_allowed=False) if self.error_on_invalidkey: raise self.prepare_exception(InvalidAPIKey()) elif skip_check: pass else: if api_key_text is not None: self.log_count("invalid") bind_threadlocal(invalid_api_key=api_key_text) if self.error_on_invalidkey: raise self.prepare_exception(InvalidAPIKey()) # If we failed to look up an ApiKey, create an empty one # rather than passing None through if api_key is None: api_key = Key() return self.view(api_key)
def check(self): api_key = None api_key_text = self.parse_apikey() skip_check = False if api_key_text is None: self.log_count(None, False) if self.error_on_invalidkey: raise self.prepare_exception(InvalidAPIKey()) if api_key_text is not None: try: session = self.request.db_session api_key = ApiKey.get(session, api_key_text) except Exception: # if we cannot connect to backend DB, skip api key check skip_check = True self.raven_client.captureException() if api_key is not None and api_key.allowed(self.view_type): self.log_count(api_key.valid_key, True) rate_key = 'apilimit:{key}:{path}:{time}'.format( key=api_key_text, path=self.metric_path, time=util.utcnow().strftime('%Y%m%d')) should_limit = rate_limit_exceeded(self.redis_client, rate_key, maxreq=api_key.maxreq) if should_limit: raise self.prepare_exception(DailyLimitExceeded()) elif skip_check: pass else: if api_key_text is not None: self.log_count('invalid', False) if self.error_on_invalidkey: raise self.prepare_exception(InvalidAPIKey()) # If we failed to look up an ApiKey, create an empty one # rather than passing None through api_key = api_key or ApiKey(valid_key=None, allow_fallback=False, allow_locate=True, allow_transfer=False, store_sample_locate=100, store_sample_submit=100) return self.view(api_key)
def check_response(self, data_queues, response, status, fallback=None, details=None): assert response.content_type == "application/json" assert response.headers["Access-Control-Allow-Origin"] == "*" assert response.headers["Access-Control-Max-Age"] == "2592000" if status == "ok": body = dict(response.json) if fallback: assert body["fallback"] == fallback del body["fallback"] assert body == self.ip_response elif status == "invalid_key": assert response.json == InvalidAPIKey().json_body() elif status == "not_found": assert response.json == LocationNotFound().json_body() elif status == "parse_error": assert response.json == ParseError(details).json_body() elif status == "limit_exceeded": assert response.json == DailyLimitExceeded().json_body() if status != "ok": self.check_queue(data_queues, 0)
def check(self): api_key = None api_key_text = self.request.GET.get('key', None) skip_check = False if api_key_text is None: self.log_count('none', False) if self.error_on_invalidkey: raise self.prepare_exception(InvalidAPIKey()) if api_key_text is not None: try: session = self.request.db_ro_session api_key = session.query(ApiKey).get(api_key_text) except Exception: # if we cannot connect to backend DB, skip api key check skip_check = True self.raven_client.captureException() if api_key is not None: self.log_count(api_key.name, api_key.should_log(self.view_type)) rate_key = 'apilimit:{key}:{path}:{time}'.format( key=api_key_text, path=self.metric_path, time=util.utcnow().strftime('%Y%m%d')) should_limit = rate_limit_exceeded(self.redis_client, rate_key, maxreq=api_key.maxreq) if should_limit: raise self.prepare_exception(DailyLimitExceeded()) elif skip_check: pass else: if api_key_text is not None: self.log_count('invalid', False) if self.error_on_invalidkey: raise self.prepare_exception(InvalidAPIKey()) # If we failed to look up an ApiKey, create an empty one # rather than passing None through api_key = api_key or ApiKey(valid_key=None) return self.view(api_key)
def _check_geoip_result(self, result, status=200): self.assertEqual(result.content_type, 'application/json') self.assertEqual(result.charset, 'UTF-8') if status == 200: self.assertEqual(result.json, {'country_name': 'United Kingdom', 'country_code': 'GB'}) elif status == 400: self.assertEqual(result.json, InvalidAPIKey.json_body()) elif status == 404: self.assertEqual(result.json, LocationNotFound.json_body())
def __call__(self): """Execute the view and return a response.""" api_key = None api_key_text = self.parse_apikey() skip_check = False if api_key_text is None: self.log_count('none') if self.error_on_invalidkey: raise self.prepare_exception(InvalidAPIKey()) if api_key_text is not None: try: api_key = get_key(self.request.db_session, api_key_text) except Exception: # if we cannot connect to backend DB, skip api key check skip_check = True self.raven_client.captureException() if api_key is not None and api_key.allowed(self.view_type): valid_key = api_key.valid_key self.log_count(valid_key) # Potentially avoid overhead of Redis connection. if self.ip_log_and_rate_limit: if self.log_ip_and_rate_limited(valid_key, api_key.maxreq): raise self.prepare_exception(DailyLimitExceeded()) elif skip_check: pass else: if api_key_text is not None: self.log_count('invalid') if self.error_on_invalidkey: raise self.prepare_exception(InvalidAPIKey()) # If we failed to look up an ApiKey, create an empty one # rather than passing None through if api_key is None: api_key = Key() return self.view(api_key)
def check_response(self, response, status): self.assertEqual(response.content_type, 'application/json') self.assertEqual(response.charset, 'UTF-8') if status == 'ok': self.assertEqual(response.json, self.ip_response) elif status == 'invalid_key': self.assertEqual(response.json, InvalidAPIKey.json_body()) elif status == 'not_found': self.assertEqual(response.json, self.not_found.json_body()) elif status == 'parse_error': self.assertEqual(response.json, ParseError.json_body()) elif status == 'limit_exceeded': self.assertEqual(response.json, DailyLimitExceeded.json_body())
def check_response(self, response, status): self.assertEqual(response.content_type, 'application/json') self.assertEqual(response.charset, 'UTF-8') self.assertEqual(response.headers['Access-Control-Allow-Origin'], '*') self.assertEqual(response.headers['Access-Control-Max-Age'], '2592000') if status == 'ok': self.assertEqual(response.json, self.ip_response) elif status == 'invalid_key': self.assertEqual(response.json, InvalidAPIKey.json_body()) elif status == 'not_found': self.assertEqual(response.json, self.not_found.json_body()) elif status == 'parse_error': self.assertEqual(response.json, ParseError.json_body()) elif status == 'limit_exceeded': self.assertEqual(response.json, DailyLimitExceeded.json_body())
def check_response(self, response, status): self.assertEqual(response.content_type, "application/json") self.assertEqual(response.charset, "UTF-8") self.assertEqual(response.headers["Access-Control-Allow-Origin"], "*") self.assertEqual(response.headers["Access-Control-Max-Age"], "2592000") if status == "ok": self.assertEqual(response.json, self.ip_response) elif status == "invalid_key": self.assertEqual(response.json, InvalidAPIKey.json_body()) elif status == "not_found": self.assertEqual(response.json, self.not_found.json_body()) elif status == "parse_error": self.assertEqual(response.json, ParseError.json_body()) elif status == "limit_exceeded": self.assertEqual(response.json, DailyLimitExceeded.json_body())
def check_response(self, data_queues, response, status): assert response.content_type == 'application/json' assert response.headers['Access-Control-Allow-Origin'] == '*' assert response.headers['Access-Control-Max-Age'] == '2592000' if status == 'ok': assert response.json == self.ip_response elif status == 'invalid_key': assert response.json == InvalidAPIKey.json_body() elif status == 'not_found': assert response.json == self.not_found.json_body() elif status == 'parse_error': assert response.json == ParseError.json_body() elif status == 'limit_exceeded': assert response.json == DailyLimitExceeded.json_body() if status != 'ok': self.check_queue(data_queues, 0)
def test_unknown_api_key(self): key = dict(mcc=FRANCE_MCC, mnc=2, lac=3, cid=4) self.session.add(Cell( lat=PARIS_LAT, lon=PARIS_LON, range=1000, radio=Radio.umts, **key) ) self.session.commit() res = self.app.post_json( '/v1/search?key=unknown_key', {'radio': Radio.gsm.name, 'cell': [ dict(radio=Radio.umts.name, **key), ]}, status=400) self.assertEqual(res.content_type, 'application/json') self.assertEqual(res.json, InvalidAPIKey.json_body()) self.check_stats(counter=['search.unknown_api_key'])
def check_response(self, data_queues, response, status, fallback=None): assert response.content_type == 'application/json' assert response.headers['Access-Control-Allow-Origin'] == '*' assert response.headers['Access-Control-Max-Age'] == '2592000' if status == 'ok': body = dict(response.json) if fallback: assert body['fallback'] == fallback del body['fallback'] assert body == self.ip_response elif status == 'invalid_key': assert response.json == InvalidAPIKey.json_body() elif status == 'not_found': assert response.json == self.not_found.json_body() elif status == 'parse_error': assert response.json == ParseError.json_body() elif status == 'limit_exceeded': assert response.json == DailyLimitExceeded.json_body() if status != 'ok': self.check_queue(data_queues, 0)
def test_unknown_api_key(self): cell = CellFactory() self.session.flush() res = self.app.post_json( '%s?key=unknown_key' % self.url, { 'radioType': cell.radio.name, 'cellTowers': [ {'mobileCountryCode': cell.mcc, 'mobileNetworkCode': cell.mnc, 'locationAreaCode': cell.lac, 'cellId': cell.cid}, ] }, status=400) self.assertEqual(res.content_type, 'application/json') self.assertEqual(res.json, InvalidAPIKey.json_body()) self.check_stats( counter=[self.metric + '.unknown_api_key'])