Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from dataclasses import dataclass, asdict
- from uuid import (
- UUID,
- uuid4,
- )
- @dataclass
- class Person:
- """
- Информация о пользователе.
- Attrs:
- login: логин пользователя.
- password: пароль пользователя.
- username: имя пользователя.
- metadata: дополнительные сведения о пользователе.
- """
- login: str = ""
- password: str = ""
- username: str = ""
- metadata: str = ""
- class PersonDB:
- _database: dict[UUID, Person]
- _login_registry: set[str]
- _min_password_len = 10
- def __init__(self) -> None:
- """Инициализирует базу данных."""
- self._database = {}
- self._login_registry = set()
- def _check_password(self, password):
- """
- Пароль считается надежным, если
- пароль содержит хотя бы одну букву английского алфавита в верхнем регистре;
- пароль содержит хотя бы одну букву английского алфавита в нижнем регистре;
- пароль содержит хотя бы одну цифру от 0 до 9;
- пароль состоит не менее чем из 10 символов;
- пароль не содержит никаких символов, кроме разрешенных.
- """
- alph_lower = 'abcdefghijklmnopqrstuvwxyz'
- alph_upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
- num = '0123456789'
- if len(password) < self._min_password_len:
- return False
- contains_alph_lower = False
- contains_alph_upper = False
- contains_num = False
- for l in password:
- if l in alph_lower:
- contains_alph_lower = True
- elif l in alph_upper:
- contains_alph_upper = True
- elif l in num:
- contains_num = True
- else:
- return False
- return contains_alph_lower and contains_alph_upper and contains_num
- def _check_login(self, login):
- """
- Логин должен быть уникальным и содержать только английские буквы в верхнем и нижнем регистре, а также цифры от 0 до 9. Логин не может быть пустой строкой.
- """
- return login != '' and login.isalnum()
- def _check_login_and_password(self, login, password):
- login_is_ok = self._check_login(login)
- if not login_is_ok:
- raise ValueError("incorrect login")
- if login in self._login_registry:
- raise ValueError("such login already exists")
- password_is_ok = self._check_password(password)
- if not password_is_ok:
- raise ValueError("incorrect password")
- def create_person(self, person: Person) -> UUID:
- """
- Создает новую запись о пользователе в базе данных.
- Args:
- person: данные о пользователе, которые будут помещены в БД.
- Returns:
- UUID - идентификатор, который будет связан с созданной записью.
- Raises:
- ValueError, если логин или пароль не удовлетворяют требованиям.
- """
- self._check_login_and_password(person.login, person.password)
- id = uuid4()
- if id in self._database:
- raise Exception("such id already exists")
- self._login_registry.add(person.login)
- self._database[id] = person
- return id
- def read_person_info(self, person_id: UUID) -> Person:
- """
- Читает актуальные данные пользователя из базы данных.
- Args:
- person_id: идентификатор пользователя в формате UUID.
- Returns:
- Данные о пользователе, упакованные в структуру Person.
- Raises:
- KeyError, если в базе данных нет пользователя с person_id.
- """
- if person_id not in self._database:
- raise KeyError("no person with such id")
- return self._database[person_id]
- def update_person_info(self, person_id: UUID, person_info_new: Person) -> None:
- """
- Обновляет данные о пользователе.
- Args:
- person_id: идентификатор пользователя в формате UUID.
- person_info_new: модель со значениями на обновление. Будут обновлены
- только те поля, чье значение отличается от пустой строки '',
- остальные поля будут оставлены без изменений.
- Raises:
- ValueError, если при обновлении логина или пароля логин или пароль
- не прошли этап валидации.
- KeyError, если в базе данных нет пользователя с person_id.
- """
- if person_id not in self._database:
- raise KeyError("no person with such id")
- self._check_login_and_password(person_info_new.login, person_info_new.password)
- old_login = self._database[person_id].login
- new_person = Person()
- dict_helper = asdict(self._database[person_id])
- # сли копироавть каждое поле отдельно - то там будет ссылка или значение копироваться?
- # как надо былобез dict_helper?
- new_person.login = dict_helper['login']
- new_person.password = dict_helper['password']
- new_person.username = dict_helper['username']
- new_person.metadata = dict_helper['metadata']
- if person_info_new.login != '':
- self._login_registry.remove(old_login)
- new_person.login = person_info_new.login
- self._login_registry.add(new_person.login)
- if person_info_new.password != '':
- new_person.password = person_info_new.password
- if person_info_new.username != '':
- new_person.username = person_info_new.username
- if person_info_new.metadata != '':
- new_person.metadata = person_info_new.metadata
- self._database[person_id] = new_person
- def delete_person(self, person_id: UUID) -> None:
- """
- Удаляет запись о пользователе.
- Args:
- person_id: идентификатор пользователя в формате UUID.
- Raises:
- KeyError, если в базе данных нет пользователя с person_id.
- """
- self._login_registry.remove(self._database[person_id].login)
- if person_id not in self._database:
- raise KeyError("no person with such id")
- self._database.pop(person_id)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement