Compare commits

...

4 Commits

Author SHA1 Message Date
3f326b74d6 feat: minlength validation
All checks were successful
continuous-integration/drone/push Build is passing
2022-01-10 10:33:07 +01:00
df35fe181a fix: show message as string 2022-01-10 10:32:54 +01:00
53a6abb7a8 feat: email validation 2022-01-10 10:27:42 +01:00
de207e3153 feat: password confirmation 2022-01-10 10:17:35 +01:00
6 changed files with 107 additions and 10 deletions

View File

@ -5,6 +5,7 @@ from datetime import datetime as dt
from datetime import timedelta from datetime import timedelta
from fastapi import APIRouter, Depends, Form, Request from fastapi import APIRouter, Depends, Form, Request
from pydantic import EmailStr, errors
from keycloak_collective_portal.dependencies import fresh_token, get_invites from keycloak_collective_portal.dependencies import fresh_token, get_invites
@ -44,7 +45,7 @@ async def register_invite(
"invalid.html", context=context "invalid.html", context=context
) )
context = {"request": request, "username": username} context = {"request": request, "invited_by": username}
return request.app.state.templates.TemplateResponse( return request.app.state.templates.TemplateResponse(
"register.html", context=context "register.html", context=context
) )
@ -58,8 +59,31 @@ def form_keycloak_register(
username: str = Form(...), username: str = Form(...),
email: str = Form(...), email: str = Form(...),
password: str = Form(...), password: str = Form(...),
password_again: str = Form(...),
invited_by: str = Form(...), invited_by: str = Form(...),
): ):
context = {
"request": request,
"invited_by": invited_by,
"first_name": first_name,
"last_name": last_name,
"username": username,
"email": email,
}
try:
EmailStr().validate(email)
except errors.EmailError:
context["exception"] = "email is not valid?"
return request.app.state.templates.TemplateResponse(
"register.html", context=context
)
if password != password_again:
context["exception"] = "passwords don't match?"
return request.app.state.templates.TemplateResponse(
"register.html", context=context
)
payload = { payload = {
"email": email, "email": email,
@ -76,7 +100,7 @@ def form_keycloak_register(
"realmRoles": [ "realmRoles": [
"user_default", "user_default",
], ],
"attributes": {"invited_by": username}, "attributes": {"invited_by": invited_by},
} }
try: try:

View File

@ -1,5 +1,6 @@
input { input {
display: block; display: block;
margin-top: 5px;
margin-bottom: 15px; margin-bottom: 15px;
} }
@ -10,3 +11,15 @@ th, td {
table, th, td { table, th, td {
border: 1px solid black; border: 1px solid black;
} }
input {
border: 2px solid currentcolor;
}
input:invalid {
border: 2px dashed red;
}
input:invalid:focus {
background-image: linear-gradient(magenta, pink);
}

View File

@ -1,5 +1,6 @@
input { input {
display: block; display: block;
margin-top: 5px;
margin-bottom: 15px; margin-bottom: 15px;
} }
@ -10,3 +11,19 @@ th, td {
table, th, td { table, th, td {
border: 1px solid black; border: 1px solid black;
} }
input {
border: 2px solid currentcolor;
}
input:invalid {
border: 2px dashed red;
}
input:invalid:focus {
background-image: linear-gradient(magenta, pink);
}
.error {
color: red;
}

View File

@ -1,26 +1,33 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<p> <p>
You've been invited by {{ username }} 🎉 You've been invited by {{ invited_by }} 🎉
</p> </p>
{% if exception %}
<p class="error">Oops, something went wrong: {{ exception }} 😬</p>
{% endif %}
<form method="post" action="{{ url_for('form_keycloak_register') }}"> <form method="post" action="{{ url_for('form_keycloak_register') }}">
<label for="first_name">First name:</label> <label for="first_name">First name:</label>
<input type="text" name="first_name" /> <input type="text" name="first_name" value="{{ first_name }}" minlength="3" />
<label for="last_name">Last name:</label> <label for="last_name">Last name:</label>
<input type="text" name="last_name" /> <input type="text" name="last_name" value="{{ last_name }}" minlength="3"/>
<label for="username">Username:</label> <label for="username">Username:</label>
<input type="text" name="username" /> <input type="text" name="username" value="{{ username }}" minlength="3"/>
<label for="email">Email:</label> <label for="email">Email:</label>
<input type="text" name="email" /> <input type="text" name="email" value="{{ email }}" minlength="3"/>
<label for="password">Password:</label> <label for="password">Password:</label>
<input type="password" name="password" /> <input type="password" name="password" minlength="8"/>
<input type="hidden" name="invited_by" value="{{ username }}"/> <label for="password_again">Password (just to be sure):</label>
<input type="password" name="password_again" minlength="8"/>
<input type="hidden" name="invited_by" value="{{ invited_by }}"/>
<input type="submit" value="Register" /> <input type="submit" value="Register" />
</form> </form>

37
poetry.lock generated
View File

@ -163,6 +163,21 @@ sdist = ["setuptools-rust (>=0.11.4)"]
ssh = ["bcrypt (>=3.1.5)"] ssh = ["bcrypt (>=3.1.5)"]
test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"]
[[package]]
name = "dnspython"
version = "2.1.0"
description = "DNS toolkit"
category = "main"
optional = false
python-versions = ">=3.6"
[package.extras]
dnssec = ["cryptography (>=2.6)"]
doh = ["requests", "requests-toolbelt"]
idna = ["idna (>=2.1)"]
curio = ["curio (>=1.2)", "sniffio (>=1.1)"]
trio = ["trio (>=0.14.0)", "sniffio (>=1.1)"]
[[package]] [[package]]
name = "ecdsa" name = "ecdsa"
version = "0.17.0" version = "0.17.0"
@ -178,6 +193,18 @@ six = ">=1.9.0"
gmpy = ["gmpy"] gmpy = ["gmpy"]
gmpy2 = ["gmpy2"] gmpy2 = ["gmpy2"]
[[package]]
name = "email-validator"
version = "1.1.3"
description = "A robust email syntax and deliverability validation library for Python 2.x/3.x."
category = "main"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
[package.dependencies]
dnspython = ">=1.15.0"
idna = ">=2.0.0"
[[package]] [[package]]
name = "fastapi" name = "fastapi"
version = "0.65.2" version = "0.65.2"
@ -642,7 +669,7 @@ python-versions = ">=3.6.1"
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "d8f978355587c9f76a7888c64b7d1409de886670a4b6a51cdfc0eedbd6ba3009" content-hash = "ecf2a823da9679d30575e15c6fcb2eac6f1d9c323870831ba8c2f1fdc47e4fd1"
[metadata.files] [metadata.files]
aiofiles = [ aiofiles = [
@ -758,10 +785,18 @@ cryptography = [
{file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2014_x86_64.whl", hash = "sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9"}, {file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2014_x86_64.whl", hash = "sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9"},
{file = "cryptography-3.4.7.tar.gz", hash = "sha256:3d10de8116d25649631977cb37da6cbdd2d6fa0e0281d014a5b7d337255ca713"}, {file = "cryptography-3.4.7.tar.gz", hash = "sha256:3d10de8116d25649631977cb37da6cbdd2d6fa0e0281d014a5b7d337255ca713"},
] ]
dnspython = [
{file = "dnspython-2.1.0-py3-none-any.whl", hash = "sha256:95d12f6ef0317118d2a1a6fc49aac65ffec7eb8087474158f42f26a639135216"},
{file = "dnspython-2.1.0.zip", hash = "sha256:e4a87f0b573201a0f3727fa18a516b055fd1107e0e5477cded4a2de497df1dd4"},
]
ecdsa = [ ecdsa = [
{file = "ecdsa-0.17.0-py2.py3-none-any.whl", hash = "sha256:5cf31d5b33743abe0dfc28999036c849a69d548f994b535e527ee3cb7f3ef676"}, {file = "ecdsa-0.17.0-py2.py3-none-any.whl", hash = "sha256:5cf31d5b33743abe0dfc28999036c849a69d548f994b535e527ee3cb7f3ef676"},
{file = "ecdsa-0.17.0.tar.gz", hash = "sha256:b9f500bb439e4153d0330610f5d26baaf18d17b8ced1bc54410d189385ea68aa"}, {file = "ecdsa-0.17.0.tar.gz", hash = "sha256:b9f500bb439e4153d0330610f5d26baaf18d17b8ced1bc54410d189385ea68aa"},
] ]
email-validator = [
{file = "email_validator-1.1.3-py2.py3-none-any.whl", hash = "sha256:5675c8ceb7106a37e40e2698a57c056756bf3f272cfa8682a4f87ebd95d8440b"},
{file = "email_validator-1.1.3.tar.gz", hash = "sha256:aa237a65f6f4da067119b7df3f13e89c25c051327b2b5b66dc075f33d62480d7"},
]
fastapi = [ fastapi = [
{file = "fastapi-0.65.2-py3-none-any.whl", hash = "sha256:39569a18914075b2f1aaa03bcb9dc96a38e0e5dabaf3972e088c9077dfffa379"}, {file = "fastapi-0.65.2-py3-none-any.whl", hash = "sha256:39569a18914075b2f1aaa03bcb9dc96a38e0e5dabaf3972e088c9077dfffa379"},
{file = "fastapi-0.65.2.tar.gz", hash = "sha256:8359e55d8412a5571c0736013d90af235d6949ec4ce978e9b63500c8f4b6f714"}, {file = "fastapi-0.65.2.tar.gz", hash = "sha256:8359e55d8412a5571c0736013d90af235d6949ec4ce978e9b63500c8f4b6f714"},

View File

@ -18,6 +18,7 @@ humanize = "^3.7.1"
python-multipart = "^0.0.5" python-multipart = "^0.0.5"
python-keycloak = "^0.25.0" python-keycloak = "^0.25.0"
aiofiles = "^0.7.0" aiofiles = "^0.7.0"
email-validator = "^1.1.3"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
black = "^21.6b0" black = "^21.6b0"