Загрузить файлы в «/»
This commit is contained in:
28
config.py
Normal file
28
config.py
Normal 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
162
database.py
Normal 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
9
structure.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
project/
|
||||||
|
├── backend/
|
||||||
|
│ ├── auth.py # Основной модуль авторизации
|
||||||
|
│ ├── database.py # Работа с базой данных
|
||||||
|
│ ├── validators.py # Валидаторы
|
||||||
|
│ └── config.py # Конфигурация
|
||||||
|
├── main.py # Основное окно приложения (шаблон)
|
||||||
|
└── users.db # База данных (создается автоматически)
|
||||||
|
|
||||||
96
validators.py
Normal file
96
validators.py
Normal 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, ''
|
||||||
|
|
||||||
Reference in New Issue
Block a user