# 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/utils/http.py
# class HttpClient:
# 
#     def __init__(self):
#         self._cert = None
#         self._headers = {
#             'Content-Type': 'application/json',
#             'X-Correlation-Id': 'WEB-APP.pewW9',
#             'User-Agent': 'pynubank Client - https://github.com/andreroggeri/pynubank',
#         }
# 
#     def set_cert(self, cert_path: str):
#         self._cert = cert_path
# 
#     def set_header(self, name: str, value: str):
#         self._headers[name] = value
# 
#     def remove_header(self, name: str):
#         self._headers.pop(name)
# 
#     def get_header(self, name: str):
#         return self._headers.get(name)
# 
#     @property
#     def _cert_args(self):
#         return {'pkcs12_filename': self._cert, 'pkcs12_password': ''} if self._cert else {}
# 
#     def _handle_response(self, response: Response) -> dict:
#         if response.status_code != 200:
#             raise NuRequestException(response)
# 
#         return response.json()
# 
#     def raw_get(self, url: str) -> Response:
#         return get(url, headers=self._headers, **self._cert_args)
# 
#     def get(self, url: str) -> dict:
#         return self._handle_response(self.raw_get(url))
# 
#     def post(self, url: str, json: dict) -> dict:
#         return self._handle_response(post(url, json=json, headers=self._headers, **self._cert_args))


import os
import OpenSSL
import pynubank
from pathlib import Path
from unittest.mock import patch
from pynubank import NuException
from pynubank.utils.certificate_generator import CertificateGenerator
from pynubank.utils.http import HttpClient
    from pynubank import cli
    from pynubank import cli




def mock_error(_):
    raise NuException('failed')


def mock_certs(*args):
    key = OpenSSL.crypto.PKey()
    key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
    p12 = OpenSSL.crypto.PKCS12()
    p12.set_privatekey(key)

    return p12, p12


def clean():
    workdir = Path(os.getcwd())

    cert = workdir.joinpath('cert.p12')

    if cert.exists():
        cert.unlink()



# 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/utils/http.py
# class HttpClient:
# 
#     def __init__(self):
#         self._cert = None
#         self._headers = {
#             'Content-Type': 'application/json',
#             'X-Correlation-Id': 'WEB-APP.pewW9',
#             'User-Agent': 'pynubank Client - https://github.com/andreroggeri/pynubank',
#         }
# 
#     def set_cert(self, cert_path: str):
#         self._cert = cert_path
# 
#     def set_header(self, name: str, value: str):
#         self._headers[name] = value
# 
#     def remove_header(self, name: str):
#         self._headers.pop(name)
# 
#     def get_header(self, name: str):
#         return self._headers.get(name)
# 
#     @property
#     def _cert_args(self):
#         return {'pkcs12_filename': self._cert, 'pkcs12_password': ''} if self._cert else {}
# 
#     def _handle_response(self, response: Response) -> dict:
#         if response.status_code != 200:
#             raise NuRequestException(response)
# 
#         return response.json()
# 
#     def raw_get(self, url: str) -> Response:
#         return get(url, headers=self._headers, **self._cert_args)
# 
#     def get(self, url: str) -> dict:
#         return self._handle_response(self.raw_get(url))
# 
#     def post(self, url: str, json: dict) -> dict:
#         return self._handle_response(post(url, json=json, headers=self._headers, **self._cert_args))


# Path: tests/test_cli.py
import os
import OpenSSL
import pynubank
from pathlib import Path
from unittest.mock import patch
from pynubank import NuException
from pynubank.utils.certificate_generator import CertificateGenerator
from pynubank.utils.http import HttpClient
    from pynubank import cli
    from pynubank import cli





def mock_error(_):
    raise NuException('failed')


def mock_certs(*args):
    key = OpenSSL.crypto.PKey()
    key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
    p12 = OpenSSL.crypto.PKCS12()
    p12.set_privatekey(key)

    return p12, p12


def clean():
    workdir = Path(os.getcwd())

    cert = workdir.joinpath('cert.p12')

    if cert.exists():
        cert.unlink()



@patch.object(pynubank.utils.certificate_generator.CertificateGenerator, 'request_code', mock_error)