sign up works

This commit is contained in:
trinkey 2024-12-20 23:44:31 -05:00
parent 42389fe7ac
commit 9bb18a6cca
16 changed files with 154 additions and 121 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
__pycache__/ __pycache__/
auth.sqlite3

9
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,9 @@
{
"cSpell.words": [
"noauth",
"noscript",
"stylesheet",
"tauth",
"TCOMMON"
]
}

View file

@ -1,8 +1,4 @@
ALLOW_NEW_USERS = True ALLOW_NEW_USERS = True
DEBUG = True
ENABLED_APPLICATIONS = { tCOMMON_URL_INTERNAL = "http://localhost:8888"
"search": False, tCOMMON_TOKEN = "Secret tCommon-specific token"
"music": False,
"messages": False,
"info": False
}

6
tauth/apps.py Normal file
View file

@ -0,0 +1,6 @@
from django.apps import AppConfig
class DBConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "tauth"

View file

@ -0,0 +1,23 @@
# Generated by Django 5.0.7 on 2024-12-21 04:40
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
migrations.CreateModel(
name='TUser',
fields=[
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)),
],
),
]

View file

6
tauth/models.py Normal file
View file

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

View file

@ -1,12 +1,25 @@
from pathlib import Path from pathlib import Path
from config import DEBUG # noqa: F401 import requests
from config import tCOMMON_TOKEN, tCOMMON_URL_INTERNAL
config = requests.get(f"{tCOMMON_URL_INTERNAL}/api/initialize/", params={
"token": tCOMMON_TOKEN
}, allow_redirects=False).json()
if not config["success"]:
raise ImportError("tCommon token doesn't match")
if not config["services"]["auth"]:
raise ImportError("tAuth isn't registered in tCommon")
DEBUG = config["debug"]
SECRET_KEY = config["services"]["auth"]["token"]
BASE_DIR = Path(__file__).resolve().parent.parent BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = "django-insecure--h3t*!a-h+(m7537)oxl9&fpjsin)#ht(5e!8w^5%ea1@f84u1" ALLOWED_HOSTS = ["*"]
ALLOWED_HOSTS = []
INSTALLED_APPS = [ INSTALLED_APPS = [
"django.contrib.admin", "django.contrib.admin",
@ -15,6 +28,7 @@ INSTALLED_APPS = [
"django.contrib.sessions", "django.contrib.sessions",
"django.contrib.messages", "django.contrib.messages",
"django.contrib.staticfiles", "django.contrib.staticfiles",
"tauth.apps.DBConfig"
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -52,7 +66,7 @@ WSGI_APPLICATION = "tauth.wsgi.application"
DATABASES = { DATABASES = {
"default": { "default": {
"ENGINE": "django.db.backends.sqlite3", "ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3", "NAME": BASE_DIR / "auth.sqlite3",
} }
} }

View file

@ -1,6 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block card %} {% block body %}
<h1>Hmm. That doesn't look right.</h1> <h1>Hmm. That doesn't look right.</h1>
Make sure the URL is correct and try again. Make sure the URL is correct and try again.
<small>(Error 404 - Page not found)</small> <small>(Error 404 - Page not found)</small>

View file

@ -8,21 +8,14 @@
<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 rel="icon" href="{{ config.services.common.url.pub }}/favicon/light/{{ accent }}/" media="(prefers-color-scheme: light)">
{% block head %}{% endblock %} {% block head %}{% endblock %}
<style> <link rel="stylesheet" href="{{ config.services.common.url.pub }}/static/css/base.css?v={{ config.version_str }}">
{% include "css/base.css" %} <style>html { --accent: var(--{{ accent }}); }</style>
{% block head_css %}{% endblock %} <script src="{{ config.services.common.url.pub }}/static/js/theme.js?v={{ config.version_str }}"></script>
html {
--accent: var(--{{ accent }});
}
</style>
<script>
{% include "js/theme.js" %}
{% block head_js %}{% endblock %}
</script>
</head> </head>
<body> <body>

View file

@ -1,60 +0,0 @@
/* Colors */
html { --rosewater: #f5e0dc; --flamingo: #f2cdcd; --pink: #f5c2e7; --mauve: #cba6f7; --red: #f38ba8; --maroon: #eba0ac; --peach: #fab387; --yellow: #f9e2af; --green: #a6e3a1; --teal: #94e2d5; --sky: #89dceb; --sapphire: #74c7ec; --blue: #89b4fa; --lavender: #b4befe; --text: #cdd6f4; --subtext1: #bac2de; --subtext0: #a6adc8; --overlay2: #9399b2; --overlay1: #7f849c; --overlay0: #6c7086; --surface2: #585b70; --surface1: #45475a; --surface0: #313244; --base: #1e1e2e; --mantle: #181825; --crust: #11111b; --base-low-op: #1e1e2ed0 }
html[data-light] { --rosewater: #dc8a78; --flamingo: #dd7878; --pink: #ea76cb; --mauve: #8839ef; --red: #d20f39; --maroon: #e64553; --peach: #fe640b; --yellow: #df8e1d; --green: #40a02b; --teal: #179299; --sky: #04a5e5; --sapphire: #209fb5; --blue: #1e66f5; --lavender: #7287fd; --text: #4c4f69; --subtext1: #5c5f77; --subtext0: #6c6f85; --overlay2: #7c7f93; --overlay1: #8c8fa1; --overlay0: #9ca0b0; --surface2: #acb0be; --surface1: #bcc0cc; --surface0: #ccd0da; --base: #eff1f5; --mantle: #e6e9ef; --crust: #dce0e8; --base-low-op: #eff1f5b0}
/* Font */
@font-face { font-family: 'DejaVu Sans'; font-style: normal; font-weight: 400; font-display: block; src: url("/static/font/DejaVuSans.ttf") format("truetype"); }
@font-face { font-family: 'DejaVu Sans'; font-style: normal; font-weight: 700; font-display: block; src: url("/static/font/DejaVuSans-Bold.ttf") format("truetype"); }
@font-face { font-family: 'DejaVu Sans'; font-style: italic; font-weight: 400; font-display: block; src: url("/static/font/DejaVuSans-Oblique.ttf") format("truetype"); }
@font-face { font-family: 'DejaVu Sans'; font-style: italic; font-weight: 700; font-display: block; src: url("/static/font/DejaVuSans-BoldOblique.ttf") format("truetype"); }
@font-face { font-family: 'DejaVu Sans'; font-style: normal; font-weight: 200; font-display: block; src: url("/static/font/DejaVuSans-ExtraLight.ttf") format("truetype"); }
@font-face { font-family: "Ubuntu Mono"; font-style: normal; font-weight: 400; font-display: block; src: url("/static/font/UbuntuMono-Regular.ttf") format("truetype"); }
@font-face { font-family: "Ubuntu Mono"; font-style: italic; font-weight: 400; font-display: block; src: url("/static/font/UbuntuMono-Italic.ttf") format("truetype"); }
@font-face { font-family: "Ubuntu Mono"; font-style: normal; font-weight: 700; font-display: block; src: url("/static/font/UbuntuMono-Bold.ttf") format("truetype"); }
@font-face { font-family: "Ubuntu Mono"; font-style: italic; font-weight: 700; font-display: block; src: url("/static/font/UbuntuMono-BoldItalic.ttf") format("truetype"); }
body {
margin: 0;
width: 100vw;
min-height: 100vh;
overflow-x: hidden;
background-color: var(--base);
color: var(--text);
font-family: "DejaVu Sans";
/* background-image: linear-gradient(
135deg,
var(--base) 25%,
var(--mantle) 25%,
var(--mantle) 50%,
var(--base) 50%,
var(--base) 75%,
var(--mantle) 75%
);
background-size: 20px 20px;
background-repeat: repeat; */
}
code, pre {
font-family: "Ubuntu Mono"
}
small, i {
color: var(--subtext0);
}
h1 {
color: var(--accent);
}
a:link,
a:visited {
color: var(--accent);
font-weight: 700;
}
#container {
text-align: center;
padding: 10px;
width: calc(100vw - 20px);
max-width: calc(100vw - 20px);
}

View file

@ -0,0 +1,6 @@
{% extends "base.html" %}
{% block body %}
<h1>Welcome back, {{ username }}!</h1>
tAuth
{% endblock %}

View file

@ -1,30 +0,0 @@
let _themeMM = matchMedia("(prefers-color-scheme: light)");
let light, useAutoTheme;
// {% if theme == "auto" %}
light = _themeMM.matches;
useAutoTheme = true;
// {% else %}
// {% if theme == "light" %}
light = true;
// {% else %}
light = false;
// {% endif %}
useAutoTheme = false;
// {% endif %}
function setTheme() {
if (light) {
document.documentElement.setAttribute("data-light", "");
} else {
document.documentElement.removeAttribute("data-light");
}
}
_themeMM.addEventListener("change", function() {
if (useAutoTheme) {
light = _themeMM.matches;
setTheme();
}
});
setTheme();

View file

@ -4,12 +4,30 @@
<h1>Sign Up</h1> <h1>Sign Up</h1>
<div>tAuth</div> <div>tAuth</div>
<p> <p>
<form> <form method="POST">
{% csrf_token %} {% csrf_token %}
<p> <p>
<div><input required type="text" pattern="[a-z0-9A-Z_][a-z0-9A-Z_\-]{0,30}[a-z0-9A-Z_]" 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>
<div><small>2-30 characters, <code>A-Z</code>, <code>0-9</code>, <code>_</code>, and <code>-</code>. Can't start or end with a <code>-</code></small></div> <label for="username"><small>
<ul class="left inline-block">
<li><b>2-30</b> characters</li>
<li><b>A-Z</b>, <b>0-9</b>, <b>underscores</b>, and <b>hyphens</b> accepted.</li>
<li>Can't start or end with a <b>hyphen</b></li>
<li>Case <b>insensitive</b></li>
</ul>
</small></label>
</p> </p>
<p>
<div><input name="password" id="password" required type="password" placeholder="Password" maxlength="100"></div>
<label for="password"><small>
<ul class="left inline-block">
<li><b>6+</b> characters</li>
<li>Must include a <b>letter</b>, <b>number</b>, and <b>special character</b></li>
<li>Can't include your <b>username</b></li>
</ul>
</small></label>
</p>
<p><input type="submit" value="Sign Up"></p>
</form> </form>
</p> </p>
{% endblock %} {% endblock %}

View file

@ -4,6 +4,8 @@ from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponse from django.http import HttpResponse
from django.template import loader from django.template import loader
from tauth.settings import config
COLORS = ["rosewater", "flamingo", "pink", "mauve", "red", "maroon", "peach", "yellow", "green", "teal", "sky", "sapphire", "blue", "lavender"] COLORS = ["rosewater", "flamingo", "pink", "mauve", "red", "maroon", "peach", "yellow", "green", "teal", "sky", "sapphire", "blue", "lavender"]
def render_template( def render_template(
@ -17,7 +19,8 @@ def render_template(
) -> HttpResponse: ) -> HttpResponse:
c = { c = {
"theme": "auto", "theme": "auto",
"accent": random.choice(COLORS) "accent": random.choice(COLORS),
"config": config
} }
for key, val in context.items(): for key, val in context.items():

View file

@ -1,19 +1,67 @@
import re
from django.contrib.auth import login as set_auth
from django.contrib.auth import logout as remove_auth
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, HttpResponseRedirect
from config import ALLOW_NEW_USERS from config import ALLOW_NEW_USERS
from tauth.models import TUser
from .helper import render_template from .helper import render_template
def index(request: WSGIRequest) -> HttpResponse: def index(request: WSGIRequest) -> HttpResponse:
if request.user.is_authenticated:
return render_template(
request, "index.html",
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
) )
def signup(request: WSGIRequest) -> HttpResponse: def signup(request: WSGIRequest) -> HttpResponse:
if request.user.is_authenticated:
return HttpResponseRedirect("/")
if ALLOW_NEW_USERS: if ALLOW_NEW_USERS:
if request.method == "POST":
username = (request.POST.get("username") or "").lower().strip()
password = (request.POST.get("password") or "")
error = None
if len(username) < 2 or len(username) > 30 or not re.match("^[a-z0-9_][a-z0-9_\\-]{0,28}[a-z0-9_]$", username):
error = "Invalid username"
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"
else:
try:
u = User.objects.create_user(
username=username,
password=password
)
except User.DoesNotExist:
error = "Username already in use"
else:
TUser.objects.create(user=u)
set_auth(request, u)
return HttpResponseRedirect("/")
return render_template(
request, "noauth/signup.html",
title="Sign Up",
error=error,
repopulate={
"username": username
}
)
return render_template( return render_template(
request, "noauth/signup.html", request, "noauth/signup.html",
title="Sign Up" title="Sign Up"