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__ __pycache__
clubhaus/static/**/* clubhaus/static/**/*
.DS_Store .DS_Store
django.log
# Created by https://www.toptal.com/developers/gitignore/api/jetbrains # Created by https://www.toptal.com/developers/gitignore/api/jetbrains
# Edit at https://www.toptal.com/developers/gitignore?templates=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_TIME = int(os.getenv("IP_RATE_LIMIT_TIME", "3600"))
IP_RATE_LIMIT_COUNT = int(os.getenv("IP_RATE_LIMIT_COUNT", "2")) 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 # 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 import settings
from django.conf.urls.static import static from django.conf.urls.static import static
from django.contrib import admin 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 = [ urlpatterns = [
path('', include('homepage.urls')), path('', include('homepage.urls')),
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
re_path(r'^favicon\.ico$', favicon_view),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
handler400 = "homepage.views.bad_request" handler400 = "homepage.views.bad_request"

View File

@ -2,16 +2,16 @@ from django.core import exceptions
class RateLimitHit(exceptions.SuspiciousOperation): class RateLimitHit(exceptions.SuspiciousOperation):
def __init__(self): def __init__(self, ip: str):
self.text = "You made to many request in a short period of time! Please try again later" self.text = f"You made to many request in a short period of time! Please try again later. Your IP: {ip}"
def __str__(self): def __str__(self):
return f"{self.__class__.__name__}: {self.text}" return f"{self.__class__.__name__}: {self.text}"
class ProxyUsageDetected(exceptions.SuspiciousOperation): class ProxyUsageDetected(exceptions.SuspiciousOperation):
def __init__(self): def __init__(self, proxy: str):
self.text = "It appears you are using a proxy! We don't want you to do that!" 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): def __str__(self):
return f"{self.__class__.__name__}: {self.text}" 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:title" content="{% block title %}Clubhaus Schornbach{% endblock %}">
<meta property="og:description" content="Clubhaus Schornbach - est. 2007"> <meta property="og:description" content="Clubhaus Schornbach - est. 2007">
<meta property="og:image" <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:type" content="website"/>
<meta property="og:image:type" content="image/svg+xml"> <meta property="og:image:type" content="image/svg+xml">
<meta property="og:image:width" content="300"> <meta property="og:image:width" content="300">
<meta property="og:image:height" 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> <title>Clubhaus Schornbach</title>
<link rel="icon" href="{% static 'homepage/logo.svg' %}" sizes="any" type="image/svg+xml"> <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="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"> <div class="h-100 p-3 text-white bg-dark rounded-3">
<h2><i class="bi-clock display-2"></i></h2> <h2><i class="bi-clock display-2"></i></h2>
<p class="fs-2 fw-bold"> {% if next_event.date %}
{{ next_event.date|date:"d.m.Y" }} <p class="fs-2 fw-bold">
<br> {{ next_event.date|date:"d.m.Y" }}
ab {{ next_event.date|date:"H:i" }} Uhr <br>
</p> ab {{ next_event.date|date:"H:i" }} Uhr
</p>
{% else %}
<p class="fs-2 fw-bold">
coming
<br>
soon
</p>
{% endif %}
</div> </div>
</div> </div>

View File

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