def test_should_allow(self): result = ApiKey(valid_key='foo', allow_fallback=True, allow_locate=False) self.assertEqual(result.should_allow('fallback'), True) self.assertEqual(result.should_allow('locate'), False) self.assertEqual(result.should_allow('unknown'), True)
def test_fields(self): key = uuid.uuid4().hex self.session.add( ApiKey( valid_key=key, maxreq=10, allow_fallback=True, allow_locate=True, fallback_name='test_fallback', fallback_url='https://localhost:9/api?key=k', fallback_ratelimit=100, fallback_ratelimit_interval=60, fallback_cache_expire=86400, )) self.session.flush() result = self.session.query(ApiKey).get(key) self.assertEqual(result.valid_key, key) self.assertEqual(result.maxreq, 10) self.assertEqual(result.allow_fallback, True) self.assertEqual(result.allow_locate, True) self.assertEqual(result.fallback_name, 'test_fallback') self.assertEqual(result.fallback_url, 'https://localhost:9/api?key=k') self.assertEqual(result.fallback_ratelimit, 100) self.assertEqual(result.fallback_ratelimit_interval, 60) self.assertEqual(result.fallback_cache_expire, 86400)
def test_fields(self, session): key = uuid.uuid4().hex session.add( ApiKey( valid_key=key, maxreq=10, allow_fallback=True, allow_locate=True, allow_region=True, fallback_name="test_fallback", fallback_schema="ichnaea/v1", fallback_url="https://localhost:9/api?key=k", fallback_ratelimit=100, fallback_ratelimit_interval=60, fallback_cache_expire=86400, ) ) session.flush() result = session.query(ApiKey).get(key) assert result.valid_key == key assert result.maxreq == 10 assert result.allow_fallback is True assert result.allow_locate is True assert result.allow_region is True assert result.fallback_name == "test_fallback" assert result.fallback_schema == "ichnaea/v1" assert result.fallback_url == "https://localhost:9/api?key=k" assert result.fallback_ratelimit == 100 assert result.fallback_ratelimit_interval == 60 assert result.fallback_cache_expire == 86400
def test_fields(self, session): key = uuid.uuid4().hex session.add( ApiKey( valid_key=key, maxreq=10, allow_fallback=True, allow_locate=True, allow_transfer=True, fallback_name='test_fallback', fallback_url='https://localhost:9/api?key=k', fallback_ratelimit=100, fallback_ratelimit_interval=60, fallback_cache_expire=86400, )) session.flush() result = session.query(ApiKey).get(key) assert result.valid_key == key assert result.maxreq == 10 assert result.allow_fallback is True assert result.allow_locate is True assert result.allow_transfer is True assert result.fallback_name == 'test_fallback' assert result.fallback_url == 'https://localhost:9/api?key=k' assert result.fallback_ratelimit == 100 assert result.fallback_ratelimit_interval == 60 assert result.fallback_cache_expire == 86400
def test_should_log(self): result = ApiKey(valid_key='foo', log_locate=True, log_region=False, log_submit=None) self.assertEqual(result.should_log('locate'), True) self.assertEqual(result.should_log('region'), False) self.assertEqual(result.should_log('submit'), False) self.assertEqual(result.should_log('unknown'), False)
def test_get(self): key = uuid.uuid4().hex self.session.add(ApiKey(valid_key=key, shortname='foo')) self.session.flush() result = ApiKey.get(self.session, key) self.assertTrue(isinstance(result, ApiKey)) # shortname wasn't loaded at first self.assertFalse('shortname' in result.__dict__) # but is eagerly loaded self.assertEqual(result.shortname, 'foo')
def __call__(self): """Execute the view and return a response.""" if self.check_api_key: return self.check() else: api_key = ApiKey(valid_key=None, allow_fallback=False, log_locate=False, log_region=False, log_submit=False) return self.view(api_key)
def __call__(self): """Execute the view and return a response.""" if self.check_api_key: return self.check() else: api_key = ApiKey(valid_key=None, allow_fallback=False, allow_locate=True) # Only use the unchecked API key in the request for simple # logging purposes. self.log_count(self.parse_apikey(), False) 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 test_fields(self): key = ApiKey( valid_key='foo-bar', maxreq=10, shortname='foo', email='Test <*****@*****.**>', description='A longer text.', ) session = self.db_master_session session.add(key) session.commit() result = session.query(key.__class__).first() self.assertEqual(result.valid_key, 'foo-bar') self.assertEqual(result.shortname, 'foo') self.assertEqual(result.email, 'Test <*****@*****.**>') self.assertEqual(result.description, 'A longer text.')
def test_fields(self): session = self.session session.add( ApiKey(valid_key='foo-bar', maxreq=10, shortname='foo', email='Test <*****@*****.**>', description='A longer text.')) session.flush() result = session.query(ApiKey).first() self.assertEqual(result.valid_key, 'foo-bar') self.assertEqual(result.shortname, 'foo') self.assertEqual(result.email, 'Test <*****@*****.**>') self.assertEqual(result.description, 'A longer text.')
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 closure(request, *args, **kwargs): raven_client = request.registry.raven_client stats_client = request.registry.stats_client api_key = None api_key_text = request.GET.get('key', None) if api_key_text is None: stats_client.incr('%s.no_api_key' % func_name) if error_on_invalidkey: return invalid_api_key_response() try: api_key = ApiKey.getkey(request.db_ro_session, api_key_text) except Exception: # pragma: no cover # if we cannot connect to backend DB, skip api key check raven_client.captureException() stats_client.incr('%s.dbfailure_skip_api_key' % func_name) if api_key is not None: stats_client.incr('%s.api_key.%s' % (func_name, api_key.name)) should_limit = rate_limit(request.registry.redis_client, api_key_text, maxreq=api_key.maxreq) if should_limit: response = HTTPForbidden() response.content_type = 'application/json' response.body = DAILY_LIMIT return response elif should_limit is None: # pragma: no cover # We couldn't connect to Redis stats_client.incr('%s.redisfailure_skip_limit' % func_name) else: stats_client.incr('%s.unknown_api_key' % func_name) if error_on_invalidkey: return invalid_api_key_response() # If we failed to look up an ApiKey, create an empty one # rather than passing None through api_key = api_key or ApiKey() return func(request, api_key, *args, **kwargs)
def test_fields(self): self.session.add( ApiKey(valid_key='foo-bar', maxreq=10, shortname='foo', log_locate=True, log_region=True, log_submit=True, allow_fallback=True, allow_locate=True)) self.session.flush() result = self.session.query(ApiKey).get('foo-bar') self.assertEqual(result.valid_key, 'foo-bar') self.assertEqual(result.maxreq, 10) self.assertEqual(result.log_locate, True) self.assertEqual(result.log_region, True) self.assertEqual(result.log_submit, True) self.assertEqual(result.allow_fallback, True) self.assertEqual(result.allow_locate, True) self.assertEqual(result.shortname, 'foo')
def test_get(self, session, session_tracker): key = uuid.uuid4().hex session.add(ApiKey(valid_key=key, shortname='foo')) session.flush() session_tracker(1) result = ApiKey.get(session, key) assert isinstance(result, ApiKey) session_tracker(2) # shortname wasn't loaded at first assert 'shortname' not in result.__dict__ with pytest.raises(DetachedInstanceError): # and cannot be eagerly loaded assert result.shortname == 'foo' session_tracker(2) result2 = ApiKey.get(session, key) assert isinstance(result2, ApiKey) session_tracker(2)
def test_str(self): assert 'foo' in str(ApiKey(valid_key='foo'))
def test_str(self): result = ApiKey(valid_key='foo') self.assertTrue('foo' in str(result))