identikey 0.8.2 → 0.9.0

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: 66d43ba4ae2d3edfe361a94fe99fb85485fd90d804fd252bb03ab6d56541fc42
4
- data.tar.gz: 723cf154216947148230acd05ba900b9ae4da15e06be73d2f2092a14034d3fbc
3
+ metadata.gz: 8b12db6aa0435e14bd281a73d2ab1c50edc993ecb41cfe8933d180607bb22c36
4
+ data.tar.gz: 322412ff65c22664df05aa4e6e7c69d9da9a7851e827b97519a19b22162ab387
5
5
  SHA512:
6
- metadata.gz: e6f2c933ab1c131c879555fb1d34a51159ea4ff022782b9cd65d59fff7f1569b3c7ab7584035d8388ddc9ea153751216aafef622d59731168490aa4a686b9676
7
- data.tar.gz: ebe4c8dbef838a97f21710350c345280750ba11bb25d070946d823e5d01b1ceb4425a73d3a9ae5a6e22755743288704694f8fca6ad6b73013e9ff68d9c1f49dd
6
+ metadata.gz: d71931f68cbca537fdecbe4771d1aa4ef393d365a1654cfc1864ea6e3a43926d80a2dfee770f7d493eb211bbfeef8010e6b4f0bdad15c47c53d527abce3d2340
7
+ data.tar.gz: f42408a94e658295522ddbfcfc9ffc90668c5e8a1d30cc0beac1f3463e2ecc12d1ade779df010236dbe9e682c476270d983f6b85774188f3db2eb095010713bb
@@ -17,6 +17,13 @@ end
17
17
 
18
18
  puts "Configured Admin WSDL #{ENV.fetch('IK_WSDL_ADMIN')} against #{ENV.fetch('IK_HOST')}"
19
19
 
