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
data/lib/idnio/timer.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#
|
2
|
+
# Time Utility
|
3
|
+
#
|
4
|
+
module Timer
|
5
|
+
@@timeStart = nil
|
6
|
+
@@timeEnd = nil
|
7
|
+
|
8
|
+
#
|
9
|
+
# Starts the timer
|
10
|
+
#
|
11
|
+
def self.start
|
12
|
+
@@timeStart = Process.clock_gettime( Process::CLOCK_MONOTONIC )
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Stops the timer
|
17
|
+
#
|
18
|
+
def self.stop
|
19
|
+
@@timeEnd = Process.clock_gettime( Process::CLOCK_MONOTONIC )
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Gets elapsed time
|
24
|
+
#
|
25
|
+
def self.elapsed
|
26
|
+
unless @@timeEnd.nil? || @@timeStart.nil?
|
27
|
+
|
28
|
+
elapsed = @@timeEnd.to_i - @@timeStart.to_i # distance between t1 and t2 in seconds
|
29
|
+
|
30
|
+
resolution = if elapsed > 29030400 # seconds in a year
|
31
|
+
[(elapsed/29030400), 'years']
|
32
|
+
elsif elapsed > 2419200
|
33
|
+
[(elapsed/2419200), 'months']
|
34
|
+
elsif elapsed > 604800
|
35
|
+
[(elapsed/604800), 'weeks']
|
36
|
+
elsif elapsed > 86400
|
37
|
+
[(elapsed/86400), 'days']
|
38
|
+
elsif elapsed > 3600 # seconds in an hour
|
39
|
+
[(elapsed/3600), 'hours']
|
40
|
+
elsif elapsed > 60
|
41
|
+
[(elapsed/60), 'minutes']
|
42
|
+
else
|
43
|
+
[elapsed, 'seconds']
|
44
|
+
end
|
45
|
+
|
46
|
+
if resolution[0] == 1
|
47
|
+
return resolution.join(' ')[0...-1]
|
48
|
+
else
|
49
|
+
return resolution.join(' ')
|
50
|
+
end
|
51
|
+
|
52
|
+
else
|
53
|
+
return nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "json"
|
3
|
+
require "idnio/idnapi"
|
4
|
+
require "idnio/program"
|
5
|
+
require "idnio/markdown"
|
6
|
+
|
7
|
+
module AccessProfiles
|
8
|
+
|
9
|
+
#
|
10
|
+
# Converts Entitlement IDs to Entitlement Names
|
11
|
+
#
|
12
|
+
def self.getEntitlements( entitlement_ids )
|
13
|
+
|
14
|
+
entitlementNames = ""
|
15
|
+
|
16
|
+
entitlement_ids.each do |entitlement_id|
|
17
|
+
|
18
|
+
response = IDNAPI.get( "#{$url}/v2/search/entitlements?query='id=#{entitlement_id}''", $token )
|
19
|
+
|
20
|
+
case response
|
21
|
+
when Net::HTTPSuccess
|
22
|
+
|
23
|
+
entitlements = JSON.parse( response.body )
|
24
|
+
|
25
|
+
entitlements.each do |entitlement|
|
26
|
+
if (entitlementNames != "")
|
27
|
+
entitlementNames << ";"
|
28
|
+
end
|
29
|
+
entitlementNames << entitlement['name']
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
return entitlementNames
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Exports Access Profile configurations.
|
40
|
+
#
|
41
|
+
def self.export( directory )
|
42
|
+
|
43
|
+
response = IDNAPI.get( "#{$url}/cc/api/accessProfile/list", $token )
|
44
|
+
|
45
|
+
case response
|
46
|
+
when Net::HTTPSuccess
|
47
|
+
|
48
|
+
accessProfiles = JSON.parse( response.body )
|
49
|
+
|
50
|
+
$log.info "\tDetected #{accessProfiles['count']} access profiles."
|
51
|
+
|
52
|
+
accessProfiles['items'].each do |accessProfile|
|
53
|
+
|
54
|
+
$log.info "\tAccess Profile: #{accessProfile["name"]}"
|
55
|
+
|
56
|
+
accessProfile['entitlementNames'] = AccessProfiles.getEntitlements( accessProfile['entitlements'] )
|
57
|
+
|
58
|
+
Program.write_file( "#{directory}/access-profiles/", "Access Profile - #{accessProfile["name"]}.json", JSON.pretty_generate( accessProfile ) )
|
59
|
+
|
60
|
+
end # transforms["items"].each do |transform|
|
61
|
+
|
62
|
+
else
|
63
|
+
$log.error "\tError: Unable to fetch access profiles."
|
64
|
+
end # case response
|
65
|
+
|
66
|
+
end # def self.export( directory )
|
67
|
+
|
68
|
+
#
|
69
|
+
# Imports Access Profile configurations.
|
70
|
+
#
|
71
|
+
def self.import( directory )
|
72
|
+
$log.warn "\tImport for object type access-profiles is not supported at this time."
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Documents Access Profile configurations.
|
77
|
+
#
|
78
|
+
def self.doc
|
79
|
+
|
80
|
+
response = IDNAPI.get( "#{$url}/cc/api/accessProfile/list", $token )
|
81
|
+
|
82
|
+
case response
|
83
|
+
when Net::HTTPSuccess
|
84
|
+
|
85
|
+
accessProfiles = JSON.parse( response.body )
|
86
|
+
|
87
|
+
$log.info "\tDetected #{accessProfiles['count']} access profiles."
|
88
|
+
|
89
|
+
Markdown.h2( "Access Profiles" )
|
90
|
+
Markdown.text( "| Name | Description | Entitlements | Requestable |\n")
|
91
|
+
Markdown.text( "|------|-------------|--------------|-------------|\n")
|
92
|
+
|
93
|
+
accessProfiles['items'].each do |accessProfile|
|
94
|
+
|
95
|
+
$log.info "\tAccess Profile: #{accessProfile["name"]}"
|
96
|
+
Markdown.text( "|#{accessProfile["name"]}|#{accessProfile["description"]}|#{accessProfile["sourceName"]}: #{AccessProfiles.getEntitlements(accessProfile["entitlements"])}|#{accessProfile["requestable"]}|\n")
|
97
|
+
|
98
|
+
end # transforms["items"].each do |transform|
|
99
|
+
|
100
|
+
else
|
101
|
+
$log.error "\tError: Unable to fetch access profiles."
|
102
|
+
end # case response
|
103
|
+
|
104
|
+
Markdown.write
|
105
|
+
end # def self.doc
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "json"
|
3
|
+
require "uri"
|
4
|
+
require "idnio/idnapi"
|
5
|
+
require "idnio/program"
|
6
|
+
require "idnio/markdown"
|
7
|
+
|
8
|
+
module AccessRequestConfig
|
9
|
+
|
10
|
+
#
|
11
|
+
# Exports Access Request Config
|
12
|
+
#
|
13
|
+
def self.export( directory )
|
14
|
+
|
15
|
+
response = IDNAPI.get( "#{$url}/beta/access-request-config/", $token )
|
16
|
+
case response
|
17
|
+
when Net::HTTPSuccess
|
18
|
+
$log.info "\tRetreived configuration."
|
19
|
+
config = JSON.parse( response.body )
|
20
|
+
Program.write_file( "#{directory}/access-request-config/", "access-request-config.json", JSON.pretty_generate( config ) )
|
21
|
+
else
|
22
|
+
$log.error "\tUnable to retreive configuration."
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Imports Access Request Config
|
29
|
+
#
|
30
|
+
def self.import( directory )
|
31
|
+
|
32
|
+
# Read from the file system to determine how many configs we have. We should really only have one.
|
33
|
+
configs = Program.read_directory( "#{directory}/access-request-config/" )
|
34
|
+
$log.info "\tRetreived configuration."
|
35
|
+
|
36
|
+
# Iterate through each transform.
|
37
|
+
configs.each do |config|
|
38
|
+
|
39
|
+
$log.debug "\tResolving fallback approver..."
|
40
|
+
|
41
|
+
unless config['approvalReminderAndEscalationConfig']['fallbackApproverRef'].nil? || config['approvalReminderAndEscalationConfig']['fallbackApproverRef']['name'].nil?
|
42
|
+
config['approvalReminderAndEscalationConfig']['fallbackApproverRef'] = ReferenceResolver.get_identity_ref( config['approvalReminderAndEscalationConfig']['fallbackApproverRef']['name'] )
|
43
|
+
end
|
44
|
+
|
45
|
+
$log.debug "\tImporting access request config..."
|
46
|
+
|
47
|
+
response = IDNAPI.put_json( "#{$url}/beta/access-request-config/", $token, JSON.parse( config ) )
|
48
|
+
|
49
|
+
case response
|
50
|
+
when Net::HTTPSuccess
|
51
|
+
$log.info "\tUpdated access request config."
|
52
|
+
else
|
53
|
+
$log.error "\tUnable to import access request config."
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Documents Access Request Config
|
60
|
+
#
|
61
|
+
def self.doc
|
62
|
+
|
63
|
+
Markdown.h2( "Access Request Config" )
|
64
|
+
|
65
|
+
response = IDNAPI.get( "#{$url}/beta/access-request-config/", $token )
|
66
|
+
case response
|
67
|
+
when Net::HTTPSuccess
|
68
|
+
$log.info "\tRetreived configuration."
|
69
|
+
|
70
|
+
config = JSON.parse( response.body )
|
71
|
+
|
72
|
+
Markdown.h3( "Request Settings" )
|
73
|
+
Markdown.text "- Allow requests on behalf of anyone, by anyone: #{config['requestOnBehalfOfConfig']['allowRequestOnBehalfOfAnyoneByAnyone']}\n"
|
74
|
+
Markdown.text "- Allow requests on behalf of employees, by manager: #{config['requestOnBehalfOfConfig']['allowRequestOnBehalfOfEmployeeByManager']}\n"
|
75
|
+
|
76
|
+
Markdown.h3( "Approval and Reminders" )
|
77
|
+
Markdown.text "- Days until escalation: #{config['approvalReminderAndEscalationConfig']['daysUntilEscalation']}\n"
|
78
|
+
Markdown.text "- Days between reminders: #{config['approvalReminderAndEscalationConfig']['daysBetweenReminders']}\n"
|
79
|
+
Markdown.text "- Maximum reminders: #{config['approvalReminderAndEscalationConfig']['maxReminders']}\n"
|
80
|
+
unless config['approvalReminderAndEscalationConfig']['fallbackApproverRef'].nil?
|
81
|
+
Markdown.text "- Fallback approver: #{config['approvalReminderAndEscalationConfig']['fallbackApproverRef']['name']}\n"
|
82
|
+
end
|
83
|
+
|
84
|
+
else
|
85
|
+
$log.error "\tUnable to retreive configuration."
|
86
|
+
end
|
87
|
+
|
88
|
+
Markdown.write
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "json"
|
3
|
+
require "idnio/idnapi"
|
4
|
+
require "idnio/program"
|
5
|
+
require "idnio/markdown"
|
6
|
+
|
7
|
+
module AccountProfiles
|
8
|
+
|
9
|
+
#
|
10
|
+
# Exports Account Profile configurations.
|
11
|
+
#
|
12
|
+
def self.export( directory )
|
13
|
+
|
14
|
+
response = IDNAPI.get( "#{$url}/cc/api/source/list", $token )
|
15
|
+
|
16
|
+
case response
|
17
|
+
when Net::HTTPSuccess
|
18
|
+
|
19
|
+
sources = JSON.parse( response.body )
|
20
|
+
|
21
|
+
$log.info "\tDetected #{sources.count} account profiles, across #{sources.count} sources."
|
22
|
+
|
23
|
+
sources.each do |source|
|
24
|
+
|
25
|
+
response = IDNAPI.get( "#{$url}/cc/api/accountProfile/list/#{source["id"]}", $token )
|
26
|
+
|
27
|
+
case response
|
28
|
+
when Net::HTTPSuccess
|
29
|
+
|
30
|
+
accountProfiles = JSON.parse( response.body )
|
31
|
+
|
32
|
+
accountProfiles.each do |accountProfile|
|
33
|
+
|
34
|
+
$log.info "\tAccount Profile: #{source["name"]} - #{accountProfile["name"]} - #{accountProfile["usage"]}"
|
35
|
+
Program.write_file( "#{directory}/account-profiles/", "Account Profile - #{source["name"]} - #{accountProfile["name"]} - #{accountProfile["usage"]}.json", JSON.pretty_generate( accountProfile ) )
|
36
|
+
|
37
|
+
end # accountProfiles.each do |accountProfile|
|
38
|
+
|
39
|
+
else
|
40
|
+
$log.error "\tError: Unable to fetch account profile for source #{source["name"]}."
|
41
|
+
end # case response
|
42
|
+
|
43
|
+
end # sources.each do |source|
|
44
|
+
|
45
|
+
else
|
46
|
+
$log.error "\tError: Unable to fetch sources, for account profiles."
|
47
|
+
end # case response
|
48
|
+
|
49
|
+
end # def self.export( directory )
|
50
|
+
|
51
|
+
#
|
52
|
+
# Imports Account Profile configurations.
|
53
|
+
#
|
54
|
+
def self.import( directory )
|
55
|
+
|
56
|
+
#
|
57
|
+
# Read from the file system to determine how many account profiles we have.
|
58
|
+
#
|
59
|
+
objects = []
|
60
|
+
Dir.glob("#{directory}/account-profiles/*.json").each do |file|
|
61
|
+
object = {
|
62
|
+
"file" => file,
|
63
|
+
"source" => File.basename( file, ".json" ).split(/\W?-\W?/)[1],
|
64
|
+
"name" => File.basename( file, ".json" ).split(/\W?-\W?/)[2],
|
65
|
+
"usage" => File.basename( file, ".json" ).split(/\W?-\W?/)[3]
|
66
|
+
}
|
67
|
+
objects.push( object )
|
68
|
+
end
|
69
|
+
|
70
|
+
$log.info "\tDetected #{objects.count} account profiles."
|
71
|
+
|
72
|
+
#
|
73
|
+
# Iterate through each account profile.
|
74
|
+
#
|
75
|
+
objects.each do |object|
|
76
|
+
|
77
|
+
$log.info "\tAccount Profile: #{object['source']} - #{object['name']} - #{object['usage']}"
|
78
|
+
|
79
|
+
#
|
80
|
+
# Get the account profile JSON.
|
81
|
+
#
|
82
|
+
template_account_profile = JSON.parse( File.read( object['file'] ) )
|
83
|
+
|
84
|
+
#
|
85
|
+
# Lookup the existing source.
|
86
|
+
#
|
87
|
+
existing_source_id = Sources.get_cc_id( object['source'] )
|
88
|
+
|
89
|
+
unless existing_source_id.nil? || template_account_profile.nil?
|
90
|
+
|
91
|
+
$log.debug "\t\tUpdating account profile..."
|
92
|
+
|
93
|
+
IDNAPI.post_json( "#{$url}/cc/api/accountProfile/update/#{existing_source_id}?usage=#{object['usage']}", $token, template_account_profile )
|
94
|
+
|
95
|
+
$log.info "\t\tUpdate complete."
|
96
|
+
|
97
|
+
else
|
98
|
+
$log.warn "\t\tSkipping account profile creation. Source [#{object['source']}] does not exist.\n"
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Documents Account Profile configurations.
|
107
|
+
#
|
108
|
+
def self.doc
|
109
|
+
|
110
|
+
response = IDNAPI.get( "#{$url}/cc/api/source/list", $token )
|
111
|
+
|
112
|
+
case response
|
113
|
+
when Net::HTTPSuccess
|
114
|
+
|
115
|
+
sources = JSON.parse( response.body )
|
116
|
+
|
117
|
+
$log.info "\tDetected #{sources.count} account profiles, across #{sources.count} sources."
|
118
|
+
|
119
|
+
Markdown.h2( "Account Profiles" )
|
120
|
+
|
121
|
+
sources.each do |source|
|
122
|
+
|
123
|
+
response = IDNAPI.get( "#{$url}/cc/api/accountProfile/list/#{source["id"]}", $token )
|
124
|
+
|
125
|
+
case response
|
126
|
+
when Net::HTTPSuccess
|
127
|
+
|
128
|
+
accountProfiles = JSON.parse( response.body )
|
129
|
+
|
130
|
+
accountProfiles.each do |accountProfile|
|
131
|
+
|
132
|
+
$log.info "\tAccount Profile: #{source["name"]} - #{accountProfile["name"]} - #{accountProfile["usage"]}"
|
133
|
+
Markdown.h3 "#{source["name"]} #{accountProfile["usage"]} #{accountProfile["name"]}"
|
134
|
+
Markdown.text " - Name: #{accountProfile["name"]}\n"
|
135
|
+
Markdown.text " - Description: #{accountProfile["description"]}\n"
|
136
|
+
Markdown.text " - Usage: #{accountProfile["usage"]}\n"
|
137
|
+
Markdown.text " - Enabled: #{accountProfile["validPolicy"]}\n"
|
138
|
+
|
139
|
+
unless accountProfile["usage"].nil? || accountProfile["usage"].empty?
|
140
|
+
|
141
|
+
Markdown.text "| Name | Type | Required | Multi-valued | Transform |\n"
|
142
|
+
Markdown.text "|------|------|----------|--------------|-----------|\n"
|
143
|
+
|
144
|
+
accountProfile["fields"].each do |field|
|
145
|
+
|
146
|
+
Markdown.text "|#{field['name']}|#{field['type']}|#{field['isRequired']}|#{field['multi']}|#{field['transform']}|\n"
|
147
|
+
|
148
|
+
end # accountProfile["fields"].each do |field|
|
149
|
+
|
150
|
+
end # unless accountProfile["usage"].nil? ...
|
151
|
+
|
152
|
+
end # accountProfiles.each do |accountProfile|
|
153
|
+
|
154
|
+
else
|
155
|
+
$log.error "\tError: Unable to fetch account profile for source #{source["name"]}."
|
156
|
+
end # case response
|
157
|
+
|
158
|
+
end # sources.each do |source|
|
159
|
+
|
160
|
+
else
|
161
|
+
$log.error "\tError: Unable to fetch sources, for account profiles."
|
162
|
+
end # case response
|
163
|
+
|
164
|
+
Markdown.write
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
@@ -0,0 +1,341 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'json'
|
3
|
+
require "idnio/idnapi"
|
4
|
+
require "idnio/program"
|
5
|
+
require "idnio/markdown"
|
6
|
+
|
7
|
+
module AccountSchemas
|
8
|
+
|
9
|
+
@@account_schema_cache = {}
|
10
|
+
|
11
|
+
def self.get_existing_schema_attribute( id, attribute_name )
|
12
|
+
|
13
|
+
unless id.nil? || attribute_name.nil?
|
14
|
+
|
15
|
+
existing_account_schema = AccountSchemas.get_by_id( id )
|
16
|
+
|
17
|
+
unless existing_account_schema.nil?
|
18
|
+
|
19
|
+
existing_account_schema['attributes'].each do |existing_attribute|
|
20
|
+
|
21
|
+
if existing_attribute['name'] == attribute_name
|
22
|
+
return existing_attribute
|
23
|
+
end # existing_attribute['name'] == attribute_name
|
24
|
+
|
25
|
+
end # existing_account_schema['attributes'].each do |existing_attribute|
|
26
|
+
|
27
|
+
end # unless existing_account_schema.nil?
|
28
|
+
|
29
|
+
end # unless id.nil? || attribute_name.nil?
|
30
|
+
|
31
|
+
return nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.get_by_id( id )
|
35
|
+
|
36
|
+
unless @@account_schema_cache.key?( id )
|
37
|
+
|
38
|
+
response = IDNAPI.get( "#{$url}/cc/api/source/getAccountSchema/#{id}", $token )
|
39
|
+
|
40
|
+
case response
|
41
|
+
when Net::HTTPSuccess
|
42
|
+
@@account_schema_cache[id] = JSON.parse( response.body )
|
43
|
+
else
|
44
|
+
@@account_schema_cache[id] = nil
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
return @@account_schema_cache[id]
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Creates a Schema Attribute
|
54
|
+
#
|
55
|
+
def self.create( id, attribute )
|
56
|
+
|
57
|
+
$log.debug "\t\t\tCreating attribute."
|
58
|
+
|
59
|
+
form_data = {
|
60
|
+
'name' => attribute['name'],
|
61
|
+
'description' => attribute['description'],
|
62
|
+
'type' => attribute['type'],
|
63
|
+
'objectType' => 'account',
|
64
|
+
'entitlement' => attribute['entitlement'],
|
65
|
+
'identityAttribute' => attribute['identityAttribute'],
|
66
|
+
'managed' => attribute['managed'],
|
67
|
+
'multi' => attribute['multi'],
|
68
|
+
'displayAttribute' => attribute['displayAttribute']
|
69
|
+
}
|
70
|
+
|
71
|
+
response = IDNAPI.post_form( "#{$url}/cc/api/source/createSchemaAttribute/#{id}", $token, form_data )
|
72
|
+
|
73
|
+
case response
|
74
|
+
when Net::HTTPSuccess
|
75
|
+
$log.debug "\t\tAttribute [#{attribute['name']}] successfully created."
|
76
|
+
else
|
77
|
+
$log.debug "\t\tError: Attribute [#{attribute['name']}] could not be successfully created."
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Updates a Schema Attribute
|
83
|
+
#
|
84
|
+
def self.update( id, attribute )
|
85
|
+
|
86
|
+
$log.debug "\t\t\tUpdating attribute."
|
87
|
+
|
88
|
+
existing_attribute = AccountSchemas.get_existing_schema_attribute( id, attribute['name'] )
|
89
|
+
|
90
|
+
#
|
91
|
+
# The API only supports updating certain properties of an attribute. The descriptions, name, type cannot be updated.
|
92
|
+
#
|
93
|
+
|
94
|
+
# Check 'entitlement's
|
95
|
+
unless ( attribute['entitlement'] == existing_attribute['entitlement'] )
|
96
|
+
|
97
|
+
form_data = {
|
98
|
+
'objectType': 'account',
|
99
|
+
'names': existing_attribute['name'],
|
100
|
+
'fieldName': 'entitlement',
|
101
|
+
'fieldValue': attribute['entitlement']
|
102
|
+
}
|
103
|
+
|
104
|
+
response = IDNAPI.post_form( "#{$url}/cc/api/source/updateSchemaAttributes/#{id}", $token, form_data )
|
105
|
+
|
106
|
+
case response
|
107
|
+
when Net::HTTPSuccess
|
108
|
+
$log.debug "\t\t\tAttribute [#{attribute['name']}] updated 'entitlement' property."
|
109
|
+
else
|
110
|
+
$log.debug "\t\tError: Attribute [#{attribute['name']}] could not update 'entitlement' property."
|
111
|
+
end
|
112
|
+
|
113
|
+
end # unless ( attribute['entitlement'] == existing_attribute['entitlement'] )
|
114
|
+
|
115
|
+
# Check 'managed'
|
116
|
+
unless ( attribute['managed'] == existing_attribute['managed'] )
|
117
|
+
|
118
|
+
form_data = {
|
119
|
+
'objectType': 'account',
|
120
|
+
'names': existing_attribute['name'],
|
121
|
+
'fieldName': 'managed',
|
122
|
+
'fieldValue': attribute['managed']
|
123
|
+
}
|
124
|
+
|
125
|
+
response = IDNAPI.post_form( "#{$url}/cc/api/source/updateSchemaAttributes/#{id}", $token, form_data )
|
126
|
+
s
|
127
|
+
case response
|
128
|
+
when Net::HTTPSuccess
|
129
|
+
$log.debug "\t\t\tAttribute [#{attribute['name']}] updated 'managed' property."
|
130
|
+
else
|
131
|
+
$log.debug "\t\tError: Attribute [#{attribute['name']}] could not update 'managed' property."
|
132
|
+
end
|
133
|
+
|
134
|
+
end # unless ( attribute['managed'] == existing_attribute['managed'] )
|
135
|
+
|
136
|
+
# Check 'multi'
|
137
|
+
unless ( attribute['multi'] == existing_attribute['multi'] )
|
138
|
+
|
139
|
+
form_data = {
|
140
|
+
'objectType': 'account',
|
141
|
+
'names': existing_attribute['name'],
|
142
|
+
'fieldName': 'multi',
|
143
|
+
'fieldValue': attribute['multi']
|
144
|
+
}
|
145
|
+
|
146
|
+
response = IDNAPI.post_form( "#{$url}/cc/api/source/updateSchemaAttributes/#{id}", $token, form_data )
|
147
|
+
|
148
|
+
case response
|
149
|
+
when Net::HTTPSuccess
|
150
|
+
$log.debug "\t\t\tAttribute [#{attribute['name']}] updated 'multi' property."
|
151
|
+
else
|
152
|
+
$log.debug "\t\tError: Attribute [#{attribute['name']}] could not update 'multi' property."
|
153
|
+
end
|
154
|
+
|
155
|
+
end # unless ( attribute['multi'] == existing_attribute['multi'] )
|
156
|
+
|
157
|
+
# Check 'displayAttribute'
|
158
|
+
unless ( attribute['displayAttribute'] == existing_attribute['displayAttribute'] )
|
159
|
+
|
160
|
+
form_data = {
|
161
|
+
'objectType': 'account',
|
162
|
+
'names': existing_attribute['name'],
|
163
|
+
'fieldName': 'displayAttribute',
|
164
|
+
'fieldValue': attribute['displayAttribute']
|
165
|
+
}
|
166
|
+
|
167
|
+
response = IDNAPI.post_form( "#{$url}/cc/api/source/updateSchemaAttributes/#{id}", $token, form_data )
|
168
|
+
|
169
|
+
case response
|
170
|
+
when Net::HTTPSuccess
|
171
|
+
$log.debug "\t\t\tAttribute [#{attribute['name']}] updated 'displayAttribute' property."
|
172
|
+
else
|
173
|
+
$log.debug "\t\tError: Attribute [#{attribute['name']}] could not update 'displayAttribute' property."
|
174
|
+
end
|
175
|
+
|
176
|
+
end # unless ( attribute['displayAttribute'] == existing_attribute['displayAttribute'] )
|
177
|
+
|
178
|
+
# Check 'identityAttribute'
|
179
|
+
unless ( attribute['identityAttribute'] == existing_attribute['identityAttribute'] )
|
180
|
+
|
181
|
+
form_data = {
|
182
|
+
'objectType': 'account',
|
183
|
+
'names': existing_attribute['name'],
|
184
|
+
'fieldName': 'identityAttribute',
|
185
|
+
'fieldValue': attribute['identityAttribute']
|
186
|
+
}
|
187
|
+
|
188
|
+
response = IDNAPI.post_form( "#{$url}/cc/api/source/updateSchemaAttributes/#{id}", $token, form_data )
|
189
|
+
|
190
|
+
case response
|
191
|
+
when Net::HTTPSuccess
|
192
|
+
$log.debug "\t\t\tAttribute [#{attribute['name']}] updated 'identityAttribute' property."
|
193
|
+
else
|
194
|
+
$log.debug "\t\tError: Attribute [#{attribute['name']}] could not update 'identityAttribute' property."
|
195
|
+
end
|
196
|
+
|
197
|
+
end # unless ( attribute['identityAttribute'] == existing_attribute['identityAttribute'] )
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
#
|
202
|
+
# Exports Account Schema configurations.
|
203
|
+
#
|
204
|
+
def self.export( directory )
|
205
|
+
|
206
|
+
response = IDNAPI.get("#{$url}/cc/api/source/list", $token)
|
207
|
+
|
208
|
+
case response
|
209
|
+
when Net::HTTPSuccess
|
210
|
+
|
211
|
+
sources = JSON.parse( response.body )
|
212
|
+
|
213
|
+
unless sources.nil?
|
214
|
+
|
215
|
+
$log.info "\tDetected #{sources.count} account schemas, across #{sources.count} sources."
|
216
|
+
|
217
|
+
sources.each do |source|
|
218
|
+
|
219
|
+
$log.info "\tAccount Schema: #{source['name']}"
|
220
|
+
|
221
|
+
response = IDNAPI.get( "#{$url}/cc/api/source/getAccountSchema/#{source['id']}", $token )
|
222
|
+
|
223
|
+
case response
|
224
|
+
when Net::HTTPSuccess
|
225
|
+
|
226
|
+
account_schema = JSON.parse( response.body )
|
227
|
+
|
228
|
+
Program.write_file("#{directory}/account-schemas/", "Account Schema - #{source['name']} - #{account_schema['objectType']}.json", JSON.pretty_generate( account_schema ) )
|
229
|
+
|
230
|
+
else
|
231
|
+
$log.error "\tError: Unable to fetch account schema for source '#{source['name']}'."
|
232
|
+
end # case response
|
233
|
+
|
234
|
+
end # sources.each do |source|
|
235
|
+
|
236
|
+
end # unless sources.nil?
|
237
|
+
|
238
|
+
else
|
239
|
+
$log.error "\tError: Unable to fetch sources."
|
240
|
+
end # case response
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
#
|
245
|
+
# Imports Account Schema configurations.
|
246
|
+
#
|
247
|
+
def self.import( directory )
|
248
|
+
|
249
|
+
# Read from the file system to determine how many account profiles we have.
|
250
|
+
objects = []
|
251
|
+
Dir.glob("#{directory}/account-schemas/*.json").each do |file|
|
252
|
+
object = {
|
253
|
+
"data" => file,
|
254
|
+
"source" => File.basename( file, ".json" ).split(" - ")[1],
|
255
|
+
"objectType" => File.basename( file, ".json" ).split(" - ")[2]
|
256
|
+
}
|
257
|
+
objects.push( object )
|
258
|
+
end
|
259
|
+
|
260
|
+
$log.info "\tDetected #{objects.count} account schemas."
|
261
|
+
|
262
|
+
objects.each do |object|
|
263
|
+
|
264
|
+
$log.info "\tAccount Schema: #{object['source']} - #{object['objectType']}"
|
265
|
+
|
266
|
+
existing_source_id = Sources.get_cc_id( object['source'] )
|
267
|
+
|
268
|
+
unless existing_source_id.nil?
|
269
|
+
|
270
|
+
data = Program.read_file( object['data'] )
|
271
|
+
|
272
|
+
unless data.nil?
|
273
|
+
|
274
|
+
account_schema = JSON.parse( data )
|
275
|
+
|
276
|
+
account_schema['attributes'].each do |attribute|
|
277
|
+
|
278
|
+
$log.debug "\t\tAnalyzing attribute [#{attribute['name']}]."
|
279
|
+
|
280
|
+
existing_attribute = AccountSchemas.get_existing_schema_attribute( existing_source_id, attribute['name'] ) # Get the existing attribute
|
281
|
+
|
282
|
+
unless attribute == existing_attribute
|
283
|
+
|
284
|
+
unless existing_attribute.nil?
|
285
|
+
AccountSchemas.update( existing_source_id, attribute ) # If the existing attribute is not-null, we'll update.
|
286
|
+
else
|
287
|
+
AccountSchemas.create( existing_source_id, attribute ) # If the existing attribute is null, we'll create.
|
288
|
+
end # unless existing_attribute.nil?
|
289
|
+
|
290
|
+
else
|
291
|
+
$log.debug "\t\t\tNo action to perform."
|
292
|
+
end # attribute == existing_attribute
|
293
|
+
|
294
|
+
end # account_schema['attributes'].each do |attribute|
|
295
|
+
|
296
|
+
end # unless data.nil?
|
297
|
+
|
298
|
+
end # unless existing_source_id.nil?
|
299
|
+
|
300
|
+
end # objects.each do |object|
|
301
|
+
|
302
|
+
end
|
303
|
+
|
304
|
+
#
|
305
|
+
# Documents Account Schema configurations.
|
306
|
+
#
|
307
|
+
def self.doc
|
308
|
+
Markdown.h2( "Account Schemas" )
|
309
|
+
|
310
|
+
response = IDNAPI.get( "#{$url}/cc/api/source/list", $token )
|
311
|
+
unless response.nil?
|
312
|
+
sources = JSON.parse( response.body )
|
313
|
+
|
314
|
+
$log.info "\tDetected #{sources.count} account schemas, across #{sources.count} sources."
|
315
|
+
|
316
|
+
sources.each do |source|
|
317
|
+
|
318
|
+
accountSchema = IDNAPI.get( "#{$url}/cc/api/source/getAccountSchema/#{source["id"]}", $token )
|
319
|
+
unless accountSchema.nil?
|
320
|
+
accountSchema = JSON.parse( accountSchema.body )
|
321
|
+
$log.info "\tAccount Schema: #{source["name"]} - #{accountSchema["objectType"]}"
|
322
|
+
|
323
|
+
unless ( accountSchema["attributes"].nil? || accountSchema["attributes"].empty? )
|
324
|
+
Markdown.h3( "#{source["name"]}" )
|
325
|
+
Markdown.text( " - Object Type: #{accountSchema["objectType"]}\n" )
|
326
|
+
Markdown.text( " - Account ID: #{accountSchema["identityAttribute"]}\n" )
|
327
|
+
Markdown.text( " - Account Name: #{accountSchema["displayAttribute"]}\n" )
|
328
|
+
Markdown.text( " - Group Attribute: #{accountSchema["groupAttribute"]}\n\n" )
|
329
|
+
Markdown.text( "| Name | Description | Type | Multi-valued | Entitlement |\n" )
|
330
|
+
Markdown.text( "|------|-------------|------|--------------|-------------|\n" )
|
331
|
+
accountSchema["attributes"].each do |attribute|
|
332
|
+
Markdown.text( "|#{attribute["name"]}|#{attribute["description"]}|#{attribute["type"]}|#{attribute["entitlement"]}|#{attribute["multi"]}|\n" )
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
Markdown.write
|
340
|
+
end
|
341
|
+
end
|