identikey 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7250ec019f47150ff6dd6c34436cda2615daad7cc2ab27a9ff24b92a8d412985
4
- data.tar.gz: dc079e945e696d1480f80e90ab1ecf339a8b441c243cca201332c199c22ed570
3
+ metadata.gz: 17806b4e8996eac32014f37f34d9e698b4668e5fd196e1102e2a30c0eb349757
4
+ data.tar.gz: 26e36da28a662d259e538ef2936d8b03a883c0e38e450a5350e548a336336ed7
5
5
  SHA512:
6
- metadata.gz: 348dc3966a4bf3e9d31afefc738a0f698572035f2fed833de9f5260d115bd2b528eb546a69599cf67982ed23561691554055b1d998255f69454c681b26f48956
7
- data.tar.gz: 8afac75cce4902ce9e3939505c7f1a6707555b7ba1e9906cec0645d136a820fb8f6108c906c76982753499adec8fcd1a9c7a771e1e3861be6c15b7f25f7ec8fa
6
+ metadata.gz: cf8893d1ae7931194b59c54d0f3a6addd824869c116859ae534f36bb5a6619cebdb1f0e87bb6d8c74c4a67988470053abb2985b6d58e2011d59a0b16eeaf1eeb
7
+ data.tar.gz: 0c4e3661f8b518f55382490c9af060580d1982f2762904afeef435e9c544e0309e6ced8230bbea0e4b3e23451a544828bd10dc486858d8fc3ca03b792e191437
@@ -6,6 +6,36 @@ module Identikey
6
6
  new(session).find(serial_no)
7
7
  end
8
8
 
9
+ def self.search(session:, query:, options: {})
10
+ query_keys = {
11
+ 'applications' => 'DIGIPASSFLD_ACTIVE_APPL_NAMES',
12
+ 'app_types' => 'DIGIPASSFLD_ACTIVE_APPL_TYPES',
13
+ 'status' => 'DIGIPASSFLD_ASSIGN_STATUS',
14
+ 'user_org_unit' => 'DIGIPASSFLD_ASSIGNED_USER_ORG_UNIT',
15
+ 'username' => 'DIGIPASSFLD_ASSIGNED_USERID',
16
+ 'device_id' => 'DIGIPASSFLD_DEVICE_ID',
17
+ 'direct' => 'DIGIPASSFLD_DIRECT_ASSIGN_ONLY',
18
+ 'domain' => 'DIGIPASSFLD_DOMAIN',
19
+ 'type' => 'DIGIPASSFLD_DPTYPE',
20
+ 'expired' => 'DIGIPASSFLD_EXPIRED',
21
+ 'grace_expired' => 'DIGIPASSFLD_GRACE_PERIOD_EXPIRED',
22
+ 'license_serial' => 'DIGIPASSFLD_LICENSE_SERNO',
23
+ 'org_unit' => 'DIGIPASSFLD_ORGANIZATIONAL_UNIT',
24
+ 'serial' => 'DIGIPASSFLD_SERNO'
25
+ }
26
+
27
+ stat, digipasses, error = session.execute(:digipass_query,
28
+ attributes: Base.search_attributes_from(query, attribute_map: query_keys),
29
+ query_options: Base.search_options_from(options))
30
+
31
+ case stat
32
+ when 'STAT_SUCCESS' then (digipasses||[]).map {|user| new(session, user) }
33
+ when 'STAT_NOT_FOUND' then []
34
+ else
35
+ raise Identikey::Error, "Search digipass failed: #{stat} - #{error}"
36
+ end
37
+ end
38
+
9
39
  def initialize(session, digipass = nil)
10
40
  @session = session
11
41
 
@@ -85,12 +85,28 @@ module Identikey
85
85
  Digipass.find session: self, serial_no: serial_no
86
86
  end
87
87
 
88
+ def search_digipasses(query)
89
+ require_logged_on!
90
+
91
+ options = query.delete(:options) || {}
92
+
93
+ Digipass.search session: self, query: query, options: options
94
+ end
95
+
88
96
  def find_user(username, domain = nil)
89
97
  require_logged_on!
90
98
 
91
99
  User.find session: self, username: username, domain: domain || self.domain
92
100
  end
93
101
 
102
+ def search_users(query)
103
+ require_logged_on!
104
+
105
+ options = query.delete(:options) || {}
106
+
107
+ User.search session: self, query: query, options: options
108
+ end
109
+
94
110
  def inspect
95
111
  "#<#{self.class.name} sid=#@session_id username=#@username domain=#@domain product=#@product>"
