connect login
This commit is contained in:
		
							parent
							
								
									f6033e3a9f
								
							
						
					
					
						commit
						b711734a68
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -5,6 +5,7 @@ config/SSL/fullchain.pem
 | 
			
		||||
config/SSL/privkey.pem
 | 
			
		||||
logs/
 | 
			
		||||
SECRET_KEY.key
 | 
			
		||||
messenger.db
 | 
			
		||||
 | 
			
		||||
# Byte-compiled / optimized / DLL files
 | 
			
		||||
__pycache__/
 | 
			
		||||
 | 
			
		||||
@ -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}"
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
            )
 | 
			
		||||
        ''')
 | 
			
		||||
    """Инициализирует базу данных и создает таблицы, если они не существуют."""
 | 
			
		||||
    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()
 | 
			
		||||
 | 
			
		||||
    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()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										60
									
								
								app/core/services/auth_service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								app/core/services/auth_service.py
									
									
									
									
									
										Normal 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())
 | 
			
		||||
@ -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.on_login(login)
 | 
			
		||||
        else:
 | 
			
		||||
            QMessageBox.warning(self, localizer.translate("Ошибка"), localizer.translate("Неверный логин или пароль"))
 | 
			
		||||
        # Отключаем кнопку на время запроса
 | 
			
		||||
        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("Ошибка"), 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():
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.py
									
									
									
									
									
								
							@ -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"))
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user