fhakfjds 0.0.1 → 0.0.3
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.
- checksums.yaml +4 -4
- data/lib/environment.rb +11 -0
- data/lib/error.rb +52 -0
- data/lib/fhakfjds.rb +17 -0
- data/lib/key.rb +33 -0
- data/lib/user/organization.rb +54 -0
- data/lib/user/project.rb +37 -0
- data/lib/user/user.rb +20 -0
- data/lib/utils/api.rb +75 -0
- data/lib/utils/cache.rb +10 -0
- data/lib/utils/case.rb +21 -0
- data/lib/utils/checks.rb +97 -0
- data/lib/utils/enum.rb +20 -0
- data/lib/utils/host.rb +11 -0
- data/lib/utils/parse.rb +54 -0
- data/lib/utils/request.rb +79 -0
- data/lib/utils/resource.rb +13 -0
- data/lib/utils/rest.rb +136 -0
- data/lib/utils/sub_resource.rb +28 -0
- data/lib/utils/url.rb +28 -0
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a7eaec29175b7d5b1ea53b2188f5ca5fa0f1fe7dfd68962c8a76fea9a13cd13
|
4
|
+
data.tar.gz: d5e04816c9c2e993b05f8a2756fc8ecf71aa175f5b1f8b5a1b8637d2f6b495ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36e3b43236654ebcd083d34f60d77efd41e9066de3f9f7583471d46a05e9c39dfc3627e1726f4dca83eb6a12e370d04d0f5cb730f6d554eaf276d9273aa1b5a8
|
7
|
+
data.tar.gz: 753124a83f85521af130c17f242445fe99ba93776fa2743a2b8f6df75fbdb3ed80d940c59d005fec838f71564aaa8416e0ec6d5082559f508a6da3476ea42dbf
|
data/lib/environment.rb
ADDED
data/lib/error.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require('json')
|
4
|
+
|
5
|
+
module StarkCore
|
6
|
+
module Error
|
7
|
+
class StarkCoreError < StandardError
|
8
|
+
attr_reader :message
|
9
|
+
def initialize(message)
|
10
|
+
@message = message
|
11
|
+
super(message)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Error < StarkCoreError
|
16
|
+
attr_reader :code, :message
|
17
|
+
def initialize(code, message)
|
18
|
+
@code = code
|
19
|
+
@message = message
|
20
|
+
super("#{code}: #{message}")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class InputErrors < StarkCoreError
|
25
|
+
attr_reader :errors
|
26
|
+
def initialize(content)
|
27
|
+
errors = []
|
28
|
+
content.each do |error|
|
29
|
+
errors << Error.new(error['code'], error['message'])
|
30
|
+
end
|
31
|
+
@errors = errors
|
32
|
+
|
33
|
+
super(content.to_json)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class InternalServerError < StarkCoreError
|
38
|
+
def initialize(message = 'Houston, we have a problem.')
|
39
|
+
super(message)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class UnknownError < StarkCoreError
|
44
|
+
def initialize(message)
|
45
|
+
super("Unknown exception encountered: #{message}")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class InvalidSignatureError < StarkCoreError
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/fhakfjds.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative "user/organization"
|
2
|
+
require_relative "user/project"
|
3
|
+
require_relative "user/user"
|
4
|
+
require_relative "utils/api"
|
5
|
+
require_relative "utils/cache"
|
6
|
+
require_relative "utils/case"
|
7
|
+
require_relative "utils/checks"
|
8
|
+
require_relative "utils/enum"
|
9
|
+
require_relative "utils/host"
|
10
|
+
require_relative "utils/request"
|
11
|
+
require_relative "utils/resource"
|
12
|
+
require_relative "utils/rest"
|
13
|
+
require_relative "utils/sub_resource"
|
14
|
+
require_relative "utils/url"
|
15
|
+
require_relative "environment"
|
16
|
+
require_relative "error"
|
17
|
+
require_relative "key"
|
data/lib/key.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require('fileutils')
|
4
|
+
require('starkbank-ecdsa')
|
5
|
+
|
6
|
+
module StarkCore
|
7
|
+
module Key
|
8
|
+
# # Generate a new key pair
|
9
|
+
# Generates a secp256k1 ECDSA private/public key pair to be used in the API
|
10
|
+
# authentications
|
11
|
+
#
|
12
|
+
# ## Parameters (optional):
|
13
|
+
# - path [string]: path to save the keys .pem files. No files will be saved if this parameter isn't provided
|
14
|
+
#
|
15
|
+
# ## Return:
|
16
|
+
# - private and public key pems
|
17
|
+
def self.create(path=nil)
|
18
|
+
private_key = EllipticCurve::PrivateKey.new
|
19
|
+
public_key = private_key.publicKey
|
20
|
+
|
21
|
+
private_key_pem = private_key.toPem
|
22
|
+
public_key_pem = public_key.toPem
|
23
|
+
|
24
|
+
unless path.nil?
|
25
|
+
FileUtils.mkdir_p(path)
|
26
|
+
File.write(File.join(path, 'private.pem'), private_key_pem)
|
27
|
+
File.write(File.join(path, 'public.pem'), public_key_pem)
|
28
|
+
end
|
29
|
+
|
30
|
+
[private_key_pem, public_key_pem]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative('user')
|
4
|
+
|
5
|
+
module StarkCore
|
6
|
+
# # Organization object
|
7
|
+
# The Organization object is an authentication entity for the SDK that
|
8
|
+
# represents your entire Organization, being able to access any Workspace
|
9
|
+
# underneath it and even create new Workspaces. Only a legal representative
|
10
|
+
# of your organization can register or change the Organization credentials.
|
11
|
+
# All requests to the Stark Bank API must be authenticated via an SDK user,
|
12
|
+
# which must have been previously created at the Stark Bank website
|
13
|
+
# [https://web.sandbox.starkbank.com] or [https://web.starkbank.com]
|
14
|
+
# before you can use it in this SDK. Organizations may be passed as the user parameter on
|
15
|
+
# each request or may be defined as the default user at the start (See README).
|
16
|
+
# If you are accessing a specific Workspace using Organization credentials, you should
|
17
|
+
# specify the workspace ID when building the Organization object or by request, using
|
18
|
+
# the Organization.replace(organization, workspace_id) method, which creates a copy of the organization
|
19
|
+
# object with the altered workspace ID. If you are listing or creating new Workspaces, the
|
20
|
+
# workspace_id should be nil.
|
21
|
+
#
|
22
|
+
# ## Parameters (required):
|
23
|
+
# - environment [string]: environment where the organization is being used. ex: 'sandbox' or 'production'
|
24
|
+
# - id [string]: unique id required to identify organization. ex: '5656565656565656'
|
25
|
+
# - private_key [string]: PEM string of the private key linked to the organization. ex: '-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEyTIHK6jYuik6ktM9FIF3yCEYzpLjO5X/\ntqDioGM+R2RyW0QEo+1DG8BrUf4UXHSvCjtQ0yLppygz23z0yPZYfw==\n-----END PUBLIC KEY-----'
|
26
|
+
# - workspace_id [string]: unique id of the accessed Workspace, if any. ex: nil or '4848484848484848'
|
27
|
+
#
|
28
|
+
# ## Attributes (return-only):
|
29
|
+
# - pem [string]: private key in pem format. ex: '-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEyTIHK6jYuik6ktM9FIF3yCEYzpLjO5X/\ntqDioGM+R2RyW0QEo+1DG8BrUf4UXHSvCjtQ0yLppygz23z0yPZYfw==\n-----END PUBLIC KEY-----'
|
30
|
+
class Organization < StarkCore::User
|
31
|
+
attr_reader :workspace_id
|
32
|
+
def initialize(id:, environment:, private_key:, workspace_id: nil)
|
33
|
+
super(environment, id, private_key)
|
34
|
+
@workspace_id = workspace_id
|
35
|
+
end
|
36
|
+
|
37
|
+
def access_id
|
38
|
+
if @workspace_id
|
39
|
+
"organization/#{@id}/workspace/#{@workspace_id}"
|
40
|
+
else
|
41
|
+
"organization/#{@id}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.replace(organization, workspace_id)
|
46
|
+
Organization.new(
|
47
|
+
environment: organization.environment,
|
48
|
+
id: organization.id,
|
49
|
+
private_key: organization.pem,
|
50
|
+
workspace_id: workspace_id
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/user/project.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative('user')
|
4
|
+
|
5
|
+
module StarkCore
|
6
|
+
# # Project object
|
7
|
+
#
|
8
|
+
# The Project object is an authentication entity for the SDK that is permanently
|
9
|
+
# linked to a specific Workspace.
|
10
|
+
# All requests to the Stark Bank API must be authenticated via an SDK user,
|
11
|
+
# which must have been previously created at the Stark Bank website
|
12
|
+
# [https://web.sandbox.starkbank.com] or [https://web.starkbank.com]
|
13
|
+
# before you can use it in this SDK. Projects may be passed as the user parameter on
|
14
|
+
# each request or may be defined as the default user at the start (See README).
|
15
|
+
#
|
16
|
+
# ## Parameters (required):
|
17
|
+
# - id [string]: unique id required to identify project. ex: '5656565656565656'
|
18
|
+
# - private_key [string]: PEM string of the private key linked to the project. ex: '-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEyTIHK6jYuik6ktM9FIF3yCEYzpLjO5X/\ntqDioGM+R2RyW0QEo+1DG8BrUf4UXHSvCjtQ0yLppygz23z0yPZYfw==\n-----END PUBLIC KEY-----'
|
19
|
+
# - environment [string]: environment where the project is being used. ex: 'sandbox' or 'production'
|
20
|
+
#
|
21
|
+
# ## Attributes (return-only):
|
22
|
+
# - name [string, default '']: project name. ex: 'MyProject'
|
23
|
+
# - allowed_ips [list of strings]: list containing the strings of the ips allowed to make requests on behalf of this project. ex: ['190.190.0.50']
|
24
|
+
# - pem [string]: private key in pem format. ex: '-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEyTIHK6jYuik6ktM9FIF3yCEYzpLjO5X/\ntqDioGM+R2RyW0QEo+1DG8BrUf4UXHSvCjtQ0yLppygz23z0yPZYfw==\n-----END PUBLIC KEY-----'
|
25
|
+
class Project < StarkCore::User
|
26
|
+
attr_reader :name, :allowed_ips
|
27
|
+
def initialize(environment:, id:, private_key:, name: '', allowed_ips: nil)
|
28
|
+
super(environment, id, private_key)
|
29
|
+
@name = name
|
30
|
+
@allowed_ips = allowed_ips
|
31
|
+
end
|
32
|
+
|
33
|
+
def access_id
|
34
|
+
"project/#{@id}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/user/user.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require('starkbank-ecdsa')
|
4
|
+
require_relative('../utils/resource')
|
5
|
+
|
6
|
+
module StarkCore
|
7
|
+
class User < StarkCore::Utils::Resource
|
8
|
+
attr_reader :pem, :environment
|
9
|
+
def initialize(environment, id, private_key)
|
10
|
+
require_relative('../utils/checks')
|
11
|
+
super(id)
|
12
|
+
@pem = StarkCore::Utils::Checks.check_private_key(private_key)
|
13
|
+
@environment = StarkCore::Utils::Checks.check_environment(environment)
|
14
|
+
end
|
15
|
+
|
16
|
+
def private_key
|
17
|
+
EllipticCurve::PrivateKey.fromPem(@pem)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/utils/api.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative('case')
|
4
|
+
|
5
|
+
module StarkCore
|
6
|
+
module Utils
|
7
|
+
module API
|
8
|
+
def self.build_entity_hash(entity)
|
9
|
+
return entity if entity.is_a?(Hash)
|
10
|
+
|
11
|
+
entity_hash = {}
|
12
|
+
entity.instance_variables.each do |key|
|
13
|
+
variable = entity.instance_variable_get(key)
|
14
|
+
entity_hash[key[1..-1]] = variable.is_a?(StarkCore::Utils::Resource) ? build_entity_hash(variable) : entity.instance_variable_get(key)
|
15
|
+
end
|
16
|
+
return entity_hash
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.api_json(entity)
|
20
|
+
built_hash = build_entity_hash(entity)
|
21
|
+
cast_json_to_api_format(built_hash)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.cast_json_to_api_format(hash)
|
25
|
+
entity_hash = {}
|
26
|
+
hash.each do |key, value|
|
27
|
+
next if value.nil?
|
28
|
+
entity_hash[StarkCore::Utils::Case.snake_to_camel(key)] = parse_value(value)
|
29
|
+
end
|
30
|
+
return entity_hash
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.parse_value(value)
|
34
|
+
return value.strftime('%Y-%m-%d') if value.is_a?(Date)
|
35
|
+
return value.strftime('%Y-%m-%dT%H:%M:%S+00:00') if value.is_a?(DateTime) || value.is_a?(Time)
|
36
|
+
return cast_json_to_api_format(value) if value.is_a?(Hash)
|
37
|
+
return value unless value.is_a?(Array)
|
38
|
+
|
39
|
+
list = []
|
40
|
+
value.each do |v|
|
41
|
+
list << (v.is_a?(Hash) ? cast_json_to_api_format(v) : v)
|
42
|
+
end
|
43
|
+
return list
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.from_api_json(resource_maker, json)
|
47
|
+
snakes = {}
|
48
|
+
json.each do |key, value|
|
49
|
+
snakes[StarkCore::Utils::Case.camel_to_snake(key)] = value
|
50
|
+
end
|
51
|
+
return resource_maker.call(snakes)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.endpoint(resource_name)
|
55
|
+
kebab = StarkCore::Utils::Case.camel_to_kebab(resource_name)
|
56
|
+
kebab.sub!('-log', '/log')
|
57
|
+
kebab.sub!('-attempt', '/attempt')
|
58
|
+
return kebab
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.last_name_plural(resource_name)
|
62
|
+
base = last_name(resource_name)
|
63
|
+
|
64
|
+
return base if base[-1].eql?('s')
|
65
|
+
return "#{base}s" if base[-2..-1].eql?('ey')
|
66
|
+
return "#{base[0...-1]}ies" if base[-1].eql?('y')
|
67
|
+
return "#{base}s"
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.last_name(resource_name)
|
71
|
+
StarkCore::Utils::Case.camel_to_kebab(resource_name).split('-').last
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/utils/cache.rb
ADDED
data/lib/utils/case.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StarkCore
|
4
|
+
module Utils
|
5
|
+
module Case
|
6
|
+
def self.camel_to_snake(camel)
|
7
|
+
return camel.to_s.gsub(/([a-z])([A-Z\d])/, '\1_\2').downcase
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.snake_to_camel(snake)
|
11
|
+
camel = snake.to_s.split('_').map(&:capitalize).join
|
12
|
+
camel[0] = camel[0].downcase
|
13
|
+
return camel
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.camel_to_kebab(camel)
|
17
|
+
return camel_to_snake(camel).tr('_', '-')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/utils/checks.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require('date')
|
4
|
+
require('starkbank-ecdsa')
|
5
|
+
require_relative('../environment')
|
6
|
+
require_relative('../user/user')
|
7
|
+
|
8
|
+
module StarkCore
|
9
|
+
module Utils
|
10
|
+
class Checks
|
11
|
+
def self.check_environment(environment)
|
12
|
+
environments = StarkCore::Environment.constants(false).map { |c| StarkCore::Environment.const_get(c) }
|
13
|
+
raise(ArgumentError, "Select a valid environment: #{environments.join(', ')}") unless environments.include?(environment)
|
14
|
+
return environment
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.check_private_key(pem)
|
18
|
+
EllipticCurve::PrivateKey.fromPem(pem)
|
19
|
+
return pem
|
20
|
+
rescue
|
21
|
+
raise(ArgumentError, 'Private-key must be a valid secp256k1 ECDSA string in pem format')
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.check_user(user)
|
25
|
+
return user if user.is_a?(StarkCore::User)
|
26
|
+
user = user.nil? ? StarkCore.user : user
|
27
|
+
raise(ArgumentError, 'A user is required to access our API. Check our README: https://github.com/starkbank/sdk-ruby/') if user.nil?
|
28
|
+
return user
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.check_language
|
32
|
+
language = StarkCore.language
|
33
|
+
accepted_languages = %w[en-US pt-BR]
|
34
|
+
raise(ArgumentError, "Select a valid language: #{accepted_languages.join(', ')}") unless accepted_languages.include?(language)
|
35
|
+
return language
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.check_date_or_datetime(data)
|
39
|
+
return if data.nil?
|
40
|
+
|
41
|
+
return data if data.is_a?(Time) || data.is_a?(DateTime)
|
42
|
+
|
43
|
+
return data if data.is_a?(Date)
|
44
|
+
|
45
|
+
data, type = check_datetime_string(data)
|
46
|
+
type == 'date' ? Date.new(data.year, data.month, data.day) : data
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.check_datetime(data)
|
50
|
+
return if data.nil?
|
51
|
+
|
52
|
+
return data if data.is_a?(Time) || data.is_a?(DateTime)
|
53
|
+
|
54
|
+
return Time.new(data.year, data.month, data.day) if data.is_a?(Date)
|
55
|
+
|
56
|
+
data, _type = check_datetime_string(data)
|
57
|
+
data
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.check_date(data)
|
61
|
+
return if data.nil?
|
62
|
+
|
63
|
+
return Date.new(data.year, data.month, data.day) if data.is_a?(Time) || data.is_a?(DateTime)
|
64
|
+
|
65
|
+
return data if data.is_a?(Date)
|
66
|
+
|
67
|
+
data, type = check_datetime_string(data)
|
68
|
+
|
69
|
+
type == 'date' ? Date.new(data.year, data.month, data.day) : data
|
70
|
+
end
|
71
|
+
|
72
|
+
class << self
|
73
|
+
private
|
74
|
+
|
75
|
+
def check_datetime_string(data)
|
76
|
+
data = data.to_s
|
77
|
+
|
78
|
+
begin
|
79
|
+
return [DateTime.strptime(data, '%Y-%m-%dT%H:%M:%S.%L+00:00'), 'datetime']
|
80
|
+
rescue ArgumentError
|
81
|
+
end
|
82
|
+
|
83
|
+
begin
|
84
|
+
return [DateTime.strptime(data, '%Y-%m-%dT%H:%M:%S+00:00'), 'datetime']
|
85
|
+
rescue ArgumentError
|
86
|
+
end
|
87
|
+
|
88
|
+
begin
|
89
|
+
return [DateTime.strptime(data, '%Y-%m-%d'), 'date']
|
90
|
+
rescue ArgumentError
|
91
|
+
raise(ArgumentError, 'invalid datetime string ' + data)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/utils/enum.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module StarkCore
|
3
|
+
module Utils
|
4
|
+
class Enum
|
5
|
+
def values
|
6
|
+
list = []
|
7
|
+
self.class.constants.each do |constant|
|
8
|
+
unless constant[0] == '_' and constant.respond_to?(:call)
|
9
|
+
list.push(self.class.const_get(constant))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
return list
|
13
|
+
end
|
14
|
+
|
15
|
+
def is_valid
|
16
|
+
return values.include?(self)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/utils/host.rb
ADDED
data/lib/utils/parse.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require('json')
|
4
|
+
require('starkbank-ecdsa')
|
5
|
+
require_relative('api')
|
6
|
+
require_relative('cache')
|
7
|
+
require_relative('request')
|
8
|
+
require_relative('../error')
|
9
|
+
|
10
|
+
module StarkCore
|
11
|
+
module Utils
|
12
|
+
module Parse
|
13
|
+
def self.parse_and_verify(content:, signature:, user: nil, resource:, key: nil)
|
14
|
+
content = verify(content:content, signature: signature, user: user)
|
15
|
+
json = JSON.parse(content)
|
16
|
+
json = JSON.parse(content)[key] unless key.nil?
|
17
|
+
|
18
|
+
StarkCore::Utils::API.from_api_json(resource[:resource_maker], json)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.verify(content:, signature:, user: nil)
|
22
|
+
begin
|
23
|
+
signature = EllipticCurve::Signature.fromBase64(signature)
|
24
|
+
rescue
|
25
|
+
raise(StarkCore::Error::InvalidSignatureError, 'The provided signature is not valid')
|
26
|
+
end
|
27
|
+
|
28
|
+
if verify_signature(content: content, signature: signature, user: user)
|
29
|
+
return content
|
30
|
+
end
|
31
|
+
|
32
|
+
if verify_signature(content: content, signature: signature, user: user, refresh: true)
|
33
|
+
return content
|
34
|
+
end
|
35
|
+
|
36
|
+
raise(StarkCore::Error::InvalidSignatureError, 'The provided signature and content do not match the Stark Infra public key')
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.verify_signature(content:, signature:, user:, refresh: false)
|
40
|
+
public_key = StarkCore::Utils::Cache.starkinfra_public_key
|
41
|
+
if public_key.nil? || refresh
|
42
|
+
pem = get_public_key_pem(user)
|
43
|
+
public_key = EllipticCurve::PublicKey.fromPem(pem)
|
44
|
+
StarkCore::Utils::Cache.starkinfra_public_key = public_key
|
45
|
+
end
|
46
|
+
EllipticCurve::Ecdsa.verify(content, signature, public_key)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.get_public_key_pem(user)
|
50
|
+
StarkCore::Utils::Request.fetch(method: 'GET', path: 'public-key', query: { limit: 1 }, user: user).json['publicKeys'][0]['content']
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require('json')
|
4
|
+
require('starkbank-ecdsa')
|
5
|
+
require('net/http')
|
6
|
+
require_relative('url')
|
7
|
+
require_relative('checks')
|
8
|
+
require_relative('../error')
|
9
|
+
|
10
|
+
module StarkCore
|
11
|
+
module Utils
|
12
|
+
module Request
|
13
|
+
class Response
|
14
|
+
attr_reader :status, :content
|
15
|
+
def initialize(status, content)
|
16
|
+
@status = status
|
17
|
+
@content = content
|
18
|
+
end
|
19
|
+
|
20
|
+
def json
|
21
|
+
JSON.parse(@content)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.fetch(method:, path:, payload: nil, query: nil, user: nil)
|
26
|
+
user = Checks.check_user(user)
|
27
|
+
language = Checks.check_language
|
28
|
+
|
29
|
+
base_url = {
|
30
|
+
Environment::PRODUCTION => 'https://api.starkbank.com/',
|
31
|
+
Environment::SANDBOX => 'https://sandbox.api.starkbank.com/'
|
32
|
+
}[user.environment] + 'v2'
|
33
|
+
|
34
|
+
url = "#{base_url}/#{path}#{StarkCore::Utils::URL.urlencode(query)}"
|
35
|
+
uri = URI(url)
|
36
|
+
|
37
|
+
access_time = Time.now.to_i
|
38
|
+
body = payload.nil? ? '' : payload.to_json
|
39
|
+
message = "#{user.access_id}:#{access_time}:#{body}"
|
40
|
+
signature = EllipticCurve::Ecdsa.sign(message, user.private_key).toBase64
|
41
|
+
|
42
|
+
case method
|
43
|
+
when 'GET'
|
44
|
+
req = Net::HTTP::Get.new(uri)
|
45
|
+
when 'DELETE'
|
46
|
+
req = Net::HTTP::Delete.new(uri)
|
47
|
+
when 'POST'
|
48
|
+
req = Net::HTTP::Post.new(uri)
|
49
|
+
req.body = body
|
50
|
+
when 'PATCH'
|
51
|
+
req = Net::HTTP::Patch.new(uri)
|
52
|
+
req.body = body
|
53
|
+
when 'PUT'
|
54
|
+
req = Net::HTTP::Put.new(uri)
|
55
|
+
req.body = body
|
56
|
+
else
|
57
|
+
raise(ArgumentError, 'unknown HTTP method ' + method)
|
58
|
+
end
|
59
|
+
|
60
|
+
req['Access-Id'] = user.access_id
|
61
|
+
req['Access-Time'] = access_time
|
62
|
+
req['Access-Signature'] = signature
|
63
|
+
req['Content-Type'] = 'application/json'
|
64
|
+
req['User-Agent'] = "Ruby-#{RUBY_VERSION}-SDK-2.6.0"
|
65
|
+
req['Accept-Language'] = language
|
66
|
+
|
67
|
+
request = Net::HTTP.start(uri.hostname, use_ssl: true) { |http| http.request(req) }
|
68
|
+
|
69
|
+
response = Response.new(Integer(request.code, 10), request.body)
|
70
|
+
|
71
|
+
raise(StarkCore::Error::InternalServerError) if response.status == 500
|
72
|
+
raise(StarkCore::Error::InputErrors, response.json['errors']) if response.status == 400
|
73
|
+
raise(StarkCore::Error::UnknownError, response.content) unless response.status == 200
|
74
|
+
|
75
|
+
response
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/utils/rest.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative('request')
|
4
|
+
require_relative('api')
|
5
|
+
|
6
|
+
module StarkCore
|
7
|
+
module Utils
|
8
|
+
module Rest
|
9
|
+
def self.get_page(resource_name:, resource_maker:, user: nil, **query)
|
10
|
+
json = StarkCore::Utils::Request.fetch(
|
11
|
+
method: 'GET',
|
12
|
+
path: StarkCore::Utils::API.endpoint(resource_name),
|
13
|
+
query: query,
|
14
|
+
user: user
|
15
|
+
).json
|
16
|
+
entities = []
|
17
|
+
json[StarkCore::Utils::API.last_name_plural(resource_name)].each do |entity_json|
|
18
|
+
entities << StarkCore::Utils::API.from_api_json(resource_maker, entity_json)
|
19
|
+
end
|
20
|
+
return entities, json['cursor']
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.get_stream(resource_name:, resource_maker:, user: nil, **query)
|
24
|
+
limit = query[:limit]
|
25
|
+
query[:limit] = limit.nil? ? limit : [limit, 100].min
|
26
|
+
|
27
|
+
Enumerator.new do |enum|
|
28
|
+
loop do
|
29
|
+
json = StarkCore::Utils::Request.fetch(
|
30
|
+
method: 'GET',
|
31
|
+
path: StarkCore::Utils::API.endpoint(resource_name),
|
32
|
+
query: query,
|
33
|
+
user: user
|
34
|
+
).json
|
35
|
+
entities = json[StarkCore::Utils::API.last_name_plural(resource_name)]
|
36
|
+
|
37
|
+
entities.each do |entity|
|
38
|
+
enum << StarkCore::Utils::API.from_api_json(resource_maker, entity)
|
39
|
+
end
|
40
|
+
|
41
|
+
unless limit.nil?
|
42
|
+
limit -= 100
|
43
|
+
query[:limit] = [limit, 100].min
|
44
|
+
end
|
45
|
+
|
46
|
+
cursor = json['cursor']
|
47
|
+
query['cursor'] = cursor
|
48
|
+
break if cursor.nil? || cursor.empty? || (!limit.nil? && limit <= 0)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.get_id(resource_name:, resource_maker:, id:, user: nil)
|
54
|
+
json = StarkCore::Utils::Request.fetch(
|
55
|
+
method: 'GET',
|
56
|
+
path: "#{StarkCore::Utils::API.endpoint(resource_name)}/#{id}",
|
57
|
+
user: user
|
58
|
+
).json
|
59
|
+
entity = json[StarkCore::Utils::API.last_name(resource_name)]
|
60
|
+
StarkCore::Utils::API.from_api_json(resource_maker, entity)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.get_content(resource_name:, resource_maker:, sub_resource_name:, id:, user: nil, **query)
|
64
|
+
StarkCore::Utils::Request.fetch(
|
65
|
+
method: 'GET',
|
66
|
+
path: "#{StarkCore::Utils::API.endpoint(resource_name)}/#{id}/#{sub_resource_name}",
|
67
|
+
query: StarkCore::Utils::API.cast_json_to_api_format(query),
|
68
|
+
user: user
|
69
|
+
).content
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.post(resource_name:, resource_maker:, entities:, user: nil)
|
73
|
+
jsons = []
|
74
|
+
entities.each do |entity|
|
75
|
+
jsons << StarkCore::Utils::API.api_json(entity)
|
76
|
+
end
|
77
|
+
payload = { StarkCore::Utils::API.last_name_plural(resource_name) => jsons }
|
78
|
+
json = StarkCore::Utils::Request.fetch(
|
79
|
+
method: 'POST',
|
80
|
+
path: StarkCore::Utils::API.endpoint(resource_name),
|
81
|
+
payload: payload,
|
82
|
+
user: user
|
83
|
+
).json
|
84
|
+
returned_jsons = json[StarkCore::Utils::API.last_name_plural(resource_name)]
|
85
|
+
entities = []
|
86
|
+
returned_jsons.each do |returned_json|
|
87
|
+
entities << StarkCore::Utils::API.from_api_json(resource_maker, returned_json)
|
88
|
+
end
|
89
|
+
entities
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.post_single(resource_name:, resource_maker:, entity:, user: nil)
|
93
|
+
json = StarkCore::Utils::Request.fetch(
|
94
|
+
method: 'POST',
|
95
|
+
path: StarkCore::Utils::API.endpoint(resource_name),
|
96
|
+
payload: StarkCore::Utils::API.api_json(entity),
|
97
|
+
user: user
|
98
|
+
).json
|
99
|
+
entity_json = json[StarkCore::Utils::API.last_name(resource_name)]
|
100
|
+
StarkCore::Utils::API.from_api_json(resource_maker, entity_json)
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.delete_id(resource_name:, resource_maker:, id:, user: nil)
|
104
|
+
json = StarkCore::Utils::Request.fetch(
|
105
|
+
method: 'DELETE',
|
106
|
+
path: "#{StarkCore::Utils::API.endpoint(resource_name)}/#{id}",
|
107
|
+
user: user
|
108
|
+
).json
|
109
|
+
entity = json[StarkCore::Utils::API.last_name(resource_name)]
|
110
|
+
StarkCore::Utils::API.from_api_json(resource_maker, entity)
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.patch_id(resource_name:, resource_maker:, id:, user: nil, **payload)
|
114
|
+
json = StarkCore::Utils::Request.fetch(
|
115
|
+
method: 'PATCH',
|
116
|
+
path: "#{StarkCore::Utils::API.endpoint(resource_name)}/#{id}",
|
117
|
+
user: user,
|
118
|
+
payload: StarkCore::Utils::API.cast_json_to_api_format(payload)
|
119
|
+
).json
|
120
|
+
entity = json[StarkCore::Utils::API.last_name(resource_name)]
|
121
|
+
StarkCore::Utils::API.from_api_json(resource_maker, entity)
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.get_sub_resource(resource_name:, sub_resource_maker:, sub_resource_name:, id:, user: nil, **query)
|
125
|
+
json = StarkCore::Utils::Request.fetch(
|
126
|
+
method: 'GET',
|
127
|
+
path: "#{StarkCore::Utils::API.endpoint(resource_name)}/#{id}/#{StarkCore::Utils::API.endpoint(sub_resource_name)}",
|
128
|
+
user: user,
|
129
|
+
query: StarkCore::Utils::API.cast_json_to_api_format(query)
|
130
|
+
).json
|
131
|
+
entity = json[StarkCore::Utils::API.last_name(sub_resource_name)]
|
132
|
+
StarkCore::Utils::API.from_api_json(sub_resource_maker, entity)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module StarkCore
|
4
|
+
module Utils
|
5
|
+
class SubResource
|
6
|
+
def to_s
|
7
|
+
string_vars = []
|
8
|
+
instance_variables.each do |key|
|
9
|
+
value = instance_variable_get(key).to_s.lines.map(&:chomp).join("\n ")
|
10
|
+
string_vars << "#{key[1..-1]}: #{value}"
|
11
|
+
end
|
12
|
+
fields = string_vars.join(",\n ")
|
13
|
+
"#{class_name}(\n #{fields}\n)"
|
14
|
+
end
|
15
|
+
|
16
|
+
def inspect
|
17
|
+
"#{class_name}[#{@id}]"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def class_name
|
23
|
+
self.class.name.split('::').last.downcase
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
data/lib/utils/url.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
|
5
|
+
module StarkCore
|
6
|
+
module Utils
|
7
|
+
module URL
|
8
|
+
# generates query string from hash
|
9
|
+
def self.urlencode(params)
|
10
|
+
return '' if params.nil?
|
11
|
+
|
12
|
+
params = StarkCore::Utils::API.cast_json_to_api_format(params)
|
13
|
+
return '' if params.empty?
|
14
|
+
|
15
|
+
string_params = {}
|
16
|
+
params.each do |key, value|
|
17
|
+
string_params[key] = value.is_a?(Array) ? value.join(',') : value
|
18
|
+
end
|
19
|
+
|
20
|
+
query_list = []
|
21
|
+
string_params.each do |key, value|
|
22
|
+
query_list << "#{key}=#{ERB::Util.url_encode(value)}"
|
23
|
+
end
|
24
|
+
'?' + query_list.join('&')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fhakfjds
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- xavier
|
@@ -71,7 +71,26 @@ email:
|
|
71
71
|
executables: []
|
72
72
|
extensions: []
|
73
73
|
extra_rdoc_files: []
|
74
|
-
files:
|
74
|
+
files:
|
75
|
+
- lib/environment.rb
|
76
|
+
- lib/error.rb
|
77
|
+
- lib/fhakfjds.rb
|
78
|
+
- lib/key.rb
|
79
|
+
- lib/user/organization.rb
|
80
|
+
- lib/user/project.rb
|
81
|
+
- lib/user/user.rb
|
82
|
+
- lib/utils/api.rb
|
83
|
+
- lib/utils/cache.rb
|
84
|
+
- lib/utils/case.rb
|
85
|
+
- lib/utils/checks.rb
|
86
|
+
- lib/utils/enum.rb
|
87
|
+
- lib/utils/host.rb
|
88
|
+
- lib/utils/parse.rb
|
89
|
+
- lib/utils/request.rb
|
90
|
+
- lib/utils/resource.rb
|
91
|
+
- lib/utils/rest.rb
|
92
|
+
- lib/utils/sub_resource.rb
|
93
|
+
- lib/utils/url.rb
|
75
94
|
homepage:
|
76
95
|
licenses:
|
77
96
|
- MIT
|