Advertisement
Korotkodul

person_clean

Sep 28th, 2024 (edited)
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.29 KB | None | 0 0
  1. from dataclasses import dataclass, asdict
  2. from uuid import (
  3.     UUID,
  4.     uuid4,
  5. )
  6. import copy
  7.  
  8.  
  9. @dataclass
  10. class Person:
  11.     """
  12.    Информация о пользователе.
  13.  
  14.    Attrs:
  15.        login: логин пользователя.
  16.        password: пароль пользователя.
  17.        username: имя пользователя.
  18.        metadata: дополнительные сведения о пользователе.
  19.    """
  20.     login: str = ""
  21.     password: str = ""
  22.     username: str = ""
  23.     metadata: str = ""
  24.  
  25.  
  26. class PersonDB:
  27.     _database: dict[UUID, Person]
  28.     _login_registry: set[str]
  29.     _min_password_len = 10
  30.  
  31.     def __init__(self) -> None:
  32.         """Инициализирует базу данных."""
  33.         self._database = {}
  34.         self._login_registry = set()
  35.  
  36.     def _check_password(self, password):
  37.         """
  38.        Пароль считается надежным, если
  39. пароль содержит хотя бы одну букву английского алфавита в верхнем регистре;
  40. пароль содержит хотя бы одну букву английского алфавита в нижнем регистре;
  41. пароль содержит хотя бы одну цифру от 0 до 9;
  42. пароль состоит не менее чем из 10 символов;
  43. пароль не содержит никаких символов, кроме разрешенных.
  44.        """
  45.         alph_lower = 'abcdefghijklmnopqrstuvwxyz'
  46.         alph_upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  47.         num = '0123456789'
  48.         if len(password) < self._min_password_len:
  49.             return False
  50.         contains_alph_lower = False
  51.         contains_alph_upper = False
  52.         contains_num = False
  53.         for l in password:
  54.             if l in alph_lower:
  55.                 contains_alph_lower = True
  56.             elif l in alph_upper:
  57.                 contains_alph_upper = True
  58.             elif l in num:
  59.                 contains_num = True
  60.             else:
  61.                 return False
  62.         return contains_alph_lower and contains_alph_upper and contains_num
  63.  
  64.     def _check_login(self, login):
  65.         """
  66.         Логин должен быть уникальным и содержать только английские буквы в верхнем и нижнем регистре, а также цифры от 0 до 9. Логин не может быть пустой строкой.
  67.        """
  68.         return login != '' and login.isalnum()
  69.  
  70.     def _check_login_and_password(self, login, password):
  71.         login_is_ok = self._check_login(login)
  72.         if not login_is_ok:
  73.             raise ValueError("incorrect login")
  74.         if login in self._login_registry:
  75.             raise ValueError("such login already exists")
  76.         password_is_ok = self._check_password(password)
  77.         if not password_is_ok:
  78.             raise ValueError("incorrect password")
  79.  
  80.     def create_person(self, person: Person) -> UUID:
  81.         """
  82.        Создает новую запись о пользователе в базе данных.
  83.  
  84.        Args:
  85.            person: данные о пользователе, которые будут помещены в БД.
  86.  
  87.        Returns:
  88.            UUID - идентификатор, который будет связан с созданной записью.
  89.  
  90.        Raises:
  91.            ValueError, если логин или пароль не удовлетворяют требованиям.
  92.        """
  93.         self._check_login_and_password(person.login, person.password)
  94.         id = uuid4()
  95.         if id in self._database:
  96.             raise Exception("such id already exists")
  97.         self._login_registry.add(person.login)
  98.         copy_person = copy.copy(person)
  99.         self._database[id] = copy_person
  100.         return id
  101.  
  102.     def read_person_info(self, person_id: UUID) -> Person:
  103.         """
  104.        Читает актуальные данные пользователя из базы данных.
  105.  
  106.        Args:
  107.            person_id: идентификатор пользователя в формате UUID.
  108.  
  109.        Returns:
  110.            Данные о пользователе, упакованные в структуру Person.
  111.  
  112.        Raises:
  113.            KeyError, если в базе данных нет пользователя с person_id.
  114.        """
  115.         if person_id not in self._database:
  116.             raise KeyError("no person with such id")
  117.         return self._database[person_id]
  118.  
  119.     def update_person_info(self, person_id: UUID, person_info_new: Person) -> None:
  120.         """
  121.        Обновляет данные о пользователе.
  122.  
  123.        Args:
  124.            person_id: идентификатор пользователя в формате UUID.
  125.            person_info_new: модель со значениями на обновление. Будут обновлены
  126.                только те поля, чье значение отличается от пустой строки '',
  127.                остальные поля будут оставлены без изменений.
  128.  
  129.        Raises:
  130.            ValueError, если при обновлении логина или пароля логин или пароль
  131.                не прошли этап валидации.
  132.            KeyError, если в базе данных нет пользователя с person_id.
  133.        """
  134.         if person_id not in self._database:
  135.             raise KeyError("no person with such id")
  136.         new_person = Person(**asdict(self._database[person_id]))
  137.         if person_info_new.login != '':
  138.             new_person.login = person_info_new.login
  139.             login_is_ok = self._check_login(new_person.login)
  140.             if not login_is_ok:
  141.                 raise ValueError("incorrect login")
  142.             old_login = self._database[person_id].login
  143.             self._login_registry.remove(old_login)
  144.             if new_person.login in self._login_registry:
  145.                 raise ValueError("such login already exists")
  146.             self._login_registry.add(new_person.login)
  147.         if person_info_new.password != '':
  148.             new_person.password = person_info_new.password
  149.             password_is_ok = self._check_password(new_person.password)
  150.             if not password_is_ok:
  151.                 raise ValueError("incorrect password")
  152.         if person_info_new.username != '':
  153.             new_person.username = person_info_new.username
  154.         if person_info_new.metadata != '':
  155.             new_person.metadata = person_info_new.metadata
  156.         self._database[person_id] = new_person
  157.  
  158.     def delete_person(self, person_id: UUID) -> None:
  159.         """
  160.        Удаляет запись о пользователе.
  161.  
  162.        Args:
  163.            person_id: идентификатор пользователя в формате UUID.
  164.  
  165.        Raises:
  166.            KeyError, если в базе данных нет пользователя с person_id.
  167.        """
  168.         if person_id not in self._database:
  169.             raise KeyError("no person with such id")
  170.         self._login_registry.remove(self._database[person_id].login)
  171.         self._database.pop(person_id)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement