Class: Tanker::Core

Inherits:
Object
  • Object
show all
Extended by:
Gem::Deprecate
Defined in:
lib/tanker/core/init.rb,
lib/tanker/core/group.rb,
lib/tanker/core/stream.rb,
lib/tanker/core/session.rb,
lib/tanker/core/version.rb,
lib/tanker/core/encryption.rb,
lib/tanker/core/log_record.rb,
lib/tanker/core/attach_result.rb

Overview

Main entry point for the Tanker SDK. Can open a Tanker session.

Defined Under Namespace

Classes: AttachResult, EncryptionSession, LogRecord, Options

Constant Summary collapse

VERSION =
'4.2.1'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Core

Returns a new instance of Core.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/tanker/core/init.rb', line 29

def initialize(options)
  # tanker_init is not called globally to avoid potential logs at global scope
  # some frameworks like to pre-execute statements at global scope and then fork, this fork can
  # interact badly with the threads used in the log handler, so never call Tanker at global scope
  CTanker.tanker_init

  # Do not spam the console of our users.
  self.class.set_log_handler { |_| } unless self.class.test_and_set_log_handler == 1 # rubocop:disable Lint/EmptyBlock

  @http_client = Http::Client.new options.sdk_type, VERSION, options.faraday_adapter
  options[:http_options] = @http_client.tanker_http_options

  @ctanker = CTanker.tanker_create(options).get
  @freed = false
  ctanker_addr = @ctanker.address
  ObjectSpace.define_finalizer(@ctanker) do |_|
    next if @freed

    CTanker.tanker_destroy(FFI::Pointer.new(:void, ctanker_addr)).get
  end
end

Class Method Details

.before_forkObject



9
10
11
# File 'lib/tanker/core/init.rb', line 9

def self.before_fork
  @log_handler_set = 0
end

.native_versionObject



7
8
9
# File 'lib/tanker/core/version.rb', line 7

def self.native_version
  CTanker.tanker_version_string
end

.prehash_password(str) ⇒ Object



76
77
78
79
80
# File 'lib/tanker/core/encryption.rb', line 76

def self.prehash_password(str)
  ASSERT_UTF8.call(str)

  CTanker.tanker_prehash_password(str).get_string
end

.set_log_handler(&block) ⇒ Object



21
22
23
24
25
26
27
# File 'lib/tanker/core/init.rb', line 21

def self.set_log_handler(&block)
  @log_handler_set = 1
  @log_handler = lambda do |clog|
    block.call LogRecord.new clog[:category], clog[:level], clog[:file], clog[:line], clog[:message]
  end
  CTanker.tanker_set_log_handler @log_handler
end

.test_and_set_log_handlerObject



13
14
15
16
17
18
19
# File 'lib/tanker/core/init.rb', line 13

def self.test_and_set_log_handler
  @log_handler_lock.synchronize do
    is_set = @log_handler_set
    @log_handler_set = 1
    return is_set
  end
end

Instance Method Details

#attach_provisional_identity(provisional_identity) ⇒ Object



69
70
71
72
73
74
75
76
77
# File 'lib/tanker/core/session.rb', line 69

def attach_provisional_identity(provisional_identity)
  attach_ptr = CTanker.tanker_attach_provisional_identity(@ctanker, provisional_identity).get
  attach_status = attach_ptr.get(:uint8, 1)
  method_ptr = attach_ptr.get_pointer(FFI::Pointer.size)
  method = (CTanker::CVerificationMethod.new(method_ptr).to_verification_method if method_ptr.address != 0)

  CTanker.tanker_free_attach_result(FFI::Pointer.new(:void, attach_ptr.address))
  AttachResult.new attach_status, method
end

#create_encryption_session(encryption_options = nil) ⇒ Object



67
68
69
70
71
72
73
74
# File 'lib/tanker/core/encryption.rb', line 67

def create_encryption_session(encryption_options = nil)
  unless !encryption_options || encryption_options.is_a?(EncryptionOptions)
    raise TypeError, "expected encryption_options to be a EncryptionOptions, but got a #{encryption_options.class}"
  end

  csession = CTanker.tanker_encryption_session_open(@ctanker, encryption_options).get
  EncryptionSession.new(csession)
