Ver Fonte

refactor: removed IP tracking from audit system and simplified router functions

unknown há 4 horas atrás
pai
commit
001a0cc3b7

+ 9 - 13
backend/routers/auth.py

@@ -26,7 +26,7 @@ except ImportError:
 router = APIRouter(prefix="/auth", tags=["auth"])
 
 @router.post("/register", response_model=schemas.UserResponse)
-async def register(request: Request, user: schemas.UserCreate, lang: str = "en"):
+async def register(user: schemas.UserCreate, lang: str = "en"):
     existing_user = db.execute_query("SELECT id FROM users WHERE email = %s", (user.email,))
     if existing_user:
         raise HTTPException(status_code=400, detail=locales.translate_error("email_already_registered", lang))
@@ -55,8 +55,7 @@ async def register(request: Request, user: schemas.UserCreate, lang: str = "en")
         action="user_register",
         target_type="user",
         target_id=user_id,
-        details={"email": user.email, "ip": ip_address},
-        request=request
+        details={"email": user.email}
     )
     return new_user[0]
 
@@ -72,7 +71,7 @@ async def verify_email(token: str, lang: str = "en"):
     return {"message": "Email verified successfully. You can now log in."}
 
 @router.post("/login", response_model=schemas.Token)
-async def login(request: Request, user_data: schemas.UserLogin, lang: str = "en"):
+async def login(user_data: schemas.UserLogin, lang: str = "en"):
     ip = request.client.host if request.client else "unknown"
     email = user_data.email.lower()
 
@@ -120,13 +119,12 @@ async def login(request: Request, user_data: schemas.UserLogin, lang: str = "en"
         action="user_login",
         target_type="user",
         target_id=user[0]['id'],
-        details={"ip": ip, "method": "credentials"},
-        request=request
+        details={"method": "credentials"}
     )
     return {"access_token": access_token, "token_type": "bearer"}
 
 @router.post("/social-login", response_model=schemas.Token)
-async def social_login(request: Request, data: schemas.SocialLogin):
+async def social_login(data: schemas.SocialLogin):
     email = data.email.lower() if data.email else None
     first_name = data.first_name
     last_name = data.last_name
