Exemple #1
0
    def setUp(self):
        self.plugin = BSONBottlePlugin()
        self.ip = "84.34.13.122"
        self.callback = Mock(wraps=self._callback)
        self.callbacknobson = Mock(wraps=self._callbackno)
        bottle.request.environ['REMOTE_ADDR'] = self.ip
        bottle.request.environ['CONTENT_TYPE'] = 'application/bson'
        self.context = Mock()
        self.context.callback = self._callback

        self.contextnobson = Mock(wraps=self._callbackno)
        self.contextnobson.callback = self._callbackno

        self.__set_bson_content({"therivermen": "ehhhhhmacarena"})
    def setUp(self):
        self.plugin = BSONBottlePlugin()
        self.ip = "84.34.13.122"
        self.callback = Mock(wraps=self._callback)
        self.callbacknobson = Mock(wraps=self._callbackno)
        bottle.request.environ['REMOTE_ADDR'] = self.ip
        bottle.request.environ['CONTENT_TYPE'] = 'application/bson'
        self.context = Mock()
        self.context.callback = self._callback

        self.contextnobson = Mock(wraps=self._callbackno)
        self.contextnobson.callback = self._callbackno

        self.__set_bson_content({"therivermen": "ehhhhhmacarena"})
Exemple #3
0
class BsonBottleTest(unittest.TestCase):
    """Bottle plugin for automatic parse a BSON request and pass a  """
    def setUp(self):
        self.plugin = BSONBottlePlugin()
        self.ip = "84.34.13.122"
        self.callback = Mock(wraps=self._callback)
        self.callbacknobson = Mock(wraps=self._callbackno)
        bottle.request.environ['REMOTE_ADDR'] = self.ip
        bottle.request.environ['CONTENT_TYPE'] = 'application/bson'
        self.context = Mock()
        self.context.callback = self._callback

        self.contextnobson = Mock(wraps=self._callbackno)
        self.contextnobson.callback = self._callbackno

        self.__set_bson_content({"therivermen": "ehhhhhmacarena"})

    def tearDown(self):
        pass

    def testAddOtherPluginWithSameKeywork(self):
        app = Mock()
        bad_plugin = Mock()
        bad_plugin.keyword = "bson_data"
        app.plugins = set([bad_plugin])
        self.assertRaises(PluginError, self.plugin.setup, app)

    def testCallbackCalled(self):
        self.plugin.apply(self.callback, self.context)()
        self.assertTrue(self.callback.called)

    def testNotBsonRequest(self):
        bottle.request.environ['CONTENT_TYPE'] = 'mouse/mikey'
        self.assertRaises(BSONBottlePluginException,
                          self.plugin.apply(self.callback, self.context))

    def testNotBsonRequestWithNoBonDataParameter(self):
        bottle.request.environ['CONTENT_TYPE'] = 'mouse/mikey'
        # If there is not bson_data parameter callback will be called correctly and without bson_data parameter
        self.plugin.apply(self.callbacknobson, self.contextnobson)()
        self.callbacknobson.assert_called_once_with()

    def testNoContent(self):
        bottle.request.environ["CONTENT_LENGTH"] = 0
        self.assertRaises(BSONBottlePluginException,
                          self.plugin.apply(self.callback, self.context))

    def testMaxContent(self):
        bottle.request.environ["CONTENT_LENGTH"] = (
            BII_MAX_MEMORY_PER_REQUEST) + 1
        self.assertRaises(BSONBottlePluginException,
                          self.plugin.apply(self.callback, self.context))

    def testAbortWithBSON(self):
        tmp = self.plugin.abort_with_bson(401, {"kk": 2})
        self.assertIsInstance(tmp, HTTPResponse)
        self.assertEquals("application/bson", tmp.content_type)
        self.assertEquals(401, tmp.status_code)
        self.assertEquals(str(BSON.encode({"kk": 2})), tmp.body)

    def _callback(self, bson_data=""):
        logger.debug("Bson: " + str(bson_data))
        pass

    def _callbackno(self):
        pass

    def __set_bson_content(self, data):
        bottle.request.environ['wsgi.input'] = str(BSON.encode(data))
        bottle.request.environ["CONTENT_LENGTH"] = len(
            bottle.request.environ['wsgi.input'])
        bottle.request.body = Mock
        bottle.request.body.read = Mock(
            return_value=bottle.request.environ['wsgi.input'])
