iniUts 1.2.1__tar.gz → 1.3.0__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.
- {iniuts-1.2.1 → iniuts-1.3.0}/CHANGELOG.txt +6 -1
- {iniuts-1.2.1/iniUts.egg-info → iniuts-1.3.0}/PKG-INFO +6 -1
- {iniuts-1.2.1 → iniuts-1.3.0}/commands.txt +1 -1
- {iniuts-1.2.1 → iniuts-1.3.0}/iniUts/__init__.py +70 -2
- iniuts-1.3.0/iniUts/secret.py +52 -0
- {iniuts-1.2.1 → iniuts-1.3.0/iniUts.egg-info}/PKG-INFO +6 -1
- {iniuts-1.2.1 → iniuts-1.3.0}/iniUts.egg-info/SOURCES.txt +1 -0
- {iniuts-1.2.1 → iniuts-1.3.0}/run.py +6 -1
- {iniuts-1.2.1 → iniuts-1.3.0}/setup.py +1 -1
- {iniuts-1.2.1 → iniuts-1.3.0}/LICENCE.txt +0 -0
- {iniuts-1.2.1 → iniuts-1.3.0}/MANIFEST.in +0 -0
- {iniuts-1.2.1 → iniuts-1.3.0}/README.md +0 -0
- {iniuts-1.2.1 → iniuts-1.3.0}/iniUts.egg-info/dependency_links.txt +0 -0
- {iniuts-1.2.1 → iniuts-1.3.0}/iniUts.egg-info/top_level.txt +0 -0
- {iniuts-1.2.1 → iniuts-1.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: iniUts
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Ini file manipulator
|
|
5
5
|
Home-page:
|
|
6
6
|
Author: Melque Lima
|
|
@@ -277,3 +277,8 @@ Change Log
|
|
|
277
277
|
1.0.7 (2023-04-28)
|
|
278
278
|
------------------
|
|
279
279
|
- changing enviornment
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
1.3.0 (2025-12-01)
|
|
283
|
+
------------------
|
|
284
|
+
- encription and decription
|
|
@@ -3,6 +3,8 @@ from dataclasses import dataclass
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
import re
|
|
5
5
|
import os
|
|
6
|
+
import types
|
|
7
|
+
from secret import decrypt, encrypt
|
|
6
8
|
|
|
7
9
|
class envar():
|
|
8
10
|
def __init__(self,key:str,default:str=None):
|
|
@@ -18,14 +20,46 @@ class envar():
|
|
|
18
20
|
raise Exception(f"envar '{self.key}' not found!")
|
|
19
21
|
return value
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
|
|
24
|
+
def save(self):
|
|
25
|
+
ini = self.__INIUTS__
|
|
26
|
+
types_to_str = [str,int,float,bool]
|
|
27
|
+
is_str = lambda t: any([t == x for x in types_to_str])
|
|
28
|
+
|
|
29
|
+
iniProd = IniUts(ini.prd_file)
|
|
30
|
+
iniDev = IniUts(ini.dev_file) if ini.dev_file else None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
for k,t in self.__annotations__.items():
|
|
34
|
+
if k in self.__ENVARS__: continue
|
|
35
|
+
|
|
36
|
+
if is_str(t):
|
|
37
|
+
value = str(getattr(self,k))
|
|
38
|
+
elif t == tuple:
|
|
39
|
+
value = getattr(self,k)
|
|
40
|
+
delimiter = ini.delimiters[f"{str(self)}_{k}"]
|
|
41
|
+
value = delimiter.join(value)
|
|
42
|
+
elif t == datetime:
|
|
43
|
+
value = getattr(self,k)
|
|
44
|
+
dateFormat = ini.dateFormats[f"{str(self)}_{k}"]
|
|
45
|
+
value = value.strftime(dateFormat)
|
|
46
|
+
|
|
47
|
+
if k in self.__CRYPTED_KEYS__:
|
|
48
|
+
k = "&_" + k
|
|
49
|
+
value = encrypt(value,ini.encription_key)
|
|
50
|
+
|
|
51
|
+
if not ini.in_prd and k in iniDev.getKeys(self.__SECTION__):
|
|
52
|
+
iniDev.write(self.__SECTION__,k,value)
|
|
53
|
+
else:
|
|
54
|
+
iniProd.write(self.__SECTION__,k,value)
|
|
22
55
|
|
|
23
56
|
|
|
24
57
|
class IniUts():
|
|
25
|
-
def __init__(self,ini_prd,ini_dev=None,in_prd=True):
|
|
58
|
+
def __init__(self,ini_prd,ini_dev=None,in_prd=True,encription_key=None):
|
|
26
59
|
self.prd_file = ini_prd
|
|
27
60
|
self.dev_file = ini_dev
|
|
28
61
|
self.in_prd = in_prd
|
|
62
|
+
self.encription_key = encription_key
|
|
29
63
|
self.delimiters = {}
|
|
30
64
|
self.dateFormats = {}
|
|
31
65
|
self.dev_sections = []
|
|
@@ -91,6 +125,13 @@ class IniUts():
|
|
|
91
125
|
|
|
92
126
|
return [k for k in config[section]]
|
|
93
127
|
|
|
128
|
+
def to_dict(self):
|
|
129
|
+
sections = self.getSections()
|
|
130
|
+
result = {}
|
|
131
|
+
for sect in sections:
|
|
132
|
+
result[sect] = self.Section2Dict(sect)
|
|
133
|
+
return result
|
|
134
|
+
|
|
94
135
|
def Section2Dict(self,section,empty_as_null=False,fileIni=None):
|
|
95
136
|
_file = self.dev_file if not self.in_prd and section in self.dev_sections else self.prd_file
|
|
96
137
|
config = cp.RawConfigParser(allow_no_value=True)
|
|
@@ -102,6 +143,9 @@ class IniUts():
|
|
|
102
143
|
|
|
103
144
|
def format_data(self,dtClass,k,v):
|
|
104
145
|
cls = dtClass.__annotations__[k]
|
|
146
|
+
if k in dtClass.__CRYPTED_KEYS__:
|
|
147
|
+
v = decrypt(v,self.encription_key)
|
|
148
|
+
|
|
105
149
|
if cls == tuple:
|
|
106
150
|
name = f"{str(dtClass)}_{k}"
|
|
107
151
|
if not name in self.delimiters:
|
|
@@ -141,6 +185,28 @@ class IniUts():
|
|
|
141
185
|
|
|
142
186
|
dtClass = self.setup_initial_values(dtClass)
|
|
143
187
|
|
|
188
|
+
dtClass.save = types.MethodType(save, dtClass)
|
|
189
|
+
dtClass.__SECTION__ = section
|
|
190
|
+
dtClass.__ENVARS__ = []
|
|
191
|
+
dtClass.__INIUTS__ = self
|
|
192
|
+
dtClass.__CRYPTED_KEYS__ = [ x.replace("&_","") for x in dt2 if "&_" in x ]
|
|
193
|
+
dt2 = { x.replace("&_",""):dt2[x] for x in dt2 }
|
|
194
|
+
dt = { x.replace("&_",""):dt[x] for x in dt }
|
|
195
|
+
|
|
196
|
+
#ENCRIPTA VARIAVEIS INICIAIS
|
|
197
|
+
for k in dtClass.__CRYPTED_KEYS__:
|
|
198
|
+
# ENCRIPTA VARIAVEIS INICIAIS NO ARQUIVO DE DEV
|
|
199
|
+
if k in dt.keys() and dt[k].startswith('&_') and not self.in_prd:
|
|
200
|
+
dt[k] = encrypt(dt[k].replace('&_',''),self.encription_key)
|
|
201
|
+
IniUts(self.dev_file).write(section,"&_" + k,dt[k])
|
|
202
|
+
|
|
203
|
+
# ENCRIPTA VARIAVEIS INICIAIS NO ARQUIVO DE PRD
|
|
204
|
+
if k in dt2.keys() and dt2[k].startswith('&_'):
|
|
205
|
+
dt2[k] = encrypt(dt2[k].replace('&_',''),self.encription_key)
|
|
206
|
+
IniUts(self.prd_file).write(section,"&_" + k,dt2[k])
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
144
210
|
#VALIDA AS KEYS NO INI DE DEV
|
|
145
211
|
for k, v in dt.items():
|
|
146
212
|
if not k in dtClass.__annotations__:
|
|
@@ -162,6 +228,7 @@ class IniUts():
|
|
|
162
228
|
if isinstance(getattr(dtClass,k),envar):
|
|
163
229
|
v = getattr(dtClass,k).get_value()
|
|
164
230
|
setattr(dtClass, k, v)
|
|
231
|
+
dtClass.__ENVARS__.append(k)
|
|
165
232
|
continue
|
|
166
233
|
if not skip_missing:
|
|
167
234
|
raise Exception(f"Cound not find '{k}' keys at section '{section}' in ini file")
|
|
@@ -173,6 +240,7 @@ class IniUts():
|
|
|
173
240
|
if isinstance(getattr(dtClass,k),envar):
|
|
174
241
|
v = getattr(dtClass,k).get_value()
|
|
175
242
|
setattr(dtClass, k, v)
|
|
243
|
+
dtClass.__ENVARS__.append(k)
|
|
176
244
|
continue
|
|
177
245
|
if not skip_missing and MissingKeysFromClass(dt):
|
|
178
246
|
raise Exception(f"Cound not find '{k}' keys at section '{section}' in ini file")
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import base64
|
|
3
|
+
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
|
4
|
+
from cryptography.hazmat.primitives import hashes
|
|
5
|
+
|
|
6
|
+
# Retorna 32 bytes (SHA-256) da senha (usada como chave final)
|
|
7
|
+
def _derive_key_from_password(password: str) -> bytes:
|
|
8
|
+
# Hash SHA-256 da senha -> chave de 32 bytes
|
|
9
|
+
digest = hashes.Hash(hashes.SHA256())
|
|
10
|
+
digest.update(password.encode('utf-8'))
|
|
11
|
+
return digest.finalize()
|
|
12
|
+
|
|
13
|
+
# Encripta texto (str) com senha (str). Retorna string Base64 contendo: nonce + ciphertext + tag
|
|
14
|
+
def encrypt(text: str, password: str) -> str:
|
|
15
|
+
"""
|
|
16
|
+
// text: texto em claro
|
|
17
|
+
// password: senha/segredo que será transformado em hash (SHA-256) para usar como chave
|
|
18
|
+
// retorna: base64(nonce || ciphertext || tag)
|
|
19
|
+
"""
|
|
20
|
+
key = _derive_key_from_password(password) # 32 bytes
|
|
21
|
+
aesgcm = AESGCM(key)
|
|
22
|
+
nonce = os.urandom(12) # nonce/IV recomendado para GCM: 12 bytes
|
|
23
|
+
plaintext = text.encode('utf-8')
|
|
24
|
+
ciphertext = aesgcm.encrypt(nonce, plaintext, None) # dados adicionais (AAD) = None
|
|
25
|
+
payload = nonce + ciphertext # armazenar nonce + ciphertext (ciphertext já inclui tag no AESGCM)
|
|
26
|
+
return base64.b64encode(payload).decode('utf-8')
|
|
27
|
+
|
|
28
|
+
# Decripta string Base64 gerada por encrypt()
|
|
29
|
+
def decrypt(token_b64: str, password: str) -> str:
|
|
30
|
+
"""
|
|
31
|
+
// token_b64: string retornada por encrypt (base64(nonce||ciphertext||tag))
|
|
32
|
+
// password: mesma senha usada na encriptação
|
|
33
|
+
// retorna: texto em claro (str) ou levanta exceção se inválido
|
|
34
|
+
"""
|
|
35
|
+
key = _derive_key_from_password(password)
|
|
36
|
+
data = base64.b64decode(token_b64)
|
|
37
|
+
if len(data) < 12:
|
|
38
|
+
raise ValueError("Payload inválido")
|
|
39
|
+
nonce = data[:12]
|
|
40
|
+
ciphertext = data[12:]
|
|
41
|
+
aesgcm = AESGCM(key)
|
|
42
|
+
plaintext = aesgcm.decrypt(nonce, ciphertext, None)
|
|
43
|
+
return plaintext.decode('utf-8')
|
|
44
|
+
|
|
45
|
+
# Exemplo de uso:
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
senha = "minha-senha-secreta"
|
|
48
|
+
texto = "mensagem ultra secreta"
|
|
49
|
+
cifrado = encrypt(texto, senha)
|
|
50
|
+
print("Cifrado:", cifrado)
|
|
51
|
+
dec = decrypt(cifrado, senha)
|
|
52
|
+
print("Decifrado:", dec)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: iniUts
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Ini file manipulator
|
|
5
5
|
Home-page:
|
|
6
6
|
Author: Melque Lima
|
|
@@ -277,3 +277,8 @@ Change Log
|
|
|
277
277
|
1.0.7 (2023-04-28)
|
|
278
278
|
------------------
|
|
279
279
|
- changing enviornment
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
1.3.0 (2025-12-01)
|
|
283
|
+
------------------
|
|
284
|
+
- encription and decription
|
|
@@ -7,7 +7,7 @@ from iniUts import *
|
|
|
7
7
|
load_dotenv()
|
|
8
8
|
|
|
9
9
|
ini = IniUts('prd_config.ini')
|
|
10
|
-
ini = IniUts('prd_config.ini','dev_config.ini',in_prd=True)
|
|
10
|
+
ini = IniUts('prd_config.ini','dev_config.ini',in_prd=True,encription_key="asdoajhsdoiuayhsoidhasoidhalijksdhaioshdioaws")
|
|
11
11
|
|
|
12
12
|
#TODAS AS CHAVES DE DEV DEVE CONTER EM PRD
|
|
13
13
|
|
|
@@ -21,6 +21,11 @@ class Person():
|
|
|
21
21
|
friends: tuple = ','
|
|
22
22
|
dob : datetime = "%Y-%m-%d"
|
|
23
23
|
|
|
24
|
+
Person.NAME = "Heitor"
|
|
25
|
+
Person.friends = ("friend1","friend2","friend3","friend4")
|
|
26
|
+
Person.save()
|
|
27
|
+
|
|
28
|
+
|
|
24
29
|
|
|
25
30
|
pass
|
|
26
31
|
# pass
|
|
@@ -10,7 +10,7 @@ classifiers = [
|
|
|
10
10
|
|
|
11
11
|
setup(
|
|
12
12
|
name='iniUts',
|
|
13
|
-
version='1.
|
|
13
|
+
version='1.3.0',
|
|
14
14
|
description='Ini file manipulator',
|
|
15
15
|
long_description=open('README.md').read() + '\n\n' + open('CHANGELOG.txt').read(),
|
|
16
16
|
long_description_content_type='text/markdown',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|