@@ -293,7 +291,7 @@ async def admin_get_users(page: int = 1, size: int = 50, search: Optional[str] =
     return {"users": users, "total": total, "page": page, "size": size}
 
 @router.post("/admin/users", response_model=schemas.UserResponse)
-async def admin_create_user(request: Request, data: schemas.UserCreate, admin: dict = Depends(require_admin)):
+async def admin_create_user(data: schemas.UserCreate, admin: dict = Depends(require_admin)):
     
     existing_user = db.execute_query("SELECT id FROM users WHERE email = %s", (data.email,))
     if existing_user:
@@ -310,15 +308,14 @@ async def admin_create_user(request: Request, data: schemas.UserCreate, admin: d
         action="admin_create_user",
         target_type="user",
         target_id=user_id,
-        details={"email": data.email, "role": "user"},
-        request=request
+        details={"email": data.email, "role": "user"}
     )
     
     user = db.execute_query("SELECT id, email, first_name, last_name, phone, shipping_address, preferred_language, role, can_chat, is_active, is_company, company_name, company_pib, company_address, ip_address, created_at FROM users WHERE id = %s", (user_id,))
     return user[0]
 
 @router.patch("/users/{target_id}/admin", response_model=schemas.UserResponse)
-async def admin_update_user(request: Request, target_id: int, data: schemas.AdminUserUpdate, admin: dict = Depends(require_admin)):
+async def admin_update_user(target_id: int, data: schemas.AdminUserUpdate, admin: dict = Depends(require_admin)):
     
     update_fields = []
     params = []
@@ -343,8 +340,7 @@ async def admin_update_user(request: Request, target_id: int, data: schemas.Admi
             action="admin_update_user",
             target_type="user",
             target_id=target_id,
-            details={"updated_fields": {k: ('***' if k == 'password_hash' else v) for k, v in update_dict.items()}},
-            request=request
+            details={"updated_fields": {k: ('***' if k == 'password_hash' else v) for k, v in update_dict.items()}}
         )
         
         # If user was deactivated, kick from active sessions

+ 13 - 19
backend/routers/catalog.py

@@ -1,4 +1,4 @@
-from fastapi import APIRouter, Depends, HTTPException, Request
+from fastapi import APIRouter, Depends, HTTPException
 from typing import List, Optional
 import db
 import schemas
@@ -69,7 +69,7 @@ async def admin_get_materials(admin: dict = Depends(require_admin)):
     return materials
 
 @router.post("/admin/materials")
-async def admin_create_material(request: Request, data: schemas.MaterialCreate, admin: dict = Depends(require_admin)):
+async def admin_create_material(data: schemas.MaterialCreate, admin: dict = Depends(require_admin)):
     colors_json = json.dumps(data.available_colors) if data.available_colors else None
     query = "INSERT INTO materials (name_en, name_ru, name_ua, name_me, desc_en, desc_ru, desc_ua, desc_me, long_desc_en, long_desc_ru, long_desc_ua, long_desc_me, price_per_cm3, available_colors, is_active) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
     params = (data.name_en, data.name_ru, data.name_ua, data.name_me, data.desc_en, data.desc_ru, data.desc_ua, data.desc_me, data.long_desc_en, data.long_desc_ru, data.long_desc_ua, data.long_desc_me, data.price_per_cm3, colors_json, data.is_active)
@@ -80,13 +80,12 @@ async def admin_create_material(request: Request, data: schemas.MaterialCreate,
         action="create_material",
         target_type="material",
         target_id=mat_id,
-        details=data.dict(),
-        request=request
+        details=data.dict()
     )
     return {"id": mat_id}
 
 @router.patch("/admin/materials/{mat_id}")
-async def admin_update_material(request: Request, mat_id: int, data: schemas.MaterialUpdate, admin: dict = Depends(require_admin)):
+async def admin_update_material(mat_id: int, data: schemas.MaterialUpdate, admin: dict = Depends(require_admin)):
     update_fields = []
     params = []
     for field, value in data.dict(exclude_unset=True).items():
@@ -105,8 +104,7 @@ async def admin_update_material(request: Request, mat_id: int, data: schemas.Mat
             action="update_material",
             target_type="material",
             target_id=mat_id,
-            details={"updated_fields": data.dict(exclude_unset=True)},
-            request=request
+            details={"updated_fields": data.dict(exclude_unset=True)}
         )
     return {"id": mat_id}
 
@@ -115,7 +113,7 @@ async def admin_get_services(admin: dict = Depends(require_admin)):
     return db.execute_query("SELECT * FROM services ORDER BY id DESC")
 
 @router.post("/admin/services")
-async def admin_create_service(request: Request, data: schemas.ServiceCreate, admin: dict = Depends(require_admin)):
+async def admin_create_service(data: schemas.ServiceCreate, admin: dict = Depends(require_admin)):
     query = "INSERT INTO services (name_en, name_ru, name_ua, name_me, desc_en, desc_ru, desc_ua, desc_me, tech_type, is_active) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
     srv_id = db.execute_commit(query, (data.name_en, data.name_ru, data.name_ua, data.name_me, data.desc_en, data.desc_ru, data.desc_ua, data.desc_me, data.tech_type, data.is_active))
     
@@ -124,13 +122,12 @@ async def admin_create_service(request: Request, data: schemas.ServiceCreate, ad
         action="create_service",
         target_type="service",
         target_id=srv_id,
-        details=data.dict(),
-        request=request
+        details=data.dict()
     )
     return {"id": srv_id}
 
 @router.patch("/admin/services/{srv_id}")
-async def admin_update_service(request: Request, srv_id: int, data: schemas.ServiceUpdate, admin: dict = Depends(require_admin)):
+async def admin_update_service(srv_id: int, data: schemas.ServiceUpdate, admin: dict = Depends(require_admin)):
     update_fields = []
     params = []
     for field, value in data.dict(exclude_unset=True).items():
@@ -149,31 +146,28 @@ async def admin_update_service(request: Request, srv_id: int, data: schemas.Serv
             action="update_service",
             target_type="service",
             target_id=srv_id,
-            details={"updated_fields": data.dict(exclude_unset=True)},
-            request=request
+            details={"updated_fields": data.dict(exclude_unset=True)}
         )
     return {"id": srv_id}
 
 @router.delete("/admin/materials/{mat_id}")
-async def admin_delete_material(request: Request, mat_id: int, admin: dict = Depends(require_admin)):
+async def admin_delete_material(mat_id: int, admin: dict = Depends(require_admin)):
     db.execute_commit("DELETE FROM materials WHERE id = %s", (mat_id,))
     await audit_service.log(
         user_id=admin.get("id"),
         action="delete_material",
         target_type="material",
-        target_id=mat_id,
-        request=request
+        target_id=mat_id
     )
     return {"id": mat_id, "status": "deleted"}
 
 @router.delete("/admin/services/{srv_id}")
-async def admin_delete_service(request: Request, srv_id: int, admin: dict = Depends(require_admin)):
+async def admin_delete_service(srv_id: int, admin: dict = Depends(require_admin)):
     db.execute_commit("DELETE FROM services WHERE id = %s", (srv_id,))
     await audit_service.log(
         user_id=admin.get("id"),
         action="delete_service",
         target_type="service",
-        target_id=srv_id,
-        request=request
+        target_id=srv_id
     )
     return {"id": srv_id, "status": "deleted"}

+ 6 - 14
backend/routers/orders.py

@@ -139,8 +139,7 @@ async def create_order(
                 "mat_id": material_id,
                 "price": float(estimated_price) if estimated_price is not None else 0.0,
                 "quantity": quantity
-            },
-            request=request
+            }
         )
         
         # Record placement for rate limiting
