idnio 2.3.2b

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.
@@ -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