Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
0
    def test_get_miss(self, session, session_tracker):
        result = ApiKey.get(session, 'unknown')
        assert result is None
        session_tracker(1)

        result2 = ApiKey.get(session, 'unknown')
        assert result2 is None
        session_tracker(1)
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
    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')
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    def test_get(self, session):
        key = uuid.uuid4().hex
        session.add(ApiKey(valid_key=key, shortname='foo'))
        session.flush()

        result = ApiKey.get(session, key)
        assert isinstance(result, ApiKey)
        # shortname wasn't loaded at first
        assert 'shortname' not in result.__dict__
        # but is eagerly loaded
        assert result.shortname == 'foo'
Ejemplo n.º 11
0
    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')
Ejemplo n.º 12
0
 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)
Ejemplo n.º 13
0
        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)
Ejemplo n.º 14
0
 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)
Ejemplo n.º 15
0
    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)
Ejemplo n.º 16
0
    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_ro_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)
        return self.view(api_key)
Ejemplo n.º 17
0
    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.')
Ejemplo n.º 18
0
    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.')
Ejemplo n.º 19
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)
Ejemplo n.º 20
0
    def check(self):
        api_key = None
        api_key_text = self.request.GET.get('key', None)

        if api_key_text is None:
            self.log_count('{view_name}.no_api_key')
            if self.error_on_invalidkey:
                return self.invalid_api_key()
        try:
            api_key = ApiKey.getkey(self.request.db_ro_session,
                                    api_key_text)
        except Exception:  # pragma: no cover
            # if we cannot connect to backend DB, skip api key check
            self.raven_client.captureException()

        if api_key is not None:
            self.log_count('{view_name}.api_key.{api_key}',
                           api_key=api_key.name)

            rate_key = 'apilimit:{key}:{time}'.format(
                key=api_key_text,
                time=util.utcnow().strftime('%Y%m%d')
            )

            should_limit = rate_limit(
                self.redis_client,
                rate_key,
                maxreq=api_key.maxreq
            )

            if should_limit:
                return self.forbidden()
        else:
            if api_key_text is not None:
                self.log_count('{view_name}.unknown_api_key')
            if self.error_on_invalidkey:
                return self.invalid_api_key()

        # 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)
Ejemplo n.º 21
0
    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')
Ejemplo n.º 22
0
        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)
Ejemplo n.º 23
0
 def test_should_log(self):
     result = ApiKey(valid_key='foo')
     self.assertTrue(result.should_log('locate'))
     self.assertTrue(result.should_log('region'))
     self.assertTrue(result.should_log('submit'))
Ejemplo n.º 24
0
 def test_str(self):
     assert 'foo' in str(ApiKey(valid_key='foo'))
Ejemplo n.º 25
0
 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)
Ejemplo n.º 26
0
 def test_get_miss(self, session):
     result = ApiKey.get(session, 'unknown')
     assert result is None
Ejemplo n.º 27
0
 def test_should_not_log(self):
     result = ApiKey(valid_key=None)
     self.assertFalse(result.should_log('locate'))
     self.assertFalse(result.should_log('region'))
     self.assertFalse(result.should_log('submit'))
Ejemplo n.º 28
0
 def test_get_miss(self):
     result = ApiKey.get(self.session, 'unknown')
     self.assertTrue(result is None)
Ejemplo n.º 29
0
 def test_get_miss(self):
     result = ApiKey.get(self.session, 'unknown')
     self.assertTrue(result is None)
Ejemplo n.º 30
0
 def test_str(self):
     result = ApiKey(valid_key='foo')
     self.assertTrue('foo' in str(result))