authentication

This commit is contained in:
trinkey 2024-12-22 00:07:17 -05:00
parent 9bb18a6cca
commit b1ab59cfdd
9 changed files with 128 additions and 12 deletions

View file

@ -8,8 +8,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="pronouns" content="she/her"> <meta name="pronouns" content="she/her">
<link rel="icon" href="{{ config.services.common.url.pub }}/favicon/dark/{{ accent }}/"> <link id="favicon" rel="icon" href="{{ config.services.common.url.pub }}/favicon/dark/{{ accent }}/">
<link rel="icon" href="{{ config.services.common.url.pub }}/favicon/light/{{ accent }}/" media="(prefers-color-scheme: light)">
{% block head %}{% endblock %} {% block head %}{% endblock %}

View file

@ -2,5 +2,9 @@
{% block body %} {% block body %}
<h1>Welcome back, {{ username }}!</h1> <h1>Welcome back, {{ username }}!</h1>
tAuth <hr>
<p>Available services:</p>
<ul class="left inline-block no-margin">
{% if config.services.message %}<li><a href="{{ config.services.message.url.pub }}{{ login_token }}">tMessage</a></li>{% endif %}
</ul>
{% endblock %} {% endblock %}

View file

@ -0,0 +1,20 @@
{% extends "base.html" %}
{% block body %}
<h1>Log In</h1>
{{ error }}
<hr>
<p>
<form method="POST">
{% csrf_token %}
<p>
<div><input name="username" id="username" required type="text" pattern="[a-z0-9A-Z_][a-z0-9A-Z_\-]{0,28}[a-z0-9A-Z_]" maxlength="30" placeholder="Username"></div>
<div><input name="password" id="password" required type="password" placeholder="Password" maxlength="100"></div>
</p>
<p><input type="submit" value="Log In"></p>
{% if new_users %}
<p><a href="/signup/{{ login_extra }}">Don't have an account?</a></p>
{% endif %}
</form>
</p>
{% endblock %}

View file

@ -2,7 +2,8 @@
{% block body %} {% block body %}
<h1>Sign Up</h1> <h1>Sign Up</h1>
<div>tAuth</div> {{ error }}
<hr>
<p> <p>
<form method="POST"> <form method="POST">
{% csrf_token %} {% csrf_token %}
@ -28,6 +29,7 @@
</small></label> </small></label>
</p> </p>
<p><input type="submit" value="Sign Up"></p> <p><input type="submit" value="Sign Up"></p>
<p><a href="/login/{{ login_extra }}">Already have an account?</a></p>
</form> </form>
</p> </p>
{% endblock %} {% endblock %}

View file

@ -1,11 +1,13 @@
from django.contrib import admin from django.contrib import admin
from django.urls import path from django.urls import path
from .views import index, login, signup from .views import index, is_logged_in, login, redirect, signup
urlpatterns = [ urlpatterns = [
path("", index), path("", index),
path("login/", login), path("login/", login),
path("signup/", signup), path("signup/", signup),
path("django-admin/", admin.site.urls), path("redirect/", redirect),
path("api/authenticated/", is_logged_in),
path("django-admin/", admin.site.urls)
] ]

View file

@ -1 +1,2 @@
from .templates import index, login, signup # noqa: F401 from .api import is_logged_in # noqa: F401
from .templates import index, login, redirect, signup # noqa: F401

28
tauth/views/api.py Normal file
View file

@ -0,0 +1,28 @@
import json
from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponse
from tauth.settings import config
def is_logged_in(request: WSGIRequest) -> HttpResponse:
try:
if request.GET.get("token") == config["services"][request.GET.get("service")]["token"]:
return HttpResponse(
json.dumps({
"success": True,
"auth": request.user.is_authenticated
}),
content_type="application/json"
)
except KeyError:
...
return HttpResponse(
json.dumps({
"success": False
}),
content_type="application/json",
status=401
)

View file

@ -18,9 +18,9 @@ def render_template(
**context **context
) -> HttpResponse: ) -> HttpResponse:
c = { c = {
"theme": "auto",
"accent": random.choice(COLORS), "accent": random.choice(COLORS),
"config": config "config": config,
"login_token": f"/auth/?sessionid={request.COOKIES.get('sessionid')}"
} }
for key, val in context.items(): for key, val in context.items():

