passphera-core 0.10.0__tar.gz → 0.11.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. {passphera_core-0.10.0 → passphera_core-0.11.1}/PKG-INFO +2 -2
  2. passphera_core-0.11.1/passphera_core/application/__init__.py +0 -0
  3. passphera_core-0.11.1/passphera_core/application/generator.py +57 -0
  4. passphera_core-0.11.1/passphera_core/application/password.py +86 -0
  5. {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core/entities.py +15 -46
  6. passphera_core-0.11.1/passphera_core/exceptions.py +19 -0
  7. passphera_core-0.11.1/passphera_core/interfaces.py +44 -0
  8. {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core.egg-info/PKG-INFO +2 -2
  9. {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core.egg-info/SOURCES.txt +1 -2
  10. {passphera_core-0.10.0 → passphera_core-0.11.1}/setup.py +2 -2
  11. passphera_core-0.10.0/passphera_core/__init__.py +0 -2
  12. passphera_core-0.10.0/passphera_core/application/generator.py +0 -78
  13. passphera_core-0.10.0/passphera_core/application/password.py +0 -118
  14. passphera_core-0.10.0/passphera_core/application/user.py +0 -56
  15. passphera_core-0.10.0/passphera_core/exceptions.py +0 -49
  16. passphera_core-0.10.0/passphera_core/interfaces.py +0 -80
  17. {passphera_core-0.10.0 → passphera_core-0.11.1}/README.md +0 -0
  18. {passphera_core-0.10.0/passphera_core/application → passphera_core-0.11.1/passphera_core}/__init__.py +0 -0
  19. {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core.egg-info/dependency_links.txt +0 -0
  20. {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core.egg-info/requires.txt +0 -0
  21. {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core.egg-info/top_level.txt +0 -0
  22. {passphera_core-0.10.0 → passphera_core-0.11.1}/setup.cfg +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: passphera-core
3
- Version: 0.10.0
3
+ Version: 0.11.1
4
4
  Summary: The core system of passphera project
5
5
  Home-page: https://github.com/passphera/core
6
6
  Author: Fathi Abdelmalek
7
7
  Author-email: abdelmalek.fathi.2001@gmail.com
8
- Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Development Status :: 4 - Beta
9
9
  Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python
@@ -0,0 +1,57 @@
1
+ from datetime import datetime, timezone
2
+ from uuid import UUID
3
+
4
+ from passphera_core.entities import Generator
5
+ from passphera_core.interfaces import GeneratorRepository
6
+
7
+
8
+ class GetGeneratorUseCase:
9
+ def __init__(self, generator_repository: GeneratorRepository):
10
+ self.generator_repository: GeneratorRepository = generator_repository
11
+
12
+ def execute(self, generator_id: UUID) -> Generator:
13
+ return self.generator_repository.get(generator_id)
14
+
15
+
16
+ class GetGeneratorPropertyUseCase:
17
+ def __init__(self, generator_repository: GeneratorRepository):
18
+ self.generator_repository: GeneratorRepository = generator_repository
19
+
20
+ def execute(self, generator_id: UUID, field: str) -> str:
21
+ generator_entity: Generator = self.generator_repository.get(generator_id)
22
+ return getattr(generator_entity, field)
23
+
24
+
25
+ class UpdateGeneratorPropertyUseCase:
26
+ def __init__(self, generator_repository: GeneratorRepository):
27
+ self.generator_repository: GeneratorRepository = generator_repository
28
+
29
+ def execute(self, generator_id: UUID, field: str, value: str) -> None:
30
+ generator_entity: Generator = self.generator_repository.get(generator_id)
31
+ setattr(generator_entity, field, value)
32
+ if field == 'algorithm':
33
+ generator_entity.get_algorithm()
34
+ generator_entity.updated_at = datetime.now(timezone.utc)
35
+ self.generator_repository.update(generator_entity)
36
+
37
+
38
+ class AddCharacterReplacementUseCase:
39
+ def __init__(self, generator_repository: GeneratorRepository):
40
+ self.generator_repository: GeneratorRepository = generator_repository
41
+
42
+ def execute(self, generator_id: UUID, character: str, replacement: str) -> None:
43
+ generator_entity: Generator = self.generator_repository.get(generator_id)
44
+ generator_entity.replace_character(character, replacement)
45
+ generator_entity.updated_at = datetime.now(timezone.utc)
46
+ self.generator_repository.update(generator_entity)
47
+
48
+
49
+ class ResetCharacterReplacementUseCase:
50
+ def __init__(self, generator_repository: GeneratorRepository,):
51
+ self.generator_repository: GeneratorRepository = generator_repository
52
+
53
+ def execute(self, generator_id: UUID, character: str) -> None:
54
+ generator_entity: Generator = self.generator_repository.get(generator_id)
55
+ generator_entity.reset_character(character)
56
+ generator_entity.updated_at = datetime.now(timezone.utc)
57
+ self.generator_repository.update(generator_entity)
@@ -0,0 +1,86 @@
1
+ from uuid import UUID
2
+
3
+ from passphera_core.entities import Password, Generator
4
+ from passphera_core.exceptions import DuplicatePasswordException, PasswordNotFoundException
5
+ from passphera_core.interfaces import PasswordRepository, GeneratorRepository
6
+
7
+
8
+ class GeneratePasswordUseCase:
9
+ def __init__(
10
+ self,
11
+ password_repository: PasswordRepository,
12
+ generator_repository: GeneratorRepository,
13
+ ):
14
+ self.password_repository: PasswordRepository = password_repository
15
+ self.generator_repository: GeneratorRepository = generator_repository
16
+
17
+ def execute(self, generator_id: UUID, context: str, text: str) -> Password:
18
+ password_entity: Password = self.password_repository.get_by_context(context)
19
+ if password_entity:
20
+ raise DuplicatePasswordException(password_entity)
21
+ generator_entity: Generator = self.generator_repository.get(generator_id)
22
+ password: str = generator_entity.generate_password(text)
23
+ password_entity: Password = Password(context=context, text=text, password=password)
24
+ password_entity.encrypt()
25
+ self.password_repository.save(password_entity)
26
+ return password_entity
27
+
28
+
29
+ class GetPasswordByContextUseCase:
30
+ def __init__(self, password_repository: PasswordRepository):
31
+ self.password_repository: PasswordRepository = password_repository
32
+
33
+ def execute(self, context: str) -> Password:
34
+ password_entity: Password = self.password_repository.get_by_context(context)
35
+ if not password_entity:
36
+ raise PasswordNotFoundException()
37
+ return password_entity
38
+
39
+
40
+ class UpdatePasswordUseCase:
41
+ def __init__(
42
+ self,
43
+ password_repository: PasswordRepository,
44
+ generator_repository: GeneratorRepository,
45
+ ):
46
+ self.password_repository: PasswordRepository = password_repository
47
+ self.generator_repository: GeneratorRepository = generator_repository
48
+
49
+ def execute(self, generator_id: UUID, context: str, text: str) -> Password:
50
+ password_entity: Password = self.password_repository.get_by_context(context)
51
+ if not password_entity:
52
+ raise PasswordNotFoundException()
53
+ generator_entity: Generator = self.generator_repository.get(generator_id)
54
+ password: str = generator_entity.generate_password(text)
55
+ password_entity.text = text
56
+ password_entity.password = password
57
+ password_entity.encrypt()
58
+ self.password_repository.update(password_entity)
59
+ return password_entity
60
+
61
+
62
+ class DeletePasswordUseCase:
63
+ def __init__(self, password_repository: PasswordRepository):
64
+ self.password_repository: PasswordRepository = password_repository
65
+
66
+ def execute(self, context: str) -> None:
67
+ password_entity: Password = self.password_repository.get_by_context(context)
68
+ if not password_entity:
69
+ raise PasswordNotFoundException()
70
+ self.password_repository.delete(password_entity)
71
+
72
+
73
+ class GetAllPasswordsUseCase:
74
+ def __init__(self, password_repository: PasswordRepository):
75
+ self.password_repository: PasswordRepository = password_repository
76
+
77
+ def execute(self) -> list[Password]:
78
+ return self.password_repository.list()
79
+
80
+
81
+ class DeleteAllPasswordsUseCase:
82
+ def __init__(self, password_repository: PasswordRepository):
83
+ self.password_repository: PasswordRepository = password_repository
84
+
85
+ def execute(self) -> None:
86
+ self.password_repository.flush()
@@ -5,22 +5,19 @@ from uuid import UUID, uuid4
5
5
  from cryptography.fernet import Fernet
6
6
 
7
7
  from cipherspy.cipher import *
8
- from cipherspy.cipher.base_cipher import BaseCipherAlgorithm
8
+ from cipherspy.exceptions import InvalidAlgorithmException
9
9
  from cipherspy.utilities import generate_salt, derive_key
10
10
 
11
- from passphera_core import exceptions
12
-
13
11
 
14
12
  @dataclass
15
13
  class Password:
16
14
  id: UUID = field(default_factory=uuid4)
17
- user_id: UUID = field(default_factory=uuid4)
18
- created_at: datetime = field(default=datetime.now(timezone.utc))
19
- updated_at: datetime = field(default=datetime.now(timezone.utc))
15
+ created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
16
+ updated_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
20
17
  context: str = field(default_factory=str)
21
18
  text: str = field(default_factory=str)
22
19
  password: str = field(default_factory=str)
23
- salt: bytes = field(default_factory=bytes)
20
+ salt: bytes = field(default_factory=lambda: bytes)
24
21
 
25
22
  def encrypt(self) -> None:
26
23
  self.salt = generate_salt()
@@ -33,9 +30,10 @@ class Password:
33
30
 
34
31
 
35
32
  @dataclass
36
- class GeneratorConfig:
33
+ class Generator:
37
34
  id: UUID = field(default_factory=uuid4)
38
- generator_id: UUID = field(default_factory=uuid4)
35
+ created_at: datetime = field(default_factory=datetime.now)
36
+ updated_at: datetime = field(default_factory=datetime.now)
39
37
  shift: int = field(default=3)
40
38
  multiplier: int = field(default=3)
41
39
  key: str = field(default="hill")
@@ -56,7 +54,7 @@ class GeneratorConfig:
56
54
  :return: BaseCipherAlgorithm: The primary algorithm used for the cipher
57
55
  """
58
56
  if self.algorithm.lower() not in self._cipher_registry:
59
- raise exceptions.InvalidAlgorithmException(self.algorithm)
57
+ raise InvalidAlgorithmException(self.algorithm)
60
58
  return self._cipher_registry[self.algorithm.lower()]
61
59
 
62
60
  def replace_character(self, char: str, replacement: str) -> None:
@@ -77,53 +75,24 @@ class GeneratorConfig:
77
75
  """
78
76
  self.characters_replacements.pop(char, None)
79
77
 
80
-
81
- @dataclass
82
- class Generator:
83
- id: UUID = field(default_factory=uuid4)
84
- user_id: UUID = field(default_factory=uuid4)
85
- created_at: datetime = field(default_factory=datetime.now)
86
- updated_at: datetime = field(default_factory=datetime.now)
87
- config_id: UUID = field(default_factory=UUID)
88
- config: GeneratorConfig = field(default_factory=GeneratorConfig)
89
-
90
- def __post_init__(self):
91
- self.config = GeneratorConfig(generator_id=self.id)
92
-
93
78
  def apply_replacements(self, password: str) -> str:
94
79
  """
95
80
  Replace character from the ciphered password with character replacements from the generator configurations
81
+ :param password: The password to perform the action on it
96
82
  :return: str: The new ciphered password after character replacements
97
83
  """
98
- translation_table = str.maketrans(self.config.characters_replacements)
84
+ translation_table: dict[int, str] = str.maketrans(self.characters_replacements)
99
85
  return password.translate(translation_table)
100
86
 
101
87
  def generate_password(self, text: str) -> str:
102
88
  """
103
89
  Generate a strong password string using the raw password (add another layer of encryption to it)
90
+ :param text: The text to generate password from it
104
91
  :return: str: The generated ciphered password
105
92
  """
106
- affine = AffineCipherAlgorithm(self.config.shift, self.config.multiplier)
107
- intermediate = affine.encrypt(f"{self.config.prefix}{text}{self.config.postfix}")
108
- main_algorithm = self.config.get_algorithm()
109
- password = main_algorithm.encrypt(intermediate)
93
+ main_algorithm: BaseCipherAlgorithm = self.get_algorithm()
94
+ secondary_algorithm: AffineCipherAlgorithm = AffineCipherAlgorithm(self.shift, self.multiplier)
95
+ intermediate: str = secondary_algorithm.encrypt(f"{self.prefix}{text}{self.postfix}")
96
+ password: str = main_algorithm.encrypt(intermediate)
110
97
  password = self.apply_replacements(password)
111
98
  return ''.join(c.upper() if c in text else c for c in password)
112
-
113
-
114
- @dataclass
115
- class User:
116
- id: UUID = field(default_factory=uuid4)
117
- created_at: datetime = field(default_factory=datetime.now)
118
- updated_at: datetime = field(default_factory=datetime.now)
119
- username: str = field(default_factory=str)
120
- email: str = field(default_factory=str)
121
- password: str = field(default_factory=str)
122
- generator_id: UUID = field(default_factory=UUID)
123
- passwords_ids: list[UUID] = field(default_factory=list[UUID])
124
-
125
- def add_password(self, password_id: UUID) -> None:
126
- self.passwords_ids.append(password_id)
127
-
128
- def delete_password(self, password_id: UUID) -> None:
129
- self.passwords_ids.remove(password_id)
@@ -0,0 +1,19 @@
1
+ from passphera_core.entities import Password
2
+
3
+
4
+ class PasswordNotFoundException(Exception):
5
+ def __init__(self) -> None:
6
+ super().__init__("Password not found")
7
+
8
+
9
+ class DuplicatePasswordException(Exception):
10
+ def __init__(self, password: Password) -> None:
11
+ self.password = password
12
+ message = self._build_message(password)
13
+ super().__init__(message)
14
+
15
+ @staticmethod
16
+ def _build_message(password: Password) -> str:
17
+ if hasattr(password, 'context') and password.context:
18
+ return f"Password for context '{password.context}' already exists"
19
+ return "Duplicate password detected"
@@ -0,0 +1,44 @@
1
+ from abc import ABC, abstractmethod
2
+ from uuid import UUID
3
+
4
+ from passphera_core.entities import Password, Generator
5
+
6
+
7
+ class PasswordRepository(ABC):
8
+ @abstractmethod
9
+ def save(self, password: Password) -> None:
10
+ pass
11
+
12
+ @abstractmethod
13
+ def get_by_context(self, context: str) -> Password:
14
+ pass
15
+
16
+ @abstractmethod
17
+ def update(self, password: Password) -> None:
18
+ pass
19
+
20
+ @abstractmethod
21
+ def delete(self, password: Password) -> None:
22
+ pass
23
+
24
+ @abstractmethod
25
+ def list(self) -> list[Password]:
26
+ pass
27
+
28
+ @abstractmethod
29
+ def flush(self) -> None:
30
+ pass
31
+
32
+
33
+ class GeneratorRepository(ABC):
34
+ @abstractmethod
35
+ def save(self, generator: Generator) -> None:
36
+ pass
37
+
38
+ @abstractmethod
39
+ def get(self, generator_id: UUID) -> Generator:
40
+ pass
41
+
42
+ @abstractmethod
43
+ def update(self, generator: Generator) -> None:
44
+ pass
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: passphera-core
3
- Version: 0.10.0
3
+ Version: 0.11.1
4
4
  Summary: The core system of passphera project
5
5
  Home-page: https://github.com/passphera/core
6
6
  Author: Fathi Abdelmalek
7
7
  Author-email: abdelmalek.fathi.2001@gmail.com
8
- Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Development Status :: 4 - Beta
9
9
  Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python
@@ -11,5 +11,4 @@ passphera_core.egg-info/requires.txt
11
11
  passphera_core.egg-info/top_level.txt
12
12
  passphera_core/application/__init__.py
13
13
  passphera_core/application/generator.py
14
- passphera_core/application/password.py
15
- passphera_core/application/user.py
14
+ passphera_core/application/password.py
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setup(
7
7
  name='passphera-core',
8
- version='0.10.0',
8
+ version='0.11.1',
9
9
  author='Fathi Abdelmalek',
10
10
  author_email='abdelmalek.fathi.2001@gmail.com',
11
11
  url='https://github.com/passphera/core',
@@ -16,7 +16,7 @@ setup(
16
16
  python_requires='>=3',
17
17
  install_requires=['cipherspy'],
18
18
  classifiers=[
19
- "Development Status :: 3 - Alpha",
19
+ "Development Status :: 4 - Beta",
20
20
  "License :: OSI Approved :: MIT License",
21
21
  "Operating System :: OS Independent",
22
22
  "Programming Language :: Python",
@@ -1,2 +0,0 @@
1
- from passphera_core.entities.generator import Generator
2
- from passphera_core.exceptions import InvalidAlgorithmException
@@ -1,78 +0,0 @@
1
- from datetime import datetime, timezone
2
- from uuid import UUID
3
-
4
- from passphera_core.entities import Generator, GeneratorConfig
5
- from passphera_core.interfaces import GeneratorRepository, GeneratorConfigRepository
6
-
7
-
8
- class GetGeneratorUseCase:
9
- def __init__(self, generator_repository: GeneratorRepository):
10
- self.generator_repository: GeneratorRepository = generator_repository
11
-
12
- def execute(self, user_id: UUID) -> Generator:
13
- return self.generator_repository.find_by_user_id(user_id)
14
-
15
-
16
- class GetGeneratorConfigPropertyUseCase:
17
- def __init__(self, generator_repository: GeneratorRepository, generator_config_repository: GeneratorConfigRepository):
18
- self.generator_repository: GeneratorRepository = generator_repository
19
- self.generator_config_repository: GeneratorConfigRepository = generator_config_repository
20
-
21
- def execute(self, user_id: UUID, field: str) -> str:
22
- generator_entity: Generator = self.generator_repository.find_by_user_id(user_id)
23
- generator_config_entity: GeneratorConfig = self.generator_config_repository.find_by_generator_id(generator_entity.id)
24
- return getattr(generator_config_entity, field)
25
-
26
-
27
- class UpdateGeneratorConfigUseCase:
28
- def __init__(
29
- self,
30
- generator_repository: GeneratorRepository,
31
- generator_config_repository: GeneratorConfigRepository,
32
- ):
33
- self.generator_repository: GeneratorRepository = generator_repository
34
- self.generator_config_repository: GeneratorConfigRepository = generator_config_repository
35
-
36
- def execute(self, user_id: UUID, field: str, value: str) -> None:
37
- generator_entity: Generator = self.generator_repository.find_by_user_id(user_id)
38
- generator_config_entity: GeneratorConfig = self.generator_config_repository.find_by_generator_id(generator_entity.id)
39
- setattr(generator_config_entity, field, value)
40
- if field == 'algorithm':
41
- generator_config_entity.get_algorithm()
42
- generator_config_entity.updated_at = datetime.now(timezone.utc)
43
- self.generator_config_repository.update(generator_config_entity)
44
-
45
-
46
-
47
- class AddCharacterReplacementUseCase:
48
- def __init__(
49
- self,
50
- generator_repository: GeneratorRepository,
51
- generator_config_repository: GeneratorConfigRepository,
52
- ):
53
- self.generator_repository: GeneratorRepository = generator_repository
54
- self.generator_config_repository: GeneratorConfigRepository = generator_config_repository
55
-
56
- def execute(self, user_id: UUID, character: str, replacement: str) -> None:
57
- generator_entity: Generator = self.generator_repository.find_by_user_id(user_id)
58
- generator_config_entity: GeneratorConfig = self.generator_config_repository.find_by_generator_id(generator_entity.id)
59
- generator_config_entity.replace_character(character, replacement)
60
- generator_config_entity.updated_at = datetime.now(timezone.utc)
61
- self.generator_config_repository.update(generator_config_entity)
62
-
63
-
64
- class ResetCharacterReplacementUseCase:
65
- def __init__(
66
- self,
67
- generator_repository: GeneratorRepository,
68
- generator_config_repository: GeneratorConfigRepository,
69
- ):
70
- self.generator_repository: GeneratorRepository = generator_repository
71
- self.generator_config_repository: GeneratorConfigRepository = generator_config_repository
72
-
73
- def execute(self, user_id: UUID, character: str) -> None:
74
- generator_entity: Generator = self.generator_repository.find_by_user_id(user_id)
75
- generator_config_entity: GeneratorConfig = self.generator_config_repository.find_by_generator_id(generator_entity.id)
76
- generator_config_entity.reset_character(character)
77
- generator_config_entity.updated_at = datetime.now(timezone.utc)
78
- self.generator_config_repository.update(generator_config_entity)
@@ -1,118 +0,0 @@
1
- from datetime import datetime, timezone
2
- from uuid import UUID
3
-
4
- from passphera_core.entities import Password, Generator, User
5
- from passphera_core.exceptions import EntityNotFoundException
6
- from passphera_core.interfaces import PasswordRepository, GeneratorRepository, UserRepository
7
-
8
-
9
- class GeneratePasswordUseCase:
10
- def __init__(
11
- self,
12
- password_repository: PasswordRepository,
13
- generator_repository: GeneratorRepository,
14
- user_repository: UserRepository
15
- ):
16
- self.password_repository: PasswordRepository = password_repository
17
- self.generator_repository: GeneratorRepository = generator_repository
18
- self.user_repository: UserRepository = user_repository
19
-
20
- def execute(self, user_id: UUID, context: str, text: str) -> Password:
21
- user_entity: User = self.user_repository.find_by_id(user_id)
22
- generator_entity: Generator = self.generator_repository.find_by_id(user_entity.generator)
23
- password: str = generator_entity.generate_password(text)
24
- password_entity: Password = Password(user_id=user_id, context=context, text=text, password=password)
25
- password_entity.encrypt()
26
- self.password_repository.save(password_entity)
27
- user_entity.add_password(password_entity.id)
28
- self.user_repository.update(user_entity)
29
- return password_entity
30
-
31
-
32
- class GetPasswordByIdUseCase:
33
- def __init__(self, password_repository: PasswordRepository):
34
- self.password_repository: PasswordRepository = password_repository
35
-
36
- def execute(self, password_id: UUID) -> Password:
37
- password_entity: Password = self.password_repository.find_by_id(password_id)
38
- if not password_entity:
39
- raise EntityNotFoundException(password_entity)
40
- return password_entity
41
-
42
-
43
- class GetPasswordByContextUseCase:
44
- def __init__(self, password_repository: PasswordRepository, user_repository: UserRepository):
45
- self.password_repository: PasswordRepository = password_repository
46
- self.user_repository: UserRepository = user_repository
47
-
48
- def execute(self, user_id: UUID, context: str) -> Password:
49
- user_entity: User = self.user_repository.find_by_id(user_id)
50
- for password_id in user_entity.passwords:
51
- password_entity: Password = self.password_repository.find_by_id(password_id)
52
- if password_entity.context == context:
53
- return password_entity
54
- raise EntityNotFoundException(Password())
55
-
56
-
57
- class UpdatePasswordUseCase:
58
- def __init__(
59
- self,
60
- password_repository: PasswordRepository,
61
- generator_repository: GeneratorRepository,
62
- user_repository: UserRepository
63
- ):
64
- self.password_repository: PasswordRepository = password_repository
65
- self.generator_repository: GeneratorRepository = generator_repository
66
- self.user_repository: UserRepository = user_repository
67
-
68
- def execute(self, user_id: UUID, context: str, text: str) -> Password:
69
- user_entity: User = self.user_repository.find_by_id(user_id)
70
- generator_entity: Generator = self.generator_repository.find_by_id(user_entity.generator)
71
- for password_id in user_entity.passwords:
72
- password_entity: Password = self.password_repository.find_by_id(password_id)
73
- if password_entity.context == context:
74
- password_entity.password = generator_entity.generate_password(text)
75
- password_entity.encrypt()
76
- password_entity.updated_at = datetime.now(timezone.utc)
77
- self.password_repository.update(password_entity)
78
- return password_entity
79
- raise EntityNotFoundException(Password())
80
-
81
-
82
- class DeletePasswordUseCase:
83
- def __init__(self, password_repository: PasswordRepository, user_repository: UserRepository):
84
- self.password_repository: PasswordRepository = password_repository
85
- self.user_repository: UserRepository = user_repository
86
-
87
- def execute(self, user_id: UUID, password_id: UUID) -> None:
88
- self.password_repository.delete(password_id)
89
- user_entity: User = self.user_repository.find_by_id(user_id)
90
- user_entity.delete_password(password_id)
91
- self.user_repository.update(user_entity)
92
-
93
-
94
- class GetAllUserPasswordsUseCase:
95
- def __init__(self, password_repository: PasswordRepository, user_repository: UserRepository):
96
- self.password_repository: PasswordRepository = password_repository
97
- self.user_repository: UserRepository = user_repository
98
-
99
- def execute(self, user_id: UUID) -> list[Password]:
100
- user_entity: User = self.user_repository.find_by_id(user_id)
101
- passwords: list[Password] = []
102
- for password_id in user_entity.passwords:
103
- password_entity: Password = self.password_repository.find_by_id(password_id)
104
- passwords.append(password_entity)
105
- return passwords
106
-
107
-
108
- class DeleteAllUserPasswordsUseCase:
109
- def __init__(self, password_repository: PasswordRepository, user_repository: UserRepository):
110
- self.password_repository: PasswordRepository = password_repository
111
- self.user_repository: UserRepository = user_repository
112
-
113
- def execute(self, user_id: UUID) -> None:
114
- user_entity: User = self.user_repository.find_by_id(user_id)
115
- for password_id in user_entity.passwords:
116
- self.password_repository.delete(password_id)
117
- user_entity.delete_password(password_id)
118
- self.user_repository.update(user_entity)
@@ -1,56 +0,0 @@
1
- from uuid import UUID
2
-
3
- from passphera_core.entities import User, Generator
4
- from passphera_core.exceptions import DuplicateEntityException
5
- from passphera_core.interfaces import UserRepository, GeneratorRepository
6
-
7
-
8
- class RegisterUserUseCase:
9
- def __init__(self, user_repository: UserRepository, generator_repository: GeneratorRepository):
10
- self.user_repository: UserRepository = user_repository
11
- self.generator_repository: GeneratorRepository = generator_repository
12
-
13
- def execute(self, user: User) -> User:
14
- if self.user_repository.find_by_email(user.email):
15
- raise DuplicateEntityException(user, 'email')
16
- if self.user_repository.find_by_username(user.username):
17
- raise DuplicateEntityException(user, 'username')
18
- user_entity: User = User(**user.__dict__)
19
- generator_entity: Generator = Generator(user_id=user_entity.id)
20
- self.generator_repository.save(generator_entity)
21
- user_entity.generator_id = generator_entity.id
22
- self.user_repository.save(user_entity)
23
- return user_entity
24
-
25
-
26
- class GetUserByIdUseCase:
27
- def __init__(self, user_repository: UserRepository):
28
- self.user_repository: UserRepository = user_repository
29
-
30
- def execute(self, id: UUID) -> User:
31
- user = self.user_repository.find_by_id(id)
32
- if not user:
33
- raise ValueError(f'User not found')
34
- return user
35
-
36
-
37
- class GetUserByUsernameUseCase:
38
- def __init__(self, user_repository: UserRepository):
39
- self.user_repository = user_repository
40
-
41
- def execute(self, username: str) -> User:
42
- user = self.user_repository.find_by_username(username)
43
- if not user:
44
- raise ValueError(f'User not found')
45
- return user
46
-
47
-
48
- class GetUserByEmailUseCase:
49
- def __init__(self, user_repository: UserRepository):
50
- self.user_repository = user_repository
51
-
52
- def execute(self, email: str) -> User:
53
- user = self.user_repository.find_by_email(email)
54
- if not user:
55
- raise ValueError(f'User not found')
56
- return user
@@ -1,49 +0,0 @@
1
- from typing import Union, Literal
2
-
3
- from passphera_core.entities import Password, Generator, User
4
-
5
-
6
- class InvalidAlgorithmException(Exception):
7
- def __init__(self, algorithm: str) -> None:
8
- self.algorithm = algorithm
9
- super().__init__(f"Invalid algorithm: '{algorithm}'")
10
-
11
-
12
- class EntityNotFoundException(Exception):
13
- def __init__(self, entity: Union[Password, Generator, User]) -> None:
14
- self.entity = entity
15
- entity_type = entity.__class__.__name__
16
- super().__init__(f"{entity_type} not found")
17
-
18
-
19
- class DuplicateEntityException(Exception):
20
- def __init__(
21
- self,
22
- entity: Union[Password, User],
23
- duplicate_field: Literal['context', 'email', 'username'] = None
24
- ) -> None:
25
- self.entity = entity
26
- self.duplicate_field = duplicate_field
27
- message = self._build_message(entity, duplicate_field)
28
- super().__init__(message)
29
-
30
- def _build_message(self, entity: Union[Password, User], duplicate_field: str | None) -> str:
31
- if isinstance(entity, Password):
32
- return self._build_password_message(entity)
33
- elif isinstance(entity, User):
34
- return self._build_user_message(entity, duplicate_field)
35
- return "Duplicate entity detected"
36
-
37
- @staticmethod
38
- def _build_password_message(password: Password) -> str:
39
- if hasattr(password, 'context') and password.context:
40
- return f"Password for context '{password.context}' already exists"
41
- return "Duplicate password detected"
42
-
43
- @staticmethod
44
- def _build_user_message(user: User, duplicate_field: str) -> str:
45
- if duplicate_field == 'email':
46
- return f"User with email '{user.email}' already exists"
47
- elif duplicate_field == 'username':
48
- return f"User with username '{user.username}' already exists"
49
- return "Duplicate user detected"
@@ -1,80 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from uuid import UUID
3
-
4
- from passphera_core.entities import Password, Generator, GeneratorConfig, User
5
-
6
-
7
- class PasswordRepository(ABC):
8
- @abstractmethod
9
- def save(self, password: Password) -> None:
10
- pass
11
-
12
- @abstractmethod
13
- def update(self, password: Password) -> None:
14
- pass
15
-
16
- @abstractmethod
17
- def delete(self, password_id: UUID) -> None:
18
- pass
19
-
20
- @abstractmethod
21
- def find_by_id(self, password_id: UUID) -> Password:
22
- pass
23
-
24
-
25
- class GeneratorRepository(ABC):
26
- @abstractmethod
27
- def save(self, generator: Generator) -> None:
28
- pass
29
-
30
- @abstractmethod
31
- def update(self, generator: Generator) -> None:
32
- pass
33
-
34
- @abstractmethod
35
- def find_by_id(self, generator_id: UUID) -> Generator:
36
- pass
37
-
38
- @abstractmethod
39
- def find_by_user_id(self, user_id: UUID) -> Generator:
40
- pass
41
-
42
-
43
- class GeneratorConfigRepository(ABC):
44
- @abstractmethod
45
- def save(self, generator_config: GeneratorConfig) -> None:
46
- pass
47
-
48
- @abstractmethod
49
- def update(self, generator_config: GeneratorConfig) -> None:
50
- pass
51
-
52
- @abstractmethod
53
- def find_by_id(self, generator_config_id: UUID) -> GeneratorConfig:
54
- pass
55
-
56
- @abstractmethod
57
- def find_by_generator_id(self, generator_id: UUID) -> GeneratorConfig:
58
- pass
59
-
60
-
61
- class UserRepository(ABC):
62
- @abstractmethod
63
- def save(self, user: User) -> None:
64
- pass
65
-
66
- @abstractmethod
67
- def update(self, user: User) -> None:
68
- pass
69
-
70
- @abstractmethod
71
- def find_by_id(self, user_id: UUID) -> User:
72
- pass
73
-
74
- @abstractmethod
75
- def find_by_username(self, username: str) -> User:
76
- pass
77
-
78
- @abstractmethod
79
- def find_by_email(self, email: str) -> User:
80
- pass