idnio 2.3.2b

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env ruby
2
+ require "json"
3
+ require "idnio/idnapi"
4
+ require "idnio/program"
5
+
6
+ module ReferenceResolver
7
+
8
+ @@default_identity_ref = nil
9
+
10
+ @@default_cluster_ref = nil
11
+
12
+ def self.get_default_identity_ref
13
+ if @@default_identity_ref.nil?
14
+ @@default_identity_ref = ReferenceResolver.get_identity_ref( "slpt.services" )
15
+ end
16
+ return @@default_identity_ref
17
+ end #def self.get_default_identity_ref
18
+
19
+ def self.get_identity_ref( name )
20
+
21
+ query = {
22
+ "queryType": "SAILPOINT",
23
+ "query": {
24
+ "query": "name:#{name}"
25
+ }
26
+ }
27
+ response = IDNAPI.post_json( "#{$url}/beta/search/identities?count=true&offset=0&limit=1", $token, query )
28
+
29
+ unless response['X-Total-Count'].nil?
30
+ count = response['X-Total-Count'].to_i
31
+
32
+ if count == 1 # Make sure we have a unique result.
33
+
34
+ identities = JSON.parse( response.body )
35
+
36
+ identity = identities.first
37
+
38
+ identity_ref = {
39
+ "type": "IDENTITY",
40
+ "id": identity['id'],
41
+ "name": identity['name']
42
+ }
43
+
44
+ return identity_ref
45
+
46
+ elsif name != "slpt.services" # We don't have a unique result, and we're not looking up slpt.services, so we'll look that up instead.
47
+
48
+ $log.debug "\t\tCannot resolve unique identity '#{name}'. Resolving identity 'slpt.services' instead."
49
+ return ReferenceResolver.get_default_identity_ref
50
+
51
+ else # We don't have a unique result, and we couldn't resolve anything else. Punt. Hopefully we never see this message.
52
+
53
+ $log.debug "\t\tCannot resolve identity '#{name}' . Giving up with no identity."
54
+ return nil
55
+
56
+ end
57
+
58
+ end # if response['X-Total-Count'].nil?
59
+
60
+ return nil # catch all.
61
+
62
+ end # def self.get_identity_ref ( name )
63
+
64
+ def self.get_default_cluster_ref
65
+
66
+ if @@default_cluster_ref.nil?
67
+
68
+ response = IDNAPI.get( "#{$url}/cc/api/cluster/list", $token )
69
+
70
+ case response
71
+ when Net::HTTPSuccess
72
+
73
+ clusters = JSON.parse( response.body )
74
+
75
+ unless clusters.nil? || clusters.empty?
76
+
77
+ cluster = clusters.first
78
+
79
+ cluster_ref = {
80
+ "type": "CLUSTER",
81
+ "id": "#{cluster['configuration']['clusterExternalId']}",
82
+ "name": "#{cluster['name']}"
83
+ }
84
+
85
+ @@default_cluster_ref = cluster_ref
86
+
87
+ end #unless clusters["items"].nil?
88
+
89
+ else
90
+ $log.error "\tError: Unable to fetch clusters."
91
+ end # case response
92
+
93
+ end # if @@default_cluster_ref.nil?
94
+
95
+ return @@default_cluster_ref
96
+
97
+ end # def self.get_default_cluster_ref
98
+
99
+ def self.get_cluster_ref( name )
100
+
101
+ response = IDNAPI.get( "#{$url}/cc/api/cluster/list", $token )
102
+
103
+ case response
104
+ when Net::HTTPSuccess
105
+
106
+ clusters = JSON.parse( response.body )
107
+
108
+ unless clusters.nil? || clusters.empty?
109
+
110
+ clusters.each do |cluster|
111
+
112
+ # If we match the name of the cluster we are looking for.
113
+ if cluster['name'] == name
114
+
115
+ cluster_ref = {
116
+ "type": "CLUSTER",
117
+ "id": "#{cluster['configuration']['clusterExternalId']}",
118
+ "name": "#{cluster['name']}"
119
+ }
120
+ return cluster_ref
121
+
122
+ end # if cluster['name'] == name
123
+
124
+ end # clusters.each do |cluster|
125
+
126
+ end # unless clusters["items"].nil?
127
+
128
+ else
129
+ $log.error "\tError: Unable to fetch clusters."
130
+ end # case response
131
+
132
+ $log.warn "\tUnable to find a cluster which matches name #{name}."
133
+
134
+ return nil
135
+
136
+ end # def self.get_cluster_ref( name )
137
+ end
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env ruby
2
+ require "json"
3
+ require "csv"
4
+ require "idnio/idnapi"
5
+ require "idnio/program"
6
+ require "idnio/markdown"
7
+
8
+ module Roles
9
+
10
+ def self.querysearch( query )
11
+
12
+ response = IDNAPI.get( "#{$url}/v2/search/roles?offset=0&limit=10&query=#{query}", $token )
13
+
14
+ case response
15
+ when Net::HTTPSuccess
16
+
17
+ roles = JSON.parse( response.body )
18
+
19
+ unless roles.nil? || roles.empty?
20
+ return roles.first
21
+ end
22
+
23
+ end
24
+
25
+ return nil
26
+
27
+ end
28
+
29
+ #
30
+ # Exports Role configurations.
31
+ #
32
+ def self.export( directory )
33
+
34
+ response = IDNAPI.get( "#{$url}/cc/api/role/list", $token )
35
+
36
+ unless response.nil?
37
+
38
+ roles = JSON.parse( response.body )
39
+
40
+ $log.info "\tDetected #{roles['count']} roles."
41
+
42
+ roles['items'].each do |role|
43
+
44
+ apNames = ""
45
+
46
+ $log.info "\tRole: #{role["displayName"]}"
47
+
48
+ role_response = IDNAPI.get( "#{$url}/cc/api/role/get/?id=#{role["id"]}", $token )
49
+
50
+ full_role = JSON.parse( role_response.body )
51
+
52
+ full_role['accessProfileIds'].each do |ap|
53
+
54
+ response = IDNAPI.get( "#{$url}/v2/search/accessprofiles?query='id=#{ap}''", $token )
55
+
56
+ unless response.nil?
57
+ result = JSON.parse( response.body )
58
+ result.each do |r|
59
+
60
+ apNames << r['name']
61
+ apNames << ";"
62
+ end
63
+ end
64
+ end
65
+ full_role['accessProfileNames'] = apNames
66
+
67
+ Program.write_file( "#{directory}/roles/", "Role - #{full_role["displayName"]}.json", JSON.pretty_generate(full_role) )
68
+ end
69
+ end
70
+ end
71
+
72
+ #
73
+ # Import Role configurations.
74
+ #
75
+ def self.import( directory )
76
+ $log.warn "\tImport for object type roles is not supported at this time."
77
+ end
78
+
79
+ #
80
+ # Documents Role configurations.
81
+ #
82
+ def self.doc
83
+ Markdown.h2( "Roles" )
84
+
85
+ Markdown.text( "| Name | Description | Selector | Access Profiles |\n")
86
+ Markdown.text( "|------|-------------|----------|-----------------|\n")
87
+
88
+ response = IDNAPI.get( "#{$url}/cc/api/role/list", $token )
89
+ unless response.nil?
90
+ roles = JSON.parse( response.body )
91
+
92
+ $log.info "\tDetected #{roles['count']} roles."
93
+
94
+ roles['items'].each do |role|
95
+ $log.info "\tRole: #{role["displayName"]}"
96
+ role_response = IDNAPI.get( "#{$url}/cc/api/role/get/?id=#{role["id"]}", $token )
97
+ full_role = JSON.parse( role_response.body )
98
+ search_role = Roles.querysearch( "name:\"#{role["displayName"]}\"" )
99
+ accessProfileNames = ""
100
+
101
+ unless search_role["accessProfiles"].nil?
102
+ search_role["accessProfiles"].each do |ap|
103
+ if accessProfileNames != ""
104
+ accessProfileNames += ","
105
+ end
106
+ accessProfileNames += ap["name"]
107
+ end
108
+ end
109
+ #end
110
+ Markdown.text( "|#{full_role["displayName"]}|#{full_role["description"]}|#{full_role["selector"]}|#{accessProfileNames}|\n")
111
+ end
112
+ end
113
+
114
+ Markdown.write
115
+ end
116
+
117
+ end
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env ruby
2
+ require "json"
3
+ require "idnio/idnapi"
4
+ require "idnio/program"
5
+ require "idnio/markdown"
6
+
7
+ module Rules
8
+
9
+ @@default_rules = [
10
+ "AccessIQ Add Usage Certification",
11
+ "Account Report Form Customizer",
12
+ "Active Directory Customization",
13
+ "After Operation Rule Template for Web Services",
14
+ "All Objects",
15
+ "Approval Library",
16
+ "Azure AD Customization",
17
+ "Before Operation Rule Template for Web Services Connector",
18
+ "Build Manual Action Approvals",
19
+ "CEFActivityCorrelation",
20
+ "CEFTransformRule",
21
+ "Certification Report Customizer",
22
+ "Check Password Policy",
23
+ "Clear CustomGlobal",
24
+ "Cloud Account Attribute Transform",
25
+ "Cloud Account Group Refresh Rule",
26
+ "Cloud Active Phase Enter Rule",
27
+ "Cloud Approval Escalation Rule",
28
+ "Cloud Calculate Authentication Alias",
29
+ "Cloud Calculate Identity Status",
30
+ "Cloud Calculate Internal Identity Status",
31
+ "Cloud Cert Item Customization Rule",
32
+ "Cloud Certification Reassignment Rule",
33
+ "Cloud Clone Existing Account",
34
+ "Cloud Correlate Manager by AccountId",
35
+ "Cloud Detect Lifecycle State Change",
36
+ "Cloud End Phase Enter Rule",
37
+ "Cloud Flat File CustomizationRule",
38
+ "Cloud Identity Refresh Rule",
39
+ "Cloud Identity Tester",
40
+ "Cloud Promote Identity Attribute",
41
+ "CMS Cert Item Customization Rule",
42
+ "CMS Certification Reassignment Rule",
43
+ "CMS Execute Campaign Filter",
44
+ "Correct Link Idx Column",
45
+ "Create Password",
46
+ "Create Unique Account ID",
47
+ "Create Unique LDAP Attribute",
48
+ "Exclude Uncorrelated Identities",
49
+ "Execute Campaign Filter",
50
+ "Get Manager LDAP DN",
51
+ "Identity Report Form Customizer",
52
+ "IdentityNowSAML",
53
+ "JDBCProvisioning Rule Adapter",
54
+ "LCM Build Identity ApprovalSet",
55
+ "LCM Build Identity Approvers",
56
+ "LCM Build Owner Approvals",
57
+ "LCM Validate Identity Name",
58
+ "LCM Validate Password",
59
+ "LCM Workflow Library",
60
+ "Microsoft Office365 Customization",
61
+ "No Correlator",
62
+ "Objects in Requestee's Assigned Scope",
63
+ "Objects in Requestor's Authorized Scopes",
64
+ "Objects in Requestor's Authorized Scopes or Requestee's Assigned Scope",
65
+ "Objects Owned by the Requestor",
66
+ "Privileged Access Report Customizer",
67
+ "Privileged Access Report Validation Rule",
68
+ "Report Completion Notification",
69
+ "Report Scorecard Value Renderer",
70
+ "SuccessFactorsOperationProvisioning",
71
+ "System Configured Locale Rule",
72
+ "Task Completion Email Rule",
73
+ "WindowsActivityRuleLibrary",
74
+ "Workflow Library"
75
+ ]
76
+
77
+ #
78
+ # Get Rule XML
79
+ #
80
+ def self.get_xml( rule )
81
+
82
+ if rule.nil?
83
+ return nil
84
+ end
85
+
86
+ rule_xml = "<?xml version='1.0' encoding='UTF-8'?>\n<!DOCTYPE Rule PUBLIC 'sailpoint.dtd' 'sailpoint.dtd'>\n<Rule language='beanshell' name='#{rule['name']}'"
87
+
88
+ unless rule['type'].nil?
89
+ rule_xml += " type='#{rule['type']}' "
90
+ end
91
+
92
+ unless rule['description'].nil?
93
+ rule_description = rule['description'].gsub(/\t+|\s+/," ").gsub(/(\r\n)+|\r+|^\s+|\s+$|\n+?/,"")
94
+ else
95
+ rule_description = ""
96
+ end
97
+
98
+ rule_xml += ">\n\t<Description>#{rule_description}</Description>\n\t<Source><![CDATA[\n#{rule['source']}\n]]></Source>\n</Rule>"
99
+
100
+ return rule_xml
101
+ end
102
+
103
+ #
104
+ # Exports Rule configurations.
105
+ #
106
+ def self.export( directory )
107
+
108
+ response = IDNAPI.get( "#{$url}/cc/api/rule/list", $token )
109
+
110
+ case response
111
+ when Net::HTTPSuccess
112
+
113
+ rules = JSON.parse( response.body )
114
+
115
+ $log.info "\tDetected #{rules["count"]} rules."
116
+
117
+ rules["items"].each do |rule|
118
+
119
+ if (!@@default_rules.include? rule["name"]) || $config["include-defaults"]
120
+
121
+ $log.info "\tRule: #{rule["name"]}"
122
+
123
+ if rule["type"].nil?
124
+ Program.write_file( "#{directory}/rules/", "Rule - Generic - #{rule["name"]}.xml", Rules.get_xml( rule ) )
125
+ else
126
+ Program.write_file( "#{directory}/rules/", "Rule - #{rule["type"]} - #{rule["name"]}.xml", Rules.get_xml( rule ) )
127
+ end
128
+
129
+ else
130
+
131
+ $log.info "\tSkipping Default Rule: #{rule["name"]}"
132
+
133
+ end # if (!@@default_transforms.include? transform["id"]...
134
+
135
+ end # rules["items"].each do |rule|
136
+
137
+ else
138
+ $log.error "\tError: Unable to fetch rules."
139
+ end # case response
140
+
141
+ end
142
+
143
+ #
144
+ # Imports Rule configurations.
145
+ #
146
+ def self.import( directory )
147
+ $log.warn "\t Import of rules is not supported. Please contact SailPoint in order to install a rule in the system."
148
+ end
149
+
150
+ #
151
+ # Documents Rule configurations.
152
+ #
153
+ def self.doc
154
+
155
+ response = IDNAPI.get( "#{$url}/cc/api/rule/list", $token )
156
+
157
+ case response
158
+ when Net::HTTPSuccess
159
+
160
+ rules = JSON.parse( response.body )
161
+
162
+ $log.info "\tDetected #{rules["count"]} rules."
163
+
164
+ Markdown.h2 "Rules"
165
+
166
+ rules["items"].each do |rule|
167
+
168
+ if (!@@default_rules.include? rule["name"]) || $config["include-defaults"]
169
+
170
+ $log.info "\tRule: #{rule["name"]}"
171
+
172
+ if rule["type"].nil?
173
+ Markdown.h3 "#{rule["name"]} (Generic)"
174
+ else
175
+ Markdown.h3 "#{rule["name"]} (#{rule["type"]})"
176
+ end
177
+
178
+ unless rule['description'].nil?
179
+ Markdown.text "#{rule['description'].gsub(/\t+|\s+/," ").gsub(/(\r\n)+|\r+|^\s+|\s+$|\n+?/,"")}\n"
180
+ end
181
+
182
+ Markdown.xml Rules.get_xml( rule )
183
+
184
+ else
185
+
186
+ $log.info "\tSkipping Default Rule: #{rule["name"]}"
187
+
188
+ end # if (!@@default_transforms.include? transform["id"]...
189
+
190
+ end # rules["items"].each do |rule|
191
+
192
+ else
193
+ $log.error "\tError: Unable to fetch rules."
194
+ end # case response
195
+
196
+ Markdown.write
197
+ end
198
+ end