コード例 #1
0
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)
コード例 #2
0
ファイル: handlers.py プロジェクト: guikingma/brasil.io
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)
コード例 #3
0
ファイル: handlers.py プロジェクト: e-ruiz/brasil.io
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
コード例 #4
0
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)
コード例 #5
0
ファイル: handlers.py プロジェクト: guikingma/brasil.io
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
コード例 #6
0
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
コード例 #7
0
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)