identikey 0.5.3 → 0.8.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 +4 -4
- data/.gitignore +2 -0
- data/Rakefile +6 -0
- data/bin/export +42 -0
- data/bin/import +89 -0
- data/identikey.gemspec +3 -1
- data/lib/identikey/administration.rb +10 -0
- data/lib/identikey/administration/session.rb +32 -2
- data/lib/identikey/administration/user.rb +44 -5
- data/lib/identikey/authentication.rb +8 -6
- data/lib/identikey/base.rb +5 -5
- data/lib/identikey/version.rb +1 -1
- metadata +36 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d67c43498ddf55203f208418268742df9af7de77fb20e1a1c3a8cc7716e4cd51
|
4
|
+
data.tar.gz: 151c8fbe4fa12a81b505ec6945d727bf5085849a954608c32c6a11dcbf410138
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40086c267d7782f4f0e5d603ee2c61545de84af6509e6ae98e6a444cdbf26a5348a3c8d03098b64bfc3e8831c2d937580231dbe4acb2a036596b6d84bbc42b10
|
7
|
+
data.tar.gz: e3307d65634d80153fbd5c102eaaf60d03adee8336bae8e51d6aa30d3fee0c9633f0fc84782fe210ccfacaf340b70559ef1f7389a383819d7f1c9cbfda436df2
|
data/.gitignore
CHANGED
data/Rakefile
CHANGED
data/bin/export
ADDED
@@ -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
|
data/bin/import
ADDED
@@ -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
|
data/identikey.gemspec
CHANGED
@@ -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", "
|
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'
|
@@ -33,4 +33,6 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_development_dependency 'simplecov'
|
34
34
|
spec.add_development_dependency 'dotenv'
|
35
35
|
spec.add_development_dependency 'guard-rspec'
|
36
|
+
spec.add_development_dependency 'vacman_controller'
|
37
|
+
spec.add_development_dependency 'code_counter'
|
36
38
|
end
|
@@ -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
|
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
|
-
|
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
|
-
|
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:
|
15
|
+
CREDFLD_COMPONENT_TYPE: client,
|
14
16
|
CREDFLD_USERID: user,
|
15
17
|
CREDFLD_DOMAIN: domain,
|
16
18
|
CREDFLD_PASSWORD_FORMAT: Unsigned(0),
|
@@ -22,13 +24,13 @@ 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
|
data/lib/identikey/base.rb
CHANGED
@@ -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
|
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
|
279
|
-
[ 'xsd:
|
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
|
288
|
+
options[:null] = true
|
289
289
|
[ 'xsd:string', '' ]
|
290
290
|
|
291
291
|
else
|
data/lib/identikey/version.rb
CHANGED
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
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcello Barnaba
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-18 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:
|
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:
|
54
|
+
version: 12.3.3
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +150,34 @@ dependencies:
|
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: vacman_controller
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: code_counter
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
153
181
|
description: This gem contains a SOAP client to consume Identikey API
|
154
182
|
email:
|
155
183
|
- vjt@openssl.it
|
@@ -165,6 +193,8 @@ files:
|
|
165
193
|
- README.md
|
166
194
|
- Rakefile
|
167
195
|
- bin/console
|
196
|
+
- bin/export
|
197
|
+
- bin/import
|
168
198
|
- bin/setup
|
169
199
|
- identikey.gemspec
|
170
200
|
- lib/identikey.rb
|