tanker-core 2.29.1.beta.4 → 2.30.1.alpha.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54d6b87442ef28205a41a9858a380f91d48a089a9c5d221c825d7388c86fef5d
4
- data.tar.gz: 8bf8475978437cbfa21f1e906a0e2d017a45d2b0b949ec04b257b3bbdf72d5fc
3
+ metadata.gz: f965af6640e6603ed8c76ceb3b9af8c02a70ac767e7c4db364df13fca40caf08
4
+ data.tar.gz: 2cad737772cb42913f419eb7e619082acef770b3477b65dcc7f35293bffcc41d
5
5
  SHA512:
6
- metadata.gz: cb677c3cd238b19056ab4e2c30a0d4c374e5b3455b2d99d9a7afc1b915cf31212e2f2d81f56353025b508c4f3913bc35b3c57fc4251b25c8112f94ecc89d975b
7
- data.tar.gz: 86f90c342b860f7d63c7076de7fb52ae6ec135b7009e71dc31c4a53a077fa031853726bed1f30430bd92ffb4380333aa8e24e54c4d8372b47b82335c6aaf6913
6
+ metadata.gz: 20b15f5fba9ea29c1f94b23be2a8d629e9b965730f9587aa377bdcc81c1631492a5c9821fea634be2938122a05e820dfadec5af0e4097e8152d2359e7989d247
7
+ data.tar.gz: 7b168937a393fc0a2d300f06454533cb738048b09aba2e04e41a4b5280cce4362f114e6c92b164f9deb637efee4f14118ae4735051ec5e455c1b908a29c5900d
@@ -7,10 +7,9 @@ module Tanker
7
7
  class Admin
8
8
  class AppUpdateOptions < FFI::Struct
9
9
  def initialize(oidc_client_id: nil, oidc_client_provider: nil,
10
- session_certificates: nil, preverified_verification: nil,
11
- user_enrollment: nil)
10
+ preverified_verification: nil, user_enrollment: nil)
12
11
  super()
13
- self[:version] = 3
12
+ self[:version] = 4
14
13
  unless oidc_client_id.nil?
15
14
  @oidc_client_id = CTanker.new_cstring oidc_client_id
16
15
  self[:oidc_client_id] = @oidc_client_id
@@ -19,12 +18,6 @@ module Tanker
19
18
  @oidc_client_provider = CTanker.new_cstring oidc_client_provider
20
19
  self[:oidc_client_provider] = @oidc_client_provider
21
20
  end
22
- unless session_certificates.nil?
23
- boolptr = FFI::MemoryPointer.new(:bool, 1)
24
- boolptr.put(:bool, 0, session_certificates)
25
- @session_certificates = boolptr
26
- self[:session_certificates] = @session_certificates
27
- end
28
21
  unless preverified_verification.nil?
29
22
  boolptr = FFI::MemoryPointer.new(:bool, 1)
30
23
  boolptr.put(:bool, 0, preverified_verification)
@@ -42,7 +35,6 @@ module Tanker
42
35
  layout :version, :uint8,
43
36
  :oidc_client_id, :pointer,
44
37
  :oidc_client_provider, :pointer,
45
- :session_certificates, :pointer,
46
38
  :preverified_verification, :pointer,
47
39
  :user_enrollment, :pointer
48
40
  end
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'ffi'
4
- require 'tanker/core/verification'
5
- require 'tanker/c_tanker/c_string'
6
4
 
7
5
  module Tanker
8
6
  module CTanker
@@ -15,11 +13,5 @@ module Tanker
15
13
  :put_cache_values, :pointer,
16
14
  :find_cache_values, :pointer
17
15
  end
18
-
19
- class CHttpOptions < FFI::Struct
20
- layout :send_request, :pointer,
21
- :cancel_request, :pointer,
22
- :data, :pointer
23
- end
24
16
  end
25
17
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ module Tanker
6
+ module CTanker
7
+ class CHttpRequest < FFI::Struct
8
+ layout :method, :string,
9
+ :url, :string,
10
+ :instance_id, :string,
11
+ :authorization, :string,
12
+ :body, :pointer,
13
+ :body_size, :int32
14
+ end
15
+
16
+ class CHttpResponse < FFI::Struct
17
+ def self.new_ok(status_code:, content_type:, body:)
18
+ new nil, status_code, content_type, body
19
+ end
20
+
21
+ def self.new_error(msg)
22
+ new msg, nil, nil, nil
23
+ end
24
+
25
+ def initialize(error_msg, status_code, content_type, body)
26
+ super()
27
+
28
+ if error_msg
29
+ @error_msg = CTanker.new_cstring(error_msg)
30
+ self[:error_msg] = @error_msg
31
+ else
32
+ @content_type = CTanker.new_cstring content_type
33
+ @body = FFI::MemoryPointer.from_string(body)
34
+
35
+ self[:error_msg] = nil
36
+ self[:content_type] = @content_type
37
+ self[:body] = @body
38
+ self[:body_size] = body.bytesize
39
+ self[:status_code] = status_code
40
+ end
41
+ end
42
+
43
+ layout :error_msg, :pointer,
44
+ :content_type, :pointer,
45
+ :body, :pointer,
46
+ :body_size, :int64,
47
+ :status_code, :int32
48
+ end
49
+
50
+ typedef :pointer, :http_request_handle
51
+
52
+ callback :http_send_request, [CHttpRequest, :pointer], :http_request_handle
53
+ callback :http_cancel_request, [CHttpRequest, :http_request_handle, :pointer], :void
54
+
55
+ class CHttpOptions < FFI::Struct
56
+ layout :send_request, :http_send_request,
57
+ :cancel_request, :http_cancel_request,
58
+ :data, :pointer
59
+
60
+ def initialize(send_request, cancel_request)
61
+ super()
62
+
63
+ self[:send_request] = send_request
64
+ self[:cancel_request] = cancel_request
65
+ self[:data] = nil
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ module FFI::Library
6
+ # Marking a function blocking releases the global Ruby lock.
7
+ # This is required for every function that could invoke a callback (including log handler) in another thread
8
+ def blocking_attach_function(func, args, returns = nil)
9
+ attach_function func, args, returns, blocking: true
10
+ end
11
+ end
12
+
13
+ module Tanker
14
+ module CTanker
15
+ extend FFI::Library
16
+ ffi_lib get_path('ctanker')
17
+ end
18
+
19
+ private_constant :CTanker
20
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'ffi'
4
+ require_relative 'c_tanker/init'
4
5
  require_relative 'core/options'
5
6
  require_relative 'sharing_options'
6
7
  require_relative 'encryption_options'
@@ -12,19 +13,8 @@ require_relative 'c_tanker/c_verification_method'
12
13
  require_relative 'c_tanker/c_log_record'
13
14
  require_relative 'c_tanker/c_device_info'
14
15
 
15
- module FFI::Library
16
- # Marking a function blocking releases the global Ruby lock.
17
- # This is required for every function that could invoke a callback (including log handler) in another thread
18
- def blocking_attach_function(func, args, returns = nil)
19
- attach_function func, args, returns, blocking: true
20
- end
21
- end
22
-
23
16
  module Tanker
24
17
  module CTanker
25
- extend FFI::Library
26
- ffi_lib get_path('ctanker')
27
-
28
18
  typedef :pointer, :session_pointer
29
19
  typedef :pointer, :enc_sess_pointer
30
20
  typedef :pointer, :stream_pointer
@@ -99,6 +89,8 @@ module Tanker
99
89
 
100
90
  blocking_attach_function :tanker_set_log_handler, [:log_handler_callback], :void
101
91
 
92
+ blocking_attach_function :tanker_http_handle_response, [CHttpRequest, CHttpResponse], :void
93
+
102
94
  blocking_attach_function :tanker_prehash_password, [:string], CFuture
103
95
 
