idnio 2.3.2b

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env ruby
2
+ require "json"
3
+ require "idnio/idnapi"
4
+ require "idnio/program"
5
+ require "idnio/markdown"
6
+
7
+ module Sources
8
+
9
+ #
10
+ # Query a Source for existence, by ID
11
+ #
12
+ def self.get_by_id( id )
13
+
14
+ response = IDNAPI.get( "#{$url}/beta/sources/#{id}", $token )
15
+
16
+ case response
17
+ when Net::HTTPSuccess
18
+ return JSON.parse( response.body )
19
+ else
20
+ return nil
21
+ end # case response
22
+
23
+ end
24
+
25
+ #
26
+ # Query a Source for existence, by name
27
+ #
28
+ def self.get_by_name( name )
29
+
30
+ response = IDNAPI.get( "#{$url}/beta/sources/?limit=1&offset=0&count=true&filters=name eq \"#{name}\"", $token )
31
+
32
+ case response
33
+ when Net::HTTPSuccess
34
+
35
+ if response.nil? || response['X-Total-Count'].nil?
36
+ return nil
37
+ end # if response['X-Total-Count'].nil?
38
+
39
+ count = response['X-Total-Count'].to_i
40
+
41
+ if count == 1
42
+ sources = JSON.parse( response.body )
43
+ return sources.first
44
+ end # if count == 1
45
+
46
+ else
47
+ return nil
48
+ end # case response
49
+
50
+ return nil
51
+
52
+ end
53
+
54
+ #
55
+ # This is a convenience method to get the CC ID of a source, given a source name.
56
+ #
57
+ def self.get_cc_id( name )
58
+ source = Sources.get_by_name( name )
59
+ return source['connectorAttributes']['cloudExternalId']
60
+ end
61
+
62
+ #
63
+ # Exports Source configurations.
64
+ #
65
+ def self.export( directory )
66
+
67
+ limit = 100
68
+ offset = 0
69
+ count = -1
70
+
71
+ loop do
72
+
73
+ response = IDNAPI.get( "#{$url}/beta/sources?limit=#{limit}&offset=#{offset}&count=true", $token )
74
+
75
+ case response
76
+ when Net::HTTPSuccess
77
+
78
+ # Determine the total count based what the API tells us.
79
+ if ( count < 0 && !response['X-Total-Count'].nil? )
80
+ count = response['X-Total-Count'].to_i
81
+ $log.info "\tDetected #{count} sources."
82
+ end
83
+
84
+ # If we don't have any sources, lets give up. There is nothing to do.
85
+ break if count == 0
86
+
87
+ # If we're here, we have sources to process.
88
+ sources = JSON.parse( response.body )
89
+
90
+ # Give up if our sources are null or empty. This is also a failsafe if count doesn't come back for some reason.
91
+ break if sources.nil? || sources.empty?
92
+
93
+ # Iterate through the sources list
94
+ sources.each do |source|
95
+ $log.info "\tSource: #{source["name"]}"
96
+ Program.write_file( "#{directory}/sources/", "Source - #{source["name"]}.json", JSON.pretty_generate( source ) )
97
+ end
98
+
99
+ # Setup our offset for the next iteration
100
+ offset += limit
101
+
102
+ else
103
+ $log.error "\tError: Unable to fetch sources."
104
+ end # case response
105
+
106
+ end # loop do
107
+
108
+ end # def self.export( directory )
109
+
110
+ #
111
+ # Imports Source configurations.
112
+ #
113
+ def self.import( directory )
114
+
115
+ #
116
+ # Read from the file system to determine how many source configurations we have.
117
+ #
118
+ sources = Program.read_directory("#{directory}/sources")
119
+ $log.info "\tDetected #{sources.length} sources."
120
+
121
+ #
122
+ # Iterate through each source.
123
+ #
124
+ sources.each do |source|
125
+
126
+ # Get the source JSON.
127
+ template_source = JSON.parse( source )
128
+
129
+ $log.info "\tSource: #{template_source["name"]}"
130
+
131
+ existing_source = Sources.get_by_name( template_source["name"] )
132
+
133
+ #
134
+ # If we don't have an existing source, lets create one.
135
+ #
136
+ if existing_source.nil?
137
+
138
+ $log.debug "\t\tCreating source..."
139
+
140
+ template_source[ "owner" ] = ReferenceResolver.get_identity_ref( template_source["owner"]["name"] )
141
+ template_source[ "cluster" ] = ReferenceResolver.get_default_cluster_ref
142
+ template_source[ "connector" ] = Connectors.get_script( template_source["type"] )
143
+ template_source[ "accountCorrelationConfig" ] = nil
144
+ template_source[ "schemas" ] = nil
145
+ template_source[ "passwordPolicies" ] = nil
146
+
147
+ # Clear these variables. Noticed some bugs when importing.
148
+ template_source['connectorAttributes']['cloudExternalId'] = nil
149
+
150
+ $log.debug template_source.to_json
151
+
152
+ IDNAPI.post_json( "#{$url}/beta/sources/", $token, template_source )
153
+
154
+ $log.info "\t\t\tCreated source."
155
+
156
+ #
157
+ # If we don't have an existing source, lets update the one we have.
158
+ #
159
+ else
160
+
161
+ $log.debug "\t\tUpdating source..."
162
+
163
+ template_source[ "id" ] = existing_source[ "id" ]
164
+ template_source[ "owner" ] = existing_source[ "owner" ]
165
+ template_source[ "cluster" ] = existing_source[ "cluster" ]
166
+ template_source[ "type" ] = existing_source[ "type" ]
167
+ template_source[ "connector" ] = existing_source[ "connector" ]
168
+ template_source[ "connectorClass" ] = existing_source[ "connectorClass" ]
169
+ template_source[ "accountCorrelationConfig" ] = existing_source[ "accountCorrelationConfig" ]
170
+ template_source[ "schemas" ] = existing_source[ "schemas" ]
171
+ template_source[ "passwordPolicies" ] = existing_source[ "passwordPolicies" ]
172
+
173
+ # Clear these variables. Noticed some bugs when importing.
174
+ template_source['connectorAttributes']['cloudExternalId'] = existing_source['connectorAttributes']['cloudExternalId']
175
+
176
+ IDNAPI.put_json( "#{$url}/beta/sources/#{existing_source["id"]}", $token, template_source )
177
+
178
+ $log.info "\t\t\tUpdated source."
179
+
180
+ end # if existing_source.nil?
181
+
182
+ end # sources.each do |source|
183
+
184
+ end # def self.import( directory )
185
+
186
+ #
187
+ # Documents Source configurations.
188
+ #
189
+ def self.doc
190
+
191
+ Markdown.h2( "Sources" )
192
+
193
+ response = IDNAPI.get( "#{$url}/cc/api/source/list", $token )
194
+ unless response.nil?
195
+ sources = JSON.parse( response.body )
196
+
197
+ $log.info "\tDetected #{sources.count} sources."
198
+
199
+ Markdown.text( "| Name | Connector | Owner | Description | Features |\n")
200
+ Markdown.text( "|------|-----------|-------|-------------|----------|\n")
201
+
202
+ sources.each do |source|
203
+
204
+ $log.info "\tSource: #{source["name"]}"
205
+
206
+ features = []
207
+ if source["useForAccounts"] then features.push( "Account Aggregation" ) end
208
+ if source["useForAuthentication"] then features.push( "Authentication" ) end
209
+ if source["useForProvisioning"] then features.push( "Provisioning" ) end
210
+ if source["useForPasswordManagement"] then features.push( "Password Management" ) end
211
+ Markdown.text( "|#{source["name"]}|#{source["sourceConnectorName"]}|#{source.dig("owner", "name")}|#{source["description"]}| #{features.join(", ")} |\n")
212
+
213
+ end
214
+ end
215
+ Markdown.write
216
+ end
217
+ end
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env ruby
2
+ require "json"
3
+ require "idnio/idnapi"
4
+ require "idnio/program"
5
+ require "idnio/markdown"
6
+
7
+ module SystemSettings
8
+
9
+ #
10
+ # These are a list of attributes which are used to update.
11
+ #
12
+ @@update_attributes = [
13
+ # "adminStrongAuthRequired",
14
+ # "countryCodes",
15
+ # "emailTestAddress",
16
+ # "emailTestMode",
17
+ # "enableAutomationGeneration",
18
+ # "enableAutomaticPasswordReplay",
19
+ # "enableExternalPasswordChange",
20
+ # "enablePasswordReplay",
21
+ "kbaReqForAuthn",
22
+ "kbaReqAnswers",
23
+ "lockoutAttemptThreshold",
24
+ "lockoutTimeMinutes",
25
+ # "netmasks",
26
+ # "notifyAuthenticationSettingChange",
27
+ # "passwordReplayState",
28
+ "systemNotificationConfig",
29
+ "systemNotificationEmails",
30
+ "usageCertRequired",
31
+ "usageCertText",
32
+ "usernameEmptyText",
33
+ "usernameLabel",
34
+ "iframeWhitelist"
35
+ # "whiteList",
36
+ ]
37
+
38
+ #
39
+ # Exports System Setting configurations.
40
+ #
41
+ def self.export( directory )
42
+
43
+ response = IDNAPI.get( "#{$url}/cc/api/org/get", $token )
44
+
45
+ case response
46
+ when Net::HTTPSuccess
47
+ $log.info "\tRetreived configuration."
48
+ config = JSON.parse( response.body )
49
+ Program.write_file( "#{directory}/system-settings/", "system-settings.json", JSON.pretty_generate( config ) )
50
+ else
51
+ $log.error "\tUnable to retreive configuration."
52
+ end # case response
53
+
54
+ end
55
+
56
+ #
57
+ # Imports System Setting configurations.
58
+ #
59
+ def self.import( directory )
60
+
61
+ # Read from the file system to determine how many identity profile configurations we have.
62
+ system_settings = Program.read_directory("#{directory}/system-settings")
63
+ $log.info "\tRetreived configuration."
64
+
65
+ # Iterate through each set of settings.
66
+ # Note: We only expect one, but in theory we could have many...
67
+ system_settings.each do |system_setting|
68
+
69
+ # Get the system setting JSON.
70
+ template_settings = JSON.parse( system_setting )
71
+
72
+ # These will be the new attributes which will be sent to update things.
73
+ update_params = Hash.new
74
+
75
+ # We only want to update some things
76
+ @@update_attributes.each do |update_attribute|
77
+ update_params[update_attribute] = template_settings[update_attribute]
78
+ end
79
+
80
+ # Update the system configuration.
81
+ response = IDNAPI.post_json( "#{$url}/cc/api/org/set", $token, update_params )
82
+
83
+ case response
84
+ when Net::HTTPSuccess
85
+ $log.info "\tUpdated system settings."
86
+ else
87
+ $log.error "\tError: System settings could not be updated."
88
+ end # case response
89
+
90
+ end
91
+ end
92
+
93
+ #
94
+ # Documents System Setting configurations.
95
+ #
96
+ def self.doc
97
+
98
+ response = IDNAPI.get( "#{$url}/cc/api/org/get", $token )
99
+
100
+ case response
101
+ when Net::HTTPSuccess
102
+ $log.info "\tRetreived configuration."
103
+
104
+ config = JSON.parse( response.body )
105
+
106
+ Markdown.h2 "System Settings"
107
+
108
+ Markdown.h3 "Usage Agreement"
109
+
110
+ Markdown.text " - XXX : #{config['usageCertRequired']}\n"
111
+ Markdown.text " - XXX : #{config['usernameLabel']}\n"
112
+ Markdown.text " - XXX : #{config['usernameEmptyText']}\n"
113
+
114
+ Markdown.h3 "Network Settings"
115
+
116
+ Markdown.text " - XXX : #{config['netmasks']}\n"
117
+ Markdown.text " - XXX : #{config['whiteList']}\n"
118
+ Markdown.text " - XXX : #{config['countryCodes']}\n"
119
+
120
+ Markdown.h3 "System Features"
121
+
122
+ Markdown.text " - XXX : #{config['features']}\n"
123
+
124
+ Markdown.h3 "Notifications"
125
+
126
+ Markdown.text " - Email 'from' Address: #{config['emailFromAddress']}\n"
127
+
128
+ Markdown.text " - XXX : #{config['emailTestMode']}\n"
129
+
130
+
131
+ Markdown.text " - XXX : #{config['emailTestAddress']}\n"
132
+
133
+ Markdown.h3 "Security Settings"
134
+
135
+ # Lockout Management
136
+
137
+ ## Sign In Lockout Settings
138
+
139
+ ### Maximum Attempts
140
+
141
+ ### Minutes until attempt count resets
142
+
143
+ Markdown.text " - XXX : #{config['lockoutAttemptThreshold']}\n"
144
+
145
+ ### Minutes until user locked out
146
+
147
+ Markdown.text " - XXX : #{config['lockoutTimeMinutes']}\n"
148
+
149
+ ## Password Reset Lockout Settings
150
+
151
+ ### Maximum Attempts
152
+
153
+ ### Minutes until user locked out
154
+
155
+ # Session Management
156
+
157
+ ## Maximum Session Length
158
+
159
+ ### End the Session when the browser is closed (enabled/disabled)
160
+
161
+ ## Idle Session Expiration
162
+
163
+ ### X hours
164
+
165
+ Markdown.text " - XXX : #{config['iframeWhitelist']}\n"
166
+ Markdown.text " - XXX : #{config['kbaReqAnswers']}\n"
167
+ Markdown.text " - XXX : #{config['kbaReqForAuthn']}\n"
168
+
169
+ Markdown.text " - KBA Attributes Required for Authentication: #{config['kbaReqForAuthn']}\n"
170
+
171
+ #
172
+ #
173
+ # Markdown.text "Attributes:\n"
174
+ # config['attributes'].each do |attribute|
175
+ # Markdown.text "- #{attribute['name']}\n"
176
+ # end
177
+
178
+ else
179
+ $log.error "\tUnable to retreive configuration."
180
+ end
181
+
182
+ Markdown.write
183
+ end
184
+
185
+ end
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env ruby
2
+ require "json"
3
+ require "uri"
4
+ require "idnio/idnapi"
5
+ require "idnio/program"
6
+ require "idnio/markdown"
7
+ #require "idnio/defaults"
8
+ #require_relative "../markdown.rb"
9
+
10
+ module Transforms
11
+
12
+ @@default_transforms = [
13
+ "ToUpper",
14
+ "ISO3166 Country Format",
15
+ "Remove Diacritical Marks",
16
+ "E.164 Phone Format",
17
+ "ToLower",
18
+ "ISO3166 Alpha-2"
19
+ ]
20
+
21
+ #
22
+ # Get a Transform by its ID.
23
+ #
24
+ def self.get_by_id( id )
25
+ response = IDNAPI.get( URI.escape("#{$url}/cc/api/transform/get/#{id}"), $token )
26
+ case response
27
+ when Net::HTTPSuccess
28
+ return JSON.parse( response.body )
29
+ else
30
+ return nil
31
+ end
32
+ end
33
+
34
+ #
35
+ # Exports Transform configurations.
36
+ #
37
+ def self.export( directory )
38
+
39
+ response = IDNAPI.get( "#{$url}/cc/api/transform/list", $token )
40
+
41
+ case response
42
+ when Net::HTTPSuccess
43
+
44
+ transforms = JSON.parse( response.body )
45
+
46
+ $log.info "\tDetected #{transforms["count"]} transforms."
47
+
48
+ transforms["items"].each do |transform|
49
+
50
+ if (!@@default_transforms.include? transform["id"] || $config["include-defaults"])
51
+
52
+ $log.info "\tTransform: #{transform["id"]}"
53
+ Program.write_file( "#{directory}/transforms/", "Transform - #{transform["id"]}.json", JSON.pretty_generate( transform ) )
54
+
55
+ else
56
+
57
+ $log.info "\tSkipping Default Transform: #{transform["id"]}"
58
+
59
+ end # if (!@@default_transforms.include? transform["id"]...
60
+
61
+ end # transforms["items"].each do |transform|
62
+
63
+ else
64
+ $log.error "\tError: Unable to fetch transforms."
65
+ end # case response
66
+
67
+ end
68
+
69
+ #
70
+ # Imports Transform configurations.
71
+ #
72
+ def self.import( directory )
73
+
74
+ # Read from the file system to determine how many transforms we have.
75
+ transforms = Program.read_directory( "#{directory}/transforms" )
76
+ $log.info "\tDetected #{transforms.length} transforms."
77
+
78
+ # Iterate through each transform.
79
+ transforms.each do |transform|
80
+
81
+ # Get the transform JSON.
82
+ template_transform = JSON.parse( transform )
83
+
84
+ $log.info "\tTransform: #{template_transform["id"]}"
85
+
86
+ existing_transform = Transforms.get_by_id( template_transform["id"] )
87
+
88
+ # If we don't have an existing transform, lets create one.
89
+ if existing_transform.nil?
90
+
91
+ # Is this a default transform? If so, skip it.
92
+ unless (@@default_transforms.include? template_transform["id"])
93
+
94
+ $log.debug "\t\tCreating transform..."
95
+
96
+ IDNAPI.post_json( "#{$url}/cc/api/transform/create", $token, template_transform )
97
+
98
+ else
99
+ $log.info "\t\tSkipping default transform."
100
+ end
101
+
102
+ # If we don't have an existing transform, lets update the one we have.
103
+ else
104
+
105
+ # Is this a default transform? If so, skip it.
106
+ unless (@@default_transforms.include? template_transform["id"])
107
+
108
+ $log.debug "\t\tUpdating transform..."
109
+
110
+ IDNAPI.post_json( "#{$url}/cc/api/transform/update", $token, template_transform )
111
+
112
+ else
113
+ $log.info "\t\tSkipping default transform."
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ #
120
+ # Documents Transform configurations.
121
+ #
122
+ def self.doc
123
+
124
+ response = IDNAPI.get( "#{$url}/cc/api/transform/list", $token )
125
+
126
+ case response
127
+ when Net::HTTPSuccess
128
+
129
+ transforms = JSON.parse( response.body )
130
+
131
+ $log.info "\tDetected #{transforms["count"]} transforms."
132
+
133
+ Markdown.h2( "Transforms" )
134
+
135
+ transforms["items"].each do |transform|
136
+
137
+ if (!@@default_transforms.include? transform["id"] || $config["include-defaults"])
138
+
139
+ $log.info "\tTransform: #{transform["id"]}"
140
+ Markdown.h3( transform["id"] )
141
+ Markdown.json( JSON.pretty_generate( transform ) )
142
+
143
+ else
144
+
145
+ $log.info "\tSkipping Default Transform: #{transform["id"]}"
146
+
147
+ end # if (!@@default_transforms.include? transform["id"]...
148
+
149
+ end # transforms["items"].each do |transform|
150
+
151
+ else
152
+ $log.error "\tError: Unable to fetch transforms."
153
+ end # case response
154
+
155
+ Markdown.write
156
+ end
157
+ end