Exemple #4
0
    def install_plugins(self):
        self.bsonplugin = BSONBottlePlugin()
        # BiiResponse plugin. All rest methods has to return
        # (data serializable | None, biiresponse) or throw BiiServiceException subclass
        logger.info("Installing BiiReturnHandlerPlugin plugin...")
        self.biiresponseplugin = BiiReturnHandlerPlugin(self.bsonplugin)
        self.install(self.biiresponseplugin)

        # Very first of all, check SSL or die
        if BII_SSL_ENABLED:  # In heroku true for all environments
            logger.info("Installing NonSSLBlockerBottlePlugin plugin...")
            nonsslblock = NonSSLBlockerBottlePlugin()
            self.install(nonsslblock)

        # First of all, check DOS attacks by IP to the API
        # Counts IP request, raise 401 if banned

        if getattr(self.store, 'ip_mc_collection', False):
            logger.info("Installing massive DOS blocker...")
            doslogin = DOSBlockerBottlePlugin(self.store.ip_mc_collection,
                                              delta=BII_DOS_ATTACK_DELTA_TIME,
                                              max_events=BII_DOS_ATTACK_MAX_REQUEST,
                                              bantime=BII_DOS_ATTACK_BAN_TIME,
                                              callback_ip_banned=self.callback_ip_banned_for_DOS,
                                              banned_http_response=self.banned_http_response_for_DOS)
            # TODO: Maybe configure a log alert (heroku) if we return 401 banned
            # to analyze the case and adjust limits?
            self.install(doslogin)

        # Second, check Http Basic auth
        logger.info("Installing http basic authentication plugin...")
        httpplugin = HttpBasicAuthenticationBottlePlugin()
        self.install(httpplugin)

        # And check auth JWT
        logger.info("Installing JWT authentication plugin...")
        jwt_manager = JWTCredentialsManagerFactory.new(self.store)
        jwt_plugin = JWTAuthenticationBottlePlugin(jwt_manager)
        self.install(jwt_plugin)

        # Third check excess of login error for an IP
        # Catch generic 401 (or 404 or other) error from authentication and stores IP,
        # raise 401 if already banned
        if getattr(self.store, 'ip_mc_collection', False):
            logger.info("Installing massive error blocker...")
            massiveerrorplugin = MassiveErrorBlockerBottlePlugin(
                                   self.store.ip_mc_collection,
                                   delta=BII_ERROR_ATTACK_DELTA_TIME,
                                   max_events=BII_ERROR_ATTACK_MAX_ATTEMPTS,
                                   bantime=BII_ERROR_ATTACK_BAN_TIME,
                                   callback_ip_banned=self.callback_ip_banned_for_many_errors,
                                   banned_http_response=self.banned_http_response_for_many_errors)
            self.install(massiveerrorplugin)

        # Last, parse BSON data
        logger.info("Installing bson plugin...")
        self.install(self.bsonplugin)

        # Logging actions
        if BII_ENABLED_BII_USER_TRACE:
            self.tracebottleplugin = BiiUserTraceBottlePlugin()
            logger.info("Installing BiiUserTraceBottlePlugin plugin...")
            self.install(self.tracebottleplugin)
class BsonBottleTest(unittest.TestCase):
    """Bottle plugin for automatic parse a BSON request and pass a  """

    def setUp(self):
        self.plugin = BSONBottlePlugin()
        self.ip = "84.34.13.122"
        self.callback = Mock(wraps=self._callback)
        self.callbacknobson = Mock(wraps=self._callbackno)
        bottle.request.environ['REMOTE_ADDR'] = self.ip
        bottle.request.environ['CONTENT_TYPE'] = 'application/bson'
        self.context = Mock()
        self.context.callback = self._callback

        self.contextnobson = Mock(wraps=self._callbackno)
        self.contextnobson.callback = self._callbackno

        self.__set_bson_content({"therivermen": "ehhhhhmacarena"})

    def tearDown(self):
        pass

    def testAddOtherPluginWithSameKeywork(self):
        app = Mock()
        bad_plugin = Mock()
        bad_plugin.keyword = "bson_data"
        app.plugins = set([bad_plugin])
        self.assertRaises(PluginError, self.plugin.setup, app)

    def testCallbackCalled(self):
        self.plugin.apply(self.callback, self.context)()
        self.assertTrue(self.callback.called)

    def testNotBsonRequest(self):
        bottle.request.environ['CONTENT_TYPE'] = 'mouse/mikey'
        self.assertRaises(BSONBottlePluginException, self.plugin.apply(self.callback, self.context))

    def testNotBsonRequestWithNoBonDataParameter(self):
        bottle.request.environ['CONTENT_TYPE'] = 'mouse/mikey'
        # If there is not bson_data parameter callback will be called correctly and without bson_data parameter
        self.plugin.apply(self.callbacknobson, self.contextnobson)()
        self.callbacknobson.assert_called_once_with()

    def testNoContent(self):
        bottle.request.environ["CONTENT_LENGTH"] = 0
        self.assertRaises(BSONBottlePluginException,
                          self.plugin.apply(self.callback, self.context))

    def testMaxContent(self):
        bottle.request.environ["CONTENT_LENGTH"] = (BII_MAX_MEMORY_PER_REQUEST) + 1
        self.assertRaises(BSONBottlePluginException,
                          self.plugin.apply(self.callback, self.context))

    def testAbortWithBSON(self):
        tmp = self.plugin.abort_with_bson(401, {"kk": 2})
        self.assertIsInstance(tmp, HTTPResponse)
        self.assertEquals("application/bson", tmp.content_type)
        self.assertEquals(401, tmp.status_code)
        self.assertEquals(str(BSON.encode({"kk": 2})), tmp.body)

    def _callback(self, bson_data=""):
        logger.debug("Bson: " + str(bson_data))
        pass

    def _callbackno(self):
        pass

    def __set_bson_content(self, data):
        bottle.request.environ['wsgi.input'] = str(BSON.encode(data))
        bottle.request.environ["CONTENT_LENGTH"] = len(bottle.request.environ['wsgi.input'])
        bottle.request.body = Mock
        bottle.request.body.read = Mock(return_value=bottle.request.environ['wsgi.input'])