def test_logging_enqueue_message_to_be_processed(request_factory): blocked_requests.clear() request = request_factory.get("/", HTTP_FOO=42, HTTP_BAR="data") log_blocked_request(request, 429) assert 1 == len(blocked_requests) assert format_request(request, 429) == blocked_requests.lpop() assert 0 == len(blocked_requests)
def handler_403(request, exception): """ Handler to deal with Ratelimited exception as exepcted. Reference: https://django-ratelimit.readthedocs.io/en/stable/usage.html#exceptions """ status = 403 msg = "Oops! Parece que você não tem permissão para acessar essa página." if isinstance(exception, Ratelimited): status, msg = 429, rate_limit_msg log_blocked_request(request, status) context = {"title_4xx": status, "message": msg} return render(request, "4xx.html", context, status=status)
def api_exception_handler(exc, context): response = exception_handler(exc, context) status_code = getattr(response, "status_code", None) if isinstance(exc, Throttled): custom_response_data = { "message": api_throtthling_msg, "available_in": f"{exc.wait} seconds" } response.data = custom_response_data if 400 <= status_code < 500: log_blocked_request(context["request"], status_code) return response
def handler_403(request, exception): """ Handler to deal with Ratelimited exception as exepcted. Reference: https://django-ratelimit.readthedocs.io/en/stable/usage.html#exceptions """ status = 403 msg = "Oops! Parece que você não tem permissão para acessar essa página." if isinstance(exception, Ratelimited): status, msg = 429, rate_limit_msg from_api = request.get_host() == settings.BRASILIO_API_HOST if from_api: msg = api_throtthling_msg data = {"message": msg} return JsonResponse(data=data, status=status) log_blocked_request(request, status) context = {"title_4xx": status, "message": msg} return render(request, "4xx.html", context, status=status)
def api_exception_handler(exc, context): response = exception_handler(exc, context) status_code = getattr(response, "status_code", None) redirect = redirect_from_older_version(exc) if redirect: return redirect if isinstance(exc, Throttled): custom_response_data = {"message": api_throtthling_msg, "available_in": f"{exc.wait} seconds"} response.data = custom_response_data if 400 <= status_code < 500: log_blocked_request(context["request"], status_code) if 401 == status_code: url = reverse("brasilio_auth:list_api_tokens", urlconf=settings.ROOT_URLCONF) msg = f"As credenciais de autenticação não foram fornecidas ou estão inválidas. Acesse https://brasil.io{url} para gerenciar suas chaves de acesso a API." response.data = {"message": msg} return response
def api_exception_handler(exc, context): response = exception_handler(exc, context) status_code = getattr(response, "status_code", None) redirect = redirect_from_older_version(exc) if redirect: return redirect if isinstance(exc, Throttled): custom_response_data = { "message": api_throtthling_msg, "available_in": f"{exc.wait} seconds" } response.data = custom_response_data if 400 <= status_code < 500: log_blocked_request(context["request"], status_code) if 401 == status_code: url = "https://brasil.io/auth/tokens-api/" blog_url = settings.API_KEYS_BLOGPOST_URL msg = f"As credenciais de autenticação não foram fornecidas ou estão inválidas. Acesse {url} para gerenciar suas chaves de acesso a API ou nosso blog post com o passo-a-passo da autenticação em {blog_url}" response.data = {"message": msg} return response
def dataset_detail(request, slug, tablename=""): if len(request.GET) > 0 and not request.user.is_authenticated: return redirect(f"{settings.LOGIN_URL}?next={request.get_full_path()}") try: dataset = Dataset.objects.get(slug=slug) except Dataset.DoesNotExist: context = {"message": "Dataset does not exist"} return render(request, "404.html", context, status=404) if not tablename: tablename = dataset.get_default_table().name return redirect( reverse( "core:dataset-table-detail", kwargs={ "slug": slug, "tablename": tablename }, )) try: allow_hidden = request.user.is_superuser table = dataset.get_table(tablename, allow_hidden=allow_hidden) except Table.DoesNotExist: context = {"message": "Table does not exist"} try: # log 404 request only if hidden table exist hidden_table = dataset.get_table(tablename, allow_hidden=True) if hidden_table: log_blocked_request(request, 404) except Table.DoesNotExist: pass return render(request, "404.html", context, status=404) querystring = request.GET.copy() page_number = querystring.pop("page", ["1"])[0].strip() or "1" items_per_page = querystring.pop("items", [str( settings.ROWS_PER_PAGE)])[0].strip() or str(settings.ROWS_PER_PAGE) download_csv = querystring.pop("format", [""]) == ["csv"] try: page = int(page_number) except ValueError: context = {"message": "Invalid page number."} return render(request, "404.html", context, status=404) try: items_per_page = int(items_per_page) except ValueError: context = {"message": "Invalid items per page."} return render(request, "404.html", context, status=404) items_per_page = min(items_per_page, 1000) version = dataset.version_set.order_by("-order").first() TableModel = table.get_model() query, search_query, order_by = parse_querystring(querystring) DynamicForm = get_table_dynamic_form(table) filter_form = DynamicForm(data=query) if filter_form.is_valid(): query = {k: v for k, v in filter_form.cleaned_data.items() if v != ""} else: query = {} all_data = TableModel.objects.composed_query(query, search_query, order_by) if download_csv: user_agent = request.headers.get("User-Agent", "") block_agent = any(True for agent in settings.BLOCKED_AGENTS if agent.lower() in user_agent.lower()) if not any([query, search_query]) or not user_agent or block_agent: # User trying to download a CSV without custom filters or invalid # user-agent specified. context = { "html_code_snippet": "core/400-csv-without-filters.html", "download_url": dataset.files_url, } return render(request, "4xx.html", context, status=400) if all_data.count() > settings.CSV_EXPORT_MAX_ROWS: context = { "message": "Max rows exceeded.", "title_4xx": "Oops! Ocorreu um erro:" } return render(request, "4xx.html", context, status=400) filename = "{}-{}.csv".format(slug, uuid.uuid4().hex) pseudo_buffer = Echo() writer = csv.writer(pseudo_buffer, dialect=csv.excel) csv_rows = queryset_to_csv(all_data, table.fields) response = StreamingHttpResponse( (writer.writerow(row) for row in csv_rows), content_type="text/csv;charset=UTF-8", ) response["Content-Disposition"] = 'attachment; filename="{}"'.format( filename) response.encoding = "UTF-8" return response paginator = Paginator(all_data, items_per_page) data = paginator.get_page(page) for key, value in list(querystring.items()): if not value: del querystring[key] context = { "data": data, "dataset": dataset, "filter_form": filter_form, "max_export_rows": settings.CSV_EXPORT_MAX_ROWS, "search_term": querystring.get("search", ""), "querystring": querystring.urlencode(), "slug": slug, "table": table, "total_count": all_data.count(), "version": version, } status = 200 if filter_form.errors: status = 400 return render(request, "core/dataset-detail.html", context, status=status)