Further into invite link display

This commit is contained in:
decentral1se 2021-06-12 02:15:50 +02:00
parent 96e718db3a
commit c5c856e6e9
Signed by: decentral1se
GPG Key ID: 92DAD76BD9567B8A
4 changed files with 72 additions and 8 deletions

View File

@ -1,6 +1,8 @@
"""Community Keycloak SSO user management."""
import json
from datetime import datetime as dt
from datetime import timedelta
from os import environ
from uuid import uuid4
@ -10,6 +12,7 @@ from authlib.integrations.starlette_client import OAuth, OAuthError
from fastapi import Depends, FastAPI, HTTPException, Request
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from humanize import naturaldelta
from starlette.exceptions import HTTPException
from starlette.middleware.sessions import SessionMiddleware
@ -26,6 +29,8 @@ REDIS_DB = environ.get("REDIS_DB")
REDIS_HOST = environ.get("REDIS_HOST")
REDIS_PORT = environ.get("REDIS_PORT")
INVITE_TIME_LIMIT = environ.get("INVITE_TIME_LIMIT")
app = FastAPI(docs_url=None, redoc_url=None)
app.add_middleware(SessionMiddleware, secret_key=APP_SECRET_KEY)
templates = Jinja2Templates(directory="templates")
@ -68,9 +73,24 @@ async def get_user(request: Request):
return request.session.get("user")
async def get_invites(request: Request, user=Depends(get_user)):
username = user["preferred_username"]
invites = await app.state.redis.get(username)
if invites:
humanised = []
for invite in json.loads(invites):
invite["human_time"] = naturaldelta(
dt.fromisoformat(invite["time"])
+ timedelta(days=int(INVITE_TIME_LIMIT))
)
humanised.append(invite)
return humanised
return []
@app.on_event("startup")
async def starup_event():
app.state.redis = create_redis_pool(
app.state.redis = await create_redis_pool(
f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}?encoding=utf-8"
)
@ -82,8 +102,10 @@ async def shutdown_event():
@app.get("/", dependencies=[Depends(logged_in)])
async def home(request: Request, user=Depends(get_user)):
context = {"request": request, "user": user}
async def home(
request: Request, user=Depends(get_user), invites=Depends(get_invites)
):
context = {"request": request, "user": user, "invites": invites}
return templates.TemplateResponse("admin.html", context=context)
@ -125,6 +147,18 @@ async def logout(request: Request):
return RedirectResponse(request.url_for("login"))
@app.get("/invite/keycloak", dependencies=[Depends(logged_in)])
async def invite_keycloak(request: Request):
pass
@app.get("/invite/keycloak/create", dependencies=[Depends(logged_in)])
async def invite_keycloak_create(
request: Request, user=Depends(get_user), invites=Depends(get_invites)
):
invites.append({"link": str(uuid4()), "time": str(dt.now())})
app.state.redis.set(user["preferred_username"], json.dumps(invites))
return RedirectResponse(request.url_for("home"))
@app.get("/invite/keycloak/delete", dependencies=[Depends(logged_in)])
async def invite_keycloak_delete(
request: Request, user=Depends(get_user), invites=Depends(get_invites)
):
invite =request.query_params.get("invite")
# TODO

17
poetry.lock generated
View File

@ -239,6 +239,17 @@ sniffio = "*"
brotli = ["brotlicffi (>=1.0.0,<2.0.0)"]
http2 = ["h2 (>=3.0.0,<4.0.0)"]
[[package]]
name = "humanize"
version = "3.7.1"
description = "Python humanize utilities"
category = "main"
optional = false
python-versions = ">=3.6"
[package.extras]
tests = ["freezegun", "pytest", "pytest-cov"]
[[package]]
name = "idna"
version = "3.2"
@ -501,7 +512,7 @@ python-versions = ">=3.6.1"
[metadata]
lock-version = "1.1"
python-versions = "^3.9"
content-hash = "3b87d7d886ec83f9a136e2535f8e9b2802f1c680464022c2938abce0033e55bd"
content-hash = "0ba44935dd5a68706610677a7e54fa3ebcd6f5a68edd05a1e1ecb8dbd9ca5947"
[metadata.files]
aioredis = [
@ -689,6 +700,10 @@ httpx = [
{file = "httpx-0.18.1-py3-none-any.whl", hash = "sha256:ad2e3db847be736edc4b272c4d5788790a7e5789ef132fc6b5fef8aeb9e9f6e0"},
{file = "httpx-0.18.1.tar.gz", hash = "sha256:0a2651dd2b9d7662c70d12ada5c290abcf57373b9633515fe4baa9f62566086f"},
]
humanize = [
{file = "humanize-3.7.1-py3-none-any.whl", hash = "sha256:a0dca9eb010dd1fab61819acaea54be344a4c22c77261f72ac4dbee183dd9a59"},
{file = "humanize-3.7.1.tar.gz", hash = "sha256:b8e7878f3063174b212bb82b9e5bee3b24bc47931e44df0bd34bcb1d8e0acf2f"},
]
idna = [
{file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"},
{file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"},

View File

@ -14,6 +14,7 @@ itsdangerous = "^2.0.1"
Authlib = "^0.15.4"
httpx = "^0.18.1"
aioredis = "^1.3.1"
humanize = "^3.7.1"
[tool.poetry.dev-dependencies]
black = "^21.6b0"

View File

@ -7,8 +7,22 @@
Hello, {{ user.preferred_username }}
<small>(<a href="{{ url_for('logout') }}">logout</a>)</small>
</p>
<table>
<tr>
<th>Link</th>
<th>Validity </th>
<th>Operations</th>
</tr>
{% for invite in invites %}
<tr>
<td> <a class="invite" href="{{ url_for('home') }}{{ invite.link }}">{{ url_for('home') }}{{ invite.link }}</a> </td>
<td> {{ invite.human_time }} </td>
<td> <a href="#">copy</a> <a href="{{ url_for('invite_keycloak_delete') }}?invite={{ invite.link }}">delete</a> </td>
</tr>
{% endfor %}
</table>
<p>
<a href="{{ url_for('invite_keycloak') }}">Generate an invite link</a>
<a href="{{ url_for('invite_keycloak_create') }}">Generate an invite link</a>
</p>
</body>
</html>