nexpose 0.0.98 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,108 +1,108 @@
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
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
@@ -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
- # user id, set to -1 to create a new user
73
- attr_reader :id
74
- # valid roles: global-admin|security-manager|site-admin|system-admin|user|custom
75
- attr_accessor :role_name
76
- # Required fields
77
- attr_reader :name
78
- attr_accessor :full_name
79
- # Will default to XML (1) for global-admin, Data Source (2) otherwise,
80
- # but caller can override (e.g., using LDAP authenticator).
81
- attr_accessor :authsrcid
82
- # Optional fields
83
- attr_accessor :email, :password, :sites, :groups
84
- # 1 to enable this user, 0 to disable
85
- attr_accessor :enabled
86
- # Boolean values
87
- attr_accessor :all_sites, :all_groups
88
-
89
- def initialize(name, full_name, password, role_name = 'user', id = -1, enabled = 1, email = nil, all_sites = false, all_groups = false)
90
- @name = name
91
- @password = password
92
- @role_name = role_name
93
- @authsrcid = ('global-admin'.eql? @role_name) ? '1' : '2'
94
- @id = id
95
- @enabled = enabled
96
- @full_name = full_name
97
- @email = email
98
- @all_sites = all_sites || role_name == 'global-admin'
99
- @all_groups = all_groups || role_name == 'global-admin'
100
- @sites = []
101
- @groups = []
102
- end
103
-
104
- def to_s
105
- out = "#{@user_name} (#{@full_name}) [ID: #{@id}, Role: #{@role_name}]"
106
- out << " Disabled" unless @enabled
107
- out << " All-Sites" if @all_sites
108
- out << " All-Groups" if @all_groups
109
- out << " e-mail: #{@email}" unless @email.nil? || @email.empty?
110
- out
111
- end
112
-
113
- def to_xml
114
- xml = "<UserConfig"
115
- xml << %Q{ id="#{@id}"}
116
- xml << %Q{ authsrcid="#{@authsrcid}"}
117
- xml << %Q{ name="#{@name}"}
118
- xml << %Q{ fullname="#{@full_name}"}
119
- xml << %Q{ role-name="#{@role_name}"}
120
- xml << %Q{ password="#{@password}"} if @password
121
- xml << %Q{ email="#{@email}"} if @email
122
- xml << %Q{ enabled="#{@enabled}"}
123
- # These two fields are keying off role_name to work around a defect.
124
- xml << %Q{ allGroups="#{@all_groups || @role_name == 'global-admin'}"}
125
- xml << %Q{ allSites="#{@all_sites || @role_name == 'global-admin'}"}
126
- xml << ">"
127
- @sites.each do |site|
128
- xml << %Q{<site id="#{site}" />}
129
- end
130
- @groups.each do |group|
131
- xml << %Q{<group id="#{group}" />}
132
- end
133
- xml << '</UserConfig>'
134
- end
135
-
136
- # Save a user configuration. Returns the (new) user ID if successful.
137
- def save(connection)
138
- xml = '<UserSaveRequest session-id="' + connection.session_id + '">'
139
- xml << to_xml
140
- xml << '</UserSaveRequest>'
141
- r = connection.execute(xml, '1.1')
142
- if r.success
143
- res = []
144
- r.res.elements.each('UserSaveResponse') do |attr|
145
- @id = attr.attributes['id'].to_i
146
- end
147
- @id
148
- else
149
- -1
150
- end
151
- end
152
-
153
- # Issue a UserConfigRequest to load an existing UserConfig from Nexpose.
154
- def self.load(connection, user_id)
155
- xml = '<UserConfigRequest session-id="' + connection.session_id + '"'
156
- xml << %Q{ id="#{user_id}"}
157
- xml << ' />'
158
- r = connection.execute(xml, '1.1')
159
- if r.success
160
- r.res.elements.each('UserConfigResponse/UserConfig') do |config|
161
- id = config.attributes['id']
162
- role_name = config.attributes['role-name']
163
- authsrcid = config.attributes['authsrcid']
164
- name = config.attributes['name']
165
- fullname = config.attributes['fullname']
166
-
167
- email = config.attributes['email']
168
- password = config.attributes['password']
169
- enabled = config.attributes['enabled'].to_i
170
- all_sites = config.attributes['allSites'] == 'true' ? true : false
171
- all_groups = config.attributes['allGroups'] == 'true' ? true : false
172
- # Not trying to load sites and groups.
173
- # Looks like API currently doesn't return that info to load.
174
- return UserConfig.new(name, fullname, password, role_name, id, enabled, email, all_sites, all_groups)
175
- end
176
- end
177
- end
178
-
179
- # Delete a user account.
180
- def self.delete(connection, user_id)
181
- xml = '<UserDeleteRequest session-id="' + connection.session_id + '"'
182
- xml << %Q{ id="#{user_id}"}
183
- xml << ' />'
184
- r = connection.execute(xml, '1.1')
185
- if r.success
186
- r.res.elements.each('UserConfigResponse/UserConfig') do |config|
187
- '1'.eql? config.attributes['id']
188
- end
189
- end
190
- end
191
-
192
- # Delete the user account associated with this object.
193
- def delete(connection)
194
- UserConfig.delete(connection, @id)
195
- end
196
- end
197
-
198
- class UserAuthenticator
199
- attr_reader :id, :auth_source, :auth_module, :external
200
-
201
- def initialize(id, auth_module, auth_source, external = false)
202
- @id = id
203
- @auth_source = auth_source
204
- @auth_module = auth_module
205
- @external = external
206
- end
207
-
208
- # Provide a list of user authentication sources.
209
- # * *Returns* : An array of known user authenticator sources.
210
- def self.list(connection)
211
- r = connection.execute('<UserAuthenticatorListingRequest session-id="' + connection.session_id + '" />', '1.1')
212
- if r.success
213
- modules = []
214
- r.res.elements.each('UserAuthenticatorListingResponse/AuthenticatorSummary') do |summary|
215
- modules << UserAuthenticator.new(summary.attributes['id'], summary.attributes['authModule'], summary.attributes['authSource'], ('1'.eql? summary.attributes['external']))
216
- end
217
- modules
218
- end
219
- end
220
- end
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