Skip to content

Commit d13a5de

Browse files
File extension checker (#77)
1 parent 9d15982 commit d13a5de

4 files changed

Lines changed: 18 additions & 2 deletions

File tree

calendar_backend/methods/utils.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
import os
33
import random
44
import string
5+
from typing import Final
56

67
import aiofiles
7-
from fastapi import File, UploadFile
8+
from fastapi import File, UploadFile, HTTPException
89
from sqlalchemy.orm import Session
910

1011
from calendar_backend.models.db import (
@@ -68,11 +69,14 @@ async def get_lecturer_lessons_in_daterange(
6869
events_list.append(lesson)
6970
return events_list
7071

72+
SUPPORTED_FILE_EXTENSIONS: Final[list[str]] = ['png', 'svg', 'jpg', 'jpeg']
7173

7274
async def upload_lecturer_photo(lecturer_id: int, session: Session, file: UploadFile = File(...)) -> Photo:
7375
lecturer = Lecturer.get(lecturer_id, session=session)
7476
random_string = ''.join(random.choice(string.ascii_letters) for _ in range(32))
7577
ext = file.filename.split('.')[-1]
78+
if ext not in SUPPORTED_FILE_EXTENSIONS:
79+
raise HTTPException(status_code=422, detail="Unsupported file extension")
7680
path = os.path.join(settings.STATIC_PATH, "photo", "lecturer", f"{random_string}.{ext}")
7781
async with aiofiles.open(path, 'wb') as out_file:
7882
content = await file.read()

tests/conftest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ def photo_path(client_auth: TestClient, dbsession: Session, lecturer_path: str):
101101
dbsession.commit()
102102

103103

104+
105+
104106
@pytest.fixture()
105107
def event_path(client_auth: TestClient, dbsession: Session, lecturer_path, room_path, group_path):
106108
RESOURCE = f"/timetable/event/"

tests/lecturer/photo.notpng

21.7 KB
Binary file not shown.

tests/lecturer/photos.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import os
2+
13
from fastapi.testclient import TestClient
24
from starlette import status
3-
from calendar_backend.settings import get_settings
45

6+
from calendar_backend.settings import get_settings
57

68
settings = get_settings()
79
settings.STATIC_PATH = './static'
@@ -25,3 +27,11 @@ def test_delete(client_auth: TestClient, photo_path: str):
2527

2628
response = client_auth.get(photo_path)
2729
assert response.status_code == status.HTTP_404_NOT_FOUND
30+
31+
32+
def test_unsupported_format(lecturer_path: str, client_auth: TestClient):
33+
RESOURCE = f"{lecturer_path}/photo"
34+
with open(os.path.dirname(__file__) + "/photo.notpng", "rb") as f:
35+
response = client_auth.post(RESOURCE, files={"photo": f})
36+
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
37+

0 commit comments

Comments
 (0)