From aeb805e9758c9de1f331e7b8090708f6e0a9cec0 Mon Sep 17 00:00:00 2001 From: Mondo Diaz Date: Tue, 27 Jan 2026 19:15:18 +0000 Subject: [PATCH] Make auth tests use configurable admin password - Add get_admin_password() and get_admin_username() helpers to conftest.py - Update test_auth_api.py to use helpers instead of hardcoded credentials - Allows tests to work with different passwords in feature/stage/prod envs The ORCHARD_TEST_PASSWORD environment variable is set by CI jobs to match the deployed environment's admin password. --- backend/tests/conftest.py | 20 ++++++++ backend/tests/integration/test_auth_api.py | 56 +++++++++++----------- 2 files changed, 49 insertions(+), 27 deletions(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 71fb905..fb11398 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -56,6 +56,26 @@ os.environ.setdefault("ORCHARD_S3_BUCKET", "test-bucket") os.environ.setdefault("ORCHARD_S3_ACCESS_KEY_ID", "test") os.environ.setdefault("ORCHARD_S3_SECRET_ACCESS_KEY", "test") + +# ============================================================================= +# Admin Credentials Helper +# ============================================================================= + + +def get_admin_password() -> str: + """Get the admin password for test authentication. + + Returns the password from ORCHARD_TEST_PASSWORD environment variable, + or 'changeme123' as the default for local development. + """ + return os.environ.get("ORCHARD_TEST_PASSWORD", "changeme123") + + +def get_admin_username() -> str: + """Get the admin username for test authentication.""" + return os.environ.get("ORCHARD_TEST_USERNAME", "admin") + + # Re-export factory functions for backward compatibility from tests.factories import ( create_test_file, diff --git a/backend/tests/integration/test_auth_api.py b/backend/tests/integration/test_auth_api.py index 13e5259..7b65bf5 100644 --- a/backend/tests/integration/test_auth_api.py +++ b/backend/tests/integration/test_auth_api.py @@ -8,6 +8,8 @@ allow these tests to run. Production uses strict rate limits (5/minute). import pytest from uuid import uuid4 +from tests.conftest import get_admin_password, get_admin_username + # Mark all tests in this module as auth_intensive (informational, not excluded from CI) pytestmark = pytest.mark.auth_intensive @@ -21,11 +23,11 @@ class TestAuthLogin: """Test successful login with default admin credentials.""" response = auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) assert response.status_code == 200 data = response.json() - assert data["username"] == "admin" + assert data["username"] == get_admin_username() assert data["is_admin"] is True assert "orchard_session" in response.cookies @@ -34,7 +36,7 @@ class TestAuthLogin: """Test login with wrong password.""" response = auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "wrongpassword"}, + json={"username": get_admin_username(), "password": "wrongpassword"}, ) assert response.status_code == 401 assert "Invalid username or password" in response.json()["detail"] @@ -58,7 +60,7 @@ class TestAuthLogout: # First login login_response = auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) assert login_response.status_code == 200 @@ -84,13 +86,13 @@ class TestAuthMe: # Login first auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) response = auth_client.get("/api/v1/auth/me") assert response.status_code == 200 data = response.json() - assert data["username"] == "admin" + assert data["username"] == get_admin_username() assert data["is_admin"] is True assert "id" in data assert "created_at" in data @@ -119,7 +121,7 @@ class TestAuthChangePassword: # Login as admin to create a test user auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) test_username = f"pwchange_{uuid4().hex[:8]}" auth_client.post( @@ -162,7 +164,7 @@ class TestAuthChangePassword: # Login as admin to create a test user auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) test_username = f"pwwrong_{uuid4().hex[:8]}" auth_client.post( @@ -194,7 +196,7 @@ class TestAPIKeys: # Login first auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) # Create API key @@ -226,7 +228,7 @@ class TestAPIKeys: # Login and create API key auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) create_response = auth_client.post( "/api/v1/auth/keys", @@ -242,12 +244,12 @@ class TestAPIKeys: headers={"Authorization": f"Bearer {api_key}"}, ) assert response.status_code == 200 - assert response.json()["username"] == "admin" + assert response.json()["username"] == get_admin_username() # Clean up auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) auth_client.delete(f"/api/v1/auth/keys/{key_id}") @@ -257,7 +259,7 @@ class TestAPIKeys: # Login and create API key auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) create_response = auth_client.post( "/api/v1/auth/keys", @@ -288,14 +290,14 @@ class TestAdminUserManagement: # Login as admin auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) response = auth_client.get("/api/v1/admin/users") assert response.status_code == 200 users = response.json() assert len(users) >= 1 - assert any(u["username"] == "admin" for u in users) + assert any(u["username"] == get_admin_username() for u in users) @pytest.mark.integration def test_create_user(self, auth_client): @@ -303,7 +305,7 @@ class TestAdminUserManagement: # Login as admin auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) # Create new user @@ -336,7 +338,7 @@ class TestAdminUserManagement: # Login as admin auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) # Create a test user @@ -362,7 +364,7 @@ class TestAdminUserManagement: # Login as admin auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) # Create a test user @@ -393,7 +395,7 @@ class TestAdminUserManagement: # Login as admin and create non-admin user auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) test_username = f"nonadmin_{uuid4().hex[:8]}" auth_client.post( @@ -423,7 +425,7 @@ class TestSecurityEdgeCases: # Login as admin and create a user auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) test_username = f"inactive_{uuid4().hex[:8]}" auth_client.post( @@ -451,7 +453,7 @@ class TestSecurityEdgeCases: """Test that short passwords are rejected when creating users.""" auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) response = auth_client.post( @@ -467,7 +469,7 @@ class TestSecurityEdgeCases: # Create test user auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) test_username = f"shortchange_{uuid4().hex[:8]}" auth_client.post( @@ -494,7 +496,7 @@ class TestSecurityEdgeCases: """Test that short passwords are rejected when resetting password.""" auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) # Create a test user first @@ -516,7 +518,7 @@ class TestSecurityEdgeCases: """Test that duplicate usernames are rejected.""" auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) test_username = f"duplicate_{uuid4().hex[:8]}" @@ -541,7 +543,7 @@ class TestSecurityEdgeCases: # Login as admin and create an API key auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) create_response = auth_client.post( "/api/v1/auth/keys", @@ -572,7 +574,7 @@ class TestSecurityEdgeCases: auth_client.cookies.clear() auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) auth_client.delete(f"/api/v1/auth/keys/{admin_key_id}") @@ -582,7 +584,7 @@ class TestSecurityEdgeCases: # Create a test user auth_client.post( "/api/v1/auth/login", - json={"username": "admin", "password": "changeme123"}, + json={"username": get_admin_username(), "password": get_admin_password()}, ) test_username = f"sessiontest_{uuid4().hex[:8]}" auth_client.post(