end

#create_group(member_identities) ⇒ Object



7
8
9
10
# File 'lib/tanker/core/group.rb', line 7

def create_group(member_identities)
  cmember_identities = CTanker.new_cstring_array member_identities
  CTanker.tanker_create_group(@ctanker, cmember_identities, member_identities.length).get_string
end

#create_oidc_nonceObject



55
56
57
# File 'lib/tanker/core/session.rb', line 55

def create_oidc_nonce
  CTanker.tanker_create_oidc_nonce(@ctanker).get_string
end

#decrypt_data(data) ⇒ Object



26
27
28
29
30
31
32
33
34
35
# File 'lib/tanker/core/encryption.rb', line 26

def decrypt_data(data)
  inbuf = FFI::MemoryPointer.from_string(data)

  decrypted_size = CTanker.tanker_decrypted_size(inbuf, data.bytesize).get.address
  outbuf = FFI::MemoryPointer.new(:char, decrypted_size)

  clear_size = CTanker.tanker_decrypt(@ctanker, outbuf, inbuf, data.bytesize).get.address

  outbuf.read_string clear_size
end

#decrypt_stream(stream) ⇒ Object



35
36
37
# File 'lib/tanker/core/stream.rb', line 35

def decrypt_stream(stream)
  Stream.do_stream_action(stream) { |cb| CTanker.tanker_stream_decrypt(@ctanker, cb, nil) }
end

#decrypt_utf8(data) ⇒ Object



37
38
39
40
# File 'lib/tanker/core/encryption.rb', line 37

def decrypt_utf8(data)
  decrypted = decrypt_data data
  decrypted.force_encoding(Encoding::UTF_8)
end

#encrypt_data(data, encryption_options = nil) ⇒ Object



9
10
11
12
13
14
15
16
17
18
# File 'lib/tanker/core/encryption.rb', line 9

def encrypt_data(data, encryption_options = nil)
  unless data.is_a?(String)
    raise TypeError, "expected data to be an ASCII-8BIT binary String, but got a #{data.class}"
  end
  unless data.encoding == Encoding::ASCII_8BIT
    raise ArgumentError, "expected data to be an ASCII-8BIT binary String, but it was #{data.encoding} encoded"
  end

  encrypt_common data, encryption_options
end

#encrypt_stream(stream, encryption_options = nil) ⇒ Object



31
32
33
# File 'lib/tanker/core/stream.rb', line 31

def encrypt_stream(stream, encryption_options = nil)
  Stream.do_stream_action(stream) { |cb| CTanker.tanker_stream_encrypt(@ctanker, cb, nil, encryption_options) }
end

#encrypt_utf8(str, encryption_options = nil) ⇒ Object



20
21
22
23
24
# File 'lib/tanker/core/encryption.rb', line 20

def encrypt_utf8(str, encryption_options = nil)
  ASSERT_UTF8.call(str)

  encrypt_common str, encryption_options
end

#enroll_user(identity, verifications) ⇒ Object



14
15
16
17
# File 'lib/tanker/core/session.rb', line 14

def enroll_user(identity, verifications)
  cverifs = CTanker::CVerificationList.new(verifications)
  CTanker.tanker_enroll_user(@ctanker, identity, cverifs).get
end

#freeObject



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/tanker/core/init.rb', line 51

def free
  @freed = true
  CTanker.tanker_destroy(@ctanker).get
  @ctanker = nil

  public_methods(false).each do |method|
    send(:define_singleton_method, method) do |*_|
      raise "using Tanker::Core##{method} after free"
    end
  end
end

#generate_verification_keyObject



19
20
21
# File 'lib/tanker/core/session.rb', line 19

def generate_verification_key
  CTanker.tanker_generate_verification_key(@ctanker).get_string
end

#get_resource_id(data) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/tanker/core/encryption.rb', line 42

def get_resource_id(data)
  unless data.is_a?(String)
    raise TypeError, "expected data to be an ASCII-8BIT binary String, but got a #{data.class}"
  end
  unless data.encoding == Encoding::ASCII_8BIT
    raise ArgumentError, "expected data to be an ASCII-8BIT binary String, but it was #{data.encoding} encoded"
  end

  inbuf = FFI::MemoryPointer.from_string(data)
  CTanker.tanker_get_resource_id(inbuf, data.bytesize).get_string
