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.
- {passphera_core-0.10.0 → passphera_core-0.11.1}/PKG-INFO +2 -2
- passphera_core-0.11.1/passphera_core/application/__init__.py +0 -0
- passphera_core-0.11.1/passphera_core/application/generator.py +57 -0
- passphera_core-0.11.1/passphera_core/application/password.py +86 -0
- {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core/entities.py +15 -46
- passphera_core-0.11.1/passphera_core/exceptions.py +19 -0
- passphera_core-0.11.1/passphera_core/interfaces.py +44 -0
- {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core.egg-info/PKG-INFO +2 -2
- {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core.egg-info/SOURCES.txt +1 -2
- {passphera_core-0.10.0 → passphera_core-0.11.1}/setup.py +2 -2
- passphera_core-0.10.0/passphera_core/__init__.py +0 -2
- passphera_core-0.10.0/passphera_core/application/generator.py +0 -78
- passphera_core-0.10.0/passphera_core/application/password.py +0 -118
- passphera_core-0.10.0/passphera_core/application/user.py +0 -56
- passphera_core-0.10.0/passphera_core/exceptions.py +0 -49
- passphera_core-0.10.0/passphera_core/interfaces.py +0 -80
- {passphera_core-0.10.0 → passphera_core-0.11.1}/README.md +0 -0
- {passphera_core-0.10.0/passphera_core/application → passphera_core-0.11.1/passphera_core}/__init__.py +0 -0
- {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core.egg-info/dependency_links.txt +0 -0
- {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core.egg-info/requires.txt +0 -0
- {passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core.egg-info/top_level.txt +0 -0
- {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.
|
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 ::
|
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
|
File without changes
|
@@ -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.
|
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
|
-
|
18
|
-
|
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
|
33
|
+
class Generator:
|
37
34
|
id: UUID = field(default_factory=uuid4)
|
38
|
-
|
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
|
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.
|
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
|
-
|
107
|
-
|
108
|
-
|
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.
|
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 ::
|
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.
|
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 ::
|
19
|
+
"Development Status :: 4 - Beta",
|
20
20
|
"License :: OSI Approved :: MIT License",
|
21
21
|
"Operating System :: OS Independent",
|
22
22
|
"Programming Language :: Python",
|
@@ -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
|
File without changes
|
File without changes
|
{passphera_core-0.10.0 → passphera_core-0.11.1}/passphera_core.egg-info/dependency_links.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|