passphera-core 0.8.1__tar.gz → 0.9.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {passphera-core-0.8.1 → passphera-core-0.9.0}/PKG-INFO +2 -2
- {passphera-core-0.8.1 → passphera-core-0.9.0}/passphera_core/__init__.py +1 -1
- passphera-core-0.9.0/passphera_core/entities.py +125 -0
- passphera-core-0.9.0/passphera_core/exceptions.py +49 -0
- passphera-core-0.9.0/passphera_core/interfaces.py +92 -0
- {passphera-core-0.8.1 → passphera-core-0.9.0}/passphera_core.egg-info/PKG-INFO +2 -2
- {passphera-core-0.8.1 → passphera-core-0.9.0}/passphera_core.egg-info/SOURCES.txt +2 -1
- {passphera-core-0.8.1 → passphera-core-0.9.0}/setup.py +2 -2
- passphera-core-0.8.1/passphera_core/exceptions.py +0 -3
- passphera-core-0.8.1/passphera_core/generator.py +0 -190
- {passphera-core-0.8.1 → passphera-core-0.9.0}/README.md +0 -0
- {passphera-core-0.8.1 → passphera-core-0.9.0}/passphera_core.egg-info/dependency_links.txt +0 -0
- {passphera-core-0.8.1 → passphera-core-0.9.0}/passphera_core.egg-info/requires.txt +0 -0
- {passphera-core-0.8.1 → passphera-core-0.9.0}/passphera_core.egg-info/top_level.txt +0 -0
- {passphera-core-0.8.1 → passphera-core-0.9.0}/setup.cfg +0 -0
@@ -1,11 +1,11 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: passphera-core
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.9.0
|
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 :: 3 - Alpha
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
10
10
|
Classifier: Operating System :: OS Independent
|
11
11
|
Classifier: Programming Language :: Python
|
@@ -1,2 +1,2 @@
|
|
1
|
-
from passphera_core.generator import
|
1
|
+
from passphera_core.entities.generator import Generator
|
2
2
|
from passphera_core.exceptions import InvalidAlgorithmException
|
@@ -0,0 +1,125 @@
|
|
1
|
+
from dataclasses import dataclass, field
|
2
|
+
from datetime import datetime, timezone
|
3
|
+
from uuid import UUID, uuid4
|
4
|
+
|
5
|
+
from cryptography.fernet import Fernet
|
6
|
+
|
7
|
+
from cipherspy.cipher import *
|
8
|
+
from cipherspy.cipher.base_cipher import BaseCipherAlgorithm
|
9
|
+
from cipherspy.utilities import generate_salt, derive_key
|
10
|
+
|
11
|
+
from passphera_core import exceptions
|
12
|
+
|
13
|
+
|
14
|
+
@dataclass
|
15
|
+
class Password:
|
16
|
+
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))
|
20
|
+
context: str = field(default_factory=str)
|
21
|
+
text: str = field(default_factory=str)
|
22
|
+
password: str = field(default_factory=str)
|
23
|
+
salt: bytes = field(default_factory=bytes)
|
24
|
+
|
25
|
+
def encrypt(self) -> None:
|
26
|
+
self.salt = generate_salt()
|
27
|
+
key = derive_key(self.password, self.salt)
|
28
|
+
self.password = Fernet(key).encrypt(self.password.encode()).decode()
|
29
|
+
|
30
|
+
def decrypt(self) -> str:
|
31
|
+
key = derive_key(self.password, self.salt)
|
32
|
+
return Fernet(key).decrypt(self.password.encode()).decode()
|
33
|
+
|
34
|
+
|
35
|
+
@dataclass
|
36
|
+
class GeneratorConfig:
|
37
|
+
id: UUID = field(default_factory=uuid4)
|
38
|
+
generator_id: UUID = field(default_factory=uuid4)
|
39
|
+
shift: int = field(default=3)
|
40
|
+
multiplier: int = field(default=3)
|
41
|
+
key: str = field(default="hill")
|
42
|
+
algorithm: str = field(default="hill")
|
43
|
+
prefix: str = field(default="secret")
|
44
|
+
postfix: str = field(default="secret")
|
45
|
+
characters_replacements: dict[str, str] = field(default_factory=dict[str, str])
|
46
|
+
_cipher_registry: dict[str, BaseCipherAlgorithm] = field(default_factory=lambda: {
|
47
|
+
'caesar': CaesarCipherAlgorithm,
|
48
|
+
'affine': AffineCipherAlgorithm,
|
49
|
+
'playfair': PlayfairCipherAlgorithm,
|
50
|
+
'hill': HillCipherAlgorithm,
|
51
|
+
}, init=False)
|
52
|
+
|
53
|
+
def get_algorithm(self) -> BaseCipherAlgorithm:
|
54
|
+
"""
|
55
|
+
Get the primary algorithm used to cipher the password
|
56
|
+
:return: BaseCipherAlgorithm: The primary algorithm used for the cipher
|
57
|
+
"""
|
58
|
+
if self.algorithm.lower() not in self._cipher_registry:
|
59
|
+
raise exceptions.InvalidAlgorithmException(self.algorithm)
|
60
|
+
return self._cipher_registry[self.algorithm.lower()]
|
61
|
+
|
62
|
+
def replace_character(self, char: str, replacement: str) -> None:
|
63
|
+
"""
|
64
|
+
Replace a character with another character or set of characters
|
65
|
+
Eg: pg.replace_character('a', '@1')
|
66
|
+
:param char: The character to be replaced
|
67
|
+
:param replacement: The (character|set of characters) to replace the first one
|
68
|
+
:return:
|
69
|
+
"""
|
70
|
+
self.characters_replacements[char[0]] = replacement
|
71
|
+
|
72
|
+
def reset_character(self, char: str) -> None:
|
73
|
+
"""
|
74
|
+
Reset a character to its original value (remove its replacement from characters_replacements)
|
75
|
+
:param char: The character to be reset to its original value
|
76
|
+
:return:
|
77
|
+
"""
|
78
|
+
self.characters_replacements.pop(char, None)
|
79
|
+
|
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: GeneratorConfig = field(default_factory=GeneratorConfig)
|
88
|
+
|
89
|
+
def apply_replacements(self, password: str) -> str:
|
90
|
+
"""
|
91
|
+
Replace character from the ciphered password with character replacements from the generator configurations
|
92
|
+
:return: str: The new ciphered password after character replacements
|
93
|
+
"""
|
94
|
+
translation_table = str.maketrans(self.config.characters_replacements)
|
95
|
+
return password.translate(translation_table)
|
96
|
+
|
97
|
+
def generate_password(self, text: str) -> str:
|
98
|
+
"""
|
99
|
+
Generate a strong password string using the raw password (add another layer of encryption to it)
|
100
|
+
:return: str: The generated ciphered password
|
101
|
+
"""
|
102
|
+
affine = AffineCipherAlgorithm(self.config.shift, self.config.multiplier)
|
103
|
+
intermediate = affine.encrypt(f"{self.config.prefix}{text}{self.config.postfix}")
|
104
|
+
main_algorithm = self.config.get_algorithm()
|
105
|
+
password = main_algorithm.encrypt(intermediate)
|
106
|
+
password = self.apply_replacements(password)
|
107
|
+
return ''.join(c.upper() if c in text else c for c in password)
|
108
|
+
|
109
|
+
|
110
|
+
@dataclass
|
111
|
+
class User:
|
112
|
+
id: UUID = field(default_factory=uuid4)
|
113
|
+
created_at: datetime = field(default_factory=datetime.now)
|
114
|
+
updated_at: datetime = field(default_factory=datetime.now)
|
115
|
+
username: str = field(default_factory=str)
|
116
|
+
email: str = field(default_factory=str)
|
117
|
+
password: str = field(default_factory=str)
|
118
|
+
generator: UUID = field(default_factory=UUID)
|
119
|
+
passwords: list[UUID] = field(default_factory=list[UUID])
|
120
|
+
|
121
|
+
def add_password(self, password_id: UUID) -> None:
|
122
|
+
self.passwords.append(password_id)
|
123
|
+
|
124
|
+
def delete_password(self, password_id: UUID) -> None:
|
125
|
+
self.passwords.remove(password_id)
|
@@ -0,0 +1,49 @@
|
|
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"
|
@@ -0,0 +1,92 @@
|
|
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 delete(self, generator_id: UUID) -> None:
|
36
|
+
pass
|
37
|
+
|
38
|
+
@abstractmethod
|
39
|
+
def find_by_id(self, generator_id: UUID) -> Generator:
|
40
|
+
pass
|
41
|
+
|
42
|
+
@abstractmethod
|
43
|
+
def find_by_user_id(self, user_id: UUID) -> Generator:
|
44
|
+
pass
|
45
|
+
|
46
|
+
|
47
|
+
class GeneratorConfigRepository(ABC):
|
48
|
+
@abstractmethod
|
49
|
+
def save(self, generator_config: GeneratorConfig) -> None:
|
50
|
+
pass
|
51
|
+
|
52
|
+
@abstractmethod
|
53
|
+
def update(self, generator_config: GeneratorConfig) -> None:
|
54
|
+
pass
|
55
|
+
|
56
|
+
@abstractmethod
|
57
|
+
def delete(self, generator_config_id: UUID) -> None:
|
58
|
+
pass
|
59
|
+
|
60
|
+
@abstractmethod
|
61
|
+
def find_by_id(self, generator_config_id: UUID) -> GeneratorConfig:
|
62
|
+
pass
|
63
|
+
|
64
|
+
@abstractmethod
|
65
|
+
def find_by_generator_id(self, generator_id: UUID) -> GeneratorConfig:
|
66
|
+
pass
|
67
|
+
|
68
|
+
|
69
|
+
class UserRepository(ABC):
|
70
|
+
@abstractmethod
|
71
|
+
def save(self, user: User) -> None:
|
72
|
+
pass
|
73
|
+
|
74
|
+
@abstractmethod
|
75
|
+
def update(self, user: User) -> None:
|
76
|
+
pass
|
77
|
+
|
78
|
+
@abstractmethod
|
79
|
+
def delete(self, user_id: UUID) -> None:
|
80
|
+
pass
|
81
|
+
|
82
|
+
@abstractmethod
|
83
|
+
def find_by_id(self, user_id: UUID) -> User:
|
84
|
+
pass
|
85
|
+
|
86
|
+
@abstractmethod
|
87
|
+
def find_by_username(self, username: str) -> User:
|
88
|
+
pass
|
89
|
+
|
90
|
+
@abstractmethod
|
91
|
+
def find_by_email(self, email: str) -> User:
|
92
|
+
pass
|
@@ -1,11 +1,11 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: passphera-core
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.9.0
|
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 :: 3 - Alpha
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
10
10
|
Classifier: Operating System :: OS Independent
|
11
11
|
Classifier: Programming Language :: Python
|
@@ -1,8 +1,9 @@
|
|
1
1
|
README.md
|
2
2
|
setup.py
|
3
3
|
passphera_core/__init__.py
|
4
|
+
passphera_core/entities.py
|
4
5
|
passphera_core/exceptions.py
|
5
|
-
passphera_core/
|
6
|
+
passphera_core/interfaces.py
|
6
7
|
passphera_core.egg-info/PKG-INFO
|
7
8
|
passphera_core.egg-info/SOURCES.txt
|
8
9
|
passphera_core.egg-info/dependency_links.txt
|
@@ -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.9.0',
|
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 :: 3 - Alpha",
|
20
20
|
"License :: OSI Approved :: MIT License",
|
21
21
|
"Operating System :: OS Independent",
|
22
22
|
"Programming Language :: Python",
|
@@ -1,190 +0,0 @@
|
|
1
|
-
from cipherspy.cipher import *
|
2
|
-
|
3
|
-
from .exceptions import InvalidAlgorithmException
|
4
|
-
|
5
|
-
|
6
|
-
class PasswordGenerator:
|
7
|
-
"""
|
8
|
-
A strong password generator use multiple cipher algorithms to cipher a given plain text
|
9
|
-
"""
|
10
|
-
def __init__(
|
11
|
-
self,
|
12
|
-
shift: int = 3,
|
13
|
-
multiplier: int = 3,
|
14
|
-
key: str = "hill",
|
15
|
-
algorithm: str = 'hill',
|
16
|
-
prefix: str = 'secret',
|
17
|
-
postfix: str = 'secret',
|
18
|
-
characters_replacements: dict = None,
|
19
|
-
):
|
20
|
-
"""
|
21
|
-
:param shift: number of characters to shift each character (default 3)
|
22
|
-
:param multiplier: number of characters to shift each character (default 3)
|
23
|
-
:param key: cipher key string (default "secret")
|
24
|
-
:param algorithm: main cipher algorithm name (default 'playfair')
|
25
|
-
:param characters_replacements: replace characters with the given values (default {})
|
26
|
-
:param text: plain text to be ciphered
|
27
|
-
"""
|
28
|
-
if characters_replacements is None:
|
29
|
-
characters_replacements = {}
|
30
|
-
self._shift: int = shift
|
31
|
-
self._multiplier: int = multiplier
|
32
|
-
self._key: str = key
|
33
|
-
self._algorithm_name: str = algorithm.lower()
|
34
|
-
self._algorithm = self._set_algorithm()
|
35
|
-
self._prefix: str = prefix
|
36
|
-
self._postfix: str = postfix
|
37
|
-
self._characters_replacements: dict = characters_replacements
|
38
|
-
|
39
|
-
@property
|
40
|
-
def shift(self) -> int:
|
41
|
-
"""
|
42
|
-
Returns the shift value for the cipher algorithm
|
43
|
-
Eg: ```shift = pg.shift```
|
44
|
-
:return: int: The shift value for the cipher algorithm
|
45
|
-
"""
|
46
|
-
return self._shift
|
47
|
-
|
48
|
-
@shift.setter
|
49
|
-
def shift(self, shift: int) -> None:
|
50
|
-
"""
|
51
|
-
Sets the shift value for the cipher algorithm
|
52
|
-
Eg: ```pg.shift = 3```
|
53
|
-
:param shift: The shift value for the cipher algorithm
|
54
|
-
:return:
|
55
|
-
"""
|
56
|
-
self._shift = shift
|
57
|
-
|
58
|
-
@property
|
59
|
-
def multiplier(self) -> int:
|
60
|
-
"""
|
61
|
-
Returns the multiplier value for the cipher algorithm
|
62
|
-
Eg: ```multiplier = pg.multiplier```
|
63
|
-
:return: int: The multiplier value for the cipher algorithm
|
64
|
-
"""
|
65
|
-
return self._multiplier
|
66
|
-
|
67
|
-
@multiplier.setter
|
68
|
-
def multiplier(self, multiplier: int) -> None:
|
69
|
-
"""
|
70
|
-
Sets the multiplier value for the cipher algorithm
|
71
|
-
Eg: ```pg.multiplier = 3```
|
72
|
-
:param multiplier: The multiplier value for the cipher algorithm
|
73
|
-
:return:
|
74
|
-
"""
|
75
|
-
self._multiplier = multiplier
|
76
|
-
|
77
|
-
@property
|
78
|
-
def key(self) -> str:
|
79
|
-
"""
|
80
|
-
Returns the key string for the cipher algorithm
|
81
|
-
Eg: ```key_str = pg.key_str```
|
82
|
-
:return: str: The key string for the cipher algorithm
|
83
|
-
"""
|
84
|
-
return self._key
|
85
|
-
|
86
|
-
@key.setter
|
87
|
-
def key(self, key: str) -> None:
|
88
|
-
"""
|
89
|
-
Sets the key string for the cipher algorithm
|
90
|
-
Eg: ```pg.key = 'secret key'```
|
91
|
-
:param key: The key string for the cipher algorithm
|
92
|
-
:return:
|
93
|
-
"""
|
94
|
-
self._key = key
|
95
|
-
|
96
|
-
@property
|
97
|
-
def algorithm(self) -> str:
|
98
|
-
"""
|
99
|
-
Returns the main cipher algorithm name
|
100
|
-
Eg: ```algorithm = pg.algorithm```
|
101
|
-
:return: str: The main cipher algorithm name
|
102
|
-
"""
|
103
|
-
return self._algorithm_name
|
104
|
-
|
105
|
-
@algorithm.setter
|
106
|
-
def algorithm(self, algorithm: str) -> None:
|
107
|
-
"""
|
108
|
-
Sets the main cipher algorithm
|
109
|
-
Eg: ```pg.algorithm = 'playfair'```
|
110
|
-
:param algorithm: The name of the main cipher algorithm
|
111
|
-
:return:
|
112
|
-
"""
|
113
|
-
self._algorithm_name = algorithm.lower()
|
114
|
-
self._algorithm = self._set_algorithm()
|
115
|
-
|
116
|
-
@property
|
117
|
-
def characters_replacements(self) -> dict:
|
118
|
-
"""
|
119
|
-
Returns the dictionary of the characters replacements
|
120
|
-
Eg: ```print(pg.characters_replacements) # {'a': '@1', 'b': '#2'}```
|
121
|
-
:return: dict: The dictionary of the characters replacements
|
122
|
-
"""
|
123
|
-
return self._characters_replacements
|
124
|
-
|
125
|
-
def _set_algorithm(self):
|
126
|
-
"""
|
127
|
-
Return new instance of the used algorithm to the given one by it's name
|
128
|
-
:return: new algorithm class
|
129
|
-
"""
|
130
|
-
match self._algorithm_name:
|
131
|
-
case 'caesar':
|
132
|
-
return CaesarCipher(self._shift)
|
133
|
-
case 'affine':
|
134
|
-
return AffineCipher(self._shift, self._multiplier)
|
135
|
-
case 'playfair':
|
136
|
-
return PlayfairCipher(self._key)
|
137
|
-
case 'hill':
|
138
|
-
return HillCipher(self._key)
|
139
|
-
case _:
|
140
|
-
raise InvalidAlgorithmException(self._algorithm_name)
|
141
|
-
|
142
|
-
def _update_algorithm_properties(self) -> None:
|
143
|
-
"""
|
144
|
-
Update the main cipher algorithm
|
145
|
-
"""
|
146
|
-
self._algorithm = self._set_algorithm()
|
147
|
-
|
148
|
-
def replace_character(self, char: str, replacement: str) -> None:
|
149
|
-
"""
|
150
|
-
Replace a character with another character or set of characters
|
151
|
-
Eg: pg.replace_character('a', '@1')
|
152
|
-
:param char: The character to be replaced
|
153
|
-
:param replacement: The (character|set of characters) to replace the first one
|
154
|
-
:return:
|
155
|
-
"""
|
156
|
-
self._characters_replacements[char[0]] = replacement
|
157
|
-
|
158
|
-
def reset_character(self, char: str) -> None:
|
159
|
-
"""
|
160
|
-
Reset a character to it's original value (remove it's replacement from characters_replacements)
|
161
|
-
:param char: The character to be reset to its original value
|
162
|
-
:return:
|
163
|
-
"""
|
164
|
-
if char in self._characters_replacements:
|
165
|
-
del self._characters_replacements[char]
|
166
|
-
|
167
|
-
def generate_raw_password(self, text: str) -> str:
|
168
|
-
"""
|
169
|
-
Generate a raw password string using the given parameters
|
170
|
-
:return: str: The generated raw password
|
171
|
-
"""
|
172
|
-
self._update_algorithm_properties()
|
173
|
-
return self._algorithm.encrypt(f"{self._prefix}{text}{self._postfix}")
|
174
|
-
|
175
|
-
def generate_password(self, text: str) -> str:
|
176
|
-
"""
|
177
|
-
Generate a strong password string using the raw password (add another layer of encryption to it)
|
178
|
-
:return: str: The generated strong password
|
179
|
-
"""
|
180
|
-
old_algorithm = self._algorithm_name
|
181
|
-
self._algorithm_name = 'affine'
|
182
|
-
password = self.generate_raw_password(text)
|
183
|
-
self._algorithm_name = old_algorithm
|
184
|
-
password = self.generate_raw_password(password)
|
185
|
-
for char, replacement in self._characters_replacements.items():
|
186
|
-
password = password.replace(char, replacement)
|
187
|
-
for char in password:
|
188
|
-
if char in text:
|
189
|
-
password = password.replace(char, char.upper())
|
190
|
-
return password
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|