1
0
mirror of https://gitlab.com/MoonTestUse1/AdministrationItDepartmens.git synced 2025-08-14 00:25:46 +02:00

Testing workable

This commit is contained in:
MoonTestUse1
2025-02-07 00:43:33 +06:00
parent 8543d7fe88
commit 6db95a5eb0
37 changed files with 911 additions and 454 deletions

View File

@@ -3,10 +3,10 @@ from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from passlib.context import CryptContext
from sqlalchemy.orm import Session
import re
from .jwt import verify_token
from ..database import get_db
from ..crud import employees
from ..models.employee import Employee
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@@ -34,20 +34,16 @@ def get_current_admin(
try:
token = credentials.credentials
token_data = verify_token(token, db)
if not token_data:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication credentials",
headers={"WWW-Authenticate": "Bearer"},
)
payload = verify_token(token, db)
employee_id = int(payload.get("sub"))
# Проверяем, что это админ
employee = employees.get_employee(db, token_data.employee_id)
# Получаем сотрудника из БД
from ..crud.employees import get_employee
employee = get_employee(db, employee_id)
if not employee or not employee.is_admin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Not enough permissions",
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
@@ -55,7 +51,7 @@ def get_current_admin(
except Exception:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication credentials",
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
@@ -73,20 +69,16 @@ def get_current_employee(
try:
token = credentials.credentials
token_data = verify_token(token, db)
if not token_data:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication credentials",
headers={"WWW-Authenticate": "Bearer"},
)
payload = verify_token(token, db)
employee_id = int(payload.get("sub"))
# Проверяем существование сотрудника
employee = employees.get_employee(db, token_data.employee_id)
# Получаем сотрудника из БД
from ..crud.employees import get_employee
employee = get_employee(db, employee_id)
if not employee:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Employee not found",
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
@@ -94,6 +86,6 @@ def get_current_employee(
except Exception:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication credentials",
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)

View File

@@ -1,67 +1,82 @@
"""JWT utilities"""
from datetime import datetime, timedelta
from jose import JWTError, jwt
from sqlalchemy.orm import Session
from typing import Optional
from jose import JWTError, jwt
from fastapi import HTTPException, status
from redis import Redis
from sqlalchemy.orm import Session
from ..core.config import settings
from ..core.test_config import test_settings
from ..models.token import Token
from ..schemas.auth import TokenData
from ..crud.employees import get_employee
def get_settings():
"""Get settings based on environment"""
return test_settings if test_settings.TESTING else settings
redis = Redis(
host=settings.REDIS_HOST,
port=settings.REDIS_PORT,
decode_responses=True
)
def create_access_token(data: dict) -> str:
"""Create access token"""
to_encode = data.copy()
config = get_settings()
expire = datetime.utcnow() + timedelta(minutes=config.ACCESS_TOKEN_EXPIRE_MINUTES)
expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, config.SECRET_KEY, algorithm=config.ALGORITHM)
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
return encoded_jwt
def verify_token(token: str) -> Optional[int]:
"""Verify token and return employee_id"""
def verify_token(token: str, db: Session) -> dict:
try:
config = get_settings()
payload = jwt.decode(token, config.SECRET_KEY, algorithms=[config.ALGORITHM])
employee_id = int(payload.get("sub"))
if employee_id is None:
return None
return employee_id
except (JWTError, ValueError):
return None
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
user_id: int = payload.get("sub")
if user_id is None:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
)
# Проверяем токен в Redis
if not redis.get(f"token:{token}"):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
)
return payload
except JWTError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
)
def verify_token_in_db(token: str, db: Session) -> Optional[TokenData]:
"""Verify token in database"""
employee_id = verify_token(token)
if employee_id is None:
return None
# Проверяем, что токен существует в базе
db_token = db.query(Token).filter(Token.token == token).first()
if not db_token:
return None
return TokenData(employee_id=employee_id)
def create_and_save_token(employee_id: int, db: Session) -> str:
"""Create and save token"""
# Создаем токен
access_token = create_access_token({"sub": str(employee_id)})
def create_and_save_token(user_id: int, db: Session) -> str:
# Создаем JWT токен
access_token = create_access_token({"sub": str(user_id)})
# Удаляем старые токены пользователя
db.query(Token).filter(Token.employee_id == employee_id).delete()
# Сохраняем новый токен в базу
# Сохраняем в БД
db_token = Token(
token=access_token,
employee_id=employee_id
user_id=user_id
)
db.add(db_token)
db.commit()
db.refresh(db_token)
return access_token
# Кэшируем в Redis
redis.setex(
f"token:{access_token}",
timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES),
"valid"
)
return access_token
def get_current_employee(token: str, db: Session):
payload = verify_token(token, db)
employee_id = int(payload.get("sub"))
if employee_id == -1: # Для админа
return {"is_admin": True}
employee = get_employee(db, employee_id)
if employee is None:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Employee not found",
)
return employee

View File

@@ -3,17 +3,20 @@ from aiogram import Bot
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
import asyncio
from datetime import datetime
import os
from logging import getLogger
from ..models.request import RequestStatus, RequestPriority
from ..crud import requests
from ..database import get_db
from ..core.config import settings
# Initialize logger
logger = getLogger(__name__)
# Initialize bot with token from settings
bot = Bot(token=settings.TELEGRAM_BOT_TOKEN)
# Initialize bot with token
TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN", "7677506032:AAHduD5EePz3bE23DKlo35KoOp2_9lZuS34")
TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID", "5057752127")
bot = Bot(token=TELEGRAM_BOT_TOKEN)
def format_priority(priority: str) -> str:
"""Format priority with emoji"""
@@ -56,7 +59,7 @@ async def send_request_notification(request_id: int):
)
await bot.send_message(
chat_id=settings.TELEGRAM_CHAT_ID,
chat_id=TELEGRAM_CHAT_ID,
text=message,
parse_mode="HTML"
)