# Path: pynubank/exception.py
# class NuException(Exception):
# 
#     def __init__(self, message):
#         super().__init__(message)
# 
# Path: pynubank/utils/certificate_generator.py
# class CertificateGenerator:
# 
#     def __init__(self, login, password, device_id, encrypted_code=None):
#         self.login = login
#         self.password = password
#         self.device_id = device_id
#         self.encrypted_code = encrypted_code
#         self.key1 = self._generate_key()
#         self.key2 = self._generate_key()
#         discovery = Discovery(HttpClient())
#         self.url = discovery.get_app_url('gen_certificate')
# 
#     def request_code(self) -> str:
#         response = requests.post(self.url, json=self._get_payload())
# 
#         if response.status_code != 401 or not response.headers.get('WWW-Authenticate'):
#             raise NuException('Authentication code request failed.')
# 
#         parsed = self._parse_authenticate_headers(response.headers.get('WWW-Authenticate'))
#         self.encrypted_code = parsed.get('device-authorization_encrypted-code')
# 
#         return parsed.get('sent-to')
# 
#     def exchange_certs(self, code: str):
#         if not self.encrypted_code:
#             raise NuException('No encrypted code found. Did you call `request_code` before exchanging certs ?')
# 
#         payload = self._get_payload()
#         payload['code'] = code
#         payload['encrypted-code'] = self.encrypted_code
# 
#         response = requests.post(self.url, json=payload)
# 
#         if response.status_code != 200:
#             raise NuRequestException(response)
# 
#         data = response.json()
# 
#         cert1 = self._parse_cert(data['certificate'])
#         cert2 = self._parse_cert(data['certificate_crypto'])
# 
#         return self._gen_cert(self.key1, cert1), self._gen_cert(self.key2, cert2)
# 
#     def _get_payload(self):
#         return {
#             'login': self.login,
#             'password': self.password,
#             'public_key': self._get_public_key(self.key1),
#             'public_key_crypto': self._get_public_key(self.key2),
#             'model': f'PyNubank Client ({self.device_id})',
#             'device_id': self.device_id
#         }
# 
#     def _parse_cert(self, content: str) -> X509:
#         return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, content.encode())
# 
#     def _gen_cert(self, key, cert):
#         p12 = OpenSSL.crypto.PKCS12()
#         p12.set_privatekey(key)
#         p12.set_certificate(cert)
# 
#         return p12
# 
#     def _generate_key(self):
#         key = OpenSSL.crypto.PKey()
#         key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
# 
#         return key
# 
#     def _get_public_key(self, key) -> str:
#         return OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, key).decode()
# 
#     def _parse_authenticate_headers(self, header_content: str) -> dict:
#         chunks = header_content.split(',')
#         parsed = {}
#         for chunk in chunks:
#             key, value = chunk.split('=')
#             key = key.strip().replace(' ', '_')
#             value = value.replace('"', '')
#             parsed[key] = value
# 
#         return parsed


import os
import random
import string
from getpass import getpass
from colorama import init, Fore, Style
from pynubank import NuException
from pynubank.utils.certificate_generator import CertificateGenerator
    return ''.join(random.choices(string.ascii_lowercase + string.digits, k=12))


def log(message, color=Fore.BLUE):
    print(f'{color}{Style.DIM}[*] {Style.NORMAL}{Fore.LIGHTBLUE_EX}{message}')


def save_cert(cert, name):
    path = os.path.join(os.getcwd(), name)
    with open(path, 'wb') as cert_file:
        cert_file.write(cert.export())


def main():
    init()

    log(f'Starting {Fore.MAGENTA}{Style.DIM}PyNubank{Style.NORMAL}{Fore.LIGHTBLUE_EX} context creation.')

    device_id = generate_random_id()

    log(f'Generated random id: {device_id}')

    cpf = input(f'[>] Enter your CPF(Numbers only): ')
    password = getpass('[>] Enter your password (Used on the app/website): ')

    generator = CertificateGenerator(cpf, password, device_id)

    log('Requesting e-mail code')
    try:
        email = generator.request_code()