96
112
  end
@@ -6,6 +6,37 @@ module Identikey
6
6
  new(session).find(username, domain)
7
7
  end
8
8
 
9
+ def self.search(session:, query:, options: {})
10
+ if query.key?(:has_digipass) && [true, false].include?(query[:has_digipass])
11
+ query[:has_digipass] = query[:has_digipass] ? 'Assigned' : 'Unassigned'
12
+ end
13
+
14
+ query_keys = {
15
+ 'has_digipass' => 'USERFLD_HAS_DP',
16
+ 'description' => 'USERFLD_DESCRIPTION',
17
+ 'disabled' => 'USERFLD_DISABLED',
18
+ 'domain' => 'USERFLD_DOMAIN',
19
+ 'email' => 'USERFLD_EMAIL',
20
+ 'expired' => 'USERFLD_EXPIRED',
21
+ 'locked' => 'USERFLD_LOCKED',
22
+ 'mobile' => 'USERFLD_MOBILE',
23
+ 'org_unit' => 'USERFLD_ORGANIZATIONAL_UNIT',
24
+ 'phone' => 'USERFLD_PHONE',
25
+ 'username' => 'USERFLD_USERID',
26
+ }
27
+
28
+ stat, users, error = session.execute(:user_query,
29
+ attributes: Base.search_attributes_from(query, attribute_map: query_keys),
30
+ query_options: Base.search_options_from(options))
31
+
32
+ case stat
33
+ when 'STAT_SUCCESS' then (users||[]).map {|user| new(session, user) }
34
+ when 'STAT_NOT_FOUND' then []
35
+ else
36
+ raise Identikey::Error, "Search user failed: #{stat} - #{error}"
37
+ end
38
+ end
39
+
9
40
  attr_accessor :username
10
41
  attr_accessor :email
11
42
  attr_accessor :mobile
@@ -25,6 +56,7 @@ module Identikey
25
56
  attr_accessor :expires_at
26
57
  attr_accessor :expired
27
58
  attr_accessor :last_auth_attempt_at
59
+ attr_accessor :description
28
60
 
29
61
  def initialize(session, user = nil)
30
62
  @session = session
@@ -116,6 +148,7 @@ module Identikey
116
148
  self.expires_at = user['USERFLD_EXPIRATION_TIME']
117
149
  self.expired = user['USERFLD_EXPIRED']
118
150
  self.last_auth_attempt_at = user['USERFLD_LASTAUTHREQ_TIME']
151
+ self.description = user['USERFLD_DESCRIPTION']
119
152
 
120
153
  @persisted = persisted
121
154
 
@@ -15,8 +15,8 @@ module Identikey
15
15
  client wsdl: './sdk/wsdl/administration.wsdl'
16
16
 
17
17
  operations :logon, :logoff, :sessionalive,
18
- :admin_session_query, :user_execute,
19
- :digipass_execute, :digipassappl_execute
18
+ :admin_session_query, :user_execute, :user_query,
19
+ :digipass_execute, :digipass_query, :digipassappl_execute
20
20
 
21
21
  def logon(username:, password:, domain:)
