Skip to content

Commit

Permalink
Modularized
Browse files Browse the repository at this point in the history
  • Loading branch information
j0rd1s3rr4n0 committed Mar 7, 2024
1 parent 9df5d65 commit f3f38d3
Show file tree
Hide file tree
Showing 7 changed files with 284 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Ignorar archivos de caché de Python
__pycache__/
*/__pycache__/
43 changes: 43 additions & 0 deletions GoFile/data_processing.py
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)
105 changes: 105 additions & 0 deletions GoFile/encryption.py
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")
11 changes: 11 additions & 0 deletions GoFile/file_io.py
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)

75 changes: 75 additions & 0 deletions GoFile/http_requests.py
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()
47 changes: 47 additions & 0 deletions GoFile/main.py
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 added requirements.txt
Binary file not shown.

0 comments on commit f3f38d3

Please sign in to comment.