104
96
  blocking_attach_function :tanker_free_buffer, [:pointer], :void
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+
5
+ module Tanker
6
+ module Http
7
+ class HttpRequest
8
+ @@mutex = Mutex.new # rubocop:disable Style/ClassVars I have no idea why you don't like class vars
9
+ @@current_request_id = 0 # rubocop:disable Style/ClassVars
10
+ # Hash(id => request)
11
+ @@running_requests = {} # rubocop:disable Style/ClassVars
12
+
13
+ attr_reader :id
14
+ attr_reader :method
15
+ attr_reader :url
16
+ attr_reader :instance_id
17
+ attr_reader :authorization
18
+ attr_reader :body
19
+ attr_reader :crequest
20
+
21
+ def self.method_str_to_symbol(method)
22
+ case method
23
+ when 'GET' then :get
24
+ when 'POST' then :post
25
+ when 'PATCH' then :patch
26
+ when 'PUT' then :put
27
+ when 'DELETE' then :delete
28
+ else raise "unknown HTTP method #{method}"
29
+ end
30
+ end
31
+
32
+ def initialize(crequest:)
33
+ @@mutex.synchronize do
34
+ @@current_request_id += 1 # rubocop:disable Style/ClassVars
35
+ @id = @@current_request_id
36
+ @@running_requests[@id] = self
37
+ end
38
+
39
+ @method = self.class.method_str_to_symbol crequest[:method]
40
+ @url = crequest[:url]
41
+ @instance_id = crequest[:instance_id]
42
+ @authorization = crequest[:authorization]
43
+ @body = crequest[:body].read_string_length(crequest[:body_size])
44
+
45
+ # Keep the crequest because we need its address to answer to Tanker
46
+ @crequest = crequest
47
+ end
48
+
49
+ # Since Ruby's HTTP libraries are not asynchronous, they do not support cancelation either.
50
+ # When a request is canceled, we let it run until the end, and then we discard its result.
51
+ def self.cancel(id)
52
+ @@mutex.synchronize do
53
+ @@running_requests.delete id
54
+ end
55
+ end
56
+
57
+ def complete_if_not_canceled(&block)
58
+ @@mutex.synchronize do
59
+ unless @@running_requests.delete @id
60
+ # Request has been canceled, don't call Tanker back
61
+ return
62
+ end
63
+
64
+ block.call
65
+ end
66
+ end
67
+ end
68
+
69
+ module ThreadPool
70
+ THREAD_POOL_SIZE = 4
71
+
72
+ def self.thread_loop
73
+ loop do
74
+ work = @queue.pop
75
+ work.call
76
+ end
77
+ end
78
+
79
+ def self.push(proc)
80
+ @queue << proc
81
+ end
82
+
83
+ # Queue is a concurrent queue in Ruby
84
+ @queue = Queue.new
85
+ @http_thread_pool = THREAD_POOL_SIZE.times do
86
+ Thread.new do
87
+ thread_loop
88
+ end
89
+ end
90
+ end
91
+
92
+ class Client
93
+ attr_reader :tanker_http_options
94
+
95
+ def initialize(sdk_type, sdk_version)
96
+ @sdk_type = sdk_type
97
+ @sdk_version = sdk_version
98
+
99
+ # This could be a proc, but for some reason, ffi gives the wrong type
100
+ # for crequest if we don't specify it explicitly here
101
+ @c_send_request = FFI::Function.new(:pointer, [CTanker::CHttpRequest.by_ref, :pointer]) do |crequest, cdata|
102
+ next send_request crequest, cdata
103
+ rescue Exception => e # rubocop:disable Lint/RescueException I do want to rescue all exceptions
104
+ cresponse = CTanker::CHttpResponse.new_error e.message
105
+ CTanker.tanker_http_handle_response(crequest, cresponse)
106
+ end
107
+ @c_cancel_request = proc do |crequest, request_id, cdata|
108
+ cancel_request crequest, request_id, cdata
109
+ rescue Exception => e # rubocop:disable Lint/RescueException I do want to rescue all exceptions
110
+ # This is not recoverable and won't be logged by FFI, let's do our best and log it here just before we crash
111
+ puts "fatal error when canceling HTTP request:\n#{e.full_message}"
112
+ raise
113
+ end
114
+
115
+ @tanker_http_options = CTanker::CHttpOptions.new @c_send_request, @c_cancel_request
116
+ end
117
+
118
+ def process_request(request)
119
+ fresponse = Faraday.run_request(request.method, request.url, request.body, {
120
+ 'X-Tanker-SdkType' => @sdk_type,
121
+ 'X-Tanker-SdkVersion' => @sdk_version,
122
+ 'Authorization' => request.authorization,
123
+ 'X-Tanker-Instanceid' => request.instance_id
124
+ }.compact)
125
+
126
+ request.complete_if_not_canceled do
127
+ cresponse = CTanker::CHttpResponse.new_ok status_code: fresponse.status,
128
+ content_type: fresponse.headers['content-type'],
129
+ body: fresponse.body
130
+ CTanker.tanker_http_handle_response(request.crequest, cresponse)
131
+ end
132
+ rescue Exception => e # rubocop:disable Lint/RescueException I do want to rescue all exceptions
133
+ # NOTE: when debugging, you might want to uncomment this to print a full backtrace
134
+ # puts "HTTP request error:\n#{e.full_message}"
135
+ cresponse = CTanker::CHttpResponse.new_error e.message
136
+ CTanker.tanker_http_handle_response(request.crequest, cresponse)
137
+ end
138
+
139
+ def send_request(crequest, _cdata)
140
+ request = HttpRequest.new crequest: crequest
141
+ ThreadPool.push(proc do
142
+ process_request request
143
+ end)
144
+ FFI::Pointer.new :void, request.id
145
+ end
146
+
147
+ def cancel_request(_crequest, prequest_id, _cdata)
148
+ request_id = prequest_id.to_i
149
+ HttpRequest.cancel(request_id)
150
+ end
151
+ end
152
+ end
153
+
154
+ private_constant :Http
155
+ end
@@ -31,6 +31,9 @@ module Tanker
31
31
  # Do not spam the console of our users.
