From 3e6eb6f2489ee92e50e4b8237547b9e9f567a825 Mon Sep 17 00:00:00 2001 From: Marc 'risson' Schmitt Date: Tue, 9 Apr 2024 14:16:58 +0200 Subject: [PATCH] add login tests Signed-off-by: Marc 'risson' Schmitt --- tests/benchmark/fixtures.py | 33 ++++++++++++++--- tests/benchmark/login.js | 73 +++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 tests/benchmark/login.js diff --git a/tests/benchmark/fixtures.py b/tests/benchmark/fixtures.py index 4dd51cfef0..1a946120f2 100755 --- a/tests/benchmark/fixtures.py +++ b/tests/benchmark/fixtures.py @@ -15,13 +15,14 @@ django.setup() from django.conf import settings from authentik.core.models import Group, User +from authentik.stages.authenticator_static.models import (StaticDevice, + StaticToken) from authentik.tenants.models import Domain, Tenant settings.CELERY["task_always_eager"] = True def user_list(): - print("user_list") # Number of users, groups per user, parents per groups tenants = [ (10, 0, 0), @@ -39,18 +40,15 @@ def user_list(): ] for tenant in tenants: - print(tenant) user_count = tenant[0] groups_per_user = tenant[1] parents_per_group = tenant[2] tenant_name = f"user-list-{user_count}-{groups_per_user}-{parents_per_group}" - print("tenant") t = Tenant.objects.create(schema_name=f"t_{tenant_name.replace('-', '_')}", name=uuid4()) Domain.objects.create(tenant=t, domain=f"{tenant_name}.localhost") with t: - print("groups") for _ in range(groups_per_user * 5): group = Group.objects.create(name=uuid4()) for _ in range(parents_per_group): @@ -58,7 +56,6 @@ def user_list(): group.parent = new_group group.save() group = new_group - print("users") for _ in range(user_count): user = User.objects.create(username=uuid4(), name=uuid4()) user.ak_groups.set( @@ -66,6 +63,29 @@ def user_list(): ) +def login(): + t = Tenant.objects.create(schema_name=f"t_login_no_mfa", name=uuid4()) + Domain.objects.create(tenant=t, domain=f"login-no-mfa.localhost") + + with t: + user = User(username="test", name=uuid4()) + user.set_password("verySecurePassword") + user.save() + + t = Tenant.objects.create(schema_name=f"t_login_with_mfa", name=uuid4()) + Domain.objects.create(tenant=t, domain=f"login-with-mfa.localhost") + + with t: + user = User(username="test", name=uuid4()) + user.set_password("verySecurePassword") + user.save() + device = user.staticdevice_set.create() + # Multiple token with same token for all the iterations in the test + device.token_set.bulk_create( + [StaticToken(device=device, token=f"staticToken") for _ in range(10000)] + ) + + def delete(): Tenant.objects.exclude(schema_name="public").delete() @@ -78,7 +98,8 @@ if __name__ == "__main__": match action: case "create": - user_list() + # user_list() + login() case "delete": delete() case _: diff --git a/tests/benchmark/login.js b/tests/benchmark/login.js new file mode 100644 index 0000000000..05ca75d4c9 --- /dev/null +++ b/tests/benchmark/login.js @@ -0,0 +1,73 @@ +import { Counter } from "k6/metrics"; +import http from "k6/http"; +import exec from "k6/execution"; +import { check, fail } from "k6"; + +export const options = { + scenarios: Object.fromEntries( + ["no-mfa", "with-mfa"].map((obj, i) => [ + obj, + { + executor: "constant-vus", + vus: 10, + duration: "300s", + startTime: `${315 * i}s`, + env: { + DOMAIN: `login-${obj}`, + }, + tags: { + testid: `login-${obj}`, + }, + }, + ]), + ), +}; + +export default function () { + const domain = __ENV.DOMAIN; + const url = `http://${domain}.localhost:9000/api/v3/flows/executor/default-authentication-flow/`; + const cookieJar = new http.CookieJar(); + const params = { + jar: cookieJar, + headers: { + "Content-Type": "application/json", + Accept: "*/*", + }, + }; + let res = http.get(url, params); + let i = 0; + while (true) { + if (i > 10) { + fail("Test made more than 10 queries."); + break; + } + check(res, { + "status is 200": (res) => res.status === 200, + }); + + const component = res.json()["component"]; + let payload = {}; + if (component === "ak-stage-identification") { + payload = { + uid_field: "test", + }; + } else if (component === "ak-stage-password") { + payload = { + password: "verySecurePassword", + }; + } else if (component === "ak-stage-authenticator-validate") { + payload = { + code: `staticToken`, + }; + } else if (component === "xak-flow-redirect") { + break; + } else { + console.log(`Unknown component type: ${component}`); + break; + } + + payload["component"] = component; + res = http.post(url, JSON.stringify(payload), params); + i++; + } +}