workato-connector-sdk 1.2.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +8 -0
- data/README.md +2 -6
- data/VERSION +1 -0
- data/lib/workato/cli/edit_command.rb +3 -1
- data/lib/workato/cli/exec_command.rb +76 -10
- data/lib/workato/cli/generate_command.rb +3 -2
- data/lib/workato/cli/main.rb +18 -10
- data/lib/workato/cli/oauth2_command.rb +4 -4
- data/lib/workato/cli/push_command.rb +23 -7
- data/lib/workato/cli/schema_command.rb +20 -6
- data/lib/workato/connector/sdk/account_properties.rb +3 -3
- data/lib/workato/connector/sdk/action.rb +20 -70
- data/lib/workato/connector/sdk/block_invocation_refinements.rb +4 -11
- data/lib/workato/connector/sdk/connection.rb +44 -21
- data/lib/workato/connector/sdk/connector.rb +73 -76
- data/lib/workato/connector/sdk/core.rb +62 -0
- data/lib/workato/connector/sdk/dsl/aws.rb +13 -3
- data/lib/workato/connector/sdk/dsl/call.rb +1 -1
- data/lib/workato/connector/sdk/dsl/csv_package.rb +133 -0
- data/lib/workato/connector/sdk/dsl/error.rb +2 -0
- data/lib/workato/connector/sdk/dsl/execution_context.rb +3 -0
- data/lib/workato/connector/sdk/dsl/http.rb +7 -2
- data/lib/workato/connector/sdk/dsl/reinvoke_after.rb +84 -0
- data/lib/workato/connector/sdk/dsl/stream_package.rb +59 -0
- data/lib/workato/connector/sdk/dsl/time.rb +0 -14
- data/lib/workato/connector/sdk/dsl/workato_package.rb +152 -0
- data/lib/workato/connector/sdk/dsl.rb +65 -10
- data/lib/workato/connector/sdk/errors.rb +28 -11
- data/lib/workato/connector/sdk/object_definitions.rb +59 -18
- data/lib/workato/connector/sdk/operation.rb +10 -3
- data/lib/workato/connector/sdk/request.rb +67 -26
- data/lib/workato/connector/sdk/schema/field/convertors.rb +2 -2
- data/lib/workato/connector/sdk/schema.rb +10 -7
- data/lib/workato/connector/sdk/settings.rb +13 -2
- data/lib/workato/connector/sdk/stream.rb +262 -0
- data/lib/workato/connector/sdk/streams.rb +72 -0
- data/lib/workato/connector/sdk/summarize.rb +4 -2
- data/lib/workato/connector/sdk/trigger.rb +14 -7
- data/lib/workato/connector/sdk/version.rb +1 -1
- data/lib/workato/connector/sdk.rb +20 -46
- data/lib/workato/extension/array.rb +2 -0
- data/lib/workato/extension/case_sensitive_headers.rb +0 -1
- data/lib/workato/extension/content_encoding_decoder.rb +2 -0
- data/lib/workato/extension/currency/countries.rb +79 -0
- data/lib/workato/extension/currency/countries.yml +18433 -0
- data/lib/workato/extension/currency/currencies.rb +55 -0
- data/lib/workato/extension/currency/currencies.yml +479 -0
- data/lib/workato/extension/currency.rb +73 -5
- data/lib/workato/extension/enumerable.rb +2 -2
- data/lib/workato/extension/metadata_fix_wrap_kw_args.rb +11 -0
- data/lib/workato/extension/string.rb +23 -111
- data/lib/workato/testing/vcr_encrypted_cassette_serializer.rb +2 -0
- data/lib/workato/testing/vcr_multipart_body_matcher.rb +1 -0
- data/lib/workato/types/binary.rb +99 -0
- data/lib/workato/types/unicode_string.rb +62 -0
- metadata +34 -62
- data/lib/workato/connector/sdk/dsl/csv.rb +0 -125
- data/lib/workato/connector/sdk/dsl/workato_code_lib.rb +0 -167
- data/lib/workato/connector/sdk/schema/type/unicode_string.rb +0 -23
@@ -0,0 +1,133 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'csv'
|
5
|
+
|
6
|
+
module Workato
|
7
|
+
module Connector
|
8
|
+
module Sdk
|
9
|
+
CsvError = Class.new(Sdk::RuntimeError)
|
10
|
+
|
11
|
+
CsvFormatError = Class.new(CsvError)
|
12
|
+
|
13
|
+
class CsvFileTooBigError < CsvError
|
14
|
+
extend T::Sig
|
15
|
+
|
16
|
+
sig { returns(Integer) }
|
17
|
+
attr_reader :size
|
18
|
+
|
19
|
+
sig { returns(Integer) }
|
20
|
+
attr_reader :max
|
21
|
+
|
22
|
+
sig { params(size: Integer, max: Integer).void }
|
23
|
+
def initialize(size, max)
|
24
|
+
super("CSV file is too big. Max allowed: #{max.to_s(:human_size)}, got: #{size.to_s(:human_size)}")
|
25
|
+
@size = T.let(size, Integer)
|
26
|
+
@max = T.let(max, Integer)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class CsvFileTooManyLinesError < CsvError
|
31
|
+
extend T::Sig
|
32
|
+
|
33
|
+
sig { returns(Integer) }
|
34
|
+
attr_reader :max
|
35
|
+
|
36
|
+
sig { params(max: Integer).void }
|
37
|
+
def initialize(max)
|
38
|
+
super("CSV file has too many lines. Max allowed: #{max}")
|
39
|
+
@max = T.let(max, Integer)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module Dsl
|
44
|
+
class CsvPackage
|
45
|
+
extend T::Sig
|
46
|
+
|
47
|
+
MAX_FILE_SIZE_FOR_PARSE = T.let(30.megabytes, Integer)
|
48
|
+
private_constant :MAX_FILE_SIZE_FOR_PARSE
|
49
|
+
|
50
|
+
MAX_LINES_FOR_PARSE = 65_000
|
51
|
+
private_constant :MAX_LINES_FOR_PARSE
|
52
|
+
|
53
|
+
sig do
|
54
|
+
params(
|
55
|
+
str: String,
|
56
|
+
headers: T.any(T::Boolean, T::Array[String], String),
|
57
|
+
col_sep: T.nilable(String),
|
58
|
+
row_sep: T.nilable(String),
|
59
|
+
quote_char: T.nilable(String),
|
60
|
+
skip_blanks: T.nilable(T::Boolean),
|
61
|
+
skip_first_line: T::Boolean
|
62
|
+
).returns(
|
63
|
+
T::Array[T::Hash[String, T.untyped]]
|
64
|
+
)
|
65
|
+
end
|
66
|
+
def parse(str, headers:, col_sep: nil, row_sep: nil, quote_char: nil, skip_blanks: nil,
|
67
|
+
skip_first_line: false)
|
68
|
+
if str.bytesize > MAX_FILE_SIZE_FOR_PARSE
|
69
|
+
raise CsvFileTooBigError.new(str.bytesize, MAX_FILE_SIZE_FOR_PARSE)
|
70
|
+
end
|
71
|
+
|
72
|
+
index = 0
|
73
|
+
options = { col_sep: col_sep, row_sep: row_sep, quote_char: quote_char, headers: headers,
|
74
|
+
skip_blanks: skip_blanks }.compact
|
75
|
+
Enumerator.new do |consumer|
|
76
|
+
CSV.parse(str, **options) do |row|
|
77
|
+
if index.zero? && skip_first_line
|
78
|
+
index += 1
|
79
|
+
next
|
80
|
+
end
|
81
|
+
if index == MAX_LINES_FOR_PARSE
|
82
|
+
raise CsvFileTooManyLinesError, MAX_LINES_FOR_PARSE
|
83
|
+
end
|
84
|
+
|
85
|
+
index += 1
|
86
|
+
consumer.yield(T.cast(row, CSV::Row).to_hash)
|
87
|
+
end
|
88
|
+
end.to_a
|
89
|
+
rescue CSV::MalformedCSVError => e
|
90
|
+
raise CsvFormatError, e
|
91
|
+
rescue ArgumentError => e
|
92
|
+
raise Sdk::RuntimeError, e.message
|
93
|
+
end
|
94
|
+
|
95
|
+
sig do
|
96
|
+
params(
|
97
|
+
str: T.nilable(String),
|
98
|
+
headers: T.nilable(T::Array[String]),
|
99
|
+
col_sep: T.nilable(String),
|
100
|
+
row_sep: T.nilable(String),
|
101
|
+
quote_char: T.nilable(String),
|
102
|
+
force_quotes: T.nilable(T::Boolean),
|
103
|
+
blk: T.proc.params(csv: CSV).void
|
104
|
+
).returns(
|
105
|
+
String
|
106
|
+
)
|
107
|
+
end
|
108
|
+
def generate(str = nil, headers: nil, col_sep: nil, row_sep: nil, quote_char: nil, force_quotes: nil, &blk)
|
109
|
+
options = { col_sep: col_sep, row_sep: row_sep, quote_char: quote_char, headers: headers,
|
110
|
+
force_quotes: force_quotes }.compact
|
111
|
+
options[:write_headers] = options[:headers].present?
|
112
|
+
|
113
|
+
::CSV.generate(str || String.new, **options, &blk)
|
114
|
+
rescue ArgumentError => e
|
115
|
+
raise Sdk::RuntimeError, e.message
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
T::Sig::WithoutRuntime.sig { params(symbol: T.any(String, Symbol), _args: T.untyped).void }
|
121
|
+
def method_missing(symbol, *_args)
|
122
|
+
raise UndefinedStdLibMethodError.new(symbol.to_s, 'workato.csv')
|
123
|
+
end
|
124
|
+
|
125
|
+
T::Sig::WithoutRuntime.sig { params(_args: T.untyped).returns(T::Boolean) }
|
126
|
+
def respond_to_missing?(*_args)
|
127
|
+
false
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'securerandom'
|
5
|
+
require 'active_support/core_ext/class/attribute'
|
5
6
|
|
6
7
|
module Workato
|
7
8
|
module Connector
|
@@ -37,6 +38,8 @@ module Workato
|
|
37
38
|
T.unsafe(self).recipe_id.reverse
|
38
39
|
end
|
39
40
|
end
|
41
|
+
|
42
|
+
private_constant :ClassMethods
|
40
43
|
end
|
41
44
|
end
|
42
45
|
end
|
@@ -8,8 +8,13 @@ module Workato
|
|
8
8
|
# https://docs.workato.com/developing-connectors/sdk/sdk-reference/http.html#http-methods
|
9
9
|
module HTTP
|
10
10
|
PARALLEL_SUCCESS_INDEX = 0
|
11
|
+
private_constant :PARALLEL_SUCCESS_INDEX
|
12
|
+
|
11
13
|
PARALLEL_RESULTS_INDEX = 1
|
14
|
+
private_constant :PARALLEL_RESULTS_INDEX
|
15
|
+
|
12
16
|
PARALLEL_ERRORS_INDEX = 2
|
17
|
+
private_constant :PARALLEL_ERRORS_INDEX
|
13
18
|
|
14
19
|
def get(url, params = {})
|
15
20
|
http_request(url, method: 'GET').params(params).response_format_json
|
@@ -52,8 +57,8 @@ module Workato
|
|
52
57
|
response = nil
|
53
58
|
exception = nil
|
54
59
|
begin
|
55
|
-
response = request.
|
56
|
-
rescue
|
60
|
+
response = request.response!
|
61
|
+
rescue StandardError => e
|
57
62
|
exception = e.to_s
|
58
63
|
end
|
59
64
|
result[PARALLEL_SUCCESS_INDEX] &&= exception.nil?
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Workato
|
5
|
+
module Connector
|
6
|
+
module Sdk
|
7
|
+
module Dsl
|
8
|
+
module ReinvokeAfter
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig do
|
12
|
+
params(
|
13
|
+
continue: T::Hash[T.untyped, T.untyped],
|
14
|
+
temp_output: T.nilable(T::Hash[T.untyped, T.untyped])
|
15
|
+
).void
|
16
|
+
end
|
17
|
+
def checkpoint!(continue:, temp_output: nil)
|
18
|
+
# no-op
|
19
|
+
end
|
20
|
+
|
21
|
+
sig do
|
22
|
+
params(
|
23
|
+
seconds: T.any(Integer, Float),
|
24
|
+
continue: T::Hash[T.untyped, T.untyped],
|
25
|
+
temp_output: T.nilable(T::Hash[T.untyped, T.untyped])
|
26
|
+
).void
|
27
|
+
end
|
28
|
+
def reinvoke_after(seconds:, continue:, temp_output: nil) # rubocop:disable Lint/UnusedMethodArgument
|
29
|
+
Kernel.throw REINVOKE_AFTER_SIGNAL, ReinvokeParams.new(
|
30
|
+
seconds: seconds,
|
31
|
+
continue: continue
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
MAX_REINVOKES = 5
|
38
|
+
private_constant :MAX_REINVOKES
|
39
|
+
|
40
|
+
REINVOKE_AFTER_SIGNAL = :reinvoke_after
|
41
|
+
private_constant :REINVOKE_AFTER_SIGNAL
|
42
|
+
|
43
|
+
class ReinvokeParams < T::Struct
|
44
|
+
prop :seconds, T.any(Float, Integer)
|
45
|
+
prop :continue, T::Hash[T.untyped, T.untyped]
|
46
|
+
end
|
47
|
+
private_constant :ReinvokeParams
|
48
|
+
|
49
|
+
sig { params(continue: T::Hash[T.any(Symbol, String), T.untyped], _blk: Proc).returns(T.untyped) }
|
50
|
+
def loop_reinvoke_after(continue, &_blk)
|
51
|
+
reinvokes_remaining = T.let(reinvoke_limit, Integer)
|
52
|
+
|
53
|
+
Kernel.loop do
|
54
|
+
reinvoke_after = Kernel.catch(REINVOKE_AFTER_SIGNAL) do
|
55
|
+
return yield(continue)
|
56
|
+
end
|
57
|
+
|
58
|
+
if reinvokes_remaining.zero?
|
59
|
+
Kernel.raise "Max number of reinvokes on SDK Gem reached. Current limit is #{reinvoke_limit}"
|
60
|
+
end
|
61
|
+
|
62
|
+
reinvokes_remaining -= 1
|
63
|
+
|
64
|
+
reinvoke_after = T.cast(reinvoke_after, ReinvokeParams)
|
65
|
+
reinvoke_sleep(reinvoke_after.seconds)
|
66
|
+
continue = reinvoke_after.continue
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
sig { params(seconds: T.any(Float, Integer)).void }
|
71
|
+
def reinvoke_sleep(seconds)
|
72
|
+
Kernel.sleep((ENV['WAIT_REINVOKE_AFTER'].presence || seconds).to_f)
|
73
|
+
end
|
74
|
+
|
75
|
+
sig { returns(Integer) }
|
76
|
+
def reinvoke_limit
|
77
|
+
@reinvoke_limit = T.let(@reinvoke_limit, T.nilable(Integer))
|
78
|
+
@reinvoke_limit ||= (ENV['MAX_REINVOKES'].presence || MAX_REINVOKES).to_i
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Workato
|
5
|
+
module Connector
|
6
|
+
module Sdk
|
7
|
+
module Dsl
|
8
|
+
class StreamPackage
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig { params(streams: Streams, connection: Connection).void }
|
12
|
+
def initialize(streams:, connection:)
|
13
|
+
@streams = streams
|
14
|
+
@connection = connection
|
15
|
+
end
|
16
|
+
|
17
|
+
sig do
|
18
|
+
params(
|
19
|
+
stream: T.any(Stream::Proxy, String, T::Hash[T.untyped, T.untyped]),
|
20
|
+
from: T.nilable(Integer),
|
21
|
+
frame_size: T.nilable(Integer),
|
22
|
+
blk: SorbetTypes::StreamInProc
|
23
|
+
).returns(T.untyped)
|
24
|
+
end
|
25
|
+
def in(stream, from: nil, frame_size: nil, &blk)
|
26
|
+
if stream.is_a?(Hash) && stream[:__stream__] && stream[:chunks].nil?
|
27
|
+
stream = out(stream[:name], stream[:input] || {})
|
28
|
+
end
|
29
|
+
|
30
|
+
Stream.each_chunk(stream: stream, from: from, frame_size: frame_size, &blk)
|
31
|
+
end
|
32
|
+
|
33
|
+
sig { params(stream_name: String, input: SorbetTypes::StreamInputHash).returns(Stream::Proxy) }
|
34
|
+
def out(stream_name, input = {})
|
35
|
+
Stream::Proxy.new(input: input, name: stream_name, stream: streams[stream_name])
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
T::Sig::WithoutRuntime.sig { params(symbol: T.any(String, Symbol), _args: T.untyped).void }
|
41
|
+
def method_missing(symbol, *_args)
|
42
|
+
raise UndefinedStdLibMethodError.new(symbol.to_s, 'workato.stream')
|
43
|
+
end
|
44
|
+
|
45
|
+
T::Sig::WithoutRuntime.sig { params(_args: T.untyped).returns(T::Boolean) }
|
46
|
+
def respond_to_missing?(*_args)
|
47
|
+
false
|
48
|
+
end
|
49
|
+
|
50
|
+
sig { returns(Connection) }
|
51
|
+
attr_reader :connection
|
52
|
+
|
53
|
+
sig { returns(Streams) }
|
54
|
+
attr_reader :streams
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -18,17 +18,3 @@ module Workato
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
22
|
-
begin
|
23
|
-
if ENV['TZ'].present? && ENV['TZ'] != 'UTC'
|
24
|
-
warn "WARNING: TZ environment variable is set to '#{ENV['TZ']}'. Set TZ=UTC for consistency with Workato platform'"
|
25
|
-
else
|
26
|
-
ENV['TZ'] = 'UTC'
|
27
|
-
end
|
28
|
-
::Time.zone = Workato::Connector::Sdk::DEFAULT_TIME_ZONE
|
29
|
-
rescue TZInfo::DataSourceNotFound
|
30
|
-
puts ''
|
31
|
-
puts "tzinfo-data is not present. Please install gem 'tzinfo-data' by 'gem install tzinfo-data'"
|
32
|
-
puts ''
|
33
|
-
exit!
|
34
|
-
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'jwt'
|
5
|
+
require_relative './csv_package'
|
6
|
+
require_relative './stream_package'
|
7
|
+
|
8
|
+
using Workato::Extension::HashWithIndifferentAccess
|
9
|
+
|
10
|
+
module Workato
|
11
|
+
module Connector
|
12
|
+
module Sdk
|
13
|
+
module Dsl
|
14
|
+
class WorkatoPackage
|
15
|
+
JWT_ALGORITHMS = %w[RS256 RS384 RS512].freeze
|
16
|
+
private_constant :JWT_ALGORITHMS
|
17
|
+
|
18
|
+
JWT_RSA_KEY_MIN_LENGTH = 2048
|
19
|
+
private_constant :JWT_RSA_KEY_MIN_LENGTH
|
20
|
+
|
21
|
+
VERIFY_RCA_ALGORITHMS = %w[SHA SHA1 SHA224 SHA256 SHA384 SHA512].freeze
|
22
|
+
private_constant :VERIFY_RCA_ALGORITHMS
|
23
|
+
|
24
|
+
RANDOM_SIZE = 32
|
25
|
+
private_constant :RANDOM_SIZE
|
26
|
+
|
27
|
+
ALLOWED_KEY_SIZES = [128, 192, 256].freeze
|
28
|
+
private_constant :ALLOWED_KEY_SIZES
|
29
|
+
|
30
|
+
def initialize(streams:, connection:)
|
31
|
+
@streams = streams
|
32
|
+
@connection = connection
|
33
|
+
end
|
34
|
+
|
35
|
+
def jwt_encode_rs256(payload, key, header_fields = {})
|
36
|
+
jwt_encode(payload, key, 'RS256', header_fields)
|
37
|
+
end
|
38
|
+
|
39
|
+
def jwt_encode(payload, key, algorithm, header_fields = {})
|
40
|
+
algorithm = algorithm.to_s.upcase
|
41
|
+
unless JWT_ALGORITHMS.include?(algorithm)
|
42
|
+
raise "Unsupported signing method. Supports only #{JWT_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
|
43
|
+
end
|
44
|
+
|
45
|
+
rsa_private = OpenSSL::PKey::RSA.new(key)
|
46
|
+
if rsa_private.n.num_bits < JWT_RSA_KEY_MIN_LENGTH
|
47
|
+
raise "A RSA key of size #{JWT_RSA_KEY_MIN_LENGTH} bits or larger MUST be used with JWT."
|
48
|
+
end
|
49
|
+
|
50
|
+
header_fields = HashWithIndifferentAccess.wrap(header_fields).except(:typ, :alg)
|
51
|
+
::JWT.encode(payload, rsa_private, algorithm, header_fields)
|
52
|
+
end
|
53
|
+
|
54
|
+
def verify_rsa(payload, certificate, signature, algorithm = 'SHA256')
|
55
|
+
algorithm = algorithm.to_s.upcase
|
56
|
+
unless VERIFY_RCA_ALGORITHMS.include?(algorithm)
|
57
|
+
raise "Unsupported signing method. Supports only #{VERIFY_RCA_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
|
58
|
+
end
|
59
|
+
|
60
|
+
cert = OpenSSL::X509::Certificate.new(certificate)
|
61
|
+
digest = OpenSSL::Digest.new(algorithm)
|
62
|
+
cert.public_key.verify(digest, signature, payload)
|
63
|
+
rescue OpenSSL::PKey::PKeyError
|
64
|
+
raise 'An error occurred during signature verification. Check arguments'
|
65
|
+
rescue OpenSSL::X509::CertificateError
|
66
|
+
raise 'Invalid certificate format'
|
67
|
+
end
|
68
|
+
|
69
|
+
def parse_yaml(yaml)
|
70
|
+
::Psych.safe_load(yaml)
|
71
|
+
rescue ::Psych::DisallowedClass => e
|
72
|
+
raise e.message
|
73
|
+
end
|
74
|
+
|
75
|
+
def render_yaml(obj)
|
76
|
+
::Psych.dump(obj)
|
77
|
+
end
|
78
|
+
|
79
|
+
def parse_json(source)
|
80
|
+
JSON.parse(source)
|
81
|
+
rescue JSON::ParserError => e
|
82
|
+
raise JSONResponseFormatError, e
|
83
|
+
end
|
84
|
+
|
85
|
+
def uuid
|
86
|
+
SecureRandom.uuid
|
87
|
+
end
|
88
|
+
|
89
|
+
def random_bytes(len)
|
90
|
+
unless (len.is_a? ::Integer) && (len <= RANDOM_SIZE)
|
91
|
+
raise "The requested length or random bytes sequence should be <= #{RANDOM_SIZE}"
|
92
|
+
end
|
93
|
+
|
94
|
+
Types::Binary.new(::OpenSSL::Random.random_bytes(len))
|
95
|
+
end
|
96
|
+
|
97
|
+
def aes_cbc_encrypt(string, key, init_vector = nil)
|
98
|
+
key_size = key.bytesize * 8
|
99
|
+
unless ALLOWED_KEY_SIZES.include?(key_size)
|
100
|
+
raise 'Incorrect key size for AES'
|
101
|
+
end
|
102
|
+
|
103
|
+
cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
|
104
|
+
cipher.encrypt
|
105
|
+
cipher.key = key
|
106
|
+
cipher.iv = init_vector if init_vector.present?
|
107
|
+
Types::Binary.new(cipher.update(string) + cipher.final)
|
108
|
+
end
|
109
|
+
|
110
|
+
def aes_cbc_decrypt(string, key, init_vector = nil)
|
111
|
+
key_size = key.bytesize * 8
|
112
|
+
unless ALLOWED_KEY_SIZES.include?(key_size)
|
113
|
+
raise 'Incorrect key size for AES'
|
114
|
+
end
|
115
|
+
|
116
|
+
cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
|
117
|
+
cipher.decrypt
|
118
|
+
cipher.key = key
|
119
|
+
cipher.iv = init_vector if init_vector.present?
|
120
|
+
Types::Binary.new(cipher.update(string) + cipher.final)
|
121
|
+
end
|
122
|
+
|
123
|
+
def pbkdf2_hmac_sha1(string, salt, iterations = 1000, key_len = 16)
|
124
|
+
Types::Binary.new(::OpenSSL::PKCS5.pbkdf2_hmac_sha1(string, salt, iterations, key_len))
|
125
|
+
end
|
126
|
+
|
127
|
+
def csv
|
128
|
+
@csv ||= CsvPackage.new
|
129
|
+
end
|
130
|
+
|
131
|
+
def stream
|
132
|
+
@stream ||= StreamPackage.new(streams: streams, connection: connection)
|
133
|
+
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
def method_missing(symbol, *_args)
|
138
|
+
raise UndefinedStdLibMethodError.new(symbol.to_s, 'workato')
|
139
|
+
end
|
140
|
+
|
141
|
+
def respond_to_missing?(*)
|
142
|
+
false
|
143
|
+
end
|
144
|
+
|
145
|
+
attr_reader :streams
|
146
|
+
|
147
|
+
attr_reader :connection
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -5,10 +5,11 @@ require_relative './block_invocation_refinements'
|
|
5
5
|
|
6
6
|
require_relative './dsl/http'
|
7
7
|
require_relative './dsl/call'
|
8
|
+
require_relative './dsl/reinvoke_after'
|
8
9
|
require_relative './dsl/error'
|
9
10
|
require_relative './dsl/account_property'
|
10
11
|
require_relative './dsl/lookup_table'
|
11
|
-
require_relative './dsl/
|
12
|
+
require_relative './dsl/workato_package'
|
12
13
|
require_relative './dsl/workato_schema'
|
13
14
|
require_relative './dsl/time'
|
14
15
|
require_relative './dsl/aws'
|
@@ -19,12 +20,31 @@ module Workato
|
|
19
20
|
module Sdk
|
20
21
|
module Dsl
|
21
22
|
module Global
|
23
|
+
extend T::Sig
|
24
|
+
extend T::Helpers
|
25
|
+
|
26
|
+
abstract!
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
sig { abstract.returns(Streams) }
|
30
|
+
def streams; end
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
sig { abstract.returns(Connection) }
|
34
|
+
def connection; end
|
35
|
+
|
22
36
|
include Time
|
23
37
|
include AccountProperty
|
24
38
|
include LookupTable
|
25
|
-
include WorkatoCodeLib
|
26
39
|
include WorkatoSchema
|
27
|
-
|
40
|
+
|
41
|
+
delegate :parse_json,
|
42
|
+
:uuid,
|
43
|
+
to: :workato
|
44
|
+
|
45
|
+
def workato
|
46
|
+
@workato ||= WorkatoPackage.new(streams: streams, connection: connection)
|
47
|
+
end
|
28
48
|
|
29
49
|
def sleep(seconds)
|
30
50
|
::Kernel.sleep(seconds.presence || 0)
|
@@ -33,6 +53,39 @@ module Workato
|
|
33
53
|
def puts(*args)
|
34
54
|
T.unsafe(::Kernel).puts(*args)
|
35
55
|
end
|
56
|
+
|
57
|
+
def encrypt(text, key)
|
58
|
+
::Kernel.require('ruby_rncryptor')
|
59
|
+
|
60
|
+
enc_text = ::RubyRNCryptor.encrypt(text, key)
|
61
|
+
::Base64.strict_encode64(enc_text)
|
62
|
+
end
|
63
|
+
|
64
|
+
def decrypt(text, key)
|
65
|
+
::Kernel.require('ruby_rncryptor')
|
66
|
+
|
67
|
+
text = ::Base64.decode64(text)
|
68
|
+
dec_text = ::RubyRNCryptor.decrypt(text, key)
|
69
|
+
Workato::Types::Binary.new(dec_text)
|
70
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
71
|
+
message = e.message.to_s
|
72
|
+
case message
|
73
|
+
when /Password may be incorrect/
|
74
|
+
::Kernel.raise 'invalid/corrupt input or key'
|
75
|
+
when /RubyRNCryptor only decrypts version/
|
76
|
+
::Kernel.raise 'invalid/corrupt input'
|
77
|
+
else
|
78
|
+
::Kernel.raise
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def blank; end
|
83
|
+
|
84
|
+
def clear; end
|
85
|
+
|
86
|
+
def null; end
|
87
|
+
|
88
|
+
def skip; end
|
36
89
|
end
|
37
90
|
|
38
91
|
class WithDsl
|
@@ -42,21 +95,23 @@ module Workato
|
|
42
95
|
|
43
96
|
using BlockInvocationRefinements
|
44
97
|
|
45
|
-
sig { params(connection: Connection,
|
46
|
-
def
|
98
|
+
sig { params(connection: Connection, streams: Streams).void }
|
99
|
+
def initialize(connection = Connection.new, streams = ProhibitedStreams.new)
|
47
100
|
@connection = connection
|
48
|
-
|
101
|
+
@streams = streams
|
49
102
|
end
|
50
103
|
|
51
|
-
|
52
|
-
|
53
|
-
T.unsafe(WithDsl.new).execute(connection, *args, &block)
|
104
|
+
def execute(...)
|
105
|
+
T.unsafe(self).instance_exec(...)
|
54
106
|
end
|
55
107
|
|
56
108
|
private
|
57
109
|
|
58
|
-
sig { returns(Connection) }
|
110
|
+
sig { override.returns(Connection) }
|
59
111
|
attr_reader :connection
|
112
|
+
|
113
|
+
sig { override.returns(Streams) }
|
114
|
+
attr_reader :streams
|
60
115
|
end
|
61
116
|
end
|
62
117
|
end
|