View file

@ -1,5 +1,6 @@
import re import re
from django.contrib.auth import authenticate
from django.contrib.auth import login as set_auth from django.contrib.auth import login as set_auth
from django.contrib.auth import logout as remove_auth from django.contrib.auth import logout as remove_auth
from django.contrib.auth.models import User from django.contrib.auth.models import User
@ -8,6 +9,7 @@ from django.http import HttpResponse, HttpResponseRedirect
from config import ALLOW_NEW_USERS from config import ALLOW_NEW_USERS
from tauth.models import TUser from tauth.models import TUser
from tauth.settings import config
from .helper import render_template from .helper import render_template
@ -18,6 +20,7 @@ def index(request: WSGIRequest) -> HttpResponse:
request, "index.html", request, "index.html",
username=request.user.get_username() username=request.user.get_username()
) )
return render_template( return render_template(
request, "noauth/index.html", request, "noauth/index.html",
new_users=ALLOW_NEW_USERS new_users=ALLOW_NEW_USERS
@ -49,14 +52,19 @@ def signup(request: WSGIRequest) -> HttpResponse:
error = "Username already in use" error = "Username already in use"
else: else:
TUser.objects.create(user=u) TUser.objects.create(user=u)
set_auth(request, u) set_auth(request, u)
to = request.GET.get("to")
if to and to in config["services"] and config["services"][to]:
return HttpResponseRedirect(f"/redirect/?to={to}&reauth")
return HttpResponseRedirect("/") return HttpResponseRedirect("/")
return render_template( return render_template(
request, "noauth/signup.html", request, "noauth/signup.html",
title="Sign Up", title="Sign Up",
error=error, error=error,
login_extra=f"?to={request.GET.get('to')}" if "to" in request.GET else "",
repopulate={ repopulate={
"username": username "username": username
} }
@ -64,7 +72,8 @@ def signup(request: WSGIRequest) -> HttpResponse:
return render_template( return render_template(
request, "noauth/signup.html", request, "noauth/signup.html",
title="Sign Up" title="Sign Up",
login_extra=f"?to={request.GET.get('to')}" if "to" in request.GET else ""
) )
return render_template( return render_template(
@ -72,7 +81,58 @@ def signup(request: WSGIRequest) -> HttpResponse:
) )
def login(request: WSGIRequest) -> HttpResponse: def login(request: WSGIRequest) -> HttpResponse:
if request.user.is_authenticated:
to = request.GET.get("to")
if to and to in config["services"] and config["services"]["to"]:
return HttpResponseRedirect(f"/redirect/?to={to}&reauth")
return HttpResponseRedirect("/")
if request.method == "POST":
username = (request.POST.get("username") or "").lower().strip()
password = (request.POST.get("password") or "")
user = authenticate(
request,
username=username,
password=password
)
if user is None:
return render_template( return render_template(
request, "noauth/login.html", request, "noauth/login.html",
title="Log In" title="Log In",
new_users=ALLOW_NEW_USERS,
error="Username or password is incorrect",
login_extra=f"?to={request.GET.get('to')}" if "to" in request.GET else "",
repopulate={
"username": username
}
) )
set_auth(request, user)
to = request.GET.get("to")
if to and to in config["services"] and config["services"][to]:
return HttpResponseRedirect(f"/redirect/?to={to}&reauth")
return HttpResponseRedirect("/")
return render_template(
request, "noauth/login.html",
title="Log In",
new_users=ALLOW_NEW_USERS,
login_extra=f"?to={request.GET.get('to')}" if "to" in request.GET else ""
)
def redirect(request: WSGIRequest) -> HttpResponseRedirect:
to = request.GET.get("to")
print(request.COOKIES)
if to and to in config["services"] and config["services"][to]:
return HttpResponseRedirect(config["services"][to]["url"]["pub"] + (f"/auth/?sessionid={request.COOKIES.get('sessionid')}" if "reauth" in request.GET else ""))
return HttpResponseRedirect("/")