cors fixes

This commit is contained in:
2026-06-16 17:50:36 +05:30
parent 85aac955ac
commit d4b64d630a
8 changed files with 18 additions and 97 deletions

View File

@@ -26,7 +26,6 @@ Example:
""" """
from openapi_first.app import OpenAPIFirstApp from openapi_first.app import OpenAPIFirstApp
from starlette_csrf import CSRFMiddleware
import routes import routes
app = OpenAPIFirstApp( app = OpenAPIFirstApp(
@@ -34,13 +33,3 @@ app = OpenAPIFirstApp(
routes_module=routes, routes_module=routes,
title="CRUD Example Service", title="CRUD Example Service",
) )
app.add_middleware(
CSRFMiddleware,
secret="change-me-in-production",
cookie_name="csrftoken",
header_name="x-csrftoken",
cookie_secure=False,
cookie_httponly=False,
cookie_samesite="lax",
)

View File

@@ -34,14 +34,6 @@ client = OpenAPIClient(
client=client, client=client,
) )
# Bootstrap CSRF token via a safe GET request
_ = client.list_items()
_CSRF_TOKEN = client.client.cookies.get("csrftoken")
def _csrf_headers() -> dict:
return {"X-CSRFToken": _CSRF_TOKEN} if _CSRF_TOKEN else {}
def test_list_items_initial(): def test_list_items_initial():
"""Initial items should be present.""" """Initial items should be present."""
@@ -79,7 +71,6 @@ def test_create_item():
response = client.create_item( response = client.create_item(
body=payload, body=payload,
headers=_csrf_headers(),
) )
assert response.status_code == 201 assert response.status_code == 201
@@ -104,7 +95,6 @@ def test_update_item():
response = client.update_item( response = client.update_item(
path_params={"item_id": 1}, path_params={"item_id": 1},
body=payload, body=payload,
headers=_csrf_headers(),
) )
assert response.status_code == 200 assert response.status_code == 200
@@ -126,7 +116,6 @@ def test_delete_item():
"""Deleting an item should remove it from the store.""" """Deleting an item should remove it from the store."""
response = client.delete_item( response = client.delete_item(
path_params={"item_id": 2}, path_params={"item_id": 2},
headers=_csrf_headers(),
) )
assert response.status_code == 204 assert response.status_code == 204

View File

@@ -27,7 +27,6 @@ Example:
from openapi_first.app import OpenAPIFirstApp from openapi_first.app import OpenAPIFirstApp
from starlette_csrf import CSRFMiddleware
import routes import routes
app = OpenAPIFirstApp( app = OpenAPIFirstApp(
@@ -35,13 +34,3 @@ app = OpenAPIFirstApp(
routes_module=routes, routes_module=routes,
title="Health Check Service", title="Health Check Service",
) )
app.add_middleware(
CSRFMiddleware,
secret="change-me-in-production",
cookie_name="csrftoken",
header_name="x-csrftoken",
cookie_secure=False,
cookie_httponly=False,
cookie_samesite="lax",
)

View File

@@ -26,7 +26,6 @@ Example:
""" """
from openapi_first.app import OpenAPIFirstApp from openapi_first.app import OpenAPIFirstApp
from starlette_csrf import CSRFMiddleware
import routes import routes
app = OpenAPIFirstApp( app = OpenAPIFirstApp(
@@ -34,13 +33,3 @@ app = OpenAPIFirstApp(
routes_module=routes, routes_module=routes,
title="Model CRUD Example Service", title="Model CRUD Example Service",
) )
app.add_middleware(
CSRFMiddleware,
secret="change-me-in-production",
cookie_name="csrftoken",
header_name="x-csrftoken",
cookie_secure=False,
cookie_httponly=False,
cookie_samesite="lax",
)

View File

@@ -33,14 +33,6 @@ client = OpenAPIClient(
client=client, client=client,
) )
# Bootstrap CSRF token via a safe GET request
_ = client.list_items()
_CSRF_TOKEN = client.client.cookies.get("csrftoken")
def _csrf_headers() -> dict:
return {"X-CSRFToken": _CSRF_TOKEN} if _CSRF_TOKEN else {}
def test_list_items_initial(): def test_list_items_initial():
"""Initial items should be present.""" """Initial items should be present."""
@@ -78,7 +70,6 @@ def test_create_item():
response = client.create_item( response = client.create_item(
body=payload, body=payload,
headers=_csrf_headers(),
) )
assert response.status_code == 201 assert response.status_code == 201
@@ -103,7 +94,6 @@ def test_update_item():
response = client.update_item( response = client.update_item(
path_params={"item_id": 1}, path_params={"item_id": 1},
body=payload, body=payload,
headers=_csrf_headers(),
) )
assert response.status_code == 200 assert response.status_code == 200
@@ -125,7 +115,6 @@ def test_delete_item():
"""Deleting an item should remove it from the store.""" """Deleting an item should remove it from the store."""
response = client.delete_item( response = client.delete_item(
path_params={"item_id": 2}, path_params={"item_id": 2},
headers=_csrf_headers(),
) )
assert response.status_code == 204 assert response.status_code == 204

View File

@@ -28,7 +28,6 @@ Example:
from starlette.middleware.cors import CORSMiddleware from starlette.middleware.cors import CORSMiddleware
from openapi_first.app import OpenAPIFirstApp from openapi_first.app import OpenAPIFirstApp
from starlette_csrf import CSRFMiddleware
import routes import routes
app = OpenAPIFirstApp( app = OpenAPIFirstApp(
@@ -37,20 +36,9 @@ app = OpenAPIFirstApp(
title="Veterinary Clinic Service", title="Veterinary Clinic Service",
) )
app.add_middleware(
CSRFMiddleware,
secret="change-me-in-production",
cookie_name="csrftoken",
header_name="x-csrftoken",
cookie_secure=False,
cookie_httponly=False,
cookie_samesite="none",
)
app.add_middleware( app.add_middleware(
CORSMiddleware, CORSMiddleware,
allow_origins=["*"], allow_origins=["http://localhost:5173"],
allow_credentials=True,
allow_methods=["*"], allow_methods=["*"],
allow_headers=["*"], allow_headers=["*"],
) )

View File

@@ -20,14 +20,6 @@ client = OpenAPIClient(
client=test_client, client=test_client,
) )
# Bootstrap CSRF token via a safe GET request
_ = client.list_parents(query={"limit": 1})
_CSRF_TOKEN = client.client.cookies.get("csrftoken")
def _csrf_headers() -> dict:
return {"X-CSRFToken": _CSRF_TOKEN} if _CSRF_TOKEN else {}
def test_list_parents(): def test_list_parents():
"""List parents returns paginated response.""" """List parents returns paginated response."""
@@ -41,7 +33,7 @@ def test_list_parents():
def test_create_parent(): def test_create_parent():
"""Creating a parent returns 201 with the created entity.""" """Creating a parent returns 201 with the created entity."""
payload = {"name": "Alice", "email": "alice@example.com"} payload = {"name": "Alice", "email": "alice@example.com"}
response = client.create_parent(body=payload, headers=_csrf_headers()) response = client.create_parent(body=payload)
assert response.status_code == 201 assert response.status_code == 201
parent = response.json() parent = response.json()
assert parent["name"] == "Alice" assert parent["name"] == "Alice"
@@ -50,7 +42,7 @@ def test_create_parent():
def test_get_parent(): def test_get_parent():
"""Get parent by ID returns the entity.""" """Get parent by ID returns the entity."""
parent = client.create_parent(body={"name": "Bob", "email": "bob@example.com"}, headers=_csrf_headers()).json() parent = client.create_parent(body={"name": "Bob", "email": "bob@example.com"}).json()
response = client.get_parent(path_params={"id": parent["id"]}) response = client.get_parent(path_params={"id": parent["id"]})
assert response.status_code == 200 assert response.status_code == 200
assert response.json()["name"] == "Bob" assert response.json()["name"] == "Bob"
@@ -58,17 +50,17 @@ def test_get_parent():
def test_update_parent(): def test_update_parent():
"""Update parent replaces its values.""" """Update parent replaces its values."""
parent = client.create_parent(body={"name": "Carol", "email": "carol@example.com"}, headers=_csrf_headers()).json() parent = client.create_parent(body={"name": "Carol", "email": "carol@example.com"}).json()
payload = {"name": "Carol Smith", "email": "carol.smith@example.com"} payload = {"name": "Carol Smith", "email": "carol.smith@example.com"}
response = client.update_parent(path_params={"id": parent["id"]}, body=payload, headers=_csrf_headers()) response = client.update_parent(path_params={"id": parent["id"]}, body=payload)
assert response.status_code == 200 assert response.status_code == 200
assert response.json()["name"] == "Carol Smith" assert response.json()["name"] == "Carol Smith"
def test_delete_parent(): def test_delete_parent():
"""Delete parent returns 204 and removes the entity.""" """Delete parent returns 204 and removes the entity."""
parent = client.create_parent(body={"name": "Dave", "email": "dave@example.com"}, headers=_csrf_headers()).json() parent = client.create_parent(body={"name": "Dave", "email": "dave@example.com"}).json()
response = client.delete_parent(path_params={"id": parent["id"]}, headers=_csrf_headers()) response = client.delete_parent(path_params={"id": parent["id"]})
assert response.status_code == 204 assert response.status_code == 204
@@ -84,7 +76,7 @@ def test_list_vets():
def test_create_vet(): def test_create_vet():
"""Creating a vet returns 201.""" """Creating a vet returns 201."""
payload = {"name": "Dr. Smith", "specialty": "Surgery", "email": "smith@clinic.com"} payload = {"name": "Dr. Smith", "specialty": "Surgery", "email": "smith@clinic.com"}
response = client.create_vet(body=payload, headers=_csrf_headers()) response = client.create_vet(body=payload)
assert response.status_code == 201 assert response.status_code == 201
assert response.json()["name"] == "Dr. Smith" assert response.json()["name"] == "Dr. Smith"
@@ -99,27 +91,26 @@ def test_list_treatments():
def test_create_treatment(): def test_create_treatment():
"""Creating a treatment returns 201.""" """Creating a treatment returns 201."""
payload = {"label": "Vaccination", "description": "Annual vaccination"} payload = {"label": "Vaccination", "description": "Annual vaccination"}
response = client.create_treatment(body=payload, headers=_csrf_headers()) response = client.create_treatment(body=payload)
assert response.status_code == 201 assert response.status_code == 201
assert response.json()["label"] == "Vaccination" assert response.json()["label"] == "Vaccination"
def test_create_pet(): def test_create_pet():
"""Creating a pet links FK references.""" """Creating a pet links FK references."""
parent = client.create_parent(body={"name": "Owner", "email": "owner@example.com"}, headers=_csrf_headers()).json() parent = client.create_parent(body={"name": "Owner", "email": "owner@example.com"}).json()
payload = {"name": "Fido", "species": "dog", "parent_ids": [parent["id"]]} payload = {"name": "Fido", "species": "dog", "parent_ids": [parent["id"]]}
response = client.create_pet(body=payload, headers=_csrf_headers()) response = client.create_pet(body=payload)
assert response.status_code == 201 assert response.status_code == 201
assert response.json()["name"] == "Fido" assert response.json()["name"] == "Fido"
def test_upload_pet_photo(): def test_upload_pet_photo():
"""Upload pet photo returns 200.""" """Upload pet photo returns 200."""
pet = client.create_pet(body={"name": "PhotoPet", "species": "cat", "parent_ids": []}, headers=_csrf_headers()).json() pet = client.create_pet(body={"name": "PhotoPet", "species": "cat", "parent_ids": []}).json()
response = client.client.post( response = client.client.post(
f"http://testserver/pets/{pet['id']}", f"http://testserver/pets/{pet['id']}",
files={"file": ("test.jpg", b"fake-image-data", "image/jpeg")}, files={"file": ("test.jpg", b"fake-image-data", "image/jpeg")},
headers=_csrf_headers(),
) )
assert response.status_code == 200 assert response.status_code == 200
@@ -135,10 +126,10 @@ def test_list_appointments():
def test_full_appointment_lifecycle(): def test_full_appointment_lifecycle():
"""Create a parent, vet, treatment, pet, then an appointment.""" """Create a parent, vet, treatment, pet, then an appointment."""
parent = client.create_parent(body={"name": "Eve", "email": "eve@example.com"}, headers=_csrf_headers()).json() parent = client.create_parent(body={"name": "Eve", "email": "eve@example.com"}).json()
vet = client.create_vet(body={"name": "Dr. Jones", "specialty": "Dentistry", "email": "jones@clinic.com"}, headers=_csrf_headers()).json() vet = client.create_vet(body={"name": "Dr. Jones", "specialty": "Dentistry", "email": "jones@clinic.com"}).json()
treatment = client.create_treatment(body={"label": "Cleaning", "description": "Teeth cleaning"}, headers=_csrf_headers()).json() treatment = client.create_treatment(body={"label": "Cleaning", "description": "Teeth cleaning"}).json()
pet = client.create_pet(body={"name": "Max", "species": "dog", "parent_ids": [parent["id"]]}, headers=_csrf_headers()).json() pet = client.create_pet(body={"name": "Max", "species": "dog", "parent_ids": [parent["id"]]}).json()
payload = { payload = {
"date": "2025-06-01T10:00:00", "date": "2025-06-01T10:00:00",
@@ -146,7 +137,7 @@ def test_full_appointment_lifecycle():
"vet_id": vet["id"], "vet_id": vet["id"],
"treatment_id": treatment["id"], "treatment_id": treatment["id"],
} }
response = client.create_appointment(body=payload, headers=_csrf_headers()) response = client.create_appointment(body=payload)
assert response.status_code == 201 assert response.status_code == 201
appointment = response.json() appointment = response.json()
assert appointment["pet_id"] == pet["id"] assert appointment["pet_id"] == pet["id"]
@@ -156,5 +147,5 @@ def test_full_appointment_lifecycle():
assert get_resp.status_code == 200 assert get_resp.status_code == 200
# Delete it # Delete it
del_resp = client.delete_appointment(path_params={"id": appointment["id"]}, headers=_csrf_headers()) del_resp = client.delete_appointment(path_params={"id": appointment["id"]})
assert del_resp.status_code == 204 assert del_resp.status_code == 204

View File

@@ -55,9 +55,6 @@ dependencies = [
# Code generation # Code generation
"datamodel-code-generator>=0.25.0", "datamodel-code-generator>=0.25.0",
# CSRF protection (scaffolded apps)
"starlette-csrf>=3.0.0",
] ]
[project.scripts] [project.scripts]