# Path: pynubank/exception.py
# class NuException(Exception):
# 
#     def __init__(self, message):
#         super().__init__(message)
# 
# Path: pynubank/utils/certificate_generator.py
# class CertificateGenerator:
# 
#     def __init__(self, login, password, device_id, encrypted_code=None):
#         self.login = login
#         self.password = password
#         self.device_id = device_id
#         self.encrypted_code = encrypted_code
#         self.key1 = self._generate_key()
#         self.key2 = self._generate_key()
#         discovery = Discovery(HttpClient())
#         self.url = discovery.get_app_url('gen_certificate')
# 
#     def request_code(self) -> str:
#         response = requests.post(self.url, json=self._get_payload())
# 
#         if response.status_code != 401 or not response.headers.get('WWW-Authenticate'):
#             raise NuException('Authentication code request failed.')
# 
#         parsed = self._parse_authenticate_headers(response.headers.get('WWW-Authenticate'))
#         self.encrypted_code = parsed.get('device-authorization_encrypted-code')
# 
#         return parsed.get('sent-to')
# 
#     def exchange_certs(self, code: str):
#         if not self.encrypted_code:
#             raise NuException('No encrypted code found. Did you call `request_code` before exchanging certs ?')
# 
#         payload = self._get_payload()
#         payload['code'] = code
#         payload['encrypted-code'] = self.encrypted_code
# 
#         response = requests.post(self.url, json=payload)
# 
#         if response.status_code != 200:
#             raise NuRequestException(response)
# 
#         data = response.json()
# 
#         cert1 = self._parse_cert(data['certificate'])
#         cert2 = self._parse_cert(data['certificate_crypto'])
# 
#         return self._gen_cert(self.key1, cert1), self._gen_cert(self.key2, cert2)
# 
#     def _get_payload(self):
#         return {
#             'login': self.login,
#             'password': self.password,
#             'public_key': self._get_public_key(self.key1),
#             'public_key_crypto': self._get_public_key(self.key2),
#             'model': f'PyNubank Client ({self.device_id})',
#             'device_id': self.device_id
#         }
# 
#     def _parse_cert(self, content: str) -> X509:
#         return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, content.encode())
# 
#     def _gen_cert(self, key, cert):
#         p12 = OpenSSL.crypto.PKCS12()
#         p12.set_privatekey(key)
#         p12.set_certificate(cert)
# 
#         return p12
# 
#     def _generate_key(self):
#         key = OpenSSL.crypto.PKey()
#         key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
# 
#         return key
# 
#     def _get_public_key(self, key) -> str:
#         return OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, key).decode()
# 
#     def _parse_authenticate_headers(self, header_content: str) -> dict:
#         chunks = header_content.split(',')
#         parsed = {}
#         for chunk in chunks:
#             key, value = chunk.split('=')
#             key = key.strip().replace(' ', '_')
#             value = value.replace('"', '')
#             parsed[key] = value
# 
#         return parsed


# Path: pynubank/cli.py
import os
import random
import string
from getpass import getpass
from colorama import init, Fore, Style
from pynubank import NuException
from pynubank.utils.certificate_generator import CertificateGenerator

    return ''.join(random.choices(string.ascii_lowercase + string.digits, k=12))


def log(message, color=Fore.BLUE):
    print(f'{color}{Style.DIM}[*] {Style.NORMAL}{Fore.LIGHTBLUE_EX}{message}')


def save_cert(cert, name):
    path = os.path.join(os.getcwd(), name)
    with open(path, 'wb') as cert_file:
        cert_file.write(cert.export())


def main():
    init()

    log(f'Starting {Fore.MAGENTA}{Style.DIM}PyNubank{Style.NORMAL}{Fore.LIGHTBLUE_EX} context creation.')

    device_id = generate_random_id()

    log(f'Generated random id: {device_id}')

    cpf = input(f'[>] Enter your CPF(Numbers only): ')
    password = getpass('[>] Enter your password (Used on the app/website): ')

    generator = CertificateGenerator(cpf, password, device_id)

    log('Requesting e-mail code')
    try:
        email = generator.request_code()

    except NuException: