1
0

Fix rate limit, add favicon

This commit is contained in:
Marcel Schwarz 2022-08-07 23:06:45 +02:00
parent 41de5fbf43
commit e2dbae13ee
9 changed files with 64 additions and 16 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
__pycache__
clubhaus/static/**/*
.DS_Store
django.log
# Created by https://www.toptal.com/developers/gitignore/api/jetbrains
# Edit at https://www.toptal.com/developers/gitignore?templates=jetbrains

View File

@ -139,4 +139,39 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
IP_RATE_LIMIT_TIME = int(os.getenv("IP_RATE_LIMIT_TIME", "3600"))
IP_RATE_LIMIT_COUNT = int(os.getenv("IP_RATE_LIMIT_COUNT", "2"))
# LOGGING
LOGGING = {
"version": 1,
# The version number of our log
"disable_existing_loggers": False,
"formatters": {
"simple": {
"format": "[{levelname}][{asctime}][{funcName}]: {message}",
"style": "{",
},
},
# django uses some of its own loggers for internal operations.
# In case you want to disable them just replace the False above with true.
# A handler for WARNING. It is basically writing the WARNING messages into a file called WARNING.log
"handlers": {
"file": {
"level": "WARNING",
"class": "logging.handlers.RotatingFileHandler",
"maxBytes": 1024 * 1024 * 5, # 5 MB
"backupCount": 5,
"filename": BASE_DIR / "django.log",
"formatter": "simple",
},
},
# A logger for WARNING which has a handler called 'file'. A logger can have multiple handler
"loggers": {
# notice the blank '', Usually you would put built in loggers like django or root here based on your needs
"": {
"handlers": ["file"], # notice how file variable is called in handler which has been defined above
"level": "WARNING",
"propagate": True,
},
},
}
# TODO: delete devserver port forward in windows firewall in hammerhead

View File

@ -16,11 +16,15 @@ Including another URLconf
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
from django.urls import path, include, re_path
from django.views.generic import RedirectView
favicon_view = RedirectView.as_view(url='/static/favicon.ico', permanent=True)
urlpatterns = [
path('', include('homepage.urls')),
path('admin/', admin.site.urls),
re_path(r'^favicon\.ico$', favicon_view),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
handler400 = "homepage.views.bad_request"

View File

@ -2,16 +2,16 @@ from django.core import exceptions
class RateLimitHit(exceptions.SuspiciousOperation):
def __init__(self):
self.text = "You made to many request in a short period of time! Please try again later"
def __init__(self, ip: str):
self.text = f"You made to many request in a short period of time! Please try again later. Your IP: {ip}"
def __str__(self):
return f"{self.__class__.__name__}: {self.text}"
class ProxyUsageDetected(exceptions.SuspiciousOperation):
def __init__(self):
self.text = "It appears you are using a proxy! We don't want you to do that!"
def __init__(self, proxy: str):
self.text = f"It appears you are using a proxy! We don't want you to do that! Your Proxy IP: {proxy}"
def __str__(self):
return f"{self.__class__.__name__}: {self.text}"

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

View File

@ -11,12 +11,12 @@
<meta property="og:title" content="{% block title %}Clubhaus Schornbach{% endblock %}">
<meta property="og:description" content="Clubhaus Schornbach - est. 2007">
<meta property="og:image"
content="{{ request.scheme }}://{{ request.get_host }}{% static 'homepage/logo-with-text.svg' %}">
content="https://{{ request.get_host }}{% static 'homepage/logo-with-text.svg' %}">
<meta property="og:type" content="website"/>
<meta property="og:image:type" content="image/svg+xml">
<meta property="og:image:width" content="300">
<meta property="og:image:height" content="300">
<meta property="og:url" content="{{ request.scheme }}://{{ request.get_host }}">
<meta property="og:url" content="https://{{ request.get_host }}">
<title>Clubhaus Schornbach</title>
<link rel="icon" href="{% static 'homepage/logo.svg' %}" sizes="any" type="image/svg+xml">

View File

@ -142,11 +142,19 @@
<div class="col-lg-3 col-md-6 mb-lg-0 mb-md-4 mb-3">
<div class="h-100 p-3 text-white bg-dark rounded-3">
<h2><i class="bi-clock display-2"></i></h2>
<p class="fs-2 fw-bold">
{{ next_event.date|date:"d.m.Y" }}
<br>
ab {{ next_event.date|date:"H:i" }} Uhr
</p>
{% if next_event.date %}
<p class="fs-2 fw-bold">
{{ next_event.date|date:"d.m.Y" }}
<br>
ab {{ next_event.date|date:"H:i" }} Uhr
</p>
{% else %}
<p class="fs-2 fw-bold">
coming
<br>
soon
</p>
{% endif %}
</div>
</div>

View File

@ -57,14 +57,14 @@ def voting(request: HttpRequest) -> django.http.HttpResponse:
request.session.clear_expired()
# Proxy use is forbidden
if request.META.get("X-Forwarded-For"):
raise ProxyUsageDetected()
if proxy := request.META.get("HTTP_X_FORWARDED_FOR"):
raise ProxyUsageDetected(proxy)
if request.method != "POST":
return HttpResponseRedirect(reverse("events"))
# Check rate limit
ip = request.META.get("REMOTE_ADDR")
ip = request.META["HTTP_X_REAL_IP"]
cache_key = f"voting_block_{ip}"
rate_cache: django.core.cache.BaseCache = cache
if ip not in rate_cache:
@ -72,7 +72,7 @@ def voting(request: HttpRequest) -> django.http.HttpResponse:
rate_cache.incr(cache_key)
if rate_cache.get(cache_key) > django_settings.IP_RATE_LIMIT_COUNT:
raise RateLimitHit()
raise RateLimitHit(ip)
# check params
if not request.POST["name"]: