identikey 0.6.0 → 0.8.2

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: '039378c49a626d18251414c4be82aeba56190ff552bcc8d7e6dae130688e1105'
4
- data.tar.gz: 0f5aceccf8fcfc3cffe519e53869b0762574cd56029615b9b6b84fd7fb55c21e
3
+ metadata.gz: 66d43ba4ae2d3edfe361a94fe99fb85485fd90d804fd252bb03ab6d56541fc42
4
+ data.tar.gz: 723cf154216947148230acd05ba900b9ae4da15e06be73d2f2092a14034d3fbc
5
5
  SHA512:
6
- metadata.gz: 857077183795724bc19eb58d498a91b7a84b5673f4b01c186722722ba6c3f15607aea0544d124f16b5eb1e35836e903ab04ec60e9043e835eb4ecbd57ef8d01d
7
- data.tar.gz: 4d70c2fdaee23134609e222d3a725f00aea0c0f267e8c84fa6d0d938c00c32f91ca87038e09cb66658f1cd90c8a0198ea063e312bb941e50c6db3f01f6efa886
6
+ metadata.gz: e6f2c933ab1c131c879555fb1d34a51159ea4ff022782b9cd65d59fff7f1569b3c7ab7584035d8388ddc9ea153751216aafef622d59731168490aa4a686b9676
7
+ data.tar.gz: ebe4c8dbef838a97f21710350c345280750ba11bb25d070946d823e5d01b1ceb4425a73d3a9ae5a6e22755743288704694f8fca6ad6b73013e9ff68d9c1f49dd
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'identikey'
5
+ require 'json'
6
+
7
+ if ARGV.size != 1
8
+ $stderr.puts "Usage: #{$0} <users.json>"
9
+ exit 1
10
+ end
11
+
12
+ Identikey::Administration.configure do
13
+ wsdl ENV.fetch('IK_WSDL_ADMIN')
14
+ endpoint ENV.fetch('IK_HOST')
15
+ end
16
+
17
+ puts "Configured Admin WSDL #{ENV.fetch('IK_WSDL_ADMIN')} against #{ENV.fetch('IK_HOST')}"
18
+
19
+ $ik = Identikey::Administration::Session.new(
20
+ username: ENV.fetch('IK_USER'),
21
+ password: ENV.fetch('IK_PASS'),
22
+ domain: ENV.fetch('IK_DOMAIN')
23
+ )
24
+
25
+ $ik.logon
26
+
27
+ puts "Opened admin session with #{ENV.fetch('IK_USER')}@#{ENV.fetch('IK_DOMAIN')} against #{ENV.fetch('IK_HOST')}"
28
+
29
+ at_exit { $ik.logoff }
30
+
31
+ users = Identikey::Administration::User.search(session: $ik, query: {})
32
+ users_slim = users.map do |u|
33
+ { username: u.username,
34
+ email: u.email,
35
+ digipass: u.digipass,
36
+ disabled: u.disabled,
37
+ locked: u.locked,
38
+ expires_at: u.expires_at
39
+ }
40
+ end
41
+
42
+ File.write ARGV[0], users_slim.to_json
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'identikey'
5
+ require 'json'
6
+
7
+ if ARGV.size != 1
8
+ $stderr.puts "Usage: #{$0} <users.json>"
9
+ exit 1
10
+ end
11
+
12
+ Identikey::Administration.configure do
13
+ wsdl ENV.fetch('IK_WSDL_ADMIN')
14
+ endpoint ENV.fetch('IK_HOST')
15
+ end
16
+
17
+ puts "Configured Admin WSDL #{ENV.fetch('IK_WSDL_ADMIN')} against #{ENV.fetch('IK_HOST')}"
18
+
19
+ $ik = Identikey::Administration::Session.new(
20
+ username: ENV.fetch('IK_USER'),
21
+ password: ENV.fetch('IK_PASS'),
22
+ domain: ENV.fetch('IK_DOMAIN')
23
+ )
24
+
25
+ $ik.logon
26
+
27
+ puts "Opened admin session with #{ENV.fetch('IK_USER')}@#{ENV.fetch('IK_DOMAIN')} against #{ENV.fetch('IK_HOST')}"
28
+
29
+ at_exit { $ik.logoff }
30
+
31
+ users = JSON.load File.read ARGV[0]
32
+
33
+ users.each do |import|
34
+
35
+ puts "Looking up #{import['username']}"
36
+ ik_user = begin
37
+ Identikey::Administration::User.find(session: $ik, username: import['username'], domain: ENV.fetch('IK_DOMAIN'))
38
+ rescue => e
39
+ puts "Cannot look up #{import['username']}: #{e.message}"
40
+ nil
41
+ end
42
+
43
+ unless ik_user
44
+ puts "User #{import['username']} not found, creating"
45
+
46
+ ik_user = Identikey::Administration::User.new($ik,
47
+ 'USERFLD_USERID' => import['username'],
48
+ 'USERFLD_EMAIL' => import['email'],
49
+ 'USERFLD_DOMAIN' => ENV.fetch('IK_DOMAIN'),
50
+ 'USERFLD_LOCAL_AUTH' => 'Default',
51
+ 'USERFLD_BACKEND_AUTH' => 'Default',
52
+ 'USERFLD_DISABLED' => import['disabled'],
53
+ 'USERFLD_LOCKED' => import['locked'],
54
+ 'USERFLD_EXPIRATION_TIME' => import['expires_at']
55
+ )
56
+
57
+ begin
58
+ ik_user.save!
59
+ puts "User #{import['username']} created"
60
+ rescue => e
61
+
62
+ puts "Cannot create #{import['username']}: #{e.message}"
63
+
64
+ next
65
+ end
66
+ end
67
+
68
+ missing_digipass = import['digipass'] - ik_user.digipass
69
+
70
+ missing_digipass.each do |digipass|
71
+ puts "Assigining digipass #{digipass} to #{import['username']}"
72
+
73
+ ik_token = begin
74
+ Identikey::Administration::Digipass.find(session: $ik, serial_no: digipass)
75
+ rescue => e
76
+ puts "Digipass #{digipass} was not found"
77
+ next
78
+ end
79
+
80
+ begin
81
+ ik_token.assign! import['username'], ENV.fetch('IK_DOMAIN')
82
+ rescue => e
83
+ puts "Digipass #{digipass} could not be assigned to #{import['username']}: #{e.message}"
84
+ end
85
+
86
+ puts "Assignment of digipass #{digipass} to #{import['username']} was successful"
87
+ end
88
+
89
+ end
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_dependency "savon", "~> 2.0"
26
26
 
