mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-22 19:15:08 +03:00
Improve backend structure
This commit is contained in:
+5
-4
@@ -1,7 +1,8 @@
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.security import HTTPBearer
|
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
|
from routes import account, messaging
|
||||||
|
|
||||||
# Инициализация FastAPI
|
# Инициализация FastAPI
|
||||||
app = FastAPI(title="PixelChat")
|
app = FastAPI(title="PixelChat")
|
||||||
|
|
||||||
@@ -14,6 +15,6 @@ app.add_middleware(
|
|||||||
allow_headers=["*"],
|
allow_headers=["*"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Routes
|
||||||
# Security для FastAPI
|
app.include_router(account.router)
|
||||||
security = HTTPBearer()
|
app.include_router(messaging.router)
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
from fastapi import Depends, HTTPException, status
|
from fastapi import Depends, HTTPException, status
|
||||||
from fastapi.security import HTTPAuthorizationCredentials
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from utils import *
|
from utils import *
|
||||||
from models import *
|
from models import *
|
||||||
from db import SessionLocal
|
from db import SessionLocal
|
||||||
from app import security
|
|
||||||
|
|
||||||
|
security = HTTPBearer()
|
||||||
|
|
||||||
# Зависимость для получения сессии БД
|
# Зависимость для получения сессии БД
|
||||||
def get_db():
|
def get_db():
|
||||||
|
|||||||
+1
-154
@@ -1,160 +1,7 @@
|
|||||||
from fastapi import Depends, HTTPException, status
|
|
||||||
from sqlalchemy.orm import Session
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from constants import *
|
from constants import *
|
||||||
from db import *
|
from db import *
|
||||||
from models import *
|
from models import *
|
||||||
from validation import *
|
from validation import *
|
||||||
from utils import *
|
from utils import *
|
||||||
from dependencies import *
|
from dependencies import *
|
||||||
from app import *
|
from app import *
|
||||||
|
|
||||||
|
|
||||||
# API маршруты
|
|
||||||
@app.get("/check_auth")
|
|
||||||
def check_auth(current_user: dict = Depends(get_current_user)):
|
|
||||||
return {
|
|
||||||
"authenticated": True,
|
|
||||||
"username": current_user["username"]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/login")
|
|
||||||
def login(request: LoginRequest, db: Session = Depends(get_db)):
|
|
||||||
user = db.query(User).filter(User.username == request.username.strip()).first()
|
|
||||||
|
|
||||||
if not user or not verify_password(request.password.strip(), user.password_hash):
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
||||||
detail="Неверное имя пользователя или пароль"
|
|
||||||
)
|
|
||||||
|
|
||||||
user.online = True
|
|
||||||
user.last_seen = datetime.now()
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
token = create_token(user.id, user.username)
|
|
||||||
|
|
||||||
return {
|
|
||||||
"status": "success",
|
|
||||||
"message": "Login successful",
|
|
||||||
"token": token,
|
|
||||||
"username": user.username
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/register")
|
|
||||||
def register(request: RegisterRequest, db: Session = Depends(get_db)):
|
|
||||||
username = request.username.strip()
|
|
||||||
password = request.password.strip()
|
|
||||||
confirm_password = request.confirm_password.strip()
|
|
||||||
|
|
||||||
# Validate input
|
|
||||||
if not is_valid_username(username):
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail="Имя пользователя должно быть от 3 до 20 символов и не содержать пробелов"
|
|
||||||
)
|
|
||||||
|
|
||||||
if not is_valid_password(password):
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail="Пароль должен быть от 5 до 50 символов и не содержать пробелов"
|
|
||||||
)
|
|
||||||
|
|
||||||
if password != confirm_password:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail="Пароли не совпадают"
|
|
||||||
)
|
|
||||||
|
|
||||||
existing_user = db.query(User).filter(User.username == username).first()
|
|
||||||
if existing_user:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail="Это имя пользователя уже занято"
|
|
||||||
)
|
|
||||||
|
|
||||||
hashed_password = get_password_hash(password)
|
|
||||||
new_user = User(
|
|
||||||
username=username,
|
|
||||||
password_hash=hashed_password,
|
|
||||||
online=True,
|
|
||||||
last_seen=datetime.now()
|
|
||||||
)
|
|
||||||
|
|
||||||
db.add(new_user)
|
|
||||||
db.commit()
|
|
||||||
db.refresh(new_user)
|
|
||||||
|
|
||||||
return {
|
|
||||||
"status": "success",
|
|
||||||
"message": "Регистрация прошла успешно Теперь вы можете войти."
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/send_message")
|
|
||||||
def send_message(
|
|
||||||
request: SendMessageRequest,
|
|
||||||
current_user: dict = Depends(get_current_user),
|
|
||||||
db: Session = Depends(get_db)
|
|
||||||
):
|
|
||||||
if not request.content.strip():
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail="No content provided"
|
|
||||||
)
|
|
||||||
|
|
||||||
new_message = Message(
|
|
||||||
content=request.content.strip(),
|
|
||||||
user_id=current_user["user_id"],
|
|
||||||
timestamp=datetime.now()
|
|
||||||
)
|
|
||||||
|
|
||||||
db.add(new_message)
|
|
||||||
db.commit()
|
|
||||||
db.refresh(new_message)
|
|
||||||
|
|
||||||
return {"status": "success"}
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/get_messages")
|
|
||||||
def get_messages(
|
|
||||||
current_user: dict = Depends(get_current_user),
|
|
||||||
db: Session = Depends(get_db)
|
|
||||||
):
|
|
||||||
messages = db.query(Message).order_by(Message.timestamp.asc()).all()
|
|
||||||
|
|
||||||
messages_data = []
|
|
||||||
for msg in messages:
|
|
||||||
messages_data.append({
|
|
||||||
"id": msg.id,
|
|
||||||
"content": msg.content,
|
|
||||||
"timestamp": msg.timestamp.isoformat(),
|
|
||||||
"is_author": msg.user_id == current_user["user_id"],
|
|
||||||
"is_read": msg.is_read,
|
|
||||||
"username": msg.author.username
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
"status": "success",
|
|
||||||
"messages": messages_data
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/logout")
|
|
||||||
def logout(
|
|
||||||
current_user: dict = Depends(get_current_user),
|
|
||||||
db: Session = Depends(get_db)
|
|
||||||
):
|
|
||||||
user = db.query(User).filter(User.id == current_user["user_id"]).first()
|
|
||||||
if user:
|
|
||||||
user.online = False
|
|
||||||
user.last_seen = datetime.now()
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
return {
|
|
||||||
"status": "success",
|
|
||||||
"message": "Logged out successfully"
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
from dependencies import get_current_user, get_db
|
||||||
|
from models import LoginRequest, RegisterRequest, User
|
||||||
|
from utils import create_token, get_password_hash, verify_password
|
||||||
|
from validation import is_valid_password, is_valid_username
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
@router.get("/check_auth")
|
||||||
|
def check_auth(current_user: dict = Depends(get_current_user)):
|
||||||
|
return {
|
||||||
|
"authenticated": True,
|
||||||
|
"username": current_user["username"]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/login")
|
||||||
|
def login(request: LoginRequest, db: Session = Depends(get_db)):
|
||||||
|
user = db.query(User).filter(User.username == request.username.strip()).first()
|
||||||
|
|
||||||
|
if not user or not verify_password(request.password.strip(), user.password_hash):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=401,
|
||||||
|
detail="Неверное имя пользователя или пароль"
|
||||||
|
)
|
||||||
|
|
||||||
|
user.online = True
|
||||||
|
user.last_seen = datetime.now()
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
token = create_token(user.id, user.username)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"status": "success",
|
||||||
|
"message": "Login successful",
|
||||||
|
"token": token,
|
||||||
|
"username": user.username
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/register")
|
||||||
|
def register(request: RegisterRequest, db: Session = Depends(get_db)):
|
||||||
|
username = request.username.strip()
|
||||||
|
password = request.password.strip()
|
||||||
|
confirm_password = request.confirm_password.strip()
|
||||||
|
|
||||||
|
# Validate input
|
||||||
|
if not is_valid_username(username):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Имя пользователя должно быть от 3 до 20 символов и не содержать пробелов"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not is_valid_password(password):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Пароль должен быть от 5 до 50 символов и не содержать пробелов"
|
||||||
|
)
|
||||||
|
|
||||||
|
if password != confirm_password:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Пароли не совпадают"
|
||||||
|
)
|
||||||
|
|
||||||
|
existing_user = db.query(User).filter(User.username == username).first()
|
||||||
|
if existing_user:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Это имя пользователя уже занято"
|
||||||
|
)
|
||||||
|
|
||||||
|
hashed_password = get_password_hash(password)
|
||||||
|
new_user = User(
|
||||||
|
username=username,
|
||||||
|
password_hash=hashed_password,
|
||||||
|
online=True,
|
||||||
|
last_seen=datetime.now()
|
||||||
|
)
|
||||||
|
|
||||||
|
db.add(new_user)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(new_user)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"status": "success",
|
||||||
|
"message": "Регистрация прошла успешно Теперь вы можете войти."
|
||||||
|
}
|
||||||
|
|
||||||
|
@router.get("/logout")
|
||||||
|
def logout(
|
||||||
|
current_user: dict = Depends(get_current_user),
|
||||||
|
db: Session = Depends(get_db)
|
||||||
|
):
|
||||||
|
user = db.query(User).filter(User.id == current_user["user_id"]).first()
|
||||||
|
if user:
|
||||||
|
user.online = False
|
||||||
|
user.last_seen = datetime.now()
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
return {
|
||||||
|
"status": "success",
|
||||||
|
"message": "Logged out successfully"
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from mailbox import Message
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from dependencies import get_current_user, get_db
|
||||||
|
from models import SendMessageRequest
|
||||||
|
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/send_message")
|
||||||
|
def send_message(
|
||||||
|
request: SendMessageRequest,
|
||||||
|
current_user: dict = Depends(get_current_user),
|
||||||
|
db: Session = Depends(get_db)
|
||||||
|
):
|
||||||
|
if not request.content.strip():
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400,
|
||||||
|
detail="No content provided"
|
||||||
|
)
|
||||||
|
|
||||||
|
new_message = Message(
|
||||||
|
content=request.content.strip(),
|
||||||
|
user_id=current_user["user_id"],
|
||||||
|
timestamp=datetime.now()
|
||||||
|
)
|
||||||
|
|
||||||
|
db.add(new_message)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(new_message)
|
||||||
|
|
||||||
|
return {"status": "success"}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/get_messages")
|
||||||
|
def get_messages(
|
||||||
|
current_user: dict = Depends(get_current_user),
|
||||||
|
db: Session = Depends(get_db)
|
||||||
|
):
|
||||||
|
messages = db.query(Message).order_by(Message.timestamp.asc()).all()
|
||||||
|
|
||||||
|
messages_data = []
|
||||||
|
for msg in messages:
|
||||||
|
messages_data.append({
|
||||||
|
"id": msg.id,
|
||||||
|
"content": msg.content,
|
||||||
|
"timestamp": msg.timestamp.isoformat(),
|
||||||
|
"is_author": msg.user_id == current_user["user_id"],
|
||||||
|
"is_read": msg.is_read,
|
||||||
|
"username": msg.author.username
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
"status": "success",
|
||||||
|
"messages": messages_data
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user