20
+ Identikey::Provisioning.configure do
21
+ wsdl ENV.fetch('IK_WSDL_PROVN')
22
+ endpoint ENV.fetch('IK_HOST')
23
+ end
24
+
25
+ puts "Configured Provisioning WSDL #{ENV.fetch('IK_WSDL_PROVN')} against #{ENV.fetch('IK_HOST')}"
26
+
20
27
  $ik = Identikey::Administration::Session.new(
21
28
  username: ENV.fetch('IK_USER'),
22
29
  password: ENV.fetch('IK_PASS'),
@@ -18,11 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
19
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
20
  end
21
- spec.bindir = "exe"
22
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
21
  spec.require_paths = ["lib"]
24
22
 
25
23
  spec.add_dependency "savon", "~> 2.0"
24
+ spec.add_dependency "wasabi", "~> 3.5.0"
26
25
 
27
26
  spec.add_development_dependency "bundler", "~> 2.0"
28
27
  spec.add_development_dependency "rake", ">= 12.3.3"
@@ -5,3 +5,4 @@ require 'identikey/error'
5
5
  require 'identikey/unsigned'
6
6
  require 'identikey/authentication'
7
7
  require 'identikey/administration'
8
+ require 'identikey/provisioning'
@@ -18,6 +18,10 @@ module Identikey
18
18
  :admin_session_query, :user_execute, :user_query,
19
19
  :digipass_execute, :digipass_query, :digipassappl_execute
20
20
 
21
+ ###
22
+ ## LOGON/LOGOFF/PING
23
+ ###
24
+
21
25
  def logon(username:, password:, domain:)
22
26
  resp = super(message: {
23
27
  attributeSet: {
@@ -95,6 +99,10 @@ module Identikey
95
99
  parse_response resp, :admin_session_query_response
96
100
  end
97
101
 
102
+ ###
103
+ ## USER_EXECUTE
104
+ ###
105
+
98
106
  def user_execute(session_id:, cmd:, attributes: [])
99
107
  resp = super(message: {
100
108
  sessionID: session_id,
@@ -180,6 +188,10 @@ module Identikey
180
188
  )
181
189
  end
182
190
 
191
+ ###
192
+ ## USER_QUERY
193
+ ###
194
+
183
195
  # Executes a userQuery command that searches users. By default, it doesn't
184
196
  # log anywhere. To enable logging to a specific destination, pass a logger
185
197
  # as the log: option. To log to the default destination, pass `true` as
@@ -199,6 +211,9 @@ module Identikey
199
211
  end
200
212
  end
201
213
 
214
+ ###
215
+ ## DIGIPASS_EXECUTE
216
+ ###
202
217
 
203
218
  def digipass_execute(session_id:, cmd:, attributes: [])
204
219
  resp = super(message: {
@@ -245,6 +260,9 @@ module Identikey
245
260
  )
246
261
  end
247
262
 
263
+ ###
264
+ ## DIGIPASS_QUERY
265
+ ###
248
266
 
249
267
  def digipass_query(session_id:, attributes:, query_options:)
250
268
  resp = super(message: {
@@ -258,6 +276,9 @@ module Identikey
258
276
  parse_response resp, :digipass_query_response
259
277
  end
260
278
 
279
+ ###
280
+ ## DIGIPASSAPPL_EXECUTE
281
+ ###
261
282
 
262
283
  def digipassappl_execute(session_id:, cmd:, attributes:)
263
284
  resp = super(message: {
@@ -314,6 +335,5 @@ module Identikey
314
335
  client.globals[:log] = old_log
315
336
  end
316
337
 
317
-
318
338
  end
319
339
  end
@@ -54,5 +54,16 @@ module Identikey
54
54
  def self.otp_validated_ok?(status, result)
55
55
  status == 'STAT_SUCCESS' && !result.key?('CREDFLD_STATUS_MESSAGE')
56
56
  end
57
+
58
+
59
+ protected
60
+ def parse_result_root(body, root_element)
61
+ root = super
62
+
63
+ # The authentication API wraps the results with another element
64
+ #
65
+ results_key = root_element.to_s.sub(/_response$/, '_results').to_sym
66
+ return root[results_key]
67
+ end
57
68
  end
58
69
  end
@@ -100,7 +100,7 @@ module Identikey
100
100
 
101
101
  # Parse the generic response types that the API returns.
102
102
  #
103
- # The returned attributes (up to now...) are always:
103
+ # The returned attributes in the Administration API are:
104
104
  #
105
105
  # - The given root element, whose name is derived from the SOAP command
106
106
  # that was invoked
@@ -111,6 +111,11 @@ module Identikey
111
111
  # or multiple ones.
112
112
  # - :error_stack, a list of error that occurred
113
113
  #
114
+ # The authentication API wraps the results element in another one
115
+ #
116
+ # The provisioning API uses a status element for the result code and
117
+ # error stack, and a result element for the results.
118
+ #
114
119
  # The returned value is a three-elements array, containing:
115
120
  #
116
121
  # [Response code, Attribute(s) list, Errors list]
@@ -129,11 +134,19 @@ module Identikey
129
134
  # formats. TODO maybe create a separate class for errors, that includes
130
135
  # the error code.
131
136
  #
132
- # TODO refactor and split in separate methods
133
- #
134
137
  def parse_response(resp, root_element)
135
- body = resp.body
138
+ root = parse_result_root(resp.body, root_element)
139
+
140
+ results = parse_result_element(root, root_element)
141
+
142
+ result_code = parse_result_code(results, root_element)
143
+ result_attributes = parse_result_attributes(results, root_element)
144
+ result_errors = parse_result_errors(results, root_element)
136
145
 
146
+ return result_code, result_attributes, result_errors
147
+ end
148
+
149
+ def parse_result_root(body, root_element)
137
150
  if body.size.zero?
138
151
  raise Identikey::ParseError, "Empty response received"
139
152
  end
@@ -144,40 +157,35 @@ module Identikey
144
157
 
145
158
  # The root results element
146
159
  #
147
- root = body[root_element]
148
-
149
- # ... that the authentication API wraps with another element
150
- #
151
- results_key = root_element.to_s.sub(/_response$/, '_results').to_sym
152
- if root.keys.size == 1 && root.key?(results_key)
153
- root = root[results_key]
154
- end
160
+ return body[root_element]
161
+ end
155
162
 
163
+ def parse_result_element(root, root_element)
156
164
  # The results element
157
165
  #
158
166
  unless root.key?(:results)
159
167
  raise Identikey::ParseError, "Results element not found below #{root_element}"
160
168
  end
161
169
 
162
- results = root[:results]
170
+ return root[:results]
171
+ end
163
172
 
164
- # Result code
165
- #
173
+ def parse_result_code(results, root_element)
166
174
  unless results.key?(:result_codes)
167
175
  raise Identikey::ParseError, "Result codes not found below #{root_element}"
168
176
  end
169
177
 
170
- result_code = results[:result_codes][:status_code_enum] || 'STAT_UNKNOWN'
178
+ results[:result_codes][:status_code_enum] || 'STAT_UNKNOWN'
179
+ end
171
180
 
172
- # Result attributes
173
- #
181
+ def parse_result_attributes(results, root_element)
174
182
  unless results.key?(:result_attribute)
175
183
  raise Identikey::ParseError, "Result attribute not found below #{root_element}"
176
184
  end
177
185
 
178
186
  results_attr = results[:result_attribute]
179
187
 
180
- result_attributes = if results_attr.key?(:attributes)
188
+ if results_attr.key?(:attributes)
181
189
  entries = [ results_attr[:attributes] ].flatten
182
190
  parse_attributes entries
183
191
 
@@ -193,16 +201,14 @@ module Identikey
193
201
  else
194
202
  nil
195
203
  end
204
+ end
196
205
 
197
- # Errors
198
- #
199
- errors = if results[:error_stack].key?(:errors)
206
+ def parse_result_errors(results, root_element)
207
+ if results[:error_stack].key?(:errors)
200
208
  parse_errors results[:error_stack][:errors]
201
209
  else
202
210
  nil
203
211
  end
204
-
205
- return result_code, result_attributes, errors
206
212
  end
207
213
 
208
214
  def parse_attributes(attributes)
@@ -0,0 +1,150 @@
1
+ require 'identikey/base'
2
+
3
+ module Identikey
4
+ # This class wraps the Provisioning API.
5
+ #
6
+ class Provisioning < Base
7
+ client wsdl: './sdk/wsdl/provisioning.wsdl'
8
+
9
+ operations :provisioning_execute, :dsapp_srp_register
10
+
11
+ ###
12
+ ## PROVISIONING_EXECUTE
13
+ ###
14
+
15
+ def provisioning_execute(cmd:, attributes:)
16
+ resp = super(message: {
17
+ cmd: cmd,
18
+ attributeSet: {
19
+ attributes: attributes
20
+ }
21
+ })
22
+
23
+ parse_response resp, :provisioning_execute_response
24
+ end
25
+
26
+ def provisioning_execute_MDL_REGISTER(component:, user:, domain:, password:)
27
+ provisioning_execute(
28
+ cmd: 'PROVISIONCMD_MDL_REGISTER',
29
+ attributes: typed_attributes_list_from(
30
+ PROVFLD_USERID: user,
31
+ PROVFLD_DOMAIN: domain,
32
+ PROVFLD_COMPONENT_TYPE: component,
33
+ PROVFLD_STATIC_PASSWORD: password,
34
+ PROVFLD_ACTIVATION_TYPE: Unsigned(0),
35
+ )
36
+ )
37
+ end
38
+
39
+ ###
40
+ ## dsappSRPRegister
41
+ ###
42
+
43
+ def dsapp_srp_register(component:, user:, domain:, password:)
44
+ resp = super(message: {
45
+ componentType: component,
46
+ user: {
47
+ userID: user,
48
+ domain: domain,
49
+ },
50
+ credential: {
51
+ staticPassword: password
52
+ }
53
+ })
54
+
55
+ parse_response resp, :dsapp_srp_register_response
56
+ end
57
+
58
+ ###
59
+ ## Wraps dsapp_srp_register and returns directly the activation
60
+ ## message through which a CRONTO image can be generated, to be
61
+ ## used for push notifications setups in combination with a MDC
62
+ ## configured on your OneSpan control panel and on Identikey.
63
+ ##
64
+ ## You may want to look into https://github.com/ifad/cronto for
65
+ ## a generator to produce PNGs to deliver to your clients.
66
+ ####
67
+ def self.cronto_code_for_srp_registration(gateway:, **kwargs)
68
+ status, result, error = new.dsapp_srp_register(**kwargs)
69
+
70
+ if status != 'STAT_SUCCESS'
71
+ raise Identikey::OperationFailed, "Error while assigning DAL: #{status} - #{[error].flatten.join('; ')}"
72
+ end
73
+
74
+ # Compose proprietary string
75
+ message = '01;01;%s;%s;%s;%s;%s' % [
76
+ result[:user][:user_id],
77
+ result[:user][:domain],
78
+ result[:registration_id],
79
+ result[:activation_password],
80
+ gateway
81
+ ]
82
+
83
+ # Encode it as hex
84
+ return message.split(//).map {|c| '%x' % c.ord}.join
85
+ end
86
+
87
+ protected
88
+ # The provisioningExecute command has the same
89
+ # design as the rest of the API, with a single
90
+ # multi-purpose `results` element that carries
91
+ # key-value results.
92
+ #
93
+ # Instead, dsappSRPRegister and other commands
94
+ # use a different design with return types and
95
+ # values predefined in the WSDL.
96
+ #
97
+ # So if we have a `results` element, this is a
98
+ # old-style response, and we delegate parsing
99
+ # to the parent class, otherwise if we detect
100
+ # the `result` and `status` elements, we parse
101
+ # in this class, basically just returning the
102
+ # values that Savon parsed for us.
103
+ #
104
+ def parse_result_element(root, root_element)
105
+ if root.key?(:results)
106
+ root[:results]
107
+ else
108
+ root
109
+ end
110
+ end
111
+
112
+ def parse_result_code(root, root_element)
113
+ if root.key?(:status)
114
+ super root[:status], root_element
115
+ else
116
+ super
117
+ end
118
+ end
119
+
120
+ # This may be an old or a new style response.
121
+ #
122
+ # New style responses may have both `result`
123
+ # and `status` elements, or only a `status`
124
+ # element.
125
+ #
126
+ # If there is no `result` but there is a
127
+ # `status`, then consider this a new style
128
+ # response and return an empty result. Else,
129
+ # pass along to the superclass to parse the
130
+ # old style response.
131
+ #
132
+ def parse_result_attributes(root, root_element)
133
+ if root.key?(:result)
134
+ root[:result]
135
+ elsif root.key?(:status)
136
+ nil
137
+ else
138
+ super
139
+ end
140
+ end
141
+
142
+ def parse_result_errors(root, root_element)
143
+ if root.key?(:status)
144
+ super root[:status], root_element
145
+ else
146
+ super
147
+ end
148
+ end
149
+ end
150
+ end
@@ -1,3 +1,3 @@
1
1
  module Identikey
2
- VERSION = "0.8.2"
2
+ VERSION = "0.9.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: identikey
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcello Barnaba
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-22 00:00:00.000000000 Z
11
+ date: 2020-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: savon
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: wasabi
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.5.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.5.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -206,6 +220,7 @@ files:
206
220
  - lib/identikey/authentication.rb
207
221
  - lib/identikey/base.rb
208
222
  - lib/identikey/error.rb
223
+ - lib/identikey/provisioning.rb
209
224
  - lib/identikey/unsigned.rb
210
225
  - lib/identikey/version.rb
211
226
  - log/.keep