27
27
  spec.add_development_dependency "bundler", "~> 2.0"
28
- spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rake", ">= 12.3.3"
29
29
  spec.add_development_dependency "rspec", "~> 3.0"
30
30
  spec.add_development_dependency 'pry'
31
31
  spec.add_development_dependency 'hirb'
@@ -169,6 +169,16 @@ module Identikey
169
169
  )
170
170
  end
171
171
 
172
+ def user_execute_UNLOCK(session_id:, username:, domain:)
173
+ user_execute(
174
+ session_id: session_id,
175
+ cmd: 'USERCMD_UNLOCK',
176
+ attributes: typed_attributes_list_from(
177
+ USERFLD_USERID: username,
178
+ USERFLD_DOMAIN: domain
179
+ )
180
+ )
181
+ end
172
182
 
173
183
  # Executes a userQuery command that searches users. By default, it doesn't
174
184
  # log anywhere. To enable logging to a specific destination, pass a logger
@@ -6,12 +6,21 @@ module Identikey
6
6
  attr_reader :session_id, :product, :version
7
7
  attr_reader :privileges, :location
8
8
 
9
- def initialize(username:, password:, domain: 'master')
9
+ def initialize(username:, password: nil, apikey: nil, domain: 'master')
10
+ if password.nil? && apikey.nil?
11
+ raise Identikey::UsageError, "Either a password or an API Key is required"
12
+ end
13
+
10
14
  @client = Identikey::Administration.new
11
15
 
12
16
  @username = username
13
17
  @password = password
14
18
  @domain = domain
19
+
20
+ if apikey
21
+ @service_user = true
22
+ @session_id = "Apikey #{username}:#{apikey}"
23
+ end
15
24
  end
16
25
 
17
26
  def endpoint
@@ -23,6 +32,8 @@ module Identikey
23
32
  end
24
33
 
25
34
  def logon
35
+ require_classic_user!
36
+
26
37
  stat, sess, error = @client.logon(username: @username, password: @password, domain: @domain)
27
38
 
28
39
  if stat != 'STAT_SUCCESS'
@@ -42,6 +53,7 @@ module Identikey
42
53
  end
43
54
 
44
55
  def logoff
56
+ require_classic_user!
45
57
  require_logged_on!
