015c622016
Add 162 integration tests covering authentication flows, TOTP MFA, SSH key/certificate management, organization workflows, multi-org access, self-service features, admin operations, authorization, security edge cases, department/principal management, CA management, policy compliance, WebAuthn passkeys, and ZeroTier network access. Includes: - Reusable API client library with session management - Test fixtures for users, organizations, memberships, and CAs - Helper functions for SSH key generation and verification - Documentation for running and writing tests Also update test configuration to disable conflicting maas plugins and configure WebAuthn/session settings for localhost testing.
88 lines
3.6 KiB
Python
88 lines
3.6 KiB
Python
"""Security and edge-case integration tests.
|
|
|
|
Covers input validation, injection attempts, and boundary conditions.
|
|
"""
|
|
import pytest
|
|
|
|
from tests.integration.client.base import ApiError
|
|
|
|
|
|
class TestInputValidation:
|
|
"""Test input validation and sanitization."""
|
|
|
|
def test_sql_injection_in_registration_email_negative(self, integration_client):
|
|
"""TEST: SEC-01 — SQL injection in registration email.
|
|
|
|
WHAT: POST /auth/register with email containing SQL injection
|
|
payload: "test' OR '1'='1".
|
|
WHY: Email fields must be parameterized; injection attempts
|
|
should fail validation.
|
|
EXPECTED: 400 Bad Request (validation error on malformed email).
|
|
"""
|
|
with pytest.raises(ApiError) as exc_info:
|
|
integration_client.auth.register(
|
|
email="test' OR '1'='1@example.com",
|
|
password="ValidPass123!",
|
|
full_name="SQL Test",
|
|
)
|
|
assert exc_info.value.status_code == 400
|
|
|
|
def test_xss_payload_in_organization_name_negative(self, integration_client, create_test_user):
|
|
"""TEST: SEC-02 — XSS payload in organization name.
|
|
|
|
WHAT: POST /organizations with name containing a script tag.
|
|
WHY: Stored XSS is a critical vulnerability. The name should
|
|
be accepted but safely stored/escaped.
|
|
EXPECTED: 201 Created (the API should accept it; XSS protection
|
|
happens at rendering layer, not storage).
|
|
"""
|
|
user = create_test_user(password="MyPassword123!")
|
|
integration_client.auth.login(email=user["email"], password="MyPassword123!")
|
|
|
|
result = integration_client.orgs.create(
|
|
name="<script>alert('xss')</script>",
|
|
slug="xss-test",
|
|
)
|
|
assert result.get("success") is not False
|
|
|
|
def test_oversized_payload_in_ssh_key_negative(self, integration_client, create_test_user):
|
|
"""TEST: SEC-03 — Oversized payload in SSH key.
|
|
|
|
WHAT: POST /ssh/keys with a very large string as public_key.
|
|
WHY: Large payloads could cause DoS or memory issues.
|
|
EXPECTED: 400 Bad Request.
|
|
"""
|
|
user = create_test_user(password="MyPassword123!")
|
|
integration_client.auth.login(email=user["email"], password="MyPassword123!")
|
|
|
|
with pytest.raises(ApiError) as exc_info:
|
|
integration_client.ssh.add_key("A" * 100000, "Oversized")
|
|
assert exc_info.value.status_code == 400
|
|
|
|
def test_malformed_json_negative(self, integration_client, create_test_user):
|
|
"""TEST: SEC-04 — Malformed JSON in request body.
|
|
|
|
WHAT: POST /auth/register with invalid JSON.
|
|
WHY: The API should handle parse errors gracefully.
|
|
EXPECTED: 400 Bad Request.
|
|
"""
|
|
user = create_test_user(password="MyPassword123!")
|
|
integration_client.auth.login(email=user["email"], password="MyPassword123!")
|
|
|
|
with pytest.raises(ApiError) as exc_info:
|
|
integration_client.post("/auth/register", data={"not": "valid"})
|
|
assert exc_info.value.status_code == 400
|
|
|
|
def test_empty_request_body_negative(self, integration_client, create_test_user):
|
|
"""TEST: SEC-05 — Empty request body where JSON required.
|
|
|
|
WHAT: POST /auth/login with empty body.
|
|
WHY: Endpoints expecting JSON should reject empty bodies.
|
|
EXPECTED: 400 Bad Request.
|
|
"""
|
|
user = create_test_user(password="MyPassword123!")
|
|
|
|
with pytest.raises(ApiError) as exc_info:
|
|
integration_client.post("/auth/login", data={})
|
|
assert exc_info.value.status_code == 400
|