nexpose 0.0.98 → 0.1.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.
- data/README.markdown +17 -7
- data/Rakefile +17 -22
- data/lib/README.md +5 -0
- data/lib/nexpose.rb +104 -130
- data/lib/nexpose/api_request.rb +133 -144
- data/lib/nexpose/common.rb +138 -0
- data/lib/nexpose/connection.rb +117 -106
- data/lib/nexpose/creds.rb +292 -279
- data/lib/nexpose/error.rb +21 -21
- data/lib/nexpose/manage.rb +83 -0
- data/lib/nexpose/misc.rb +85 -122
- data/lib/nexpose/report.rb +783 -603
- data/lib/nexpose/role.rb +27 -0
- data/lib/nexpose/scan.rb +264 -285
- data/lib/nexpose/scan_engine.rb +344 -350
- data/lib/nexpose/silo.rb +348 -347
- data/lib/nexpose/site.rb +826 -898
- data/lib/nexpose/ticket.rb +108 -108
- data/lib/nexpose/user.rb +223 -221
- data/lib/nexpose/util.rb +36 -36
- data/lib/nexpose/vuln.rb +510 -520
- metadata +37 -23
- data/README +0 -0
- data/nexpose.gemspec +0 -20
data/lib/nexpose/ticket.rb
CHANGED
@@ -1,108 +1,108 @@
|
|
1
|
-
module Nexpose
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
end
|
1
|
+
module Nexpose
|
2
|
+
module NexposeAPI
|
3
|
+
include XMLUtils
|
4
|
+
|
5
|
+
#
|
6
|
+
# Create a Nexpose ticket
|
7
|
+
#
|
8
|
+
# ticket_info: A hash of the data to be used to create a ticket in Nexpose:
|
9
|
+
# :name => The name of the ticket (Required)
|
10
|
+
# :device_id => The Nexpose device ID for the device being ticketed (Required)
|
11
|
+
# :assigned_to => The Nexpose user to whom this ticket is assigned (Required)
|
12
|
+
# :priority => "low,moderate,normal,high,critical" (Required)
|
13
|
+
#
|
14
|
+
# :vulnerabilities => An array of Nexpose vuln IDs. This is NOT the same as vuln ID. (Required)
|
15
|
+
# :comments => An array of comments to accompany this ticket
|
16
|
+
#
|
17
|
+
# @return The ticket ID if the ticket creation was successful, {@code false} otherwise
|
18
|
+
#
|
19
|
+
def create_ticket ticket_info
|
20
|
+
ticket_name = ticket_info[:name]
|
21
|
+
unless ticket_name
|
22
|
+
raise ArgumentError.new 'Ticket name is required'
|
23
|
+
end
|
24
|
+
|
25
|
+
device_id = ticket_info[:device_id]
|
26
|
+
unless device_id
|
27
|
+
raise ArgumentError.new 'Device ID is required'
|
28
|
+
end
|
29
|
+
|
30
|
+
assigned_to = ticket_info[:assigned_to]
|
31
|
+
unless assigned_to
|
32
|
+
raise ArgumentError.new 'Assignee name is required'
|
33
|
+
end
|
34
|
+
|
35
|
+
priority = ticket_info[:priority]
|
36
|
+
unless priority
|
37
|
+
raise ArgumentError.new 'Ticket priority is required'
|
38
|
+
end
|
39
|
+
|
40
|
+
vulnerabilities = ticket_info[:vulnerabilities]
|
41
|
+
if not vulnerabilities or vulnerabilities.count < 1
|
42
|
+
raise ArgumentError.new 'Vulnerabilities are required'
|
43
|
+
end
|
44
|
+
|
45
|
+
comments = ticket_info[:comments]
|
46
|
+
base_xml = make_xml 'TicketCreateRequest'
|
47
|
+
|
48
|
+
required_attributes = {
|
49
|
+
'name' => ticket_name,
|
50
|
+
'priority' => priority,
|
51
|
+
'device-id' => device_id,
|
52
|
+
'assigned-to' => assigned_to
|
53
|
+
}
|
54
|
+
|
55
|
+
create_request_xml = REXML::Element.new 'TicketCreate'
|
56
|
+
create_request_xml.add_attributes required_attributes
|
57
|
+
|
58
|
+
# Add vulnerabilities
|
59
|
+
vulnerabilities_xml = REXML::Element.new 'Vulnerabilities'
|
60
|
+
vulnerabilities.each do |vuln_id|
|
61
|
+
vulnerabilities_xml.add_element 'Vulnerability', {'id' => vuln_id}
|
62
|
+
end
|
63
|
+
create_request_xml.add_element vulnerabilities_xml
|
64
|
+
|
65
|
+
# Add comments
|
66
|
+
if comments and comments.count > 0
|
67
|
+
comments_xml = REXML::Element.new 'Comments'
|
68
|
+
comments.each do |comment|
|
69
|
+
comment_xml = REXML::Element.new 'Comment'
|
70
|
+
comment_xml.add_text comment
|
71
|
+
comments_xml.add_element comment_xml
|
72
|
+
end
|
73
|
+
|
74
|
+
create_request_xml.add_element comments_xml
|
75
|
+
end
|
76
|
+
|
77
|
+
base_xml.add_element create_request_xml
|
78
|
+
r = execute base_xml, '1.2'
|
79
|
+
if r.success
|
80
|
+
r.res.elements.each('TicketCreateResponse') do |group|
|
81
|
+
return group.attributes['id'].to_i
|
82
|
+
end
|
83
|
+
else
|
84
|
+
false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# Deletes a Nexpose ticket.
|
90
|
+
#
|
91
|
+
# ticket_ids: An array of ticket IDs to be deleted.
|
92
|
+
#
|
93
|
+
# @returns {@code true} iff the call was successfull. {@code false} otherwise.
|
94
|
+
#
|
95
|
+
def delete_ticket ticket_ids
|
96
|
+
if not ticket_ids or ticket_ids.count < 1
|
97
|
+
raise ArgumentError.new 'The tickets to delete should not be null or empty'
|
98
|
+
end
|
99
|
+
|
100
|
+
base_xml = make_xml 'TicketDeleteRequest'
|
101
|
+
ticket_ids.each do |id|
|
102
|
+
base_xml.add_element 'Ticket', {'id' => id}
|
103
|
+
end
|
104
|
+
|
105
|
+
(execute base_xml, '1.2').success
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/nexpose/user.rb
CHANGED
@@ -1,221 +1,223 @@
|
|
1
|
-
module Nexpose
|
2
|
-
|
3
|
-
# Summary only returned by API when issuing a listing request.
|
4
|
-
class UserSummary
|
5
|
-
attr_reader :id, :auth_source, :auth_module, :user_name, :full_name, :email
|
6
|
-
attr_reader :is_admin, :is_disabled, :is_locked, :site_count, :group_count
|
7
|
-
|
8
|
-
def initialize(id, auth_source, auth_module, user_name, full_name, email, is_admin, is_disabled, is_locked, site_count, group_count)
|
9
|
-
@id = id
|
10
|
-
@auth_source = auth_source
|
11
|
-
@auth_module = auth_module
|
12
|
-
@user_name = user_name
|
13
|
-
@full_name = full_name
|
14
|
-
@email = email
|
15
|
-
@is_admin = is_admin
|
16
|
-
@is_disabled = is_disabled
|
17
|
-
@is_locked = is_locked
|
18
|
-
@site_count = site_count
|
19
|
-
@group_count = group_count
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_s
|
23
|
-
out = "#{@user_name} (#{@full_name}) [ID: #{@id}]"
|
24
|
-
out << " e-mail: #{@email}" unless @email.empty?
|
25
|
-
out << " Administrator" if @is_admin
|
26
|
-
out << " Disabled" if @is_disabled
|
27
|
-
out << " Locked" if @is_locked
|
28
|
-
out << ", sites: #{@site_count}"
|
29
|
-
out << ", groups: #{@group_count}"
|
30
|
-
end
|
31
|
-
|
32
|
-
# Provide a list of user accounts and information about those accounts.
|
33
|
-
def self.listing(connection)
|
34
|
-
xml = '<UserListingRequest session-id="' + connection.session_id + '" />'
|
35
|
-
r = connection.execute(xml, '1.1')
|
36
|
-
if r.success
|
37
|
-
res = []
|
38
|
-
r.res.elements.each('UserListingResponse/UserSummary') do |summary|
|
39
|
-
res << UserSummary.new(
|
40
|
-
summary.attributes['id'].to_i,
|
41
|
-
summary.attributes['authSource'],
|
42
|
-
summary.attributes['authModule'],
|
43
|
-
summary.attributes['userName'],
|
44
|
-
summary.attributes['fullName'],
|
45
|
-
summary.attributes['email'],
|
46
|
-
summary.attributes['administrator'].to_s.chomp.eql?('1'),
|
47
|
-
summary.attributes['disabled'].to_s.chomp.eql?('1'),
|
48
|
-
summary.attributes['locked'].to_s.chomp.eql?('1'),
|
49
|
-
summary.attributes['siteCount'].to_i,
|
50
|
-
summary.attributes['groupCount'].to_i)
|
51
|
-
end
|
52
|
-
res
|
53
|
-
else
|
54
|
-
false
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# Retrieve the User ID based upon the user's login name.
|
59
|
-
def self.get_user_id(connection, user_name)
|
60
|
-
xml = '<UserListingRequest session-id="' + connection.session_id + '" />'
|
61
|
-
r = connection.execute(xml, '1.1')
|
62
|
-
if r.success
|
63
|
-
r.res.elements.each('UserListingResponse/UserSummary') do |user|
|
64
|
-
return user.attributes['id'] if user_name.eql? user.attributes['userName']
|
65
|
-
end
|
66
|
-
end
|
67
|
-
return -1
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
class UserConfig
|
72
|
-
|
73
|
-
|
74
|
-
#
|
75
|
-
|
76
|
-
#
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
#
|
83
|
-
attr_accessor :
|
84
|
-
#
|
85
|
-
attr_accessor :
|
86
|
-
#
|
87
|
-
attr_accessor :
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
@
|
93
|
-
@
|
94
|
-
@
|
95
|
-
@
|
96
|
-
@
|
97
|
-
@
|
98
|
-
@
|
99
|
-
@
|
100
|
-
@
|
101
|
-
@
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
out
|
108
|
-
out << "
|
109
|
-
out << "
|
110
|
-
out
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
xml
|
117
|
-
xml << %Q{
|
118
|
-
xml << %Q{
|
119
|
-
xml << %Q{
|
120
|
-
xml << %Q{
|
121
|
-
xml << %Q{
|
122
|
-
xml << %Q{
|
123
|
-
|
124
|
-
xml << %Q{
|
125
|
-
|
126
|
-
xml << "
|
127
|
-
@
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
xml
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
xml
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
xml
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
@
|
205
|
-
@
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
end
|
1
|
+
module Nexpose
|
2
|
+
|
3
|
+
# Summary only returned by API when issuing a listing request.
|
4
|
+
class UserSummary
|
5
|
+
attr_reader :id, :auth_source, :auth_module, :user_name, :full_name, :email
|
6
|
+
attr_reader :is_admin, :is_disabled, :is_locked, :site_count, :group_count
|
7
|
+
|
8
|
+
def initialize(id, auth_source, auth_module, user_name, full_name, email, is_admin, is_disabled, is_locked, site_count, group_count)
|
9
|
+
@id = id
|
10
|
+
@auth_source = auth_source
|
11
|
+
@auth_module = auth_module
|
12
|
+
@user_name = user_name
|
13
|
+
@full_name = full_name
|
14
|
+
@email = email
|
15
|
+
@is_admin = is_admin
|
16
|
+
@is_disabled = is_disabled
|
17
|
+
@is_locked = is_locked
|
18
|
+
@site_count = site_count
|
19
|
+
@group_count = group_count
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
out = "#{@user_name} (#{@full_name}) [ID: #{@id}]"
|
24
|
+
out << " e-mail: #{@email}" unless @email.empty?
|
25
|
+
out << " Administrator" if @is_admin
|
26
|
+
out << " Disabled" if @is_disabled
|
27
|
+
out << " Locked" if @is_locked
|
28
|
+
out << ", sites: #{@site_count}"
|
29
|
+
out << ", groups: #{@group_count}"
|
30
|
+
end
|
31
|
+
|
32
|
+
# Provide a list of user accounts and information about those accounts.
|
33
|
+
def self.listing(connection)
|
34
|
+
xml = '<UserListingRequest session-id="' + connection.session_id + '" />'
|
35
|
+
r = connection.execute(xml, '1.1')
|
36
|
+
if r.success
|
37
|
+
res = []
|
38
|
+
r.res.elements.each('UserListingResponse/UserSummary') do |summary|
|
39
|
+
res << UserSummary.new(
|
40
|
+
summary.attributes['id'].to_i,
|
41
|
+
summary.attributes['authSource'],
|
42
|
+
summary.attributes['authModule'],
|
43
|
+
summary.attributes['userName'],
|
44
|
+
summary.attributes['fullName'],
|
45
|
+
summary.attributes['email'],
|
46
|
+
summary.attributes['administrator'].to_s.chomp.eql?('1'),
|
47
|
+
summary.attributes['disabled'].to_s.chomp.eql?('1'),
|
48
|
+
summary.attributes['locked'].to_s.chomp.eql?('1'),
|
49
|
+
summary.attributes['siteCount'].to_i,
|
50
|
+
summary.attributes['groupCount'].to_i)
|
51
|
+
end
|
52
|
+
res
|
53
|
+
else
|
54
|
+
false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Retrieve the User ID based upon the user's login name.
|
59
|
+
def self.get_user_id(connection, user_name)
|
60
|
+
xml = '<UserListingRequest session-id="' + connection.session_id + '" />'
|
61
|
+
r = connection.execute(xml, '1.1')
|
62
|
+
if r.success
|
63
|
+
r.res.elements.each('UserListingResponse/UserSummary') do |user|
|
64
|
+
return user.attributes['id'] if user_name.eql? user.attributes['userName']
|
65
|
+
end
|
66
|
+
end
|
67
|
+
return -1
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class UserConfig
|
72
|
+
include Sanitize
|
73
|
+
|
74
|
+
# user id, set to -1 to create a new user
|
75
|
+
attr_reader :id
|
76
|
+
# valid roles: global-admin|security-manager|site-admin|system-admin|user|custom
|
77
|
+
attr_accessor :role_name
|
78
|
+
# Required fields
|
79
|
+
attr_reader :name
|
80
|
+
attr_accessor :full_name
|
81
|
+
# Will default to XML (1) for global-admin, Data Source (2) otherwise,
|
82
|
+
# but caller can override (e.g., using LDAP authenticator).
|
83
|
+
attr_accessor :authsrcid
|
84
|
+
# Optional fields
|
85
|
+
attr_accessor :email, :password, :sites, :groups
|
86
|
+
# 1 to enable this user, 0 to disable
|
87
|
+
attr_accessor :enabled
|
88
|
+
# Boolean values
|
89
|
+
attr_accessor :all_sites, :all_groups
|
90
|
+
|
91
|
+
def initialize(name, full_name, password, role_name = 'user', id = -1, enabled = 1, email = nil, all_sites = false, all_groups = false)
|
92
|
+
@name = name
|
93
|
+
@password = password
|
94
|
+
@role_name = role_name
|
95
|
+
@authsrcid = ('global-admin'.eql? @role_name) ? '1' : '2'
|
96
|
+
@id = id
|
97
|
+
@enabled = enabled
|
98
|
+
@full_name = full_name
|
99
|
+
@email = email
|
100
|
+
@all_sites = all_sites || role_name == 'global-admin'
|
101
|
+
@all_groups = all_groups || role_name == 'global-admin'
|
102
|
+
@sites = []
|
103
|
+
@groups = []
|
104
|
+
end
|
105
|
+
|
106
|
+
def to_s
|
107
|
+
out = "#{@user_name} (#{@full_name}) [ID: #{@id}, Role: #{@role_name}]"
|
108
|
+
out << " Disabled" unless @enabled
|
109
|
+
out << " All-Sites" if @all_sites
|
110
|
+
out << " All-Groups" if @all_groups
|
111
|
+
out << " e-mail: #{@email}" unless @email.nil? || @email.empty?
|
112
|
+
out
|
113
|
+
end
|
114
|
+
|
115
|
+
def to_xml
|
116
|
+
xml = "<UserConfig"
|
117
|
+
xml << %Q{ id="#{@id}"}
|
118
|
+
xml << %Q{ authsrcid="#{@authsrcid}"}
|
119
|
+
xml << %Q{ name="#{@name}"}
|
120
|
+
xml << %Q{ fullname="#{@full_name}"}
|
121
|
+
xml << %Q{ role-name="#{@role_name}"}
|
122
|
+
xml << %Q{ password="#{replace_entities(@password)}"} if @password
|
123
|
+
xml << %Q{ email="#{@email}"} if @email
|
124
|
+
xml << %Q{ enabled="#{@enabled}"}
|
125
|
+
# These two fields are keying off role_name to work around a defect.
|
126
|
+
xml << %Q{ allGroups="#{@all_groups || @role_name == 'global-admin'}"}
|
127
|
+
xml << %Q{ allSites="#{@all_sites || @role_name == 'global-admin'}"}
|
128
|
+
xml << ">"
|
129
|
+
@sites.each do |site|
|
130
|
+
xml << %Q{<site id="#{site}" />}
|
131
|
+
end
|
132
|
+
@groups.each do |group|
|
133
|
+
xml << %Q{<group id="#{group}" />}
|
134
|
+
end
|
135
|
+
xml << '</UserConfig>'
|
136
|
+
end
|
137
|
+
|
138
|
+
# Save a user configuration. Returns the (new) user ID if successful.
|
139
|
+
def save(connection)
|
140
|
+
xml = '<UserSaveRequest session-id="' + connection.session_id + '">'
|
141
|
+
xml << to_xml
|
142
|
+
xml << '</UserSaveRequest>'
|
143
|
+
r = connection.execute(xml, '1.1')
|
144
|
+
if r.success
|
145
|
+
res = []
|
146
|
+
r.res.elements.each('UserSaveResponse') do |attr|
|
147
|
+
@id = attr.attributes['id'].to_i
|
148
|
+
end
|
149
|
+
@id
|
150
|
+
else
|
151
|
+
-1
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Issue a UserConfigRequest to load an existing UserConfig from Nexpose.
|
156
|
+
def self.load(connection, user_id)
|
157
|
+
xml = '<UserConfigRequest session-id="' + connection.session_id + '"'
|
158
|
+
xml << %Q{ id="#{user_id}"}
|
159
|
+
xml << ' />'
|
160
|
+
r = connection.execute(xml, '1.1')
|
161
|
+
if r.success
|
162
|
+
r.res.elements.each('UserConfigResponse/UserConfig') do |config|
|
163
|
+
id = config.attributes['id']
|
164
|
+
role_name = config.attributes['role-name']
|
165
|
+
authsrcid = config.attributes['authsrcid']
|
166
|
+
name = config.attributes['name']
|
167
|
+
fullname = config.attributes['fullname']
|
168
|
+
|
169
|
+
email = config.attributes['email']
|
170
|
+
password = config.attributes['password']
|
171
|
+
enabled = config.attributes['enabled'].to_i
|
172
|
+
all_sites = config.attributes['allSites'] == 'true' ? true : false
|
173
|
+
all_groups = config.attributes['allGroups'] == 'true' ? true : false
|
174
|
+
# Not trying to load sites and groups.
|
175
|
+
# Looks like API currently doesn't return that info to load.
|
176
|
+
return UserConfig.new(name, fullname, password, role_name, id, enabled, email, all_sites, all_groups)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Delete a user account.
|
182
|
+
def self.delete(connection, user_id)
|
183
|
+
xml = '<UserDeleteRequest session-id="' + connection.session_id + '"'
|
184
|
+
xml << %Q{ id="#{user_id}"}
|
185
|
+
xml << ' />'
|
186
|
+
r = connection.execute(xml, '1.1')
|
187
|
+
if r.success
|
188
|
+
r.res.elements.each('UserConfigResponse/UserConfig') do |config|
|
189
|
+
'1'.eql? config.attributes['id']
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# Delete the user account associated with this object.
|
195
|
+
def delete(connection)
|
196
|
+
UserConfig.delete(connection, @id)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
class UserAuthenticator
|
201
|
+
attr_reader :id, :auth_source, :auth_module, :external
|
202
|
+
|
203
|
+
def initialize(id, auth_module, auth_source, external = false)
|
204
|
+
@id = id
|
205
|
+
@auth_source = auth_source
|
206
|
+
@auth_module = auth_module
|
207
|
+
@external = external
|
208
|
+
end
|
209
|
+
|
210
|
+
# Provide a list of user authentication sources.
|
211
|
+
# * *Returns* : An array of known user authenticator sources.
|
212
|
+
def self.list(connection)
|
213
|
+
r = connection.execute('<UserAuthenticatorListingRequest session-id="' + connection.session_id + '" />', '1.1')
|
214
|
+
if r.success
|
215
|
+
modules = []
|
216
|
+
r.res.elements.each('UserAuthenticatorListingResponse/AuthenticatorSummary') do |summary|
|
217
|
+
modules << UserAuthenticator.new(summary.attributes['id'], summary.attributes['authModule'], summary.attributes['authSource'], ('1'.eql? summary.attributes['external']))
|
218
|
+
end
|
219
|
+
modules
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|