46
58
 
47
59
  stat, _, error = @client.logoff session_id: @session_id
@@ -60,6 +72,8 @@ module Identikey
60
72
  end
61
73
 
62
74
  def alive?(log: true)
75
+ require_classic_user!
76
+
63
77
  return false unless logged_on?
64
78
 
65
79
  stat, _ = @client.ping session_id: @session_id, log: log
@@ -108,7 +122,17 @@ module Identikey
108
122
  end
109
123
 
110
124
  def inspect
111
- "#<#{self.class.name} sid=#@session_id username=#@username domain=#@domain product=#@product>"
125
+ descr = if service_user?
126
+ "SERVICE USER"
127
+ else
128
+ "domain=#@domain product=#@product"
129
+ end
130
+
131
+ "#<#{self.class.name} sid=#@session_id username=#@username #{descr}>"
132
+ end
133
+
134
+ def service_user?
135
+ !!@service_user
112
136
  end
113
137
 
114
138
  alias sid session_id
@@ -123,6 +147,12 @@ module Identikey
123
147
  end
124
148
  end
125
149
 
150
+ def require_classic_user!
151
+ if service_user?
152
+ raise Identikey::UsageError, "This command is not supported with Service users"
153
+ end
154
+ end
155
+
126
156
  def parse_privileges(privileges)
127
157
  privileges.split(', ').inject({}) do |h, priv|
128
158
  privilege, status = priv.split(' ')
@@ -6,7 +6,7 @@ module Identikey
6
6
  new(session).find(username, domain)
7
7
  end
8
8
 
9
- def self.search(session:, query:, options: {})
9
+ def self.search(session:, query:, options: {}, log: false)
10
10
  [:has_digipass, :not_has_digipass].each do |funky_boolean|
11
11
  if query.key?(funky_boolean) && [true, false].include?(query[funky_boolean])
12
12
  query[funky_boolean] = query[funky_boolean] ? 'Assigned' : 'Unassigned'
@@ -29,10 +29,12 @@ module Identikey
29
29
 
30
30
  stat, users, error = session.execute(:user_query,
31
31
  attributes: Base.search_attributes_from(query, attribute_map: query_keys),
32
- query_options: Base.search_options_from(options))
32
+ query_options: Base.search_options_from(options),
33
+ log: log
34
+ )
33
35
 
34
36
  case stat
35
- when 'STAT_SUCCESS' then (users||[]).map {|user| new(session, user) }
37
+ when 'STAT_SUCCESS' then (users||[]).map {|user| new(session, user, persisted: true) }
36
38
  when 'STAT_NOT_FOUND' then []
37
39
  else
38
40
  raise Identikey::Error, "Search user failed: #{stat} - #{error}"
@@ -59,11 +61,17 @@ module Identikey
59
61
  attr_accessor :expired
60
62
  attr_accessor :last_auth_attempt_at
61
63
  attr_accessor :description
64
+ attr_accessor :passwd_last_set_at
65
+ attr_accessor :has_password
62
66
 
63
- def initialize(session, user = nil)
67
+ alias locked? locked
68
+ alias digipass? has_digipass
69
+ alias password? has_password
70
+
71
+ def initialize(session, user = nil, persisted: false)
64
72
  @session = session
65
73
 
66
- replace(user) if user
74
+ replace(user, persisted: persisted) if user
67
75
  end
68
76
 
69
77
  def find(username, domain)
@@ -133,6 +141,8 @@ module Identikey
133
141
  raise Identikey::OperationFailed, "Clear user #{self.username} password failed: #{stat} - #{error}"
134
142
  end
135
143
 
144
+ self.has_password = false
145
+
136
146
  true
137
147
  end
138
148
 
@@ -146,6 +156,33 @@ module Identikey
146
156
  raise Identikey::OperationFailed, "Set user #{self.username} password failed: #{stat} - #{error}"
147
157
  end
148
158
 
159
+ self.has_password = true
160
+
161
+ true
162
+ end
163
+
164
+ def set_local_auth!(value)
165
+ ensure_persisted!
166
+
167
+ self.local_auth = value
168
+
169
+ self.save!
170
+
171
+ self
172
+ end
173
+
174
+ def unlock!
175
+ ensure_persisted!
176
+
177
+ stat, _, error = @session.execute(
178
+ :user_execute_UNLOCK, username: username, domain: domain)
179
+
180
+ if stat != 'STAT_SUCCESS'
181
+ raise Identikey::OperationFailed, "Unlock user #{self.username} failed: #{stat} - #{error}"
182
+ end
183
+
184
+ self.locked = false
185
+
149
186
  true