@@ -298,7 +297,6 @@ async def get_admin_orders(
 
 @router.patch("/{order_id}")
 async def update_order(
-    request: Request,
     order_id: int,
     data: schemas.AdminOrderUpdate,
     background_tasks: BackgroundTasks,
@@ -436,8 +434,7 @@ async def update_order(
             action="update_order",
             target_type="order",
             target_id=order_id,
-            details={"updated_fields": {k.split(" = ")[0]: v for k, v in zip(update_fields, params)}},
-            request=request
+            details={"updated_fields": {k.split(" = ")[0]: v for k, v in zip(update_fields, params)}}
         )
         
         # NOTIFY USER VIA WEBSOCKET
@@ -492,7 +489,6 @@ async def admin_attach_file(
 async def admin_delete_file(
     order_id: int,
     file_id: int,
-    request: Request,
     admin: dict = Depends(require_admin)
 ):
         
@@ -517,8 +513,7 @@ async def admin_delete_file(
         action="delete_order_file",
         target_type="order",
         target_id=order_id,
-        details={"file_id": file_id},
-        request=request
+        details={"file_id": file_id}
     )
 
     # NOTIFY USER VIA WEBSOCKET
@@ -539,7 +534,7 @@ async def get_order_items(order_id: int):
     return items
 
 @router.put("/{order_id}/items")
-async def update_order_items(request: Request, order_id: int, items: List[OrderItemSchema], admin: dict = Depends(require_admin)):
+async def update_order_items(order_id: int, items: List[OrderItemSchema], admin: dict = Depends(require_admin)):
     db.execute_commit("DELETE FROM order_items WHERE order_id = %s", (order_id,))
     
     total_order_price = 0
@@ -562,8 +557,7 @@ async def update_order_items(request: Request, order_id: int, items: List[OrderI
         action="update_order_items",
         target_type="order",
         target_id=order_id,
-        details={"total_price": total_order_price, "items": items_summary},
-        request=request
+        details={"total_price": total_order_price, "items": items_summary}
     )
 
     # NOTIFY USER VIA WEBSOCKET
@@ -576,7 +570,6 @@ async def update_order_items(request: Request, order_id: int, items: List[OrderI
 @router.delete("/{order_id}/admin")
 async def delete_order_admin(
     order_id: int,
-    request: Request,
     admin: dict = Depends(require_admin)
 ):
     # Fetch user_id before deletion to notify later
@@ -625,8 +618,7 @@ async def delete_order_admin(
             action="delete_order_entirely",
             target_type="order",
             target_id=order_id,
-            details={"order_id": order_id},
-            request=request
+            details={"order_id": order_id}
         )
 
         # NOTIFY USER VIA WEBSOCKET

+ 6 - 10
backend/routers/portfolio.py

@@ -1,4 +1,4 @@
-from fastapi import APIRouter, Depends, HTTPException, Form, UploadFile, File, Request
+from fastapi import APIRouter, Depends, HTTPException, Form, UploadFile, File
 import db
 import schemas
 import auth_utils
@@ -37,7 +37,6 @@ async def admin_get_all_photos(admin: dict = Depends(require_admin)):
 
 @router.post("/admin/orders/{order_id}/photos")
 async def admin_upload_order_photo(
-    request: Request,
     order_id: int, 
     is_public: bool = Form(False),
     file: UploadFile = File(...), 
@@ -63,8 +62,7 @@ async def admin_upload_order_photo(
         action="upload_order_photo",
         target_type="order",
         target_id=order_id,
-        details={"photo_id": photo_id, "is_public": is_public},
-        request=request
+        details={"photo_id": photo_id, "is_public": is_public}
     )
 
     # NOTIFY USER VIA WEBSOCKET
@@ -75,7 +73,7 @@ async def admin_upload_order_photo(
     return {"id": photo_id, "file_path": db_file_path, "is_public": is_public}
 
 @router.patch("/admin/photos/{photo_id}")
-async def admin_update_photo_status(request: Request, photo_id: int, data: schemas.PhotoUpdate, admin: dict = Depends(require_admin)):
+async def admin_update_photo_status(photo_id: int, data: schemas.PhotoUpdate, admin: dict = Depends(require_admin)):
     query = "SELECT p.*, o.allow_portfolio FROM order_photos p JOIN orders o ON p.order_id = o.id WHERE p.id = %s"
     photo_data = db.execute_query(query, (photo_id,))
     if not photo_data: raise HTTPException(status_code=404, detail="Photo not found")
@@ -88,8 +86,7 @@ async def admin_update_photo_status(request: Request, photo_id: int, data: schem
         action="update_photo_visibility",
         target_type="photo",
         target_id=photo_id,
-        details={"is_public": data.is_public},
-        request=request
+        details={"is_public": data.is_public}
     )
 
     # NOTIFY USER VIA WEBSOCKET
@@ -101,7 +98,7 @@ async def admin_update_photo_status(request: Request, photo_id: int, data: schem
     return {"id": photo_id, "is_public": data.is_public}
 
 @router.delete("/admin/photos/{photo_id}")
-async def admin_delete_photo(request: Request, photo_id: int, admin: dict = Depends(require_admin)):
+async def admin_delete_photo(photo_id: int, admin: dict = Depends(require_admin)):
     photo = db.execute_query("SELECT file_path, order_id FROM order_photos WHERE id = %s", (photo_id,))
     if not photo:
         raise HTTPException(status_code=404, detail="Photo not found")
@@ -122,8 +119,7 @@ async def admin_delete_photo(request: Request, photo_id: int, admin: dict = Depe
         action="delete_photo",
         target_type="photo",
         target_id=photo_id,
-        details={"order_id": order_id},
-        request=request
+        details={"order_id": order_id}
     )
 
     # NOTIFY USER VIA WEBSOCKET

+ 4 - 10
backend/routers/warehouse.py

@@ -1,4 +1,4 @@
-from fastapi import APIRouter, Depends, HTTPException, Query, Request
+from fastapi import APIRouter, Depends, HTTPException, Query
 from typing import List, Optional
 import db
 import schemas
@@ -57,7 +57,6 @@ async def get_warehouse_stock(
 
 @router.post("/stock", response_model=dict)
 async def add_stock_item(
-    request: Request,
     data: schemas.WarehouseItemCreate,
     admin: dict = Depends(require_admin)
 ):
@@ -82,8 +81,7 @@ async def add_stock_item(
             "color": data.color_name,
             "quantity": data.quantity,
             "units_count": data.units_count
-        },
-        request=request
+        }
     )
         
     return {"id": item_id, "message": "Stock item added successfully"}
@@ -91,7 +89,6 @@ async def add_stock_item(
 @router.patch("/stock/{item_id}", response_model=dict)
 async def update_stock_item(
     item_id: int,
-    request: Request,
     data: schemas.WarehouseItemUpdate,
     admin: dict = Depends(require_admin)
 ):
@@ -131,8 +128,7 @@ async def update_stock_item(
         action="warehouse_update_item",
         target_type="warehouse_stock",
         target_id=item_id,
-        details=data.model_dump(exclude_unset=True),
-        request=request
+        details=data.model_dump(exclude_unset=True)
     )
     
     return {"message": "Stock item updated successfully"}
@@ -140,7 +136,6 @@ async def update_stock_item(
 @router.delete("/stock/{item_id}", response_model=dict)
 async def delete_stock_item(
     item_id: int,
-    request: Request,
     admin: dict = Depends(require_admin)
 ):
     # Fetch item before deleting for logs
@@ -155,8 +150,7 @@ async def delete_stock_item(
             action="warehouse_delete_item",
             target_type="warehouse_stock",
             target_id=item_id,
-            details=item[0],
-            request=request
+            details=item[0]
         )
 
     return {"message": "Stock item deleted successfully"}

+ 4 - 10
backend/services/audit_service.py

@@ -2,7 +2,6 @@ import db
 import json
 import redis
 import config
-from fastapi import Request
 from typing import Optional, Any
 
 class AuditService:
@@ -58,13 +57,8 @@ class AuditService:
         action: str, 
         target_type: Optional[str] = None, 
         target_id: Optional[int] = None, 
-        details: Optional[Any] = None,
-        request: Optional[Request] = None
+        details: Optional[Any] = None
     ):
-        ip_address = None
-        if request:
-            ip_address = request.headers.get("X-Forwarded-For", request.client.host if request.client else None)
-        
         details_str = None
         if details:
             if isinstance(details, (dict, list)):
@@ -79,10 +73,10 @@ class AuditService:
         
         # 1. Save to DB
         query = """
-            INSERT INTO audit_logs (user_id, action, target_type, target_id, details, ip_address)
-            VALUES (%s, %s, %s, %s, %s, %s)
+            INSERT INTO audit_logs (user_id, action, target_type, target_id, details)
+            VALUES (%s, %s, %s, %s, %s)
         """
-        db.execute_commit(query, (user_id, action, target_type, target_id, details_str, ip_address))
+        db.execute_commit(query, (user_id, action, target_type, target_id, details_str))
 
         # 2. Push to Telegram Queue if CHAT_ID is configured
         if config.TELEGRAM_CHAT_ID and self.redis_client: