This commit is contained in:
trinkey 2024-12-23 13:22:07 -05:00
parent b1ab59cfdd
commit 6f6ff87a85
9 changed files with 78 additions and 22 deletions

View file

@ -1,4 +1,2 @@
ALLOW_NEW_USERS = True
tCOMMON_URL_INTERNAL = "http://localhost:8888" tCOMMON_URL_INTERNAL = "http://localhost:8888"
tCOMMON_TOKEN = "Secret tCommon-specific token" tCOMMON_TOKEN = "Secret tCommon-specific token"

View file

@ -15,7 +15,7 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='TUser', name='tUser',
fields=[ fields=[
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)),
], ],

View file

@ -2,5 +2,5 @@ from django.contrib.auth.models import User
from django.db import models from django.db import models
class TUser(models.Model): class tUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True) user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)

View file

@ -1,10 +1,12 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block body %} {% block body %}
<h1>Welcome back, {{ username }}!</h1> <h1>Hey there, {{ username }}!</h1>
<hr> <hr>
<p>Available services:</p> <p>Available services:</p>
<ul class="left inline-block no-margin"> <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 %} {% if config.services.message %}<li><a href="{{ config.services.message.url.pub }}{{ login_token }}">tMessage</a></li>{% endif %}
</ul> </ul>
<hr class="sub">
<small><a href="/logout/">Log out</a></small>
{% endblock %} {% endblock %}

View file

@ -2,10 +2,10 @@
{% block body %} {% block body %}
<h1>Sign Up</h1> <h1>Sign Up</h1>
{{ error }} <div id="error">{{ error }}</div>
<hr> <hr>
<p> <p>
<form method="POST"> <form method="POST" onsubmit="if (document.getElementById('password').value !== document.getElementById('confirm').value) {event.preventDefault(); document.getElementById('error').innerText = 'Passwords don\'t match!';}">
{% csrf_token %} {% csrf_token %}
<p> <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="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>
@ -28,6 +28,7 @@
</ul> </ul>
</small></label> </small></label>
</p> </p>
<p><div><input id="confirm" required type="password" placeholder="Confirm password" maxlength="100"></div></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> <p><a href="/login/{{ login_extra }}">Already have an account?</a></p>
</form> </form>

View file

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

View file

@ -1,2 +1,3 @@
from .api import is_logged_in # noqa: F401 from .api import get_username, username_exists # noqa: F401
from .templates import index, login, redirect, signup # noqa: F401 from .templates import (auth, index, login, logout, redirect, # noqa: F401
signup)

View file

@ -1,18 +1,21 @@
import json import json
from django.contrib.auth.models import User
from django.core.handlers.wsgi import WSGIRequest from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponse from django.http import HttpResponse
from tauth.settings import config from tauth.settings import config
def is_logged_in(request: WSGIRequest) -> HttpResponse: def get_username(request: WSGIRequest) -> HttpResponse:
try: try:
if request.GET.get("token") == config["services"][request.GET.get("service")]["token"]: if request.GET.get("token") == config["services"][request.GET.get("service")]["token"]:
authenticated = request.user.is_authenticated
return HttpResponse( return HttpResponse(
json.dumps({ json.dumps({
"success": True, "success": True,
"auth": request.user.is_authenticated "authenticated": authenticated,
"username": request.user.get_username() if authenticated else None
}), }),
content_type="application/json" content_type="application/json"
) )
@ -26,3 +29,31 @@ def is_logged_in(request: WSGIRequest) -> HttpResponse:
content_type="application/json", content_type="application/json",
status=401 status=401
) )
def username_exists(request: WSGIRequest) -> HttpResponse:
try:
if request.GET.get("token") == config["services"][request.GET.get("service")]["token"]:
exists = True
try:
User.objects.get(username=request.GET.get("username"))
except User.DoesNotExist:
exists = False
return HttpResponse(
json.dumps({
"success": True,
"exists": exists
}),
content_type="application/json"
)
except KeyError:
...
return HttpResponse(
json.dumps({
"success": False
}),
content_type="application/json",
status=401
)

View file

@ -1,4 +1,5 @@
import re import re
from datetime import datetime
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.contrib.auth import login as set_auth from django.contrib.auth import login as set_auth
@ -7,13 +8,21 @@ from django.contrib.auth.models import User
from django.core.handlers.wsgi import WSGIRequest from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from config import ALLOW_NEW_USERS from tauth.models import tUser
from tauth.models import TUser
from tauth.settings import config from tauth.settings import config
from .helper import render_template from .helper import render_template
def auth(request: WSGIRequest) -> HttpResponseRedirect:
resp = HttpResponseRedirect("/")
if "remove" in request.GET:
resp.set_cookie("sessionid", "", max_age=0, expires=datetime(0, 0, 0))
else:
resp.set_cookie("sessionid", request.GET.get("sessionid") or "")
return resp
def index(request: WSGIRequest) -> HttpResponse: def index(request: WSGIRequest) -> HttpResponse:
if request.user.is_authenticated: if request.user.is_authenticated:
return render_template( return render_template(
@ -23,14 +32,14 @@ def index(request: WSGIRequest) -> HttpResponse:
return render_template( return render_template(
request, "noauth/index.html", request, "noauth/index.html",
new_users=ALLOW_NEW_USERS new_users=config["new_users"]
) )
def signup(request: WSGIRequest) -> HttpResponse: def signup(request: WSGIRequest) -> HttpResponse:
if request.user.is_authenticated: if request.user.is_authenticated:
return HttpResponseRedirect("/") return HttpResponseRedirect("/")
if ALLOW_NEW_USERS: if config["new_users"]:
if request.method == "POST": if request.method == "POST":
username = (request.POST.get("username") or "").lower().strip() username = (request.POST.get("username") or "").lower().strip()
password = (request.POST.get("password") or "") password = (request.POST.get("password") or "")
@ -42,6 +51,9 @@ def signup(request: WSGIRequest) -> HttpResponse:
elif len(password) < 6 or len(password) > 100 or not (any([i.isalpha() for i in password]) and any([i.isnumeric() for i in password]) and any([not i.isalnum() for i in password])): elif len(password) < 6 or len(password) > 100 or not (any([i.isalpha() for i in password]) and any([i.isnumeric() for i in password]) and any([not i.isalnum() for i in password])):
error = "Invalid password" error = "Invalid password"
elif username.lower() in password.lower():
error = "Password can't contain username"
else: else:
try: try:
u = User.objects.create_user( u = User.objects.create_user(
@ -51,7 +63,7 @@ def signup(request: WSGIRequest) -> HttpResponse:
except User.DoesNotExist: except User.DoesNotExist:
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") to = request.GET.get("to")
@ -103,7 +115,7 @@ def login(request: WSGIRequest) -> HttpResponse:
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, new_users=config["new_users"],
error="Username or password is incorrect", error="Username or password is incorrect",
login_extra=f"?to={request.GET.get('to')}" if "to" in request.GET else "", login_extra=f"?to={request.GET.get('to')}" if "to" in request.GET else "",
repopulate={ repopulate={
@ -123,16 +135,23 @@ def login(request: WSGIRequest) -> HttpResponse:
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, new_users=config["new_users"],
login_extra=f"?to={request.GET.get('to')}" if "to" in request.GET else "" login_extra=f"?to={request.GET.get('to')}" if "to" in request.GET else ""
) )
def redirect(request: WSGIRequest) -> HttpResponseRedirect: def redirect(request: WSGIRequest) -> HttpResponseRedirect:
to = request.GET.get("to") to = request.GET.get("to")
print(request.COOKIES)
if to and to in config["services"] and config["services"][to]: 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(config["services"][to]["url"]["pub"] + (f"/auth/?sessionid={request.COOKIES.get('sessionid')}" if "reauth" in request.GET else ""))
return HttpResponseRedirect("/") return HttpResponseRedirect("/")
def logout(request: WSGIRequest) -> HttpResponseRedirect:
remove_auth(request)
to = request.GET.get("to")
if to and to in config["services"] and config["services"][to]:
return HttpResponseRedirect(config["services"][to]["url"]["pub"] + "/auth/?remove")
return HttpResponseRedirect("/")