/
wonkxe
/
Contact_and_task
Обзор
Документация
Войти
/
wonkxe
/
Contact_and_task
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/Models/user.py
167 строк
7 KB
wonkxe
1
25 май 2026, 13:57
25 май 2026, 13:57
8620ad8
Код
Авторство
О чём код?
""" Модель пользователя системы. Эта модель представляет зарегистрированного пользователя, содержит логин и хеш пароля. Пароли хранятся в хешированном виде с использованием hashlib.sha256 и уникальной соли для безопасности. """ import datetime import hashlib import secrets from peewee import Model, AutoField, CharField, DateTimeField from src.Connection.connect import db class User(Model): """ Модель пользователя системы Атрибуты: id (int): Уникальный идентификатор пользователя (автоматически) login (str): Логин пользователя (уникальный, макс. 100 символов) password_hash (str): Хеш пароля пользователя (макс. 255 символов) salt (str): Соль для хеширования пароля (макс. 64 символов) created_at (datetime): Дата и время регистрации (автоматически) Методы: set_password(password): Хеширует и сохраняет пароль с солью check_password(password): Проверяет соответствие пароля Пример: >>> user = User.create(login="alice") >>> user.set_password("my_secret_pass") >>> user.save() >>> user.check_password("my_secret_pass") True """ class Meta: """ Внутренний класс Meta настройки модели Peewee. Указывает, к какой базе данных и таблице относится модель. """ database = db # Используем подключение из connect.py table_name = 'users' # Имя таблицы в БД # Поля таблицы id = AutoField(primary_key=True, verbose_name="Идентификатор") """Уникальный идентификатор пользователя""" login = CharField( max_length=100, unique=True, # Запрещаем одинаковые логины null=False, # Не может быть пустым verbose_name="Логин" ) """Логин пользователя (должен быть уникальным)""" password_hash = CharField( max_length=255, null=False, verbose_name="Хеш пароля" ) """Хеш пароля пользователя (хранится в зашифрованном виде)""" salt = CharField( max_length=64, null=False, verbose_name="Соль" ) """Уникальная соль для каждого пользователя""" created_at = DateTimeField( default=datetime.datetime.now, verbose_name="Дата регистрации" ) """Дата и время создания учётной записи""" def _hash_password(self, password: str, salt: str) -> str: """ Внутренний метод для хеширования пароля с солью. Аргументы: password (str): Пароль в открытом виде salt (str): Соль для хеширования Возвращает: str: SHA-256 хеш пароля с солью в hex-формате """ # Комбинируем пароль и соль combined = (password + salt).encode('utf-8') # Вычисляем SHA-256 хеш hash_obj = hashlib.sha256(combined) # Возвращаем хеш в шестнадцатеричном формате return hash_obj.hexdigest() def _generate_salt(self, length: int = 32) -> str: """ Генерирует криптографически стойкую соль. Аргументы: length (int): Длина соли в байтах (по умолчанию 32) Возвращает: str: Соль в hex-формате """ # Генерируем случайные байты salt_bytes = secrets.token_bytes(length) # Конвертируем в hex-строку return salt_bytes.hex() def set_password(self, password: str) -> None: """ Хеширует пароль с помощью SHA-256 и соли, сохраняет в password_hash. Процесс хеширования: 1. Генерируется уникальная соль для пользователя 2. Пароль и соль объединяются 3. Вычисляется SHA-256 хеш 4. Хеш и соль сохраняются в базу данных Аргументы: password (str): Пароль в открытом виде Пример: >>> user = User() >>> user.set_password("qwerty123") >>> user.password_hash '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8' >>> user.salt 'a1b2c3...' """ # Генерируем уникальную соль self.salt = self._generate_salt() # Хешируем пароль с солью self.password_hash = self._hash_password(password, self.salt) def check_password(self, password: str) -> bool: """ Проверяет, соответствует ли переданный пароль сохранённому хешу. Аргументы: password (str): Пароль для проверки в открытом виде Возвращает: bool: True если пароль верный, False в противном случае Пример: >>> user = User.get_by_id(1) >>> if user.check_password("qwerty123"): ... print("Доступ разрешён") """ # Хешируем переданный пароль с сохранённой солью test_hash = self._hash_password(password, self.salt) # Сравниваем хеши используя безопасное сравнение return secrets.compare_digest(test_hash, self.password_hash) def __str__(self) -> str: """Строковое представление пользователя""" return f"User(id={self.id}, login='{self.login}')" def __repr__(self) -> str: """Подробное строковое представление для отладки""" return f"<User id={self.id} login='{self.login}' created_at={self.created_at}>" if __name__ == '__main__': print(db.create_tables([User]))