-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9df5d65
commit f3f38d3
Showing
7 changed files
with
284 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Ignorar archivos de caché de Python | ||
__pycache__/ | ||
*/__pycache__/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import json | ||
import xml.etree.ElementTree as ET | ||
|
||
class DataProcessor: | ||
@staticmethod | ||
def process_data(uploadedFile, format="json", verbose=False): | ||
def recursive_conversion(value): | ||
if isinstance(value, dict): | ||
return {key: recursive_conversion(val) for key, val in value.items()} | ||
return value | ||
|
||
processed_data = recursive_conversion(uploadedFile) | ||
|
||
if format == "json": | ||
return json.dumps(processed_data, indent=4) | ||
elif format == "xml": | ||
def dict_to_xml(dictionary, root): | ||
for key, value in dictionary.items(): | ||
if isinstance(value, dict): | ||
elem = ET.Element(key) | ||
dict_to_xml(value, elem) | ||
else: | ||
elem = ET.Element(key) | ||
elem.text = str(value) | ||
root.append(elem) | ||
return root | ||
|
||
root = ET.Element("uploadedFile") | ||
dict_to_xml(processed_data, root) | ||
xml_data = ET.tostring(root, encoding="unicode") | ||
xml_data = '<?xml version="1.0" encoding="UTF-8" ?>'+xml_data | ||
return xml_data | ||
elif format == "plaintext": | ||
def dict_to_plaintext(dictionary, indent=0): | ||
result = "" | ||
for key, value in dictionary.items(): | ||
if isinstance(value, dict): | ||
result += " " * indent + f"{key} :\n{dict_to_plaintext(value, indent + 4)}" | ||
else: | ||
result += " " * indent + f"{key.ljust(15)} : {value}\n" | ||
return result | ||
|
||
return dict_to_plaintext(processed_data) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
from cryptography.hazmat.primitives.asymmetric import rsa | ||
from cryptography.hazmat.primitives.asymmetric import padding | ||
from cryptography.hazmat.primitives import serialization | ||
from cryptography.hazmat.backends import default_backend | ||
from cryptography.hazmat.primitives import hashes | ||
from cryptography.hazmat.primitives import padding as sym_padding | ||
|
||
class Encryption: | ||
@staticmethod | ||
def _pad(data): | ||
padder = sym_padding.PKCS7(128).padder() | ||
padded_data = padder.update(data) | ||
padded_data += padder.finalize() | ||
return padded_data | ||
|
||
@staticmethod | ||
def _unpad(padded_data): | ||
unpadder = sym_padding.PKCS7(128).unpadder() | ||
data = unpadder.update(padded_data) | ||
data += unpadder.finalize() | ||
return data | ||
|
||
@staticmethod | ||
def _derive_key(password, salt=b''): | ||
backend = default_backend() | ||
kdf = PBKDF2HMAC( | ||
algorithm=hashes.SHA256(), | ||
length=32, | ||
salt=salt, | ||
iterations=100000, | ||
backend=backend | ||
) | ||
return kdf.derive(password.encode()) | ||
|
||
@staticmethod | ||
def generate_rsa_key(): | ||
private_key = rsa.generate_private_key( | ||
public_exponent=65537, | ||
key_size=2048, | ||
backend=default_backend() | ||
) | ||
public_key = private_key.public_key() | ||
return private_key, public_key | ||
|
||
@staticmethod | ||
def serialize_key(key): | ||
return key.private_bytes( | ||
encoding=serialization.Encoding.PEM, | ||
format=serialization.PrivateFormat.TraditionalOpenSSL, | ||
encryption_algorithm=serialization.NoEncryption() | ||
) | ||
|
||
@staticmethod | ||
def deserialize_key(serialized_key): | ||
return serialization.load_pem_private_key( | ||
serialized_key, | ||
password=None, | ||
backend=default_backend() | ||
) | ||
|
||
@staticmethod | ||
def encrypt_text(text, password, algorithm="AES"): | ||
if algorithm == "AES": | ||
iv = os.urandom(16) | ||
key = Encryption._derive_key(password) | ||
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) | ||
encryptor = cipher.encryptor() | ||
padded_data = Encryption._pad(text.encode()) | ||
encrypted_text = encryptor.update(padded_data) + encryptor.finalize() | ||
return encrypted_text, iv | ||
elif algorithm == "RSA": | ||
private_key, _ = Encryption.generate_rsa_key() | ||
ciphertext = private_key.encrypt( | ||
text.encode(), | ||
padding.OAEP( | ||
mgf=padding.MGF1(algorithm=hashes.SHA256()), | ||
algorithm=hashes.SHA256(), | ||
label=None | ||
) | ||
) | ||
return ciphertext, None | ||
else: | ||
raise ValueError("Unknown encryption algorithm") | ||
|
||
@staticmethod | ||
def decrypt_text(encrypted_text, iv, password, algorithm="AES"): | ||
if algorithm == "AES": | ||
key = Encryption._derive_key(password) | ||
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) | ||
decryptor = cipher.decryptor() | ||
decrypted_data = decryptor.update(encrypted_text) + decryptor.finalize() | ||
return Encryption._unpad(decrypted_data).decode() | ||
elif algorithm == "RSA": | ||
private_key, _ = Encryption.generate_rsa_key() | ||
decrypted_text = private_key.decrypt( | ||
encrypted_text, | ||
padding.OAEP( | ||
mgf=padding.MGF1(algorithm=hashes.SHA256()), | ||
algorithm=hashes.SHA256(), | ||
label=None | ||
) | ||
) | ||
return decrypted_text.decode() | ||
else: | ||
raise ValueError("Unknown decryption algorithm") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
class FileIO: | ||
@staticmethod | ||
def read_file(filepath): | ||
with open(filepath, "r") as file: | ||
return file.read() | ||
|
||
@staticmethod | ||
def write_file(filepath, data): | ||
with open(filepath, "w") as file: | ||
file.write(data) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import requests | ||
import json | ||
|
||
class HTTPRequest: | ||
@staticmethod | ||
def get_server(verbose): | ||
url = "https://api.gofile.io/getServer" | ||
response = requests.get(url) | ||
|
||
if response.status_code == 200: | ||
data = json.loads(json.dumps(response.json())) | ||
if data['status'] == "ok": | ||
servername = data["data"]["server"] | ||
if verbose: | ||
print("La solicitud GET exitosa. JSON PARSEABLE") | ||
return servername | ||
if verbose: | ||
print("La solicitud GET exitosa. JSON NO PARSEABLE") | ||
return 0 | ||
else: | ||
if verbose: | ||
print("La solicitud GET no fue exitosa.") | ||
return 0 | ||
|
||
@staticmethod | ||
def upload_file(filepath, verbose): | ||
def get_server(verbose): | ||
url = "https://api.gofile.io/getServer" | ||
response = requests.get(url) | ||
|
||
if response.status_code == 200: | ||
data = response.json() | ||
if data['status'] == "ok": | ||
servername = data["data"]["server"] | ||
if verbose: | ||
print("La solicitud GET exitosa. JSON PARSEABLE") | ||
return servername | ||
if verbose: | ||
print("La solicitud GET exitosa. JSON NO PARSEABLE") | ||
return 0 | ||
else: | ||
if verbose: | ||
print("La solicitud GET no fue exitosa.") | ||
return 0 | ||
|
||
if get_server(verbose) != 0: | ||
server = get_server(verbose) | ||
url = f"https://{server}.gofile.io/uploadFile" | ||
if verbose: | ||
print('Preparando para enviar el archivo: '+filepath) | ||
files = {'file': (filepath, open(filepath, 'rb'))} | ||
if verbose: | ||
print('Realizando petición a "'+url+'"') | ||
response = requests.post(url, files=files) | ||
if verbose: | ||
print('Petición Realizada') | ||
if response.status_code == 200: | ||
return response.json() | ||
|
||
@staticmethod | ||
def download_file(server, fileId, fileName, verbose): | ||
url = f"https://{server}.gofile.io/download/{fileId}/{fileName}" | ||
if verbose: | ||
print('Realizando petición a "'+url+'"') | ||
response = requests.get(url) | ||
if response.status_code == 200: | ||
return response.json() | ||
|
||
@staticmethod | ||
def download_file_url(url, verbose): | ||
if verbose: | ||
print('Realizando petición a "'+url+'"') | ||
response = requests.get(url) | ||
if response.status_code == 200: | ||
return response.json() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import argparse | ||
from http_requests import HTTPRequest | ||
from data_processing import DataProcessor | ||
from file_io import FileIO | ||
from encryption import Encryption | ||
|
||
if __name__ == "__main__": | ||
parser = argparse.ArgumentParser(description="Programa para cargar y descargar archivos en GoFile.io") | ||
parser.add_argument("-v", "--verbose", action="store_true", help="Modo Verbose: Mostrar todos los datos") | ||
parser.add_argument("-d", "--download-url", nargs=1, metavar=("url"), help="Descargar archivo por URL") | ||
parser.add_argument("-s", "--download", nargs=3, metavar=("server", "fileId", "fileName"), help="Descargar archivo por server, fileId y fileName") | ||
parser.add_argument("-u", "--upload", help="Cargar archivo desde la ruta local") | ||
parser.add_argument("--json", action="store_true", help="Devolver datos en formato JSON") | ||
parser.add_argument("--xml", action="store_true", help="Devolver datos en formato XML") | ||
parser.add_argument("--plaintext", action="store_true", help="Devolver datos en formato plano") | ||
parser.add_argument("-o", "--output", help="Guardar datos en un archivo") | ||
|
||
args = parser.parse_args() | ||
print(args) | ||
|
||
if args.verbose: | ||
print("Modo Verbose habilitado.") | ||
|
||
if hasattr(args, 'download_url') and args.download_url: | ||
data = HTTPRequest.download_file_url(args.download_url[0], args.verbose) | ||
elif args.download: | ||
server, fileId, fileName = args.download | ||
data = HTTPRequest.download_file(server, fileId, fileName, args.verbose) | ||
elif args.upload: | ||
data = HTTPRequest.upload_file(args.upload, args.verbose) | ||
else: | ||
filepath = input("Ruta del archivo a cargar (/home/user/file.txt): ") | ||
data = HTTPRequest.upload_file(filepath, args.verbose) | ||
|
||
# Si no se especifica ninguno de los formatos, se utiliza plaintext como formato predeterminado | ||
if not (args.json or args.xml or args.plaintext): | ||
args.plaintext = True | ||
|
||
processed_data = DataProcessor.process_data(data, format="json" if args.json else "xml" if args.xml else "plaintext", verbose=args.verbose) | ||
|
||
if args.output: | ||
with open(args.output, "w") as output_file: | ||
output_file.write(processed_data) | ||
if args.verbose: | ||
print(f'Datos guardados en {args.output}') | ||
else: | ||
print(processed_data) |
Binary file not shown.