canaille-globuzma/tests/oidc/test_client_admin.py
Éloi Rivard b4908d5e57
modals are HTML pages instead of JS elements
This will help providing the very same user experience for users with
and without javascript. We will still be able to re-enable javascript
modals in the future, but this should be done from the ground up, HTML
first and javascript after.
2023-07-18 18:34:10 +02:00

283 lines
9.7 KiB
Python

import datetime
from canaille.app import models
from werkzeug.security import gen_salt
def test_no_logged_no_access(testclient):
testclient.get("/admin/client", status=403)
def test_no_admin_no_access(testclient, logged_user):
testclient.get("/admin/client", status=403)
def test_invalid_client_edition(testclient, logged_admin):
testclient.get("/admin/client/edit/invalid", status=404)
def test_client_list(testclient, client, logged_admin):
res = testclient.get("/admin/client")
res.mustcontain(client.client_name)
def test_client_list_pagination(testclient, logged_admin, client, other_client):
res = testclient.get("/admin/client")
res.mustcontain("2 items")
clients = []
for _ in range(25):
client = models.Client(client_id=gen_salt(48), client_name=gen_salt(48))
client.save()
clients.append(client)
res = testclient.get("/admin/client")
res.mustcontain("27 items")
client_name = res.pyquery(
".clients tbody tr:nth-of-type(1) td:nth-of-type(2) a"
).text()
assert client_name
form = res.forms["next"]
form["page"] = 2
res = form.submit()
assert client_name not in res.pyquery(
".clients tbody tr td:nth-of-type(2) a"
).text().split(" ")
for client in clients:
client.delete()
res = testclient.get("/admin/client")
res.mustcontain("2 items")
def test_client_list_bad_pages(testclient, logged_admin):
res = testclient.get("/admin/client")
form = res.forms["next"]
testclient.post(
"/admin/client",
{"csrf_token": form["csrf_token"].value, "page": "2"},
status=404,
)
res = testclient.get("/admin/client")
form = res.forms["next"]
testclient.post(
"/admin/client",
{"csrf_token": form["csrf_token"].value, "page": "-1"},
status=404,
)
def test_client_list_search(testclient, logged_admin, client, other_client):
res = testclient.get("/admin/client")
res.mustcontain("2 items")
res.mustcontain(client.client_name)
res.mustcontain(other_client.client_name)
form = res.forms["search"]
form["query"] = "other"
res = form.submit()
res.mustcontain("1 item")
res.mustcontain(other_client.client_name)
res.mustcontain(no=client.client_name)
def test_client_add(testclient, logged_admin):
res = testclient.get("/admin/client/add")
data = {
"client_name": "foobar",
"contacts-0": "foo@bar.com",
"client_uri": "https://foo.bar",
"redirect_uris-0": "https://foo.bar/callback",
"grant_types": ["password", "authorization_code"],
"scope": "openid profile",
"response_types": ["code", "token"],
"token_endpoint_auth_method": "none",
"logo_uri": "https://foo.bar/logo.png",
"tos_uri": "https://foo.bar/tos",
"policy_uri": "https://foo.bar/policy",
"software_id": "software",
"software_version": "1",
"jwk": "jwk",
"jwks_uri": "https://foo.bar/jwks.json",
"audience": [],
"preconsent": False,
"post_logout_redirect_uris-0": "https://foo.bar/disconnected",
}
for k, v in data.items():
res.form[k].force_value(v)
res = res.form.submit(status=302, name="action", value="add")
res = res.follow(status=200)
client_id = res.forms["readonly"]["client_id"].value
client = models.Client.get(client_id=client_id)
assert client.client_name == "foobar"
assert client.contacts == ["foo@bar.com"]
assert client.client_uri == "https://foo.bar"
assert client.redirect_uris == ["https://foo.bar/callback"]
assert client.grant_types == ["password", "authorization_code"]
assert client.scope == ["openid", "profile"]
assert client.response_types == ["code", "token"]
assert client.token_endpoint_auth_method == "none"
assert client.logo_uri == "https://foo.bar/logo.png"
assert client.tos_uri == "https://foo.bar/tos"
assert client.policy_uri == "https://foo.bar/policy"
assert client.software_id == "software"
assert client.software_version == "1"
assert client.jwk == "jwk"
assert client.jwks_uri == "https://foo.bar/jwks.json"
assert client.audience == [client]
assert not client.preconsent
assert client.post_logout_redirect_uris == ["https://foo.bar/disconnected"]
client.delete()
def test_add_missing_fields(testclient, logged_admin):
res = testclient.get("/admin/client/add")
res = res.form.submit(status=200, name="action", value="edit")
assert (
"error",
"The client has not been added. Please check your information.",
) in res.flashes
def test_client_edit(testclient, client, logged_admin, other_client):
res = testclient.get("/admin/client/edit/" + client.client_id)
data = {
"client_name": "foobar",
"contacts-0": "foo@bar.com",
"client_uri": "https://foo.bar",
"redirect_uris-0": "https://foo.bar/callback",
"grant_types": ["password", "authorization_code"],
"scope": "openid profile",
"response_types": ["code", "token"],
"token_endpoint_auth_method": "none",
"logo_uri": "https://foo.bar/logo.png",
"tos_uri": "https://foo.bar/tos",
"policy_uri": "https://foo.bar/policy",
"software_id": "software",
"software_version": "1",
"jwk": "jwk",
"jwks_uri": "https://foo.bar/jwks.json",
"audience": [client.id, other_client.id],
"preconsent": True,
"post_logout_redirect_uris-0": "https://foo.bar/disconnected",
}
for k, v in data.items():
res.forms["clientaddform"][k].force_value(v)
res = res.forms["clientaddform"].submit(status=302, name="action", value="edit")
assert (
"error",
"The client has not been edited. Please check your information.",
) not in res.flashes
assert ("success", "The client has been edited.") in res.flashes
client.reload()
assert client.client_name == "foobar"
assert client.contacts == ["foo@bar.com"]
assert client.client_uri == "https://foo.bar"
assert client.redirect_uris == [
"https://foo.bar/callback",
"https://mydomain.tld/redirect2",
]
assert client.grant_types == ["password", "authorization_code"]
assert client.scope == ["openid", "profile"]
assert client.response_types == ["code", "token"]
assert client.token_endpoint_auth_method == "none"
assert client.logo_uri == "https://foo.bar/logo.png"
assert client.tos_uri == "https://foo.bar/tos"
assert client.policy_uri == "https://foo.bar/policy"
assert client.software_id == "software"
assert client.software_version == "1"
assert client.jwk == "jwk"
assert client.jwks_uri == "https://foo.bar/jwks.json"
assert client.audience == [client, other_client]
assert not client.preconsent
assert client.post_logout_redirect_uris == ["https://foo.bar/disconnected"]
def test_client_edit_missing_fields(testclient, client, logged_admin, other_client):
res = testclient.get("/admin/client/edit/" + client.client_id)
res.forms["clientaddform"]["client_name"] = ""
res = res.forms["clientaddform"].submit(name="action", value="edit")
assert (
"error",
"The client has not been edited. Please check your information.",
) in res.flashes
client.reload()
assert client.client_name
def test_client_delete(testclient, logged_admin):
client = models.Client(client_id="client_id")
client.save()
token = models.Token(
token_id="id",
client=client,
issue_datetime=datetime.datetime.now(datetime.timezone.utc),
)
token.save()
consent = models.Consent(
consent_id="consent_id", subject=logged_admin, client=client, scope="openid"
)
consent.save()
models.AuthorizationCode(authorization_code_id="id", client=client, subject=client)
res = testclient.get("/admin/client/edit/" + client.client_id)
res = res.forms["clientaddform"].submit(name="action", value="confirm-delete")
res = res.form.submit(name="action", value="delete")
res = res.follow()
assert not models.Client.get()
assert not models.Token.get()
assert not models.AuthorizationCode.get()
assert not models.Consent.get()
def test_client_delete_invalid_client(testclient, logged_admin, client):
res = testclient.get(f"/admin/client/edit/{client.client_id}")
testclient.post(
"/admin/client/edit/invalid",
{
"action": "delete",
"csrf_token": res.forms["clientaddform"]["csrf_token"].value,
},
status=404,
)
def test_client_edit_preauth(testclient, client, logged_admin, other_client):
assert not client.preconsent
res = testclient.get("/admin/client/edit/" + client.client_id)
res.forms["clientaddform"]["preconsent"] = True
res = res.forms["clientaddform"].submit(name="action", value="edit")
assert ("success", "The client has been edited.") in res.flashes
client.reload()
assert client.preconsent
res = testclient.get("/admin/client/edit/" + client.client_id)
res.forms["clientaddform"]["preconsent"] = False
res = res.forms["clientaddform"].submit(name="action", value="edit")
assert ("success", "The client has been edited.") in res.flashes
client.reload()
assert not client.preconsent
def test_client_edit_invalid_uri(testclient, client, logged_admin, other_client):
res = testclient.get("/admin/client/edit/" + client.client_id)
res.forms["clientaddform"]["client_uri"] = "invalid"
res = res.forms["clientaddform"].submit(status=200, name="action", value="edit")
assert (
"error",
"The client has not been edited. Please check your information.",
) in res.flashes
res.mustcontain("This is not a valid URL")