lib/nubank_sdk/auth.rb in nubank_sdk-0.5.0 vs lib/nubank_sdk/auth.rb in nubank_sdk-0.5.1

- old
+ new

@@ -1,23 +1,38 @@ -# frozen_string_literal: true - module NubankSdk class Auth attr_reader :refresh_token, :refresh_before, :access_token + # + # Auth method to connect with the nubank api + # + # @param [String] cpf the cpf to authenticate + # @param [String] device_id the device id to authenticate + # @param [NubankSdk::ApiRoutes] api_routes the api routes to connect + # @param [[Symbol, Faraday::Adapter::Test::Stubs]] adapter the adapter to connect def initialize(cpf:, device_id: nil, api_routes: nil, connection_adapter: nil) @cpf = cpf @device_id = device_id || generate_device_id @api_routes = api_routes || NubankSdk::ApiRoutes.new @connection_adapter = connection_adapter end + # + # Return the instance of user certificate + # + # @return [NubankSdk::Certificate] the certificate instance def certificate @certificate ||= NubankSdk::Certificate.new(@cpf) end + # + # Authenticate with the nubank api to get a new access token + # + # @param [String] password the password to authenticate + # + # @return [NubankSdk::ApiRoutes] the api routes with the new links def authenticate_with_certificate(password) token_url = @api_routes.entrypoint(path: :app, entrypoint: :token) response = ssl_connection.post(token_url, token_payload(password)) response_hash = Client.get_body(response) @@ -27,19 +42,29 @@ @access_token = response_hash[:access_token] update_api_routes(response_hash[:_links]) end + # + # Request to nubank api to generate a new certificate + # + # @param [String] password the password to authenticate + # + # @return [String] email was has been received the code def request_email_code(password) response = default_connection.post(@gen_certificate_path, payload(password)) response_parsed = parse_authenticate_headers(response.headers['WWW-Authenticate']) @encrypted_code = response_parsed[:device_authorization_encrypted_code] response_parsed[:sent_to] end + # + # Verify communication with the nubank api + # + # @return [File] the certificate file def exchange_certs(email_code, password) response = default_connection.post(@gen_certificate_path, payload(password).merge({ code: email_code, 'encrypted-code': @encrypted_code }) @@ -49,10 +74,16 @@ certificate.process_decoded(key, response_data[:certificate]) end private + # @!visibility private + # parse the headers of the authenticate response + # + # @param [String] header_content the headers to parse + # + # @return [Hash] the parsed header def parse_authenticate_headers(header_content) chunks = header_content.split(',') parsed = {} chunks.each do |chunk| @@ -63,34 +94,56 @@ end parsed end + # @!visibility private + # Create a payload to generate a new certificate + # + # @param [String] password the password to authenticate + # + # @return [Hash] the payload to generate a new certificate def payload(password) { login: @cpf, password: password, public_key: key.public_key.to_pem, device_id: @device_id, model: "NubankSdk Client (#@device_id)", } end + # @!visibility private + # Create a payload to authenticate with the nubank api + # + # @param [String] password the password to authenticate + # + # @return [Hash] the payload to authenticate def token_payload(password) { 'grant_type': 'password', 'client_id': 'legacy_client_id', 'client_secret': 'legacy_client_secret', 'login': @cpf, 'password': password } end + # @!visibility private + # Generates a new key for the certificate communication + # + # @return [OpenSSL::PKey::RSA] a new key def generate_key OpenSSL::PKey::RSA.new 2048 end + # @!visibility private + # Add the new links to the api routes + # + # @param [Hash] links the new links to add + # + # @return [NubankSdk::ApiRoutes] the api routes with the new links def update_api_routes(links) feed_url_keys = ['events', 'magnitude'] bills_url_keys = ['bills_summary'] customer_url_keys = ['customer'] account_url_keys = ['account'] @@ -98,42 +151,70 @@ @api_routes.add_entrypoint(path: :ssl, entrypoint: :query, url: links[:ghostflame][:href]) @api_routes.add_entrypoint(path: :ssl, entrypoint: :feed, url: find_url(feed_url_keys, links)) @api_routes.add_entrypoint(path: :ssl, entrypoint: :bills, url: find_url(bills_url_keys, links)) @api_routes.add_entrypoint(path: :ssl, entrypoint: :customer, url: find_url(customer_url_keys, links)) @api_routes.add_entrypoint(path: :ssl, entrypoint: :account, url: find_url(account_url_keys, links)) + @api_routes end + # @!visibility private + # Return the url of the first key found in the links + # + # @param [Array] keys the keys to search in the links + # @param [Hash] list of the links to search in + # + # @return [String] the url of the first key found def find_url(keys, list) links_keys = list.keys keys.each do |url_key| return list[url_key]['href'] if links_keys.include?(url_key) end '' end + # @!visibility private + # Generates a new connection with certificate + # + # @return [Client::HTTPS] a new connection with certificate def prepare_default_connection uri, @gen_certificate_path = @api_routes.entrypoint( path: :app, entrypoint: :gen_certificate, type: :splitted ) Client::HTTP.new(uri, @connection_adapter) end + # @!visibility private + # Create a new default connection to the nubank api + # + # @return [Client::HTTP] a new default connection def default_connection @default_connection ||= prepare_default_connection end + # @!visibility private + # Create a new ssl connection to the nubank api + # + # @return [Client::HTTPS] a new ssl connection def ssl_connection @ssl_connection ||= Client::HTTPS.new(certificate.encoded, @connection_adapter) end + # @!visibility private + # return the key of the certificate communication + # + # @return [OpenSSL::PKey::RSA] the key of the certificate def key @key ||= generate_key end + # @!visibility private + # Generates a random device id + # + # @return [String] a random device id def generate_device_id SecureRandom.uuid.split('-').last end end end