idnio 2.3.2b
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/idnio.rb +295 -0
- data/lib/idnio/crypto.rb +34 -0
- data/lib/idnio/idnapi.rb +158 -0
- data/lib/idnio/markdown.rb +345 -0
- data/lib/idnio/program.rb +153 -0
- data/lib/idnio/timer.rb +57 -0
- data/lib/idnio/version.rb +4 -0
- data/lib/objects/access-profiles.rb +107 -0
- data/lib/objects/access-request-config.rb +90 -0
- data/lib/objects/account-profiles.rb +167 -0
- data/lib/objects/account-schemas.rb +341 -0
- data/lib/objects/applications.rb +145 -0
- data/lib/objects/attribute-sync-config.rb +122 -0
- data/lib/objects/branding.rb +49 -0
- data/lib/objects/campaign-filters.rb +61 -0
- data/lib/objects/connectors.rb +291 -0
- data/lib/objects/email-templates.rb +226 -0
- data/lib/objects/identity-attributes.rb +136 -0
- data/lib/objects/identity-profiles.rb +206 -0
- data/lib/objects/integrations.rb +149 -0
- data/lib/objects/lifecycle-states.rb +86 -0
- data/lib/objects/password-policies.rb +107 -0
- data/lib/objects/password-sync-groups.rb +100 -0
- data/lib/objects/public-identities-config.rb +78 -0
- data/lib/objects/reference-resolver.rb +137 -0
- data/lib/objects/roles.rb +117 -0
- data/lib/objects/rules.rb +198 -0
- data/lib/objects/sources.rb +217 -0
- data/lib/objects/system-settings.rb +185 -0
- data/lib/objects/transforms.rb +157 -0
- metadata +124 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a338413e2b8be16c9974354d15d8bc953e54a3378601a62c07e9609d29c63bb9
|
4
|
+
data.tar.gz: e5c86b39c1e50cf90d652c77957065bc4caeaa28531d0527991fdec6d5344680
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e3b13ab5922d07ba762603c50ff6d783eaa88f485dc925ddfe34fa3551d15411505085ed2adbb90de81d4080d4bf1b2e95b8b4264f9ebe1d0198f7879935ec1e
|
7
|
+
data.tar.gz: 2ef7893e6c0fe821d1b198cca854ace82ad5b8c656ad129e026e705cad6d06dd88d6ea094aca05ff3188c156410ab0dcb84c1f97a87160086690c39b8ce7adae
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
Binary file
|
data/lib/idnio.rb
ADDED
@@ -0,0 +1,295 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'logger'
|
3
|
+
require "date"
|
4
|
+
require "idnio/version"
|
5
|
+
require "idnio/program"
|
6
|
+
require "idnio/markdown"
|
7
|
+
require "objects/transforms"
|
8
|
+
require "objects/system-settings"
|
9
|
+
require "objects/sources"
|
10
|
+
require "objects/account-schemas"
|
11
|
+
require "objects/account-profiles"
|
12
|
+
require "objects/access-profiles"
|
13
|
+
require "objects/applications"
|
14
|
+
require "objects/attribute-sync-config"
|
15
|
+
require "objects/branding"
|
16
|
+
require "objects/campaign-filters"
|
17
|
+
require "objects/connectors"
|
18
|
+
require "objects/email-templates"
|
19
|
+
require "objects/identity-attributes"
|
20
|
+
require "objects/identity-profiles"
|
21
|
+
require "objects/integrations"
|
22
|
+
require "objects/lifecycle-states"
|
23
|
+
require "objects/password-policies"
|
24
|
+
require "objects/password-sync-groups"
|
25
|
+
require "objects/public-identities-config"
|
26
|
+
require "objects/access-request-config"
|
27
|
+
require "objects/reference-resolver"
|
28
|
+
require "objects/roles"
|
29
|
+
require "objects/rules"
|
30
|
+
|
31
|
+
module IDNIO
|
32
|
+
|
33
|
+
$config = nil
|
34
|
+
|
35
|
+
$log = Logger.new(STDOUT)
|
36
|
+
$log.level = Logger::WARN
|
37
|
+
$log.datetime_format = '%Y-%m-%d %H:%M:%S'
|
38
|
+
$log.formatter = proc do |severity, datetime, progname, msg|
|
39
|
+
"#{msg}\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.setConfig(config)
|
43
|
+
$config = config
|
44
|
+
|
45
|
+
unless $config["log-level"].nil?
|
46
|
+
$log.level = $config["log-level"]
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.docs()
|
52
|
+
|
53
|
+
#
|
54
|
+
# Program Start / Version
|
55
|
+
#
|
56
|
+
Program.start( "IdentityNow I/O Documenter", "Neil McGlennon, Dustin Yeager", Idnio::VERSION, Idnio::UPDATE_DATE )
|
57
|
+
|
58
|
+
#
|
59
|
+
# Constants
|
60
|
+
#
|
61
|
+
$output = File.join( $config['output-directory'], $tenant, "README.md")
|
62
|
+
|
63
|
+
#
|
64
|
+
# Initialize Markdown
|
65
|
+
#
|
66
|
+
Markdown.open( $output )
|
67
|
+
Markdown.text( "![SailPoint](https://files.accessiq.sailpoint.com/modules/builds/static-assets/perpetual/sailpoint/logo/1.0/sailpoint_logo_color_228x50.png)\n\n\n" )
|
68
|
+
Markdown.h1( "IdentityNow Configuration" )
|
69
|
+
Markdown.ul( [
|
70
|
+
"Generated on **#{Date.today.iso8601}**",
|
71
|
+
"Generated for **#{$tenant}**"
|
72
|
+
] )
|
73
|
+
Markdown.toc
|
74
|
+
Markdown.write
|
75
|
+
|
76
|
+
#
|
77
|
+
# Main Process
|
78
|
+
#
|
79
|
+
$config['process'].each do |key, value|
|
80
|
+
if value
|
81
|
+
Program.output( "Documenting #{key}..." )
|
82
|
+
case key
|
83
|
+
when "access-profiles"
|
84
|
+
AccessProfiles.doc
|
85
|
+
when "account-profiles"
|
86
|
+
AccountProfiles.doc
|
87
|
+
when "account-schemas"
|
88
|
+
AccountSchemas.doc
|
89
|
+
when "applications"
|
90
|
+
Applications.doc
|
91
|
+
when "attribute-sync-config"
|
92
|
+
AttributeSyncConfig.doc
|
93
|
+
when "branding"
|
94
|
+
Branding.doc
|
95
|
+
when "campaign-filters"
|
96
|
+
CampaignFilters.doc
|
97
|
+
when "connectors"
|
98
|
+
Connectors.doc
|
99
|
+
when "email-templates"
|
100
|
+
EmailTemplates.doc
|
101
|
+
when "identity-attributes"
|
102
|
+
IdentityAttributes.doc
|
103
|
+
when "identity-profiles"
|
104
|
+
IdentityProfiles.doc
|
105
|
+
when "integrations"
|
106
|
+
Integrations.doc
|
107
|
+
when "lifecycle-states"
|
108
|
+
LifecycleStates.doc
|
109
|
+
when "password-policies"
|
110
|
+
PasswordPolicies.doc
|
111
|
+
when "password-sync-groups"
|
112
|
+
PasswordSyncGroups.doc
|
113
|
+
when "roles"
|
114
|
+
Roles.doc
|
115
|
+
when "rules"
|
116
|
+
Rules.doc
|
117
|
+
when "sources"
|
118
|
+
Sources.doc
|
119
|
+
when "system-settings"
|
120
|
+
SystemSettings.doc
|
121
|
+
when "public-identities-config"
|
122
|
+
PublicIdentitiesConfig.doc
|
123
|
+
when "access-request-config"
|
124
|
+
AccessRequestConfig.doc
|
125
|
+
when "transforms"
|
126
|
+
Transforms.doc
|
127
|
+
else
|
128
|
+
$log.warn "#{key} is not a valid doc type! Skipping."
|
129
|
+
end
|
130
|
+
else
|
131
|
+
Program.output( "Skipping #{key}, since it is disabled." )
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
#
|
136
|
+
# Completion!
|
137
|
+
#
|
138
|
+
Program.end
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.import()
|
142
|
+
|
143
|
+
#
|
144
|
+
# Program Start / Version
|
145
|
+
#
|
146
|
+
Program.start( "IdentityNow I/O Importer", "Neil McGlennon, Dustin Yeager", Idnio::VERSION, Idnio::UPDATE_DATE )
|
147
|
+
|
148
|
+
#
|
149
|
+
# Constants
|
150
|
+
#
|
151
|
+
$input = File.join( $config['input-directory'], $tenant )
|
152
|
+
|
153
|
+
#
|
154
|
+
# Main Process
|
155
|
+
#
|
156
|
+
$config['process'].each do |key, value|
|
157
|
+
if value
|
158
|
+
Program.output( "Importing #{key}..." )
|
159
|
+
case key
|
160
|
+
when "access-profiles"
|
161
|
+
AccessProfiles.import( $input )
|
162
|
+
when "account-profiles"
|
163
|
+
AccountProfiles.import( $input )
|
164
|
+
when "account-schemas"
|
165
|
+
AccountSchemas.import( $input )
|
166
|
+
when "applications"
|
167
|
+
Applications.import( $input )
|
168
|
+
when "attribute-sync-config"
|
169
|
+
AttributeSyncConfig.import( $input )
|
170
|
+
when "branding"
|
171
|
+
Branding.import( $input )
|
172
|
+
when "campaign-filters"
|
173
|
+
CampaignFilters.import( $input )
|
174
|
+
when "connectors"
|
175
|
+
Connectors.import( $input )
|
176
|
+
when "email-templates"
|
177
|
+
EmailTemplates.import( $input )
|
178
|
+
when "identity-attributes"
|
179
|
+
IdentityAttributes.import( $input )
|
180
|
+
when "identity-profiles"
|
181
|
+
IdentityProfiles.import( $input )
|
182
|
+
when "integrations"
|
183
|
+
Integrations.import( $input )
|
184
|
+
when "lifecycle-states"
|
185
|
+
LifecycleStates.import( $input )
|
186
|
+
when "password-policies"
|
187
|
+
PasswordPolicies.import( $input )
|
188
|
+
when "password-sync-groups"
|
189
|
+
PasswordSyncGroups.import( $input )
|
190
|
+
when "roles"
|
191
|
+
Roles.import( $input )
|
192
|
+
when "rules"
|
193
|
+
Rules.import( $input )
|
194
|
+
when "sources"
|
195
|
+
Sources.import( $input )
|
196
|
+
when "system-settings"
|
197
|
+
SystemSettings.import( $input )
|
198
|
+
when "public-identities-config"
|
199
|
+
PublicIdentitiesConfig.import( $input )
|
200
|
+
when "access-request-config"
|
201
|
+
AccessRequestConfig.import( $input )
|
202
|
+
when "transforms"
|
203
|
+
Transforms.import( $input )
|
204
|
+
else
|
205
|
+
$log.warn "#{key} is not a valid export type! Skipping."
|
206
|
+
end
|
207
|
+
else
|
208
|
+
Program.output( "Skipping #{key}, since it is disabled." )
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
#
|
213
|
+
# Completion!
|
214
|
+
#
|
215
|
+
Program.end
|
216
|
+
end
|
217
|
+
|
218
|
+
def self.export()
|
219
|
+
|
220
|
+
#
|
221
|
+
# Program Start / Version
|
222
|
+
#
|
223
|
+
Program.start( "IdentityNow I/O Exporter", "Neil McGlennon, Dustin Yeager", Idnio::VERSION, Idnio::UPDATE_DATE )
|
224
|
+
|
225
|
+
#
|
226
|
+
# Constants
|
227
|
+
#
|
228
|
+
$output = File.join( $config['output-directory'], $tenant )
|
229
|
+
|
230
|
+
#
|
231
|
+
# Main Process
|
232
|
+
#
|
233
|
+
$config['process'].each do |key, value|
|
234
|
+
if value
|
235
|
+
Program.output( "Exporting #{key}..." )
|
236
|
+
case key
|
237
|
+
when "access-profiles"
|
238
|
+
AccessProfiles.export( $output )
|
239
|
+
when "account-profiles"
|
240
|
+
AccountProfiles.export( $output )
|
241
|
+
when "account-schemas"
|
242
|
+
AccountSchemas.export( $output )
|
243
|
+
when "applications"
|
244
|
+
Applications.export( $output )
|
245
|
+
when "attribute-sync-config"
|
246
|
+
AttributeSyncConfig.export( $output )
|
247
|
+
when "branding"
|
248
|
+
Branding.export( $output )
|
249
|
+
when "campaign-filters"
|
250
|
+
CampaignFilters.export( $output)
|
251
|
+
when "connectors"
|
252
|
+
Connectors.export( $output )
|
253
|
+
when "email-templates"
|
254
|
+
EmailTemplates.export( $output )
|
255
|
+
when "identity-attributes"
|
256
|
+
IdentityAttributes.export( $output )
|
257
|
+
when "identity-profiles"
|
258
|
+
IdentityProfiles.export( $output )
|
259
|
+
when "integrations"
|
260
|
+
Integrations.export( $output )
|
261
|
+
when "lifecycle-states"
|
262
|
+
LifecycleStates.export( $output )
|
263
|
+
when "password-policies"
|
264
|
+
PasswordPolicies.export( $output )
|
265
|
+
when "password-sync-groups"
|
266
|
+
PasswordSyncGroups.export( $output )
|
267
|
+
when "roles"
|
268
|
+
Roles.export( $output )
|
269
|
+
when "rules"
|
270
|
+
Rules.export( $output )
|
271
|
+
when "sources"
|
272
|
+
Sources.export( $output )
|
273
|
+
when "system-settings"
|
274
|
+
SystemSettings.export( $output )
|
275
|
+
when "public-identities-config"
|
276
|
+
PublicIdentitiesConfig.export( $output )
|
277
|
+
when "access-request-config"
|
278
|
+
AccessRequestConfig.export( $output )
|
279
|
+
when "transforms"
|
280
|
+
Transforms.export( $output )
|
281
|
+
else
|
282
|
+
$log.warn "#{key} is not a valid export type! Skipping."
|
283
|
+
end
|
284
|
+
else
|
285
|
+
Program.output( "Skipping #{key}, since it is disabled." )
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
#
|
290
|
+
# Completion!
|
291
|
+
#
|
292
|
+
Program.end
|
293
|
+
end
|
294
|
+
|
295
|
+
end
|
data/lib/idnio/crypto.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
#
|
5
|
+
# Auxillary Cryptography classes for hashing and RSA encryption.
|
6
|
+
#
|
7
|
+
module Crypto
|
8
|
+
|
9
|
+
#
|
10
|
+
# Hashes a password given a password and a salt.
|
11
|
+
#
|
12
|
+
def self.hash_password( password, salt )
|
13
|
+
if ( password.nil? || salt.nil? )
|
14
|
+
return nil
|
15
|
+
end
|
16
|
+
|
17
|
+
return Digest::SHA256.hexdigest( password + Digest::SHA256.hexdigest( salt.downcase ) )
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Encrypts the password using RSA encryption. Used for password reset utilities.
|
22
|
+
# public_key_string must be in the format:
|
23
|
+
# "-----BEGIN PUBLIC KEY-----\nMIIBI...+QwIDAQAB\n-----END PUBLIC KEY-----"
|
24
|
+
#
|
25
|
+
def self.encrypt_password( public_key_string, password )
|
26
|
+
if ( public_key_string.nil? || password.nil? )
|
27
|
+
return nil
|
28
|
+
end
|
29
|
+
|
30
|
+
public_key = OpenSSL::PKey::RSA.new( public_key_string )
|
31
|
+
return Base64.encode64( public_key.public_encrypt( password ) )
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/lib/idnio/idnapi.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require "net/http"
|
3
|
+
require "uri"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
#
|
7
|
+
# IDN API Utility
|
8
|
+
#
|
9
|
+
module IDNAPI
|
10
|
+
|
11
|
+
#
|
12
|
+
# Utility method to call the API (for GET calls only).
|
13
|
+
#
|
14
|
+
def self.get( url, token )
|
15
|
+
|
16
|
+
$log.debug "Calling GET #{url}"
|
17
|
+
|
18
|
+
url = URI.parse( url )
|
19
|
+
http = Net::HTTP.new( url.host, url.port )
|
20
|
+
http.use_ssl = true
|
21
|
+
header = {
|
22
|
+
"Authorization": "Bearer #{token}"
|
23
|
+
}
|
24
|
+
request = Net::HTTP::Get.new( url, header )
|
25
|
+
response = http.request( request )
|
26
|
+
|
27
|
+
return analyze_response( request, response )
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Utility method to call the API for Unauthenticated POST calls only
|
33
|
+
#
|
34
|
+
def self.post_unauth( url )
|
35
|
+
|
36
|
+
$log.debug "Calling (unathenticated) POST #{url} with no data."
|
37
|
+
|
38
|
+
url = URI( url )
|
39
|
+
http = Net::HTTP.new( url.host, url.port )
|
40
|
+
http.use_ssl = true
|
41
|
+
header = {}
|
42
|
+
request = Net::HTTP::Post.new( url, header )
|
43
|
+
response = http.request( request )
|
44
|
+
|
45
|
+
return analyze_response( request, response )
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Utility method to call the API (for JSON POST calls only).
|
51
|
+
#
|
52
|
+
def self.post_json( url, token, json_object )
|
53
|
+
|
54
|
+
$log.debug "Calling POST #{url} with data: #{json_object}"
|
55
|
+
|
56
|
+
url = URI( url )
|
57
|
+
http = Net::HTTP.new( url.host, url.port )
|
58
|
+
http.use_ssl = true
|
59
|
+
header = {
|
60
|
+
"Authorization": "Bearer #{token}",
|
61
|
+
"Content-Type":"application/json",
|
62
|
+
"cache-control": "no-cache"
|
63
|
+
}
|
64
|
+
request = Net::HTTP::Post.new( url, header )
|
65
|
+
unless json_object.nil?
|
66
|
+
request.body = json_object.to_json
|
67
|
+
end
|
68
|
+
response = http.request( request )
|
69
|
+
|
70
|
+
return analyze_response( request, response )
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Utility method to call the API (for JSON POST calls only).
|
76
|
+
#
|
77
|
+
def self.put_json( url, token, json_object )
|
78
|
+
|
79
|
+
$log.debug "Calling PUT #{url} with data: #{json_object}"
|
80
|
+
|
81
|
+
url = URI( url )
|
82
|
+
http = Net::HTTP.new( url.host, url.port )
|
83
|
+
http.use_ssl = true
|
84
|
+
header = {
|
85
|
+
"Authorization": "Bearer #{token}",
|
86
|
+
"Content-Type":"application/json",
|
87
|
+
"cache-control": "no-cache"
|
88
|
+
}
|
89
|
+
request = Net::HTTP::Put.new( url, header )
|
90
|
+
request.body = json_object.to_json
|
91
|
+
response = http.request( request )
|
92
|
+
|
93
|
+
return analyze_response( request, response )
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Utility method to call the API (for form POST calls only)
|
99
|
+
#
|
100
|
+
def self.post_form( url, token, form_data )
|
101
|
+
|
102
|
+
$log.debug "Calling POST #{url} with data: #{form_data}"
|
103
|
+
|
104
|
+
url = URI( url )
|
105
|
+
http = Net::HTTP.new( url.host, url.port )
|
106
|
+
http.use_ssl = true
|
107
|
+
header = {
|
108
|
+
"Authorization": "Bearer #{token}",
|
109
|
+
"Content-Type":"application/x-www-form-urlencoded",
|
110
|
+
"cache-control": "no-cache"
|
111
|
+
}
|
112
|
+
|
113
|
+
request = Net::HTTP::Post.new( url, header )
|
114
|
+
request.body = URI.encode_www_form( form_data )
|
115
|
+
response = http.request( request )
|
116
|
+
|
117
|
+
return analyze_response( request, response )
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
#
|
122
|
+
# Utility method to analyze the responses
|
123
|
+
#
|
124
|
+
def self.analyze_response( request, response )
|
125
|
+
|
126
|
+
$log.debug( "Received response: #{response.code} #{response.message} #{response.body}")
|
127
|
+
|
128
|
+
case response
|
129
|
+
when Net::HTTPSuccess
|
130
|
+
$log.debug "Successful response recieved."
|
131
|
+
return response
|
132
|
+
when Net::HTTPForbidden
|
133
|
+
$log.fatal "Error: Forbidden. Try logging in as an admin, or stepping up auth."
|
134
|
+
abort
|
135
|
+
when Net::HTTPUnauthorized
|
136
|
+
$log.fatal "Error: The token has expired. Update your session token and try again."
|
137
|
+
abort
|
138
|
+
when Net::OpenTimeout
|
139
|
+
$log.fatal "Error: API has been unresponsive. Please retry the operation."
|
140
|
+
abort
|
141
|
+
when Net::HTTPBadRequest
|
142
|
+
$log.debug "\tError: Bad Request."
|
143
|
+
when Net::HTTPNotFound
|
144
|
+
$log.debug "\tWarning: Not Found."
|
145
|
+
when Net::HTTPServerError
|
146
|
+
$log.debug "\tError: Server Error."
|
147
|
+
else
|
148
|
+
unless response.body.nil?
|
149
|
+
$log.debug "\tError: #{ response.body }"
|
150
|
+
else
|
151
|
+
$log.debug "\tError: Unknown."
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
return response
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|