conexa 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,116 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'jwt'
4
-
5
-
6
- module Conexa
7
- # Valid client types for authentication
8
- CLIENT_TYPES = [:pdv, :e_comerce].freeze
9
- #
10
- # Class to hold client authetication data
11
- #
12
- class Client
13
- attr_reader :secret_key, :access_key, :client_id, :key, :type
14
- attr_accessor :default
15
-
16
-
17
- #
18
- # Initialize Client instance
19
- #
20
- # @param [Hash] **options Options required
21
- # @options [String] :secret_key (Defaults to Conexa.secret_key)
22
- # @options [String] :access_key (Defaults to Conexa.access_key)
23
- # @options [String] :client_id (Required) The client identifier
24
- # @options [String] :key (Defaults to Conexa.default_client_key)
25
- # @options [Boolean] :default (Defaults to true) Param to define if client is the default one ( Not fully used)
26
- # @options [Symbol] :type (Defaults to :pdv) Param to define if client is an PDV or E-Commerce [:pdv, :e_comerce]. Raises ParamError if not included in these types.
27
- def initialize(**options)
28
- begin
29
- @secret_key = options.fetch(:secret_key, Conexa.secret_key)
30
- @access_key = options.fetch(:access_key, Conexa.access_key)
31
- @client_id = options.fetch(:client_id)
32
- @key = Conexa::Util.to_sym(options.fetch(:key, Conexa.default_client_key ))
33
- @default = options.fetch(:default, true)
34
- @type = options.fetch(:type, :pdv)
35
- raise ParamError.new("Incorrect client type, must be one of #{CLIENT_TYPES}", :type, "Symbol") unless CLIENT_TYPES.include? @type
36
- rescue KeyError => e
37
- raise ParamError.new("Missing data for credentials: #{e.key}, (#{e.message})", "Credentials", "Symbol or String") unless CLIENT_TYPES.include? @type
38
- end
39
- end
40
-
41
- #
42
- # Convert Client instance to hash
43
- #
44
- # @return [Hash] Return Client in hash form
45
- #
46
- def to_h
47
- {
48
- secret_key: @secret_key,
49
- access_key: @access_key,
50
- client_id: @client_id,
51
- key: @key
52
- }
53
- end
54
- end
55
-
56
- class Authenticator
57
- attr_reader :key, :client
58
-
59
- #
60
- # Initialize Authenticator Class
61
- #
62
- # @param [Client] client Receives Client instance to initialize authenticator
63
- #
64
- def initialize(client)
65
- @client = client
66
- @key = client.key
67
- authenticate
68
- end
69
-
70
- #
71
- # Return client authentication token
72
- #
73
- # @return [String] Returns cleint authentication token
74
- #
75
- def token
76
- refresh_token_if_expired
77
- @a_token
78
- end
79
-
80
- private
81
-
82
- #
83
- # Call api to authenticate client, receiving auth and refresh token
84
- #
85
- # @return [String] Refresh token
86
- #
87
- def authenticate
88
- set_token_from_request Conexa::Request.auth('/pdvauth', {params: {client_id: @client.client_id, secret_key: @client.secret_key, access_key: @client.access_key, client_key: @key}}).run
89
- end
90
-
91
- #
92
- # Refreshes token to receive a new, not expired, JWT auth_token
93
- #
94
- # @return [<Type>] <description>
95
- #
96
- def refresh_token
97
- set_token_from_request Conexa::Request.auth('/refresh-token', {headers: { authorization: 'Bearer ' + @r_token}, client_key: @key}).run
98
- end
99
-
100
- def refresh_token_if_expired
101
- refresh_token if Time.at(JWT.decode(@a_token, nil, false).first.dig('exp')) < Time.now()
102
- end
103
-
104
- #
105
- # Sets tokens based on response of request
106
- #
107
- # @param [ConexaObject] response Response from authentication or refresh request
108
- # @note Must include 'access_token' and 'refresh_token'
109
- # @return [String] Refresh token
110
- #
111
- def set_token_from_request response
112
- @a_token = response['access_token']
113
- @r_token = response['refresh_token']
114
- end
115
- end
116
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Conexa
4
- class OrderCommon < Model
5
- # Keep old name as alias for backwards compatibility
6
- OrderCommom = self
7
-
8
- #
9
- # Request refund to Conexa api for this order
10
- #
11
- # @param [Hash] params Parameters for function
12
- # @option params [Numeric] :amount (Required) The amount that will be refunded in float format
13
- # @return [Order] Return model order instance
14
- # @example Refund 1.0 from order
15
- # order_instance.refund(amount: 1.0)
16
- def refund(params={})
17
- raise ParamError.new("Missing ammount param", :amount, :float, url('refund')) unless params.has_key? :amount
18
- update Conexa::Request.delete(url_delete('refund'), params: params.merge(client_key: @client_key)).call(underscored_class_name)
19
- self
20
- end
21
-
22
- #
23
- # Defines primary key for model
24
- #
25
- # @return [String] Return the primary_key field value
26
- def primary_key
27
- order_id
28
- end
29
-
30
- def url_delete(*params)
31
- raise RequestError.new('Invalid ID') unless primary_key.present?
32
- ["/order", CGI.escape(primary_key.to_s), *params].join('/')
33
- end
34
-
35
- #
36
- # Request order Cancel to Conexa api
37
- #
38
- # @return [Order] Return model order instance
39
- def cancel()
40
- update Conexa::Request.delete(url_delete, client_key: @client_key).call(underscored_class_name)
41
- self
42
- end
43
- end
44
- end
@@ -1,136 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Conexa
4
-
5
- #
6
- # Class to manage Tokens with singleton structure
7
- #
8
- class TokenManager
9
- attr_reader :authenticators, :mutex
10
-
11
- # private_class_method :new
12
-
13
- #
14
- # Initializes TokenManager
15
- #
16
- # This class builds authentication array with a mutex to share tokens
17
- def initialize()
18
- tokens = nil
19
- if Conexa.credentials
20
- case Conexa.credentials
21
- when Array
22
- tokens = Conexa.credentials
23
- when Hash
24
- tokens = [Conexa.credentials]
25
- end
26
- else
27
- tokens = [{
28
- secret_key: Conexa.secret_key,
29
- access_key: Conexa.access_key,
30
- client_id: Conexa.client_id,
31
- key: :default,
32
- default: true
33
- }]
34
- end
35
-
36
- @mutex = Mutex.new
37
- @authenticators = nil
38
- setup_autenticators tokens
39
- end
40
-
41
- #
42
- # Sets authenticators based on tokens passed by constructor
43
- #
44
- # @param [Array] tokens Array of tokens to be registered as clients
45
- #
46
- # @return [Array] Authenticators array
47
- #
48
- def setup_autenticators tokens
49
- return @authenticators if @authenticators
50
- tokens = tokens.map{|t| Conexa::Client.new(**t)}
51
- @mutex.synchronize do
52
- @authenticators = []
53
- tokens.each do |client|
54
- @authenticators << Authenticator.new(client)
55
- end
56
- end
57
- end
58
-
59
- #
60
- # Find a token for a specific Client Key
61
- #
62
- # @param [Symbol] key Client Key to be found in Authenticators Array
63
- #
64
- # @return [String] Auth token
65
- #
66
- def self.token_for(key = Conexa.default_client_key)
67
- self.instance unless @instance
68
- k = Conexa::Util.to_sym(key)
69
- raise MissingCredentialsError.new("Missing credentials for key: '#{key}'") unless @instance.authenticators
70
-
71
- @instance.mutex.synchronize do
72
- auth = @instance.authenticators.find { |obj| obj.key == k}
73
-
74
- raise MissingCredentialsError.new("Missing credentials for key: '#{key}'") if auth.blank?
75
- auth.token
76
- end
77
- end
78
-
79
- #
80
- # Registers a new client to be used
81
- #
82
- # @param [Conexa::Client] client Client instance to be registered in TokenManager
83
- #
84
- # @return [Array] Authenticators array
85
- # @example Ads a new client to be used in calls to Conexa Api
86
- # Conexa::TokenManager.add_client Client.new(client_id: <CLIENT_KEY>, key: :<CLIENT_ALIAS>)
87
- def self.add_client client
88
- self.instance unless @instance
89
- client = (client.is_a? Conexa::Client)? client : Conexa::Client.new(**client)
90
-
91
- raise ParamError.new("Client key '#{client.key}' already exists", 'Key', '') if self.client_for client.key
92
-
93
- @instance.mutex.synchronize do
94
- @instance.authenticators << Authenticator.new(client)
95
- end
96
- end
97
-
98
-
99
-
100
- #
101
- # Find a Client for a specific Key
102
- #
103
- # @param [Symbol] key Client Key to be found in Authenticators Array ( Defaults to Conexa.default_client_key)
104
- #
105
- # @return [Conexa::Client] Client instance registed with the key passed
106
- #
107
- def self.client_for(key = Conexa.default_client_key)
108
- k = Conexa::Util.to_sym(key)
109
- self.instance unless @instance
110
- return nil unless @instance.authenticators.present?
111
-
112
- @instance.mutex.synchronize do
113
- auth = @instance.authenticators.find { |obj| obj.key == k}
114
- auth&.client
115
- end
116
- end
117
-
118
- #
119
- # Find a Client Type for a specific Key
120
- #
121
- # @param [Symbol] key Client Key to be found in Authenticators Array ( Defaults to Conexa.default_client_key)
122
- #
123
- # @return [Symbol] Return the cleint type ( :pdv or :e_commerce) ( Defaults to :pdv if not found)
124
- #
125
- def self.client_type_for key = Conexa.default_client_key
126
- client_for(key)&.type || :pdv
127
- end
128
-
129
- def self.instance
130
- return @instance if @instance
131
-
132
- @instance = TokenManager.new
133
- end
134
- end
135
- end
136
-
@@ -1,35 +0,0 @@
1
- require 'json'
2
-
3
- collection = JSON.parse(File.read('docs/postman-collection.json'))
4
-
5
- fixtures_dir = 'spec/fixtures'
6
- Dir.mkdir(fixtures_dir) unless Dir.exist?(fixtures_dir)
7
-
8
- count = 0
9
-
10
- collection['item'].each do |section|
11
- section_name = section['name'].downcase.gsub(' ', '_').gsub(/[^a-z0-9_]/, '')
12
- next if section_name.include?('desenvolvimento')
13
-
14
- (section['item'] || []).each do |endpoint|
15
- method = endpoint.dig('request', 'method') || 'UNKNOWN'
16
- responses = endpoint['response'] || []
17
-
18
- responses.each_with_index do |resp, idx|
19
- next unless resp['code'] && resp['code'] < 300
20
- next unless resp['body']
21
-
22
- begin
23
- body = JSON.parse(resp['body'])
24
- key = "#{section_name}_#{method.downcase}_#{idx}"
25
- File.write("#{fixtures_dir}/#{key}.json", JSON.pretty_generate(body))
26
- puts "Created: #{key}.json"
27
- count += 1
28
- rescue JSON::ParserError
29
- # skip
30
- end
31
- end
32
- end
33
- end
34
-
35
- puts "\nTotal: #{count} fixtures"