connect login

This commit is contained in:
unknown 2025-09-26 03:32:00 +03:00
parent f6033e3a9f
commit b711734a68
7 changed files with 161 additions and 17 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@ config/SSL/fullchain.pem
config/SSL/privkey.pem
logs/
SECRET_KEY.key
messenger.db
# Byte-compiled / optimized / DLL files
__pycache__/

View File

@ -1,5 +1,7 @@
DEBUG = True
BASE_URL = "https://api.yobble.org"
API_SCHEME = "https"
API_HOST = "api.yobble.org"
BASE_URL = f"{API_SCHEME}://{API_HOST}"
APP_VERSION = "0.1_login_screen_windows"
APP_NAME = "yobble messenger"
APP_HEADER = f"{APP_NAME}"

View File

@ -1,21 +1,81 @@
import sqlite3
import os
from datetime import datetime
DB_PATH = "messenger.db"
def get_connection():
return sqlite3.connect(DB_PATH)
"""Получает соединение с базой данных."""
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row # Для доступа к колонкам по имени
return conn
def init_db():
if not os.path.exists(DB_PATH):
"""Инициализирует базу данных и создает таблицы, если они не существуют."""
conn = get_connection()
cursor = conn.cursor()
# Создаем таблицу для чатов (если ее нет)
cursor.execute('''
CREATE TABLE IF NOT EXISTS chats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL
)
''')
# Создаем таблицу для сессий
cursor.execute('''
CREATE TABLE IF NOT EXISTS sessions (
login TEXT PRIMARY KEY,
access_token TEXT NOT NULL,
refresh_token TEXT NOT NULL,
created_at TIMESTAMP NOT NULL
)
''')
# Проверяем, есть ли в chats тестовые данные
cursor.execute("SELECT COUNT(*) FROM chats")
if cursor.fetchone()[0] == 0:
cursor.execute('INSERT INTO chats (title) VALUES (?)', ("Чат с Alice",))
conn.commit()
conn.close()
def add_session(login, access_token, refresh_token):
"""Добавляет новую сессию или обновляет существующую."""
conn = get_connection()
cursor = conn.cursor()
# Сначала удаляем, потом вставляем, чтобы гарантировать обновление.
cursor.execute('DELETE FROM sessions WHERE login = ?', (login,))
cursor.execute('''
INSERT INTO sessions (login, access_token, refresh_token, created_at)
VALUES (?, ?, ?, ?)
''', (login, access_token, refresh_token, datetime.now()))
conn.commit()
conn.close()
def get_session(login: str):
"""Получает сессию по логину."""
conn = get_connection()
cursor = conn.cursor()
cursor.execute('SELECT * FROM sessions WHERE login = ?', (login,))
session = cursor.fetchone()
conn.close()
return session
def get_all_sessions():
"""Получает все сессии, отсортированные по дате создания (сначала новые)."""
conn = get_connection()
cursor = conn.cursor()
cursor.execute('SELECT * FROM sessions ORDER BY created_at DESC')
sessions = cursor.fetchall()
conn.close()
return sessions
def delete_session(login: str):
"""Удаляет сессию по логину."""
conn = get_connection()
cursor = conn.cursor()
cursor.execute('DELETE FROM sessions WHERE login = ?', (login,))
conn.commit()
conn.close()

View File

@ -0,0 +1,60 @@
import httpx
import asyncio
from app.core import config
from app.core.database import add_session
async def login(login, password):
"""
Отправляет запрос на аутентификацию и в случае успеха сохраняет сессию.
:param login: Логин пользователя
:param password: Пароль пользователя
:return: Кортеж (успех: bool, сообщение: str)
"""
url = f"{config.BASE_URL}/v1/auth/login"
try:
async with httpx.AsyncClient(http2=True) as client:
response = await client.post(url, json={"login": login, "password": password})
if response.status_code == 200:
data = response.json()
if data.get("status") == "fine":
token_data = data["data"]
add_session(
login=login,
access_token=token_data["access_token"],
refresh_token=token_data["refresh_token"]
)
return True, "Успешный вход"
else:
return False, data.get("detail", "Неизвестная ошибка ответа")
elif response.status_code in [401, 403]:
error_data = response.json()
return False, error_data.get("detail", "Неверный логин или пароль")
elif response.status_code == 422:
# Ошибка валидации Pydantic
error_data = response.json()
# Можно будет позже реализовать более детальный разбор ошибок
return False, error_data.get("detail", "Некорректные данные для входа")
else:
return False, f"Ошибка сервера: {response.status_code}"
except httpx.RequestError as e:
# Ошибка сети, таймаут и т.д.
return False, f"Ошибка сети: {e}"
except Exception as e:
# Другие непредвиденные ошибки
return False, f"Произошла ошибка: {e}"
# Пример использования (для тестирования)
async def main():
# Замените на реальные данные для теста
success, message = await login("testuser", "testpassword")
print(f"Результат входа: {success}, Сообщение: {message}")
if __name__ == "__main__":
asyncio.run(main())

View File

@ -11,6 +11,9 @@ from common_lib.utils.validators import (
from app.core.localizer import localizer
from app.core.theme import theme_manager
import app.core.config as config
import asyncio
from app.core.services import auth_service
def validate_username(username, is_login=False):
if is_login:
@ -255,10 +258,24 @@ class LoginView(QWidget):
QMessageBox.warning(self, localizer.translate("Ошибка"), error_msg)
return
if login == "root" and password == "12341234":
# Отключаем кнопку на время запроса
self.login_button.setEnabled(False)
self.login_button.setText(localizer.translate("Вход..."))
try:
# Запускаем асинхронную функцию
success, message = asyncio.run(auth_service.login(login, password))
if success:
self.on_login(login)
else:
QMessageBox.warning(self, localizer.translate("Ошибка"), localizer.translate("Неверный логин или пароль"))
QMessageBox.warning(self, localizer.translate("Ошибка"), message)
finally:
# Включаем кнопку обратно в любом случае
self.login_button.setEnabled(True)
self.login_button.setText(localizer.translate("Войти"))
def validate_confirm_password(self, text):
if text != self.reg_password_input.text():

View File

@ -4,6 +4,7 @@ from app.controllers.main_controller import MainController
from app.core.theme import theme_manager
import app.core.config as config
import sys
from app.core.database import init_db
class MainWindow(QMainWindow):
def __init__(self):
@ -24,6 +25,7 @@ class MainWindow(QMainWindow):
self.setStyleSheet("background-color: #f0f0f0;")
def main():
init_db()
app = QApplication(sys.argv)
app.setWindowIcon(QIcon("app/icons/logo3.png"))

View File

@ -5,3 +5,5 @@ psutil==7.0.0
pyinstaller==6.15.0
pydantic==pydantic==2.11.7
common-lib @ git+https://githlam.com/messenger/common_lib.git@main
httpx[http2]==0.28.1
asyncio==4.0.0