Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ __pycache__/
.venv/

# app
/secrets.json
/static/CACHE/
/media/*
!/media/robots.txt
!/media/sitemap.xml
config.json
*.log
/ops/*
/static/ops/*

23 changes: 7 additions & 16 deletions auth_app/templates/auth/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,6 @@
<link rel="icon" href="{% static "shared/images/nstrat.ico" %}">
<link rel="stylesheet" href="{% static 'shared/css/bulma.css' %}">
<link rel="stylesheet" href="{% static 'auth_app/css/login.css' %}">
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback"
defer></script>
<script>
window.onloadTurnstileCallback = function () {
turnstile.render("#login_box", {
sitekey: "0x4AAAAAAAOs7enSVbUYlAD-",
callback: function(token) {
console.log(`Challenge Success ${token}`);
},
});
};
</script>
</head>
<body>
<div id="login_box" class="box">
Expand All @@ -33,8 +21,11 @@
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
{{ form }}
<button type="submit" class="button is-link">Login</button>
</form>
</div>
</body>
</br>
<div class="cf-turnstile" data-sitekey="{{ TURNSTILE_SITE_KEY }}"></div>
<button type="submit" class="button is-link">Login</button>
</form>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" defer></script>
</div>
</body>
</html>
37 changes: 34 additions & 3 deletions auth_app/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
import requests
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import redirect, render

from .forms import LoginForm

TURNSTILE_VERIFY_URL = "https://challenges.cloudflare.com/turnstile/v0/siteverify"


def verify_turnstile(token, ip=None):
data = {
"secret": settings.CLOUDFLARE_TURNSTILE_SECRET_KEY,
"response": token,
}
if ip:
data["remoteip"] = ip

r = requests.post(TURNSTILE_VERIFY_URL, data=data, timeout=5)
return r.json()


def user_login(request):
if request.user.is_authenticated:
Expand All @@ -12,6 +29,16 @@ def user_login(request):
form = LoginForm(initial={"next": initial_next})

if request.method == "POST":
# cf turnstile
token = request.POST.get("cf-turnstile-response")
if not token:
messages.error(request, "Captcha missing.")
return redirect("login")
result = verify_turnstile(token, request.META.get("REMOTE_ADDR"))
if not result.get("success"):
messages.error(request, "Captcha failed. Try again.")

# auth
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
Expand All @@ -24,7 +51,11 @@ def user_login(request):
else:
messages.error(request, "Invalid username or password.")

return render(request, "auth/login.html", {"form": form})
return render(
request,
"auth/login.html",
{"form": form, "TURNSTILE_SITE_KEY": settings.CLOUDFLARE_TURNSTILE_SITE_KEY},
)


def user_logout(request):
Expand Down
4 changes: 4 additions & 0 deletions error_handlers/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from django.urls import path
from . import views

app_name = "error_handlers"
11 changes: 11 additions & 0 deletions error_handlers/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ def error_400(request, exception):
)


def error_401(request, exception):
status_code = 401
message = "UNAUTHORIZED"
return render(
request,
"error.html",
{"status_code": " ".join(str(status_code)), "message": message},
status=status_code,
)


def error_403(request, exception):
status_code = 403
message = "PERMISSION DENIED"
Expand Down
21 changes: 21 additions & 0 deletions nukeops/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,24 @@
"compressor.finders.CompressorFinder",
]
COMPRESS_ROOT = STATIC_ROOT if conf["static_path"] else "static/"

try:
from ops.overwrite import app_overwrite

INSTALLED_APPS = app_overwrite(INSTALLED_APPS)
except ImportError:
pass

# Secrets
BASE_DIR = Path(__file__).resolve().parent.parent

SECRETS_FILE = BASE_DIR / "secrets.json"

if SECRETS_FILE.exists():
with open(SECRETS_FILE) as f:
secrets = json.load(f)
else:
secrets = {}

CLOUDFLARE_TURNSTILE_SITE_KEY = secrets.get("TURNSTILE_SITE_KEY", "")
CLOUDFLARE_TURNSTILE_SECRET_KEY = secrets.get("TURNSTILE_SECRET_KEY", "")
13 changes: 11 additions & 2 deletions nukeops/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf.urls import handler404, handler500

# from django.conf.urls import handler404, handler500
from django.contrib import admin
from django.urls import include, path, re_path
from django.views.static import serve

from auth_app.views import user_login
from error_handlers.views import error_400, error_403, error_404, error_500
from error_handlers.views import error_400, error_401, error_403, error_404, error_500

from .settings import MEDIA_ROOT
from .views import media_access
Expand All @@ -38,6 +39,14 @@
]

handler400 = error_400
handler401 = error_401
handler403 = error_403
handler404 = error_404
handler500 = error_500

try:
from ops.overwrite import urls_overwrite

urlpatterns = urls_overwrite(urlpatterns)
except ImportError:
pass
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
wheel==0.42.0
channels==4.0.0
Django==5.0.2
requests==2.32.5
mysqlclient==2.2.0
daphne==4.0.0
channels-redis==4.1.0
Expand Down