32
32
  self.class.set_log_handler { |_| } unless self.class.test_and_set_log_handler == 1 # rubocop:disable Lint/EmptyBlock
33
33
 
34
+ @http_client = Http::Client.new options.sdk_type, VERSION
35
+ options[:http_options] = @http_client.tanker_http_options
36
+
34
37
  @ctanker = CTanker.tanker_create(options).get
35
38
  @freed = false
36
39
  ctanker_addr = @ctanker.address
@@ -2,7 +2,8 @@
2
2
 
3
3
  require 'ffi'
4
4
  require 'tanker/c_tanker/c_string'
5
- require 'tanker/c_tanker/c_backends'
5
+ require 'tanker/c_tanker/c_datastore'
6
+ require 'tanker/c_tanker/c_http'
6
7
 
7
8
  module Tanker
8
9
  # Options that can be given when opening a Tanker session
@@ -20,22 +21,25 @@ module Tanker
20
21
  SDK_TYPE = 'client-ruby'
21
22
  SDK_VERSION = CTanker.new_cstring Core::VERSION
22
23
 
24
+ attr_reader :sdk_type
25
+
23
26
  def initialize(app_id:, url: nil, sdk_type: SDK_TYPE, persistent_path: nil, cache_path: nil)
24
27
  super()
25
28
 
26
29
  # NOTE: Instance variables are required to keep the CStrings alive
27
- @app_id = CTanker.new_cstring app_id
28
- @url = CTanker.new_cstring url
29
- @persistent_path = CTanker.new_cstring persistent_path
30
- @cache_path = CTanker.new_cstring cache_path
31
- @sdk_type = CTanker.new_cstring sdk_type
30
+ @c_app_id = CTanker.new_cstring app_id
31
+ @c_url = CTanker.new_cstring url
32
+ @c_persistent_path = CTanker.new_cstring persistent_path
33
+ @c_cache_path = CTanker.new_cstring cache_path
34
+ @sdk_type = sdk_type
35
+ @c_sdk_type = CTanker.new_cstring sdk_type
32
36
 
