Skip to content

Commit

Permalink
chore: rate limit requests (#24324)
Browse files Browse the repository at this point in the history
  • Loading branch information
betodealmeida authored Aug 11, 2023
1 parent f5ed407 commit 4bc4600
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 5 deletions.
14 changes: 14 additions & 0 deletions superset/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,20 @@ def _try_json_readsha(filepath: str, length: int) -> str | None:
# Configuration for scheduling queries from SQL Lab.
SCHEDULED_QUERIES: dict[str, Any] = {}

# FAB Rate limiting: this is a security feature for preventing DDOS attacks. The
# feature is on by default to make Superset secure by default, but you should
# fine tune the limits to your needs. You can read more about the different
# parameters here: https://flask-limiter.readthedocs.io/en/stable/configuration.html
RATELIMIT_ENABLED = True
RATELIMIT_APPLICATION = "50 per second"
AUTH_RATE_LIMITED = True
AUTH_RATE_LIMIT = "5 per second"
# A storage location conforming to the scheme in storage-scheme. See the limits
# library for allowed values: https://limits.readthedocs.io/en/stable/storage.html
# RATELIMIT_STORAGE_URI = "redis://host:port"
# A callable that returns the unique identity of the current request.
# RATELIMIT_REQUEST_IDENTIFIER = flask.Request.endpoint

# ------------------------------
# GLOBALS FOR APP Builder
# ------------------------------
Expand Down
2 changes: 1 addition & 1 deletion superset/dashboards/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ def export(self, **kwargs: Any) -> Response: # pylint: disable=too-many-locals
Dashboard.id.in_(requested_ids)
)
query = self._base_filters.apply_all(query)
ids = [item.id for item in query.all()]
ids = {item.id for item in query.all()}
if not ids:
return self.response_404()
export = Dashboard.export_dashboards(ids)
Expand Down
3 changes: 2 additions & 1 deletion superset/models/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,8 @@ def clear_cache_for_datasource(cls, datasource_id: int) -> None:

@classmethod
def export_dashboards( # pylint: disable=too-many-locals
cls, dashboard_ids: list[int]
cls,
dashboard_ids: set[int],
) -> str:
copied_dashboards = []
datasource_ids = set()
Expand Down
4 changes: 2 additions & 2 deletions superset/utils/dashboard_import_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ def export_dashboards(session: Session) -> str:
"""Returns all dashboards metadata as a json dump"""
logger.info("Starting export")
dashboards = session.query(Dashboard)
dashboard_ids = []
dashboard_ids = set()
for dashboard in dashboards:
dashboard_ids.append(dashboard.id)
dashboard_ids.add(dashboard.id)
data = Dashboard.export_dashboards(dashboard_ids)
return data
2 changes: 1 addition & 1 deletion superset/views/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def mulexport(
@expose("/export_dashboards_form")
def download_dashboards(self) -> FlaskResponse:
if request.args.get("action") == "go":
ids = request.args.getlist("id")
ids = set(request.args.getlist("id"))
return Response(
DashboardModel.export_dashboards(ids),
headers=generate_download_headers("json"),
Expand Down
2 changes: 2 additions & 0 deletions tests/integration_tests/superset_test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ def GET_FEATURE_FLAGS_FUNC(ff):
REDIS_RESULTS_DB = os.environ.get("REDIS_RESULTS_DB", 3)
REDIS_CACHE_DB = os.environ.get("REDIS_CACHE_DB", 4)

RATELIMIT_ENABLED = False


CACHE_CONFIG = {
"CACHE_TYPE": "RedisCache",
Expand Down

0 comments on commit 4bc4600

Please sign in to comment.