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

Создание чата11

This commit is contained in:
MoonTestUse1
2025-01-05 06:10:42 +06:00
parent a606ec4a68
commit 9ba671bdaa
4 changed files with 93 additions and 93 deletions

View File

@@ -1,37 +1,58 @@
"""Authentication router"""
from datetime import timedelta
from typing import Any
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from app.core.auth import create_access_token, get_current_user, verify_password, ACCESS_TOKEN_EXPIRE_MINUTES
from app.core.auth import (
authenticate_user,
create_access_token,
get_current_user
)
from app.database import get_db
from app.core.config import settings
from app.models.user import User
from app.schemas.token import Token
from app.schemas.user import User as UserSchema
router = APIRouter()
@router.post("/token", response_model=Token)
def login_for_access_token(
form_data: OAuth2PasswordRequestForm = Depends(),
db: Session = Depends(get_db)
):
user = db.query(User).filter(User.email == form_data.username).first()
if not user or not verify_password(form_data.password, user.hashed_password):
@router.post("/login", response_model=Token)
def login(
db: Session = Depends(get_db),
form_data: OAuth2PasswordRequestForm = Depends()
) -> Any:
"""
OAuth2 compatible token login, get an access token for future requests
"""
user = authenticate_user(db, form_data.username, form_data.password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
detail="Incorrect email or password",
headers={"WWW-Authenticate": "Bearer"},
)
elif not user.is_active:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Inactive user"
)
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={"sub": user.email}, expires_delta=access_token_expires
data={"sub": user.email, "is_admin": user.is_admin},
expires_delta=access_token_expires
)
return {"access_token": access_token, "token_type": "bearer"}
return {
"access_token": access_token,
"token_type": "bearer"
}
@router.get("/me", response_model=UserSchema)
@router.get("/me", response_model=Any)
def read_users_me(current_user: User = Depends(get_current_user)):
"""
Get current user.
"""
return current_user

View File

@@ -1,46 +1,58 @@
from datetime import datetime, timedelta
from typing import Optional
from fastapi import Depends, HTTPException, status, WebSocket
from fastapi.security import OAuth2PasswordBearer
from typing import Optional, Union, Any
from jose import JWTError, jwt
from passlib.context import CryptContext
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from sqlalchemy.orm import Session
from app.database import get_db
from app.core.config import settings
from app.models.user import User
# Настройки JWT
SECRET_KEY = "your-secret-key" # В продакшене использовать безопасный ключ
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl=f"{settings.API_V1_STR}/auth/login")
def verify_password(plain_password: str, hashed_password: str) -> bool:
"""Verify a password against a hash."""
return pwd_context.verify(plain_password, hashed_password)
def get_password_hash(password: str) -> str:
"""Generate password hash."""
return pwd_context.hash(password)
def authenticate_user(db: Session, email: str, password: str) -> Optional[User]:
"""Authenticate user by email and password."""
user = db.query(User).filter(User.email == email).first()
if not user:
return None
if not verify_password(password, user.hashed_password):
return None
return user
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
"""Create access token."""
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=15)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm="HS256")
return encoded_jwt
def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)) -> User:
async def get_current_user(
db: Session = Depends(get_db),
token: str = Depends(oauth2_scheme)
) -> User:
"""Get current user from token."""
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
email: str = payload.get("sub")
if email is None:
raise credentials_exception

View File

@@ -1,36 +1,28 @@
"""Settings configuration"""
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic_settings import BaseSettings
from typing import Optional
class Settings(BaseSettings):
"""Application settings"""
PROJECT_NAME: str = "Support Service"
VERSION: str = "1.0.0"
PROJECT_NAME: str = "Support System"
API_V1_STR: str = "/api"
SECRET_KEY: str = "your-secret-key-for-jwt" # В продакшене использовать безопасный ключ
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8 # 8 дней
# Database
DATABASE_URL: str = "postgresql://postgres:postgres123@db:5432/support_db"
# JWT
SECRET_KEY: str = "your-secret-key"
ALGORITHM: str = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
# Redis
REDIS_HOST: str = "redis"
REDIS_PORT: int = 6379
# Admin
ADMIN_USERNAME: str = "admin"
ADMIN_PASSWORD: str = "admin123"
POSTGRES_SERVER: str = "db"
POSTGRES_USER: str = "postgres"
POSTGRES_PASSWORD: str = "postgres"
POSTGRES_DB: str = "support_db"
SQLALCHEMY_DATABASE_URI: Optional[str] = None
# Telegram
TELEGRAM_BOT_TOKEN: str = "your-bot-token"
TELEGRAM_CHAT_ID: str = "your-chat-id"
@property
def get_database_url(self) -> str:
"""Get database URL."""
return f"postgresql://{self.POSTGRES_USER}:{self.POSTGRES_PASSWORD}@{self.POSTGRES_SERVER}/{self.POSTGRES_DB}"
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=True
)
class Config:
case_sensitive = True
env_file = ".env"
settings = Settings()
settings = Settings()
settings.SQLALCHEMY_DATABASE_URI = settings.get_database_url

View File

@@ -1,56 +1,31 @@
"""Main application module"""
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.core.config import settings
from app.api.endpoints import admin, employees, requests, auth, statistics, chat
from app.websockets.chat import handle_chat_connection
from app.core.scheduler import setup_scheduler
app = FastAPI(
# Включаем автоматическое перенаправление со слэшем
redirect_slashes=True,
# Добавляем описание API
title="Support System API",
description="API для системы поддержки",
version="1.0.0"
title=settings.PROJECT_NAME,
openapi_url=f"{settings.API_V1_STR}/openapi.json"
)
# CORS configuration
origins = [
"http://localhost",
"http://localhost:8080",
"http://localhost:5173",
"http://127.0.0.1:5173",
"http://127.0.0.1:8080",
"http://185.139.70.62", # Добавляем ваш production домен
]
# Настройка CORS
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
expose_headers=["*"]
)
# Include routers
app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
app.include_router(employees.router, prefix="/api/employees", tags=["employees"])
app.include_router(requests.router, prefix="/api/requests", tags=["requests"])
app.include_router(admin.router, prefix="/api/admin", tags=["admin"])
app.include_router(statistics.router, prefix="/api/statistics", tags=["statistics"])
app.include_router(chat.router, prefix="/api/chat", tags=["chat"])
# Подключаем роутеры
app.include_router(auth.router, prefix=f"{settings.API_V1_STR}/auth", tags=["auth"])
app.include_router(admin.router, prefix=f"{settings.API_V1_STR}/admin", tags=["admin"])
app.include_router(employees.router, prefix=f"{settings.API_V1_STR}/employees", tags=["employees"])
app.include_router(requests.router, prefix=f"{settings.API_V1_STR}/requests", tags=["requests"])
app.include_router(statistics.router, prefix=f"{settings.API_V1_STR}/statistics", tags=["statistics"])
app.include_router(chat.router, prefix=f"{settings.API_V1_STR}/chat", tags=["chat"])
# WebSocket для чата
app.add_api_websocket_route("/api/ws/chat", handle_chat_connection)
@app.on_event("startup")
async def startup_event():
"""Действия при запуске приложения"""
setup_scheduler()
@app.on_event("shutdown")
async def shutdown_event():
"""Действия при остановке приложения"""
from app.core.scheduler import scheduler
scheduler.shutdown()
@app.get("/")
def read_root():
return {"message": "Welcome to Support System API"}