diff --git a/mywebdav/auth.py b/mywebdav/auth.py index 1b2808b..fe9bbc3 100644 --- a/mywebdav/auth.py +++ b/mywebdav/auth.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from typing import Optional from fastapi import Depends, HTTPException, status @@ -39,9 +39,9 @@ async def authenticate_user(username: str, password: str, two_factor_code: Optio def create_access_token(data: dict, expires_delta: Optional[timedelta] = None, two_factor_verified: bool = False): to_encode = data.copy() if expires_delta: - expire = datetime.utcnow() + expires_delta + expire = datetime.now(timezone.utc) + expires_delta else: - expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) + expire = datetime.now(timezone.utc) + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) to_encode.update({"exp": expire, "2fa_verified": two_factor_verified}) encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM) return encoded_jwt diff --git a/mywebdav/billing/invoice_generator.py b/mywebdav/billing/invoice_generator.py index 2e5982d..86a73c0 100644 --- a/mywebdav/billing/invoice_generator.py +++ b/mywebdav/billing/invoice_generator.py @@ -1,4 +1,4 @@ -from datetime import datetime, date, timedelta +from datetime import datetime, date, timedelta, timezone from decimal import Decimal from typing import Optional from calendar import monthrange @@ -182,6 +182,6 @@ The MyWebdav Team @staticmethod async def mark_invoice_paid(invoice: Invoice) -> Invoice: invoice.status = "paid" - invoice.paid_at = datetime.utcnow() + invoice.paid_at = datetime.now(timezone.utc) await invoice.save() return invoice diff --git a/mywebdav/billing/models.py b/mywebdav/billing/models.py index 926430a..40ab5a0 100644 --- a/mywebdav/billing/models.py +++ b/mywebdav/billing/models.py @@ -69,7 +69,7 @@ class Invoice(models.Model): user = fields.ForeignKeyField("models.User", related_name="invoices") invoice_number = fields.CharField(max_length=50, unique=True) stripe_invoice_id = fields.CharField(max_length=255, unique=True, null=True) - period_start = fields.DateField(index=True) + period_start = fields.DateField(db_index=True) period_end = fields.DateField() subtotal = fields.DecimalField(max_digits=10, decimal_places=4) tax = fields.DecimalField(max_digits=10, decimal_places=4, default=0) diff --git a/mywebdav/billing/usage_tracker.py b/mywebdav/billing/usage_tracker.py index 598c57f..f110d29 100644 --- a/mywebdav/billing/usage_tracker.py +++ b/mywebdav/billing/usage_tracker.py @@ -1,5 +1,5 @@ import uuid -from datetime import datetime, date +from datetime import datetime, date, timezone from decimal import Decimal from typing import Optional from tortoise.transactions import in_transaction @@ -15,7 +15,7 @@ class UsageTracker: resource_id: int = None, metadata: dict = None ): - idempotency_key = f"storage_{user.id}_{datetime.utcnow().timestamp()}_{uuid.uuid4().hex[:8]}" + idempotency_key = f"storage_{user.id}_{datetime.now(timezone.utc).timestamp()}_{uuid.uuid4().hex[:8]}" await UsageRecord.create( user=user, @@ -37,7 +37,7 @@ class UsageTracker: metadata: dict = None ): record_type = f"bandwidth_{direction}" - idempotency_key = f"{record_type}_{user.id}_{datetime.utcnow().timestamp()}_{uuid.uuid4().hex[:8]}" + idempotency_key = f"{record_type}_{user.id}_{datetime.now(timezone.utc).timestamp()}_{uuid.uuid4().hex[:8]}" await UsageRecord.create( user=user, diff --git a/mywebdav/main.py b/mywebdav/main.py index 3d0352e..5e7a40d 100644 --- a/mywebdav/main.py +++ b/mywebdav/main.py @@ -86,7 +86,7 @@ async def http_exception_handler(request: Request, exc: HTTPException): logger.error(f"HTTPException: {exc.status_code} - {exc.detail} for URL: {request.url}") return JSONResponse( status_code=exc.status_code, - content=ErrorResponse(code=exc.status_code, message=exc.detail).dict(), + content=ErrorResponse(code=exc.status_code, message=exc.detail).model_dump(), ) diff --git a/mywebdav/schemas.py b/mywebdav/schemas.py index b956f54..9eb52b9 100644 --- a/mywebdav/schemas.py +++ b/mywebdav/schemas.py @@ -1,5 +1,5 @@ from datetime import datetime -from pydantic import BaseModel, EmailStr +from pydantic import BaseModel, EmailStr, ConfigDict from typing import Optional, List from tortoise.contrib.pydantic import pydantic_model_creator @@ -58,8 +58,7 @@ class TeamOut(BaseModel): owner_id: int created_at: datetime - class Config: - from_attributes = True + model_config = ConfigDict(from_attributes=True) class ActivityOut(BaseModel): id: int @@ -70,8 +69,7 @@ class ActivityOut(BaseModel): ip_address: Optional[str] = None timestamp: datetime - class Config: - from_attributes = True + model_config = ConfigDict(from_attributes=True) class FileRequestCreate(BaseModel): title: str @@ -90,8 +88,7 @@ class FileRequestOut(BaseModel): expires_at: Optional[datetime] = None is_active: bool - class Config: - from_attributes = True + model_config = ConfigDict(from_attributes=True) from mywebdav.models import Folder, File, Share, FileVersion diff --git a/tests/conftest.py b/tests/conftest.py index a4997b7..7d6fdc9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,5 @@ import pytest +import pytest_asyncio import asyncio from tortoise import Tortoise @@ -22,7 +23,7 @@ def event_loop(): yield loop loop.close() -@pytest.fixture(scope="session", autouse=True) +@pytest_asyncio.fixture(scope="session", autouse=True) async def cleanup_db(): yield await Tortoise.close_connections()