Initial commit
This commit is contained in:
commit
aeb052f26e
15 changed files with 247 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
__pycache__/
|
||||||
|
message.sqlite3
|
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"TAUTH",
|
||||||
|
"tmessage"
|
||||||
|
]
|
||||||
|
}
|
2
config.py
Normal file
2
config.py
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
tCOMMON_URL_INTERNAL = "http://localhost:8888"
|
||||||
|
tCOMMON_TOKEN = "Secret tCommon-specific token"
|
14
manage.py
Executable file
14
manage.py
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tmessage.settings")
|
||||||
|
try:
|
||||||
|
from django.core.management import execute_from_command_line
|
||||||
|
except ImportError as exc:
|
||||||
|
raise ImportError("Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?") from exc
|
||||||
|
execute_from_command_line(sys.argv)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
0
tmessage/__init__.py
Normal file
0
tmessage/__init__.py
Normal file
6
tmessage/asgi.py
Normal file
6
tmessage/asgi.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tmessage.settings")
|
||||||
|
application = get_asgi_application()
|
78
tmessage/settings.py
Normal file
78
tmessage/settings.py
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
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"]["message"]:
|
||||||
|
raise ImportError("tMessage isn't registered in tCommon")
|
||||||
|
|
||||||
|
DEBUG = config["debug"]
|
||||||
|
SECRET_KEY = config["services"]["message"]["token"]
|
||||||
|
|
||||||
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = ["*"]
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
"django.contrib.admin",
|
||||||
|
"django.contrib.auth",
|
||||||
|
"django.contrib.contenttypes",
|
||||||
|
"django.contrib.sessions",
|
||||||
|
"django.contrib.messages"
|
||||||
|
]
|
||||||
|
|
||||||
|
MIDDLEWARE = [
|
||||||
|
"django.middleware.security.SecurityMiddleware",
|
||||||
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
|
"django.middleware.common.CommonMiddleware",
|
||||||
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
|
"django.contrib.messages.middleware.MessageMiddleware",
|
||||||
|
"django.middleware.clickjacking.XFrameOptionsMiddleware"
|
||||||
|
]
|
||||||
|
|
||||||
|
ROOT_URLCONF = "tmessage.urls"
|
||||||
|
|
||||||
|
TEMPLATES = [
|
||||||
|
{
|
||||||
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||||
|
"DIRS": [
|
||||||
|
BASE_DIR / "tmessage/templates"
|
||||||
|
],
|
||||||
|
"APP_DIRS": True,
|
||||||
|
"OPTIONS": {
|
||||||
|
"context_processors": [
|
||||||
|
"django.template.context_processors.debug",
|
||||||
|
"django.template.context_processors.request",
|
||||||
|
"django.contrib.auth.context_processors.auth",
|
||||||
|
"django.contrib.messages.context_processors.messages",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
WSGI_APPLICATION = "tmessage.wsgi.application"
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
"default": {
|
||||||
|
"ENGINE": "django.db.backends.sqlite3",
|
||||||
|
"NAME": BASE_DIR / "message.sqlite3",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AUTH_PASSWORD_VALIDATORS = []
|
||||||
|
|
||||||
|
LANGUAGE_CODE = "en-us"
|
||||||
|
TIME_ZONE = "UTC"
|
||||||
|
USE_I18N = True
|
||||||
|
USE_TZ = True
|
||||||
|
|
||||||
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
7
tmessage/templates/404.html
Normal file
7
tmessage/templates/404.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<h1>Hmm. That doesn't look right.</h1>
|
||||||
|
Make sure the URL is correct and try again.
|
||||||
|
<small>(Error 404 - Page not found)</small>
|
||||||
|
{% endblock %}
|
28
tmessage/templates/base.html
Normal file
28
tmessage/templates/base.html
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{% block title %}{% if title %}{{ title }} - {% endif %}{% endblock %}tMessage</title>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<meta name="pronouns" content="she/her">
|
||||||
|
|
||||||
|
<link id="favicon" rel="icon" href="{{ config.services.common.url.pub }}/favicon/dark/{{ accent }}/">
|
||||||
|
|
||||||
|
{% block head %}{% endblock %}
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="{{ config.services.common.url.pub }}/static/css/base.css?v={{ config.version_str }}">
|
||||||
|
<style>html { --accent: var(--{{ accent }}); }</style>
|
||||||
|
<script src="{{ config.services.common.url.pub }}/static/js/theme.js?v={{ config.version_str }}"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="container">
|
||||||
|
<noscript>Please enable JavaScript!</noscript>
|
||||||
|
{% block body %}
|
||||||
|
Something went horribly wrong! Please contact us so we can fix this.
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
9
tmessage/templates/noauth/index.html
Normal file
9
tmessage/templates/noauth/index.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<h1>tMessage</h1>
|
||||||
|
<div>Anonymously message your friends</div>
|
||||||
|
<p>
|
||||||
|
<a href="{{ config.services.auth.url.pub }}/login/?to=message">Log in</a>
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
12
tmessage/urls.py
Normal file
12
tmessage/urls.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from .views import auth, index, message, profile
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path("", index),
|
||||||
|
path("auth/", auth),
|
||||||
|
path("u/<str:username>/", profile),
|
||||||
|
path("m/<str:username>/", message),
|
||||||
|
path("django-admin/", admin.site.urls)
|
||||||
|
]
|
1
tmessage/views/__init__.py
Normal file
1
tmessage/views/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
from .templates import auth, index, message, profile # noqa: F401
|
43
tmessage/views/helper.py
Normal file
43
tmessage/views/helper.py
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import random
|
||||||
|
from urllib.parse import quote as url_escape
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from django.core.handlers.wsgi import WSGIRequest
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.template import loader
|
||||||
|
|
||||||
|
from tmessage.settings import config
|
||||||
|
|
||||||
|
COLORS = ["rosewater", "flamingo", "pink", "mauve", "red", "maroon", "peach", "yellow", "green", "teal", "sky", "sapphire", "blue", "lavender"]
|
||||||
|
|
||||||
|
def render_template(
|
||||||
|
request: WSGIRequest,
|
||||||
|
template: str,
|
||||||
|
/, *,
|
||||||
|
status: int=200,
|
||||||
|
headers: dict[str, str]={},
|
||||||
|
content_type: str="text/html",
|
||||||
|
**context
|
||||||
|
) -> HttpResponse:
|
||||||
|
c = {
|
||||||
|
"accent": random.choice(COLORS),
|
||||||
|
"config": config
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, val in context.items():
|
||||||
|
c[key] = val
|
||||||
|
|
||||||
|
resp = HttpResponse(
|
||||||
|
loader.get_template(template).render(c, request),
|
||||||
|
status=status,
|
||||||
|
content_type=content_type
|
||||||
|
)
|
||||||
|
|
||||||
|
for key, val in headers.items():
|
||||||
|
resp[key] = val
|
||||||
|
|
||||||
|
return resp
|
||||||
|
|
||||||
|
def is_logged_in(request: WSGIRequest) -> dict | None:
|
||||||
|
resp = requests.get(config["services"]["auth"]["url"]["int"] + f"/api/authenticated/?token={url_escape(config['services']['message']['token'])}&service=message", cookies={**request.COOKIES}).json()
|
||||||
|
return resp["success"] and resp["auth"]
|
33
tmessage/views/templates.py
Normal file
33
tmessage/views/templates.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from django.core.handlers.wsgi import WSGIRequest
|
||||||
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
|
|
||||||
|
from .helper import is_logged_in, 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:
|
||||||
|
if is_logged_in(request):
|
||||||
|
return dashboard(request)
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
request, "noauth/index.html"
|
||||||
|
)
|
||||||
|
|
||||||
|
def profile(request: WSGIRequest, username: str) -> HttpResponse:
|
||||||
|
...
|
||||||
|
|
||||||
|
def message(request: WSGIRequest, username: str) -> HttpResponse:
|
||||||
|
...
|
||||||
|
|
||||||
|
def dashboard(request: WSGIRequest) -> HttpResponse:
|
||||||
|
return render_template(request, "base.html")
|
6
tmessage/wsgi.py
Normal file
6
tmessage/wsgi.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tmessage.settings")
|
||||||
|
application = get_wsgi_application()
|
Loading…
Reference in a new issue