end

#get_verification_methodsObject

rubocop:disable Naming/AccessorMethodName



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/tanker/core/session.rb', line 38

def get_verification_methods # rubocop:disable Naming/AccessorMethodName
  method_list_ptr = CTanker.tanker_get_verification_methods(@ctanker).get
  count = method_list_ptr.get(:uint32, FFI::Pointer.size)

  method_base_addr = method_list_ptr.read_pointer
  method_list = count.times.map do |i|
    method_ptr = method_base_addr + (i * CTanker::CVerificationMethod.size)
    CTanker::CVerificationMethod.new(method_ptr).to_verification_method
  end
  CTanker.tanker_free_verification_method_list method_list_ptr
  method_list
end

#oidc_test_nonce=(nonce) ⇒ Object



60
61
62
# File 'lib/tanker/core/session.rb', line 60

def oidc_test_nonce=(nonce)
  CTanker.tanker_set_oidc_test_nonce(@ctanker, nonce).get
end

#register_identity(verification, options = nil) ⇒ Object



23
24
25
26
# File 'lib/tanker/core/session.rb', line 23

def register_identity(verification, options = nil)
  cverif = CTanker::CVerification.new(verification)
  CTanker.tanker_register_identity(@ctanker, cverif, options).get_maybe_string
end

#set_verification_method(verification, options = nil) ⇒ Object



33
34
35
36
# File 'lib/tanker/core/session.rb', line 33

def set_verification_method(verification, options = nil)
  cverif = CTanker::CVerification.new(verification)
  CTanker.tanker_set_verification_method(@ctanker, cverif, options).get_maybe_string
end

#share(resource_ids, sharing_options) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/tanker/core/encryption.rb', line 54

def share(resource_ids, sharing_options)
  unless resource_ids.is_a?(Array)
    raise TypeError, "expected resource_ids to be an array of strings, but got a #{resource_ids.class}"
  end
  unless sharing_options.is_a?(SharingOptions)
    raise TypeError, "expected sharing_options to be a SharingOptions, but got a #{sharing_options.class}"
  end

  cresource_ids = CTanker.new_cstring_array resource_ids

  CTanker.tanker_share(@ctanker, cresource_ids, resource_ids.length, sharing_options).get
end

#start(identity) ⇒ Object



10
11
12
# File 'lib/tanker/core/session.rb', line 10

def start(identity)
  CTanker.tanker_start(@ctanker, identity).get.address
end

#statusObject



65
66
67
# File 'lib/tanker/core/session.rb', line 65

def status
  CTanker.tanker_status(@ctanker)
end

#stopObject



51
52
53
# File 'lib/tanker/core/session.rb', line 51

def stop
  CTanker.tanker_stop(@ctanker).get
end

#update_group_members(group_id, users_to_add: [], users_to_remove: []) ⇒ Object



12
13
14
15
16
17
# File 'lib/tanker/core/group.rb', line 12

def update_group_members(group_id, users_to_add: [], users_to_remove: [])
  cadd_identities = CTanker.new_cstring_array users_to_add
  cremove_identities = CTanker.new_cstring_array users_to_remove
  CTanker.tanker_update_group_members(@ctanker, group_id, cadd_identities, users_to_add.length, cremove_identities,
                                      users_to_remove.length).get
end

#verify_identity(verification, options = nil) ⇒ Object



28
29
30
31
# File 'lib/tanker/core/session.rb', line 28

def verify_identity(verification, options = nil)
  cverif = CTanker::CVerification.new(verification)
  CTanker.tanker_verify_identity(@ctanker, cverif, options).get_maybe_string
end

#verify_provisional_identity(verification) ⇒ Object



79
80
81
82
# File 'lib/tanker/core/session.rb', line 79

def verify_provisional_identity(verification)
  cverif = CTanker::CVerification.new(verification)
  CTanker.tanker_verify_provisional_identity(@ctanker, cverif).get
end