150
187
  end
151
188
 
@@ -171,6 +208,8 @@ module Identikey
171
208
  self.expired = user['USERFLD_EXPIRED']
172
209
  self.last_auth_attempt_at = user['USERFLD_LASTAUTHREQ_TIME']
173
210
  self.description = user['USERFLD_DESCRIPTION']
211
+ self.passwd_last_set_at = user['USERFLD_LAST_PASSWORD_SET_TIME']
212
+ self.has_password = !user['USERFLD_PASSWORD'].nil?
174
213
 
175
214
  @persisted = persisted
176
215
 
@@ -6,11 +6,13 @@ module Identikey
6
6
 
7
7
  operations :auth_user
8
8
 
9
- def auth_user(user, domain, otp)
9
+ def auth_user(user, domain, otp, client = nil)
10
+ client ||= 'Administration Program'
11
+
10
12
  resp = super(message: {
11
13
  credentialAttributeSet: {
12
14
  attributes: typed_attributes_list_from(
13
- CREDFLD_COMPONENT_TYPE: 'Administration Program',
15
+ CREDFLD_COMPONENT_TYPE: client,
14
16
  CREDFLD_USERID: user,
15
17
  CREDFLD_DOMAIN: domain,
16
18
  CREDFLD_PASSWORD_FORMAT: Unsigned(0),
@@ -22,18 +24,18 @@ module Identikey
22
24
  parse_response resp, :auth_user_response
23
25
  end
24
26
 
25
- def self.valid_otp?(user, domain, otp)
26
- status, result, _ = new.auth_user(user, domain, otp)
27
+ def self.valid_otp?(user, domain, otp, client = nil)
28
+ status, result, _ = new.auth_user(user, domain, otp, client)
27
29
  return otp_validated_ok?(status, result)
28
30
  end
29
31
 
30
- def self.validate!(user, domain, otp)
31
- status, result, error_stack = new.auth_user(user, domain, otp)
32
+ def self.validate!(user, domain, otp, client = nil)
33
+ status, result, error_stack = new.auth_user(user, domain, otp, client)
32
34
 
33
35
  if otp_validated_ok?(status, result)
34
36
  return true
35
37
  else
36
- error_message = result['CREDFLD_STATUS_MESSAGE']
38
+ error_message = result ? result['CREDFLD_STATUS_MESSAGE'] : 'no status returned'
37
39
  raise Identikey::OperationFailed.new("OTP Validation error (#{status}): #{error_message}", error_stack)
38
40
  end
39
41
  end
@@ -264,8 +264,8 @@ module Identikey
264
264
  parse = /^(not_)?(.*)/i.match(full_name.to_s)
265
265
  name = parse[2]
266
266
 
267
- options = []
268
- options.push(negative: true) if !parse[1].nil?
267
+ options = {}
268
+ options[:negative] = true if !parse[1].nil?
269
269
 
270
270
  type, value = case value
271
271
 
@@ -275,8 +275,8 @@ module Identikey
275
275
  when Integer
276
276
  [ 'xsd:int', value.to_s ]
277
277
 
278
- when DateTime, Time
279
- [ 'xsd:datetime', value.utc.iso8601 ]
278
+ when Time
279
+ [ 'xsd:dateTime', value.utc.iso8601 ]
280
280
 
281
281
  when TrueClass, FalseClass
282
282
  [ 'xsd:boolean', value.to_s ]
@@ -285,7 +285,7 @@ module Identikey
285
285
  [ 'xsd:string', value.to_s ]
286
286
 
287
287
  when NilClass
288
- options.push(null: true)
288
+ options[:null] = true
289
289
  [ 'xsd:string', '' ]
290
290
 
291
291
  else
@@ -1,3 +1,3 @@
1
1
  module Identikey
2
- VERSION = "0.6.0"
2
+ VERSION = "0.8.2"
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.6.0
4
+ version: 0.8.2
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-12-24 00:00:00.000000000 Z
11
+ date: 2020-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: savon
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: 12.3.3
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: 12.3.3
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -193,6 +193,8 @@ files:
193
193
  - README.md
194
194
  - Rakefile
195
195
  - bin/console
196
+ - bin/export
197
+ - bin/import
196
198
  - bin/setup
197
199
  - identikey.gemspec
198
200
  - lib/identikey.rb