22
22
  resp = super(message: {
@@ -150,6 +150,20 @@ module Identikey
150
150
  )
151
151
  end
152
152
 
153
+
154
+ def user_query(session_id:, attributes:, query_options:)
155
+ resp = super(message: {
156
+ sessionID: session_id,
157
+ attributeSet: {
158
+ attributes: typed_attributes_query_list_from(attributes)
159
+ },
160
+ queryOptions: query_options
161
+ })
162
+
163
+ parse_response resp, :user_query_response
164
+ end
165
+
166
+
153
167
  def digipass_execute(session_id:, cmd:, attributes: [])
154
168
  resp = super(message: {
155
169
  sessionID: session_id,
@@ -195,6 +209,20 @@ module Identikey
195
209
  )
196
210
  end
197
211
 
212
+
213
+ def digipass_query(session_id:, attributes:, query_options:)
214
+ resp = super(message: {
215
+ sessionID: session_id,
216
+ attributeSet: {
217
+ attributes: typed_attributes_query_list_from(attributes)
218
+ },
219
+ queryOptions: query_options
220
+ })
221
+
222
+ parse_response resp, :digipass_query_response
223
+ end
224
+
225
+
198
226
  def digipassappl_execute(session_id:, cmd:, attributes:)
199
227
  resp = super(message: {
200
228
  sessionID: session_id,
@@ -220,12 +220,35 @@ module Identikey
220
220
  end
221
221
  end
222
222
 
223
+ def typed_attributes_list_from(hash)
224
+ self.class.typed_attributes_list_from(hash)
225
+ end
226
+
227
+ # Calls typed_attribute_query_list_from() by removing the
228
+ # nil values from the given hash.
229
+ #
230
+ # The nil values are ignored when calling API endpoints that
231
+ # are not query ones, as such there is no point in adding an
232
+ # attributeOption null:true on those.
233
+ #
234
+ def self.typed_attributes_list_from(hash)
235
+ typed_attributes_query_list_from(hash.reject {|k,v| v.nil?})
236
+ end
237
+
238
+ def typed_attributes_query_list_from(hash)
239
+ self.class.typed_attributes_query_list_from(hash)
240
+ end
241
+
223
242
  # Converts and hash keyed by attribute name into an array of hashes
224
243
  # whose keys are the attribute name as attributeID and the value as
225
244
  # a Gyoku-compatible hash with the xsd:type annotation. The type is
226
245
  # inferred from the Ruby value type and the contents are serialized
227
246
  # as a string formatted as per the XSD DTD definition.
228
247
  #
248
+ # Further, this supports "virtual" attributes with a "NOT_" prefix.
249
+ # If the NOT_ prefix is set to the attribute name then the negative
250
+ # attributeOption is set.
251
+ #
229
252
  # <rant>
230
253
  # This code should not exist, because defining argument types is what
231
254
  # WSDL is for. However, in the braindead web services implementation
@@ -235,8 +258,15 @@ module Identikey
235
258
  # than an aid.
236
259
  # </rant>
237
260
  #
238
- def typed_attributes_list_from(hash)
239
- hash.map do |name, value|
261
+ def self.typed_attributes_query_list_from(hash)
262
+ hash.map do |full_name, value|
263
+
264
+ parse = /^(not_)?(.*)/i.match(full_name.to_s)
265
+ name = parse[2]
266
+
267
+ options = []
268
+ options.push(negative: true) if !parse[1].nil?
269
+
240
270
  type, value = case value
241
271
 
242
272
  when Unsigned
@@ -255,17 +285,61 @@ module Identikey
255
285
  [ 'xsd:string', value.to_s ]
256
286
 
257
287
  when NilClass
258
- next
288
+ options.push(null: true)
289
+ [ 'xsd:string', '' ]
259
290
 
260
291
  else
261
- raise Identikey::UsageError, "#{name} type #{value.class} is unsupported"
292
+ raise Identikey::UsageError, "#{full_name} type #{value.class} is unsupported"
262
293
  end
263
294
 
264
- { attributeID: name.to_s,
295
+ { attributeID: name,
296
+ attributeOptions: options,
265
297
  value: { '@xsi:type': type, content!: value } }
266
298
  end.compact
267
299
  end
268
300
 
301
+ # Translates the given attributes map into an hash suitable to be passed
302
+ # to typed_attributes_query_list_from(). This is used only to DRY the
303
+ # invocations across the _query methods.
304
+ #
305
+ def self.search_attributes_from(query, attribute_map:)
306
+ query.inject({}) do |ret, (key, value)|
307
+
308
+ parse = /^(not_)?(.*)/.match(key.to_s)
309
+ negate = !parse[1].nil?
310
+ name = parse[2]
311
+
312
+ attribute = attribute_map.fetch(name, nil)
313
+
314
+ if attribute.nil?
315
+ raise Identikey::UsageError, "Invalid search key: #{key}"
316
+ end
317
+
318
+ attribute = "NOT_#{attribute}" if negate
319
+
320
+ ret.update(attribute => value)
321
+ end
322
+ end
323
+
324
+ # Translate our search interface options into Identikey's _query methods
325
+ # interface options.
326
+ #
327
+ def self.search_options_from(options)
328
+ options.inject({}) do |ret, (option, value)|
329
+ attribute = {
330
+ 'distinct' => 'distinct',
331
+ 'limit' => 'rowcount',
332
+ 'offset' => 'rowoffset',
333
+ }.fetch(option.to_s, nil)
334
+
335
+ if attribute.nil?
336
+ raise Identikey::UsageError, "Invalid search option: #{option}"
337
+ end
338
+
339
+ ret.update(attribute => value)
340
+ end
341
+ end
342
+
269
343
  # protected
270
344
 
271
345
  end
@@ -1,3 +1,3 @@
1
1
  module Identikey
2
- VERSION = "0.4.3"
2
+ VERSION = "0.5.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.4.3
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcello Barnaba
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-24 00:00:00.000000000 Z
11
+ date: 2019-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: savon