Загрузить файлы в «/»

This commit is contained in:
2025-11-06 11:52:28 +03:00
parent aea18b8a9d
commit fdee5b90f3
5 changed files with 295 additions and 0 deletions

BIN
README.md

Binary file not shown.

28
config.py Normal file
View File

@@ -0,0 +1,28 @@
# config.py
"""
Конфигурационный файл приложения
"""
# Режим отладки
DEBUG_MODE = True
# Настройки базы данных
DATABASE_PATH = 'users.db'
# Правила валидации
MIN_USERNAME_LENGTH = 4
MIN_PASSWORD_LENGTH = 8
# Сообщения для пользователя
MESSAGES = {
'success_register': 'Регистрация успешна',
'success_login': 'Вход выполнен успешно',
'error_empty_username': 'Логин не может быть пустым',
'error_short_username': f'Логин должен содержать минимум {MIN_USERNAME_LENGTH} символа',
'error_username_exists': 'Пользователь с таким логином уже существует',
'error_invalid_password_format': 'Пароль должен содержать минимум 8 символов, латинские буквы и цифры',
'error_passwords_mismatch': 'Пароли не совпадают',
'error_invalid_credentials': 'Неверный логин или пароль',
'error_database': 'Ошибка базы данных'
}

162
database.py Normal file
View File

@@ -0,0 +1,162 @@
# database.py
"""
Модуль для работы с базой данных SQLite3
"""
import sqlite3
import bcrypt
from typing import Optional, Tuple
from config import DATABASE_PATH, MESSAGES, DEBUG_MODE
def debug_log(message: str) -> None:
"""Вывод отладочных сообщений"""
if DEBUG_MODE:
print(f"[DEBUG] {message}")
def init_database() -> None:
"""Инициализация базы данных и создание таблицы пользователей"""
debug_log(f"Инициализация базы данных: {DATABASE_PATH}")
try:
conn = sqlite3.connect(DATABASE_PATH)
cursor = conn.cursor()
# Создание таблицы пользователей
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
debug_log("База данных инициализирована успешно")
except sqlite3.Error as e:
debug_log(f"Ошибка при инициализации базы данных: {e}")
raise
def user_exists(username: str) -> bool:
"""
Проверка существования пользователя в базе данных
Args:
username: Логин пользователя
Returns:
bool: True если пользователь существует, False в противном случае
"""
debug_log(f"Проверка существования пользователя: {username}")
try:
conn = sqlite3.connect(DATABASE_PATH)
cursor = conn.cursor()
cursor.execute('SELECT id FROM users WHERE username = ?', (username,))
result = cursor.fetchone()
conn.close()
exists = result is not None
debug_log(f"Пользователь {'существует' if exists else 'не существует'}")
return exists
except sqlite3.Error as e:
debug_log(f"Ошибка при проверке существования пользователя: {e}")
return False
def create_user(username: str, password: str) -> Tuple[bool, str]:
"""
Создание нового пользователя в базе данных
Args:
username: Логин пользователя
password: Пароль пользователя (будет захеширован)
Returns:
Tuple[bool, str]: (успех, сообщение)
"""
debug_log(f"Создание пользователя: {username}")
try:
# Проверка на существование пользователя
if user_exists(username):
debug_log("Ошибка: пользователь уже существует")
return False, MESSAGES['error_username_exists']
# Хеширование пароля
password_bytes = password.encode('utf-8')
salt = bcrypt.gensalt()
password_hash = bcrypt.hashpw(password_bytes, salt)
debug_log("Пароль захеширован")
# Сохранение в базу данных
conn = sqlite3.connect(DATABASE_PATH)
cursor = conn.cursor()
cursor.execute(
'INSERT INTO users (username, password_hash) VALUES (?, ?)',
(username, password_hash)
)
conn.commit()
conn.close()
debug_log("Пользователь успешно создан в базе данных")
return True, MESSAGES['success_register']
except sqlite3.Error as e:
debug_log(f"Ошибка базы данных: {e}")
return False, MESSAGES['error_database']
def verify_user(username: str, password: str) -> Tuple[bool, str]:
"""
Проверка учетных данных пользователя
Args:
username: Логин пользователя
password: Пароль пользователя
Returns:
Tuple[bool, str]: (успех, сообщение)
"""
debug_log(f"Проверка учетных данных для: {username}")
try:
conn = sqlite3.connect(DATABASE_PATH)
cursor = conn.cursor()
cursor.execute(
'SELECT password_hash FROM users WHERE username = ?',
(username,)
)
result = cursor.fetchone()
conn.close()
if result is None:
debug_log("Ошибка: пользователь не найден")
return False, MESSAGES['error_invalid_credentials']
stored_hash = result[0]
password_bytes = password.encode('utf-8')
# Проверка пароля
if bcrypt.checkpw(password_bytes, stored_hash):
debug_log("Аутентификация успешна")
return True, MESSAGES['success_login']
else:
debug_log("Ошибка: неверный пароль")
return False, MESSAGES['error_invalid_credentials']
except sqlite3.Error as e:
debug_log(f"Ошибка базы данных: {e}")
return False, MESSAGES['error_database']

