Files
Docker-Compose-Stacks/obin-ad-user-creator/tests/test_app.py
T

111 lines
3.8 KiB
Python

import os
import pytest
from fastapi.testclient import TestClient
os.environ.update({
"APP_TITLE": "Wheelytho Account Creation",
"AD_LDAPS_URL": "ldaps://dc.example.test:636",
"AD_BIND_USERNAME": "svc-create@example.test",
"AD_BIND_PASSWORD": "secret",
"AD_BASE_DN": "DC=example,DC=test",
"AD_CREATE_OU": "OU=WheelzUsers,DC=example,DC=test",
"AD_DEFAULT_GROUPS": "Authelia-Family",
"AD_DOMAIN_UPN_SUFFIX": "example.test",
"APP_REQUIRE_INVITE_CODE": "false",
"APP_INVITE_CODE": "",
"WELCOME_URL": "https://welcome.wheelytho.com/",
"AUTHELIA_SETUP_URL": "https://auth.wheelytho.com/",
})
from app.main import app, get_ad_client
class FakeADClient:
def __init__(self):
self.created = []
def create_user(self, username, password, email):
self.created.append({"username": username, "password": password, "email": email})
return {"username": username, "email": email, "groups": ["Authelia-Family"]}
@pytest.fixture()
def fake_client(monkeypatch):
monkeypatch.setenv("APP_REQUIRE_INVITE_CODE", "false")
fake = FakeADClient()
app.dependency_overrides[get_ad_client] = lambda: fake
yield TestClient(app, follow_redirects=False), fake
app.dependency_overrides.clear()
def test_form_loads():
client = TestClient(app)
response = client.get("/")
assert response.status_code == 200
assert "Wheelytho Account Creation" in response.text
assert "name='username'" in response.text
assert "name='email'" in response.text
assert "name='password'" in response.text
def test_create_user_success_returns_redirect_and_never_echoes_password(fake_client):
client, fake = fake_client
response = client.post("/api/create-user", data={
"username": "new.family",
"password": "CorrectHorseBatteryStaple!42",
"email": "New.Family@Example.com",
})
assert response.status_code == 303
assert response.headers["location"].startswith("/created?username=new.family")
assert fake.created == [{"username": "new.family", "password": "CorrectHorseBatteryStaple!42", "email": "new.family@example.com"}]
assert "CorrectHorseBatteryStaple" not in response.text
def test_create_user_rejects_unsafe_username_before_ad_call(fake_client):
client, fake = fake_client
response = client.post("/api/create-user", data={
"username": "../../admin",
"password": "CorrectHorseBatteryStaple!42",
"email": "bad@example.com",
})
assert response.status_code == 400
assert fake.created == []
def test_create_user_rejects_weak_password_before_ad_call(fake_client):
client, fake = fake_client
response = client.post("/api/create-user", data={
"username": "newuser",
"password": "short",
"email": "newuser@example.com",
})
assert response.status_code == 400
assert fake.created == []
def test_create_user_requires_invite_code_when_enabled(monkeypatch):
monkeypatch.setenv("APP_REQUIRE_INVITE_CODE", "true")
monkeypatch.setenv("APP_INVITE_CODE", "family-only")
fake = FakeADClient()
app.dependency_overrides[get_ad_client] = lambda: fake
client = TestClient(app, follow_redirects=False)
response = client.post("/api/create-user", data={
"username": "newuser",
"password": "CorrectHorseBatteryStaple!42",
"email": "newuser@example.com",
"invite_code": "wrong",
})
assert response.status_code == 403
assert fake.created == []
app.dependency_overrides.clear()
def test_created_page_contains_2fa_instructions_and_welcome_link():
client = TestClient(app)
response = client.get("/created?username=newuser&email=newuser%40example.com")
assert response.status_code == 200
assert "Set up 2FA" in response.text
assert "https://auth.wheelytho.com/" in response.text
assert "https://welcome.wheelytho.com/" in response.text