starkcore 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 597f29968666f97ec42b8c6bef044896258eb166daf282d88a20bf1428f96a6e
4
+ data.tar.gz: f4ae2a817c7db41b8bd14f03600297e1439332804f4d7dcce75f49217f52b5c4
5
+ SHA512:
6
+ metadata.gz: 1794d7632dcb540c513ff403643b9770d73e32610d7a5505157d3f63209873d65ec781f543a7b6e65d4a0cdc0ff463981c98fa36ed9afba6f4ace418b4b9717a
7
+ data.tar.gz: 28eb48e9984fe0fa24949f7785c7f87224c1f0912382e96f953400c53615bf170cc31585062dbd3416f38419bdc0c4dd9275ad6c742afcb443136d45f8eb9a1a
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StarkCore
4
+ class Environment
5
+ PRODUCTION = 'production'
6
+ SANDBOX = 'sandbox'
7
+
8
+ public_constant :PRODUCTION, :SANDBOX;
9
+ end
10
+ end
data/lib/error.rb ADDED
@@ -0,0 +1,51 @@
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
+ super(content.to_json)
33
+ end
34
+ end
35
+
36
+ class InternalServerError < StarkCoreError
37
+ def initialize(message = 'Houston, we have a problem.')
38
+ super(message)
39
+ end
40
+ end
41
+
42
+ class UnknownError < StarkCoreError
43
+ def initialize(message)
44
+ super("Unknown exception encountered: #{message}")
45
+ end
46
+ end
47
+
48
+ class InvalidSignatureError < StarkCoreError
49
+ end
50
+ end
51
+ end
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
data/lib/starkcore.rb ADDED
@@ -0,0 +1,24 @@
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/parse"
11
+ require_relative "utils/request"
12
+ require_relative "utils/resource"
13
+ require_relative "utils/rest"
14
+ require_relative "utils/sub_resource"
15
+ require_relative "utils/url"
16
+ require_relative "environment"
17
+ require_relative "error"
18
+ require_relative "key"
19
+
20
+ module StarkCore
21
+ @user = nil
22
+ @language = 'en-US'
23
+ class << self; attr_accessor :user, :language; end
24
+ end
@@ -0,0 +1,52 @@
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 and Stark Infra API must be authenticated via an SDK user,
12
+ # which must have been previously created at the Stark Bank or Stark Infra websites
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
+ return "organization/#{@id}/workspace/#{@workspace_id}" if @workspace_id
39
+
40
+ return "organization/#{@id}"
41
+ end
42
+
43
+ def self.replace(organization, workspace_id)
44
+ Organization.new(
45
+ environment: organization.environment,
46
+ id: organization.id,
47
+ private_key: organization.pem,
48
+ workspace_id: workspace_id
49
+ )
50
+ end
51
+ end
52
+ end
@@ -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,19 @@
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
+ super(id)
11
+ @pem = StarkCore::Utils::Checks.check_private_key(private_key)
12
+ @environment = StarkCore::Utils::Checks.check_environment(environment)
13
+ end
14
+
15
+ def private_key
16
+ return EllipticCurve::PrivateKey.fromPem(@pem)
17
+ end
18
+ end
19
+ end
data/lib/utils/api.rb ADDED
@@ -0,0 +1,86 @@
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
+ entity_hash = {}
10
+ entity_hash = entity if entity.is_a?(Hash)
11
+
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::SubResource) ? 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 api_json(value) if value.is_a?(SubResource)
35
+ return value.strftime('%Y-%m-%d') if value.is_a?(Date)
36
+ return value.strftime('%Y-%m-%dT%H:%M:%S+00:00') if value.is_a?(DateTime) || value.is_a?(Time)
37
+ return cast_json_to_api_format(value) if value.is_a?(Hash)
38
+ return value unless value.is_a?(Array)
39
+
40
+ list = []
41
+ value.each do |v|
42
+ if v.is_a?(Hash)
43
+ list << cast_json_to_api_format(v)
44
+ next
45
+ end
46
+ if v.is_a?(SubResource)
47
+ list << api_json(v)
48
+ next
49
+ end
50
+ list << v
51
+ end
52
+ return list
53
+ end
54
+
55
+ def self.from_api_json(resource_maker, json)
56
+ snakes = {}
57
+ json.each do |key, value|
58
+ snakes[StarkCore::Utils::Case.camel_to_snake(key)] = value
59
+ end
60
+
61
+ resource_maker.call(snakes)
62
+ end
63
+
64
+ def self.endpoint(resource_name)
65
+ kebab = StarkCore::Utils::Case.camel_to_kebab(resource_name)
66
+ kebab.sub!('-log', '/log')
67
+ kebab.sub!('-attempt', '/attempt')
68
+ return kebab
69
+ end
70
+
71
+ def self.last_name_plural(resource_name)
72
+ base = last_name(resource_name)
73
+
74
+ return base if base[-1].eql?('s')
75
+ return "#{base}s" if base[-2..-1].eql?('ey')
76
+ return "#{base[0...-1]}ies" if base[-1].eql?('y')
77
+
78
+ return "#{base}s"
79
+ end
80
+
81
+ def self.last_name(resource_name)
82
+ return StarkCore::Utils::Case.camel_to_kebab(resource_name).split('-').last
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StarkCore
4
+ module Utils
5
+ module Cache
6
+ @starkbank_public_key = nil
7
+ class << self; attr_accessor :starkbank_public_key; end
8
+ end
9
+ end
10
+ end
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
@@ -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(language)
32
+ language = language.nil? ? StarkCore.language : 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
+ return 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,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StarkCore
4
+ module Utils
5
+ class Enum
6
+ def values
7
+ list = []
8
+ self.class.constants.each do |constant|
9
+ unless constant[0] == '_' and constant.respond_to?(:call)
10
+ list.push(self.class.const_get(constant))
11
+ end
12
+ end
13
+ return list
14
+ end
15
+
16
+ def is_valid
17
+ return values.include?(self)
18
+ end
19
+ end
20
+ end
21
+ end
data/lib/utils/host.rb ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StarkCore
4
+ module Utils
5
+ class StarkHost < Enum
6
+ INFRA = "infra"
7
+ BANK = "bank"
8
+ SIGN = "sign"
9
+
10
+ public_constant :INFRA, :BANK, :SIGN
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,81 @@
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:, sdk_version:, api_version:,
14
+ host:, resource: nil, user:, language:, timeout:, key: nil)
15
+ content = verify(content: content, signature: signature, sdk_version: sdk_version,
16
+ api_version: api_version, host: host, user: user, language: language,
17
+ timeout: timeout)
18
+ json = JSON.parse(content)
19
+ json = JSON.parse(content)[key] unless key.nil?
20
+
21
+ StarkCore::Utils::API.from_api_json(resource[:resource_maker], json)
22
+ end
23
+
24
+ def self.verify(content:, signature:, sdk_version:, api_version:, host:,
25
+ user:, language:, timeout:)
26
+ begin
27
+ signature = EllipticCurve::Signature.fromBase64(signature)
28
+ rescue
29
+ raise(StarkCore::Error::InvalidSignatureError, 'The provided signature is not valid')
30
+ end
31
+
32
+ if verify_signature(content: content, signature: signature, sdk_version: sdk_version,
33
+ host: host, api_version: api_version, user: user,
34
+ language: language, timeout: timeout)
35
+ return content
36
+ end
37
+
38
+ if verify_signature(content: content, signature: signature, sdk_version: sdk_version,
39
+ host: host, api_version: api_version, user: user,
40
+ language: language, timeout: timeout, refresh: true)
41
+ return content
42
+ end
43
+
44
+ raise(StarkCore::Error::InvalidSignatureError, 'The provided signature and content do not match the Stark bank public key')
45
+ end
46
+
47
+ def self.verify_signature(content:, signature:, sdk_version:, host:, api_version:,
48
+ user:, language:, timeout:, refresh: false)
49
+ public_key = get_public_key_pem(
50
+ sdk_version: sdk_version,
51
+ host: host,
52
+ api_version: api_version,
53
+ user: user,
54
+ language: language,
55
+ timeout: timeout,
56
+ refresh: refresh
57
+ )
58
+ return EllipticCurve::Ecdsa.verify(content, signature, public_key)
59
+ end
60
+
61
+ def self.get_public_key_pem(sdk_version:, host:, api_version:, user:, language:, timeout:, refresh: false, **query)
62
+ public_key = StarkCore::Utils::Cache.starkbank_public_key
63
+ return public_key unless (public_key.nil? || refresh)
64
+
65
+ pem = StarkCore::Utils::Rest.get_raw(
66
+ sdk_version: sdk_version,
67
+ host: host,
68
+ api_version: api_version,
69
+ path: "public-key",
70
+ user: user,
71
+ language: language,
72
+ timeout: timeout,
73
+ limit: 1
74
+ )['publicKeys'][0]['content']
75
+ public_key = EllipticCurve::PublicKey.fromPem(pem)
76
+ StarkCore::Utils::Cache.starkbank_public_key = public_key
77
+ return public_key
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,86 @@
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(host:, sdk_version:, user:, method:, path:, payload: nil, query: nil,
26
+ api_version: "v2", language: "en-US", timeout: 15)
27
+ user = Checks.check_user(user)
28
+ language = Checks.check_language(language)
29
+
30
+ service = {
31
+ StarkCore::Utils::StarkHost::INFRA => "starkinfra",
32
+ StarkCore::Utils::StarkHost::BANK => "starkbank",
33
+ StarkCore::Utils::StarkHost::SIGN => "starksign",
34
+ }[host]
35
+
36
+ base_url = {
37
+ Environment::PRODUCTION => "https://api.#{service}.com/",
38
+ Environment::SANDBOX => "https://sandbox.api.#{service}.com/"
39
+ }[user.environment] + 'v2'
40
+
41
+ url = "#{base_url}/#{path}#{StarkCore::Utils::URL.urlencode(query)}"
42
+ uri = URI(url)
43
+
44
+ access_time = Time.now.to_i
45
+ body = payload.nil? ? '' : payload.to_json
46
+ message = "#{user.access_id}:#{access_time}:#{body}"
47
+ signature = EllipticCurve::Ecdsa.sign(message, user.private_key).toBase64
48
+
49
+ case method
50
+ when 'GET'
51
+ req = Net::HTTP::Get.new(uri)
52
+ when 'DELETE'
53
+ req = Net::HTTP::Delete.new(uri)
54
+ when 'POST'
55
+ req = Net::HTTP::Post.new(uri)
56
+ req.body = body
57
+ when 'PATCH'
58
+ req = Net::HTTP::Patch.new(uri)
59
+ req.body = body
60
+ when 'PUT'
61
+ req = Net::HTTP::Put.new(uri)
62
+ req.body = body
63
+ else
64
+ raise(ArgumentError, 'unknown HTTP method ' + method)
65
+ end
66
+
67
+ req['Access-Id'] = user.access_id
68
+ req['Access-Time'] = access_time
69
+ req['Access-Signature'] = signature
70
+ req['Content-Type'] = 'application/json'
71
+ req['User-Agent'] = "Ruby-#{RUBY_VERSION}-SDK-#{host}-#{sdk_version}"
72
+ req['Accept-Language'] = language
73
+
74
+ request = Net::HTTP.start(uri.hostname, use_ssl: true) { |http| http.request(req) }
75
+
76
+ response = Response.new(Integer(request.code, 10), request.body)
77
+
78
+ raise(StarkCore::Error::InternalServerError) if response.status == 500
79
+ raise(StarkCore::Error::InputErrors, response.json['errors']) if response.status == 400
80
+ raise(StarkCore::Error::UnknownError, response.content) unless response.status == 200
81
+
82
+ return response
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative("sub_resource")
4
+
5
+ module StarkCore
6
+ module Utils
7
+ class Resource < StarkCore::Utils::SubResource
8
+ attr_reader :id
9
+ def initialize(id = nil)
10
+ @id = id
11
+ end
12
+ end
13
+ end
14
+ end
data/lib/utils/rest.rb ADDED
@@ -0,0 +1,212 @@
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:, sdk_version:, host:, api_version:, user:, language:, timeout:, **query)
10
+ json = StarkCore::Utils::Request.fetch(
11
+ host: host,
12
+ sdk_version: sdk_version,
13
+ user: user,
14
+ method: 'GET',
15
+ path: StarkCore::Utils::API.endpoint(resource_name),
16
+ query: query,
17
+ api_version: api_version,
18
+ language: language,
19
+ timeout: timeout,
20
+ ).json
21
+ entities = []
22
+ json[StarkCore::Utils::API.last_name_plural(resource_name)].each do |entity_json|
23
+ entities << StarkCore::Utils::API.from_api_json(resource_maker, entity_json)
24
+ end
25
+ return entities, json['cursor']
26
+ end
27
+
28
+ def self.get_stream(resource_name:, resource_maker:, sdk_version:, host:, api_version:, user:, language:, timeout:, **query)
29
+ limit = query[:limit]
30
+ query[:limit] = limit.nil? ? limit : [limit, 100].min
31
+
32
+ Enumerator.new do |enum|
33
+ loop do
34
+ json = StarkCore::Utils::Request.fetch(
35
+ host: host,
36
+ sdk_version: sdk_version,
37
+ user: user,
38
+ method: 'GET',
39
+ path: StarkCore::Utils::API.endpoint(resource_name),
40
+ query: query,
41
+ api_version: api_version,
42
+ language: language,
43
+ timeout: timeout,
44
+ ).json
45
+ entities = json[StarkCore::Utils::API.last_name_plural(resource_name)]
46
+
47
+ entities.each do |entity|
48
+ enum << StarkCore::Utils::API.from_api_json(resource_maker, entity)
49
+ end
50
+
51
+ unless limit.nil?
52
+ limit -= 100
53
+ query[:limit] = [limit, 100].min
54
+ end
55
+
56
+ cursor = json['cursor']
57
+ query['cursor'] = cursor
58
+ break if cursor.nil? || cursor.empty? || (!limit.nil? && limit <= 0)
59
+ end
60
+ end
61
+ end
62
+
63
+ def self.get_id(resource_name:, resource_maker:, sdk_version:, host:, api_version:, user:, id:, language:, timeout:, **query)
64
+ json = StarkCore::Utils::Request.fetch(
65
+ host: host,
66
+ sdk_version: sdk_version,
67
+ user: user,
68
+ method: 'GET',
69
+ path: "#{StarkCore::Utils::API.endpoint(resource_name)}/#{id}",
70
+ query: query,
71
+ api_version: api_version,
72
+ language: language,
73
+ timeout: timeout,
74
+ ).json
75
+ entity = json[StarkCore::Utils::API.last_name(resource_name)]
76
+ return StarkCore::Utils::API.from_api_json(resource_maker, entity)
77
+ end
78
+
79
+ def self.get_content(resource_name:, resource_maker:, sdk_version:, host:, api_version:, user:, language:, timeout:, sub_resource_name:, id:, **query)
80
+ return StarkCore::Utils::Request.fetch(
81
+ host: host,
82
+ sdk_version: sdk_version,
83
+ user: user,
84
+ method: 'GET',
85
+ path: "#{StarkCore::Utils::API.endpoint(resource_name)}/#{id}/#{StarkCore::Utils::API.endpoint(sub_resource_name)}",
86
+ query: query,
87
+ api_version: api_version,
88
+ language: language,
89
+ timeout: timeout,
90
+ ).content
91
+ end
92
+
93
+ def self.get_sub_resource(resource_name:, sub_resource_maker:, sub_resource_name:, sdk_version:, host:, api_version:, user:, language:, timeout:, id:, **query)
94
+ json = StarkCore::Utils::Request.fetch(
95
+ host: host,
96
+ sdk_version: sdk_version,
97
+ user: user,
98
+ method: 'GET',
99
+ path: "#{StarkCore::Utils::API.endpoint(resource_name)}/#{id}/#{StarkCore::Utils::API.endpoint(sub_resource_name)}",
100
+ query: StarkCore::Utils::API.cast_json_to_api_format(query),
101
+ api_version: api_version,
102
+ timeout: timeout,
103
+ ).json
104
+ entity = json[StarkCore::Utils::API.last_name(sub_resource_name)]
105
+ return StarkCore::Utils::API.from_api_json(sub_resource_maker, entity)
106
+ end
107
+
108
+ def self.get_sub_resources(resource_name:, sub_resource_maker:, sub_resource_name:, sdk_version:, host:, api_version:, user:, language:, timeout:, id:, **query)
109
+ json = StarkCore::Utils::Request.fetch(
110
+ host: host,
111
+ sdk_version: sdk_version,
112
+ user: user,
113
+ method: 'GET',
114
+ path: "#{StarkCore::Utils::API.endpoint(resource_name)}/#{id}/#{StarkCore::Utils::API.endpoint(sub_resource_name)}",
115
+ query: StarkCore::Utils::API.cast_json_to_api_format(query),
116
+ api_version: api_version,
117
+ timeout: timeout,
118
+ ).json
119
+ returned_jsons = json[StarkCore::Utils::API.last_name_plural(sub_resource_name)]
120
+ entities = []
121
+ returned_jsons.each do |returned_json|
122
+ entities << StarkCore::Utils::API.from_api_json(sub_resource_maker, returned_json)
123
+ end
124
+ return entities
125
+ end
126
+
127
+ def self.post(resource_name:, resource_maker:, sdk_version:, host:, api_version:, user:, language:, timeout:, entities:, **query)
128
+
129
+ jsons = []
130
+ entities.each do |entity|
131
+ jsons << StarkCore::Utils::API.api_json(entity)
132
+ end
133
+ payload = { StarkCore::Utils::API.last_name_plural(resource_name) => jsons }
134
+
135
+ json = StarkCore::Utils::Request.fetch(
136
+ host: host,
137
+ sdk_version: sdk_version,
138
+ user: user,
139
+ method: 'POST',
140
+ path: StarkCore::Utils::API.endpoint(resource_name),
141
+ query: query,
142
+ payload: payload,
143
+ api_version: api_version,
144
+ timeout: timeout
145
+ ).json
146
+ returned_jsons = json[StarkCore::Utils::API.last_name_plural(resource_name)]
147
+ entities = []
148
+ returned_jsons.each do |returned_json|
149
+ entities << StarkCore::Utils::API.from_api_json(resource_maker, returned_json)
150
+ end
151
+ return entities
152
+ end
153
+
154
+ def self.post_single(resource_name:, resource_maker:, sdk_version:, host:, api_version:, user:, language:, timeout:, entity:)
155
+ payload = StarkCore::Utils::API.api_json(entity)
156
+ json = StarkCore::Utils::Request.fetch(
157
+ host: host,
158
+ sdk_version: sdk_version,
159
+ user: user,
160
+ method: 'POST',
161
+ path: StarkCore::Utils::API.endpoint(resource_name),
162
+ payload: payload,
163
+ api_version: api_version,
164
+ timeout: timeout
165
+ ).json
166
+ entity_json = json[StarkCore::Utils::API.last_name(resource_name)]
167
+ return StarkCore::Utils::API.from_api_json(resource_maker, entity_json)
168
+ end
169
+
170
+ def self.delete_id(resource_name:, resource_maker:, sdk_version:, host:, api_version:, user:, language:, timeout:, id:)
171
+ json = StarkCore::Utils::Request.fetch(
172
+ host: host,
173
+ sdk_version: sdk_version,
174
+ user: user,
175
+ method: 'DELETE',
176
+ path: "#{StarkCore::Utils::API.endpoint(resource_name)}/#{id}",
177
+ api_version: api_version,
178
+ timeout: timeout
179
+ ).json
180
+ entity = json[StarkCore::Utils::API.last_name(resource_name)]
181
+ return StarkCore::Utils::API.from_api_json(resource_maker, entity)
182
+ end
183
+
184
+ def self.patch_id(resource_name:, resource_maker:, sdk_version:, host:, api_version:, user:, language:, timeout:, id:, **payload)
185
+ json = StarkCore::Utils::Request.fetch(
186
+ host: host,
187
+ sdk_version: sdk_version,
188
+ user: user,
189
+ method: 'PATCH',
190
+ path: "#{StarkCore::Utils::API.endpoint(resource_name)}/#{id}",
191
+ payload: StarkCore::Utils::API.cast_json_to_api_format(payload),
192
+ api_version: api_version,
193
+ timeout: timeout
194
+ ).json
195
+ entity = json[StarkCore::Utils::API.last_name(resource_name)]
196
+ return StarkCore::Utils::API.from_api_json(resource_maker, entity)
197
+ end
198
+
199
+ def self.get_raw(sdk_version:, host:, api_version:, path:, user:, language:, timeout:, **query)
200
+ return json = StarkCore::Utils::Request.fetch(
201
+ host: host,
202
+ sdk_version: sdk_version,
203
+ user: user,
204
+ method: 'GET',
205
+ path: path,
206
+ api_version: api_version,
207
+ timeout: timeout
208
+ ).json
209
+ end
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
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 class_name
17
+ self.class.name.split('::').last.downcase
18
+ end
19
+ end
20
+ end
21
+ end
data/lib/utils/url.rb ADDED
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'erb'
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
+ return '?' + query_list.join('&')
25
+ end
26
+ end
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: starkcore
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - starkinfra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-01-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: starkbank-ecdsa
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 5.14.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 5.14.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.81'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.81'
69
+ description:
70
+ email:
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/environment.rb
76
+ - lib/error.rb
77
+ - lib/key.rb
78
+ - lib/starkcore.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
94
+ homepage: https://github.com/starkinfra/core-ruby
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '2.3'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubygems_version: 3.0.3.1
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Basic SDK functionalities for the starkbank and starkinfra SDKs
117
+ test_files: []