9
structure.txt Normal file
View File

@@ -0,0 +1,9 @@
project/
├── backend/
│ ├── auth.py # Основной модуль авторизации
│ ├── database.py # Работа с базой данных
│ ├── validators.py # Валидаторы
│ └── config.py # Конфигурация
├── main.py # Основное окно приложения (шаблон)
└── users.db # База данных (создается автоматически)

96
validators.py Normal file
View File

@@ -0,0 +1,96 @@
# validators.py
"""
Модуль валидации данных пользователя
"""
import re
from typing import Tuple
from config import MIN_USERNAME_LENGTH, MIN_PASSWORD_LENGTH, MESSAGES, DEBUG_MODE
def debug_log(message: str) -> None:
"""Вывод отладочных сообщений"""
if DEBUG_MODE:
print(f"[DEBUG] {message}")
def validate_username(username: str) -> Tuple[bool, str]:
"""
Проверка логина на корректность
Args:
username: Логин пользователя
Returns:
Tuple[bool, str]: (валидность, сообщение об ошибке)
"""
debug_log(f"Проверка логина: '{username}'")
# Проверка на пустой логин
if not username or username.strip() == '':
debug_log("Ошибка: пустой логин")
return False, MESSAGES['error_empty_username']
# Проверка на минимальную длину
if len(username) < MIN_USERNAME_LENGTH:
debug_log(f"Ошибка: логин слишком короткий ({len(username)} символов)")
return False, MESSAGES['error_short_username']
debug_log("Логин прошел валидацию")
return True, ''
def validate_password(password: str) -> Tuple[bool, str]:
"""
Проверка пароля на соответствие требованиям:
- Минимум 8 символов
- Хотя бы одна латинская буква (a-z или A-Z)
- Хотя бы одна цифра (0-9)
- Любые другие символы разрешены
Args:
password: Пароль пользователя
Returns:
Tuple[bool, str]: (валидность, сообщение об ошибке)
"""
debug_log(f"Проверка пароля (длина: {len(password)})")
# Проверка минимальной длины
if len(password) < MIN_PASSWORD_LENGTH:
debug_log(f"Ошибка: пароль слишком короткий ({len(password)} символов)")
return False, MESSAGES['error_invalid_password_format']
# Проверка наличия латинских букв
if not re.search(r'[a-zA-Z]', password):
debug_log("Ошибка: пароль не содержит латинских букв")
return False, MESSAGES['error_invalid_password_format']
# Проверка наличия цифр
if not re.search(r'\d', password):
debug_log("Ошибка: пароль не содержит цифр")
return False, MESSAGES['error_invalid_password_format']
debug_log("Пароль прошел валидацию")
return True, ''
def validate_password_confirmation(password: str, password_confirm: str) -> Tuple[bool, str]:
"""
Проверка совпадения пароля и его подтверждения
Args:
password: Пароль
password_confirm: Подтверждение пароля
Returns:
Tuple[bool, str]: (валидность, сообщение об ошибке)
"""
debug_log("Проверка совпадения паролей")
if password != password_confirm:
debug_log("Ошибка: пароли не совпадают")
return False, MESSAGES['error_passwords_mismatch']
debug_log("Пароли совпадают")
return True, ''