33
37
  self[:version] = 4
34
- self[:app_id] = @app_id
35
- self[:url] = @url
36
- self[:persistent_path] = @persistent_path
37
- self[:cache_path] = @cache_path
38
- self[:sdk_type] = @sdk_type
38
+ self[:app_id] = @c_app_id
39
+ self[:url] = @c_url
40
+ self[:persistent_path] = @c_persistent_path
41
+ self[:cache_path] = @c_cache_path
42
+ self[:sdk_type] = @c_sdk_type
39
43
  self[:sdk_version] = SDK_VERSION
40
44
  end
41
45
  end
@@ -166,7 +166,7 @@ module Tanker
166
166
  buffer.put_bytes(0, rbbuf)
167
167
  CTanker.tanker_stream_read_operation_finish(operation, rbbuf.size)
168
168
  end
169
- rescue StandardError => e
169
+ rescue Exception => e # rubocop:disable Lint/RescueException I do want to rescue all exceptions
170
170
  @mutex.synchronize do
171
171
  return if @closed
172
172
 
@@ -227,7 +227,7 @@ module Tanker
227
227
 
228
228
  @write.write(ffibuf.read_string(nb_read))
229
229
  end
230
- rescue StandardError => e
230
+ rescue Exception => e # rubocop:disable Lint/RescueException I do want to rescue all exceptions
231
231
  @error = @substream.error || e
232
232
  ensure
233
233
  @write.close
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Tanker
4
4
  class Core
5
- VERSION = '2.29.1.beta.4'
5
+ VERSION = '2.30.1.alpha.1'
6
6
 
7
7
  def self.native_version
8
8
  CTanker.tanker_version_string
data/lib/tanker/core.rb CHANGED
@@ -5,6 +5,7 @@ require 'set'
5
5
  require_relative 'core/version'
6
6
  require_relative 'c_tanker'
7
7
  require_relative 'error'
8
+ require_relative 'core/http'
8
9
  require_relative 'core/session'
9
10
  require_relative 'core/verification'
10
11
  require_relative 'core/encryption'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tanker-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.29.1.beta.4
4
+ version: 2.30.1.alpha.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanker team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-19 00:00:00.000000000 Z
11
+ date: 2022-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -140,20 +140,23 @@ files:
140
140
  - lib/tanker/admin/c_admin/c_app_descriptor.rb
141
141
  - lib/tanker/admin/c_admin/c_app_update_options.rb
142
142
  - lib/tanker/c_tanker.rb
143
- - lib/tanker/c_tanker/c_backends.rb
143
+ - lib/tanker/c_tanker/c_datastore.rb
144
144
  - lib/tanker/c_tanker/c_device_info.rb
145
145
  - lib/tanker/c_tanker/c_future.rb
146
+ - lib/tanker/c_tanker/c_http.rb
146
147
  - lib/tanker/c_tanker/c_lib.rb
147
148
  - lib/tanker/c_tanker/c_log_record.rb
148
149
  - lib/tanker/c_tanker/c_string.rb
149
150
  - lib/tanker/c_tanker/c_tanker_error.rb
150
151
  - lib/tanker/c_tanker/c_verification.rb
151
152
  - lib/tanker/c_tanker/c_verification_method.rb
153
+ - lib/tanker/c_tanker/init.rb
152
154
  - lib/tanker/core.rb
153
155
  - lib/tanker/core/attach_result.rb
154
156
  - lib/tanker/core/encryption.rb
155
157
  - lib/tanker/core/encryption_session.rb
156
158
  - lib/tanker/core/group.rb
159
+ - lib/tanker/core/http.rb
157
160
  - lib/tanker/core/init.rb
158
161
  - lib/tanker/core/log_record.rb
159
162
  - lib/tanker/core/options.rb