identitynow_rule_validator 1.0.0b
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/lib/identitynow_rule_validator.rb +179 -0
- data/lib/program.rb +167 -0
- data/lib/rules.json +228 -0
- metadata +102 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: f72bbdbdfce7f45b1010ee5bc4f170fe219c83fd8e9b156d7b719dc912b7147d
|
|
4
|
+
data.tar.gz: 832e3afdb507f4d7d080709c209aa82edd338b82c5d281a4bc6a27909ca88206
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 86e792cc08b0964c237e725e84895883854f40e45b5ea65b5571ddfbed39438e1f872989d48561d4f0fe2508b3e4ca55b470b13c63152a416299414f406fb06b
|
|
7
|
+
data.tar.gz: 70b4295494b9129f7df960015ecd52f73744e201895de2086a2933b5d8f90f7dd86f7537afddb4dd2d6b7907e22ba2b39e69d081fb37bb5f51f971798c520d84
|
checksums.yaml.gz.sig
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
uH:B�\�o�P[�Qò9�슫Wĩz"�i����2�J(������8�xY^)๕� ��s��UUZ��en����~D����5(�yg��K��Se؎��9�g~L fuyK��dmr���d�K������=�sч+N�B��%�-����<�Vt����n�pvr�8�O���)q�A �`Z�3��TLB�'*T�i&\:
|
|
2
|
+
��_G���'�'�9ܚ��8t���H�� ]Tp�VK.ԋ$UH��x�Rn�"��$���>7� �\9+0���i��8��Ixv A�%sj��$1� 8�,wu�H�xCݢ����]f=?�r*Na��ڱ�fN�[�2��4������4��A��h�>>E_�
|
data.tar.gz.sig
ADDED
|
Binary file
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'colorize'
|
|
3
|
+
require 'program'
|
|
4
|
+
|
|
5
|
+
class IdentityNowRuleValidator
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# This will collect findings for each file.
|
|
9
|
+
#
|
|
10
|
+
@@findings = []
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# This holds details about the files.
|
|
14
|
+
#
|
|
15
|
+
@@filesCount = 0;
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
# These are the rules which are used for validation.
|
|
19
|
+
#
|
|
20
|
+
@@rules = []
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
# This will help determine if we're still showing findings for the same file.
|
|
24
|
+
#
|
|
25
|
+
@@previousFile = nil
|
|
26
|
+
|
|
27
|
+
def self.validate_directory( directory )
|
|
28
|
+
|
|
29
|
+
self.initialize
|
|
30
|
+
|
|
31
|
+
puts "Validating files from directory: #{directory}"
|
|
32
|
+
|
|
33
|
+
Dir.glob( File.join( directory + '**/*.xml' ) ).each do |file|
|
|
34
|
+
|
|
35
|
+
self.analyze_file( file )
|
|
36
|
+
|
|
37
|
+
end # files.each do |file|
|
|
38
|
+
|
|
39
|
+
self.report_findings
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.validate_files( files )
|
|
44
|
+
|
|
45
|
+
self.initialize
|
|
46
|
+
|
|
47
|
+
puts "Validating files: #{files}"
|
|
48
|
+
|
|
49
|
+
if ( !files.nil? && !files.empty? )
|
|
50
|
+
|
|
51
|
+
files.each do |file|
|
|
52
|
+
|
|
53
|
+
self.analyze_file( file )
|
|
54
|
+
|
|
55
|
+
end # files.each do |file|
|
|
56
|
+
|
|
57
|
+
end # if ( !files.nil? && !files.empty? )
|
|
58
|
+
|
|
59
|
+
self.report_findings
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.validate_file( file )
|
|
64
|
+
|
|
65
|
+
self.initialize
|
|
66
|
+
|
|
67
|
+
puts "Validating file: #{file}"
|
|
68
|
+
|
|
69
|
+
self.analyze_file( file )
|
|
70
|
+
|
|
71
|
+
self.report_findings
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def self.initialize
|
|
78
|
+
|
|
79
|
+
#
|
|
80
|
+
# Initialize findings to be empty.
|
|
81
|
+
#
|
|
82
|
+
@@findings = []
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# Initialize filesCount to be 0.
|
|
86
|
+
#
|
|
87
|
+
@@filesCount = 0;
|
|
88
|
+
|
|
89
|
+
#
|
|
90
|
+
# Initialize rules from JSON.
|
|
91
|
+
#
|
|
92
|
+
@@rules = JSON.parse( File.read( File.join( __dir__, "rules.json" ) ) )
|
|
93
|
+
|
|
94
|
+
#
|
|
95
|
+
# Initialize previous file to empty
|
|
96
|
+
#
|
|
97
|
+
@@previousFile = nil
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# Program Start / Version
|
|
101
|
+
#
|
|
102
|
+
Program.start( "IdentityNow Rule Validator", "Neil McGlennon (neil.mcglennon@sailpoint.com)", "1.0.0b", "2020-01-21" )
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def self.analyze_file( file )
|
|
107
|
+
|
|
108
|
+
#
|
|
109
|
+
# Make sure we are working with files, not directories.
|
|
110
|
+
#
|
|
111
|
+
if File.file?( file )
|
|
112
|
+
|
|
113
|
+
@@filesCount += 1;
|
|
114
|
+
puts "\t" + File.basename( file )
|
|
115
|
+
|
|
116
|
+
File.readlines( file ).each_with_index do |line, lineNumber|
|
|
117
|
+
|
|
118
|
+
@@rules.each do |rule|
|
|
119
|
+
|
|
120
|
+
if line.valid_encoding?
|
|
121
|
+
if( line.match( /#{rule['pattern']}/ ) )
|
|
122
|
+
|
|
123
|
+
finding = {
|
|
124
|
+
'file': file,
|
|
125
|
+
'line': lineNumber + 1,
|
|
126
|
+
'text': line.strip,
|
|
127
|
+
'message': rule['message'],
|
|
128
|
+
'type': rule['type']
|
|
129
|
+
}
|
|
130
|
+
@@findings.push finding
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
end # if( line.match( /#{rule['pattern']}/ ) )
|
|
134
|
+
|
|
135
|
+
end # @@rules.each do |rule|
|
|
136
|
+
|
|
137
|
+
end # File.readlines( file ).each_with_index do |line, lineNumber|
|
|
138
|
+
|
|
139
|
+
end # if File.file?( file )
|
|
140
|
+
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def self.report_findings
|
|
144
|
+
|
|
145
|
+
#
|
|
146
|
+
# Iterate through all of our findings.
|
|
147
|
+
#
|
|
148
|
+
@@findings.each do |finding|
|
|
149
|
+
|
|
150
|
+
#
|
|
151
|
+
# Output the file header
|
|
152
|
+
#
|
|
153
|
+
if ( finding[:file] != @@previousFile )
|
|
154
|
+
puts File.dirname( finding[:file] ) + "\n"
|
|
155
|
+
puts File.basename( finding[:file] ).bold + "\n\n"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
#
|
|
159
|
+
# Output the issue
|
|
160
|
+
#
|
|
161
|
+
puts "\tLine #{finding[:line]}: #{finding[:text][0..80].gsub(/\s\w+$/,'...').light_black}"
|
|
162
|
+
type = ( finding[:type] == "error" ) ? "Error".red : "Warning".yellow
|
|
163
|
+
puts "\t#{type}: #{finding[:message]}\n\n"
|
|
164
|
+
|
|
165
|
+
#
|
|
166
|
+
# Set this for the next iteration
|
|
167
|
+
#
|
|
168
|
+
@@previousFile = finding[:file]
|
|
169
|
+
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
#
|
|
173
|
+
# Completion!
|
|
174
|
+
#
|
|
175
|
+
Program.end
|
|
176
|
+
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
end
|
data/lib/program.rb
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# require "./lib/timer.rb"
|
|
2
|
+
require "json"
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# Time Utility
|
|
6
|
+
#
|
|
7
|
+
module Timer
|
|
8
|
+
@@timeStart = nil
|
|
9
|
+
@@timeEnd = nil
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# Starts the timer
|
|
13
|
+
#
|
|
14
|
+
def self.start
|
|
15
|
+
@@timeStart = Process.clock_gettime( Process::CLOCK_MONOTONIC )
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# Stops the timer
|
|
20
|
+
#
|
|
21
|
+
def self.stop
|
|
22
|
+
@@timeEnd = Process.clock_gettime( Process::CLOCK_MONOTONIC )
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Gets elapsed time
|
|
27
|
+
#
|
|
28
|
+
def self.elapsed
|
|
29
|
+
unless @@timeEnd.nil? || @@timeStart.nil?
|
|
30
|
+
|
|
31
|
+
elapsed = @@timeEnd.to_i - @@timeStart.to_i # distance between t1 and t2 in seconds
|
|
32
|
+
|
|
33
|
+
resolution = if elapsed > 29030400 # seconds in a year
|
|
34
|
+
[(elapsed/29030400), 'years']
|
|
35
|
+
elsif elapsed > 2419200
|
|
36
|
+
[(elapsed/2419200), 'months']
|
|
37
|
+
elsif elapsed > 604800
|
|
38
|
+
[(elapsed/604800), 'weeks']
|
|
39
|
+
elsif elapsed > 86400
|
|
40
|
+
[(elapsed/86400), 'days']
|
|
41
|
+
elsif elapsed > 3600 # seconds in an hour
|
|
42
|
+
[(elapsed/3600), 'hours']
|
|
43
|
+
elsif elapsed > 60
|
|
44
|
+
[(elapsed/60), 'minutes']
|
|
45
|
+
else
|
|
46
|
+
[elapsed, 'seconds']
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if resolution[0] == 1
|
|
50
|
+
return resolution.join(' ')[0...-1]
|
|
51
|
+
else
|
|
52
|
+
return resolution.join(' ')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
else
|
|
56
|
+
return nil
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#
|
|
63
|
+
# Program Utility
|
|
64
|
+
#
|
|
65
|
+
module Program
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# Utility method for printing messages.
|
|
69
|
+
#
|
|
70
|
+
def self.line( )
|
|
71
|
+
puts ( "-" * 62 )
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
#
|
|
75
|
+
# Utility method for printing messages.
|
|
76
|
+
#
|
|
77
|
+
def self.output( message )
|
|
78
|
+
Program.line
|
|
79
|
+
puts " #{message}"
|
|
80
|
+
Program.line
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Utility to start the program
|
|
85
|
+
#
|
|
86
|
+
def self.start( name, author, version, date )
|
|
87
|
+
Timer.start
|
|
88
|
+
|
|
89
|
+
Program.line
|
|
90
|
+
puts " #{name} "
|
|
91
|
+
Program.line
|
|
92
|
+
puts " Version: #{version}"
|
|
93
|
+
puts " Date: #{date}"
|
|
94
|
+
puts " Author: #{author}"
|
|
95
|
+
Program.line
|
|
96
|
+
|
|
97
|
+
$tenant = nil
|
|
98
|
+
|
|
99
|
+
unless $tenant.nil?
|
|
100
|
+
puts " Tenant: #{$tenant}"
|
|
101
|
+
Program.line
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
#
|
|
107
|
+
# Utility to end the program
|
|
108
|
+
#
|
|
109
|
+
def self.end( )
|
|
110
|
+
Timer.stop
|
|
111
|
+
output( "Process completed in #{Timer.elapsed}" )
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
# Utility method to write output files to a directory.
|
|
117
|
+
#
|
|
118
|
+
def self.write_file( directory, name, text )
|
|
119
|
+
name.gsub!(/[^0-9A-Za-z. -]/,"-")
|
|
120
|
+
FileUtils.mkdir_p directory
|
|
121
|
+
File.open( File.join( directory, name ), 'w+') { |file| file.write( text ) }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def self.get_filenames( directory )
|
|
125
|
+
output = Array.new
|
|
126
|
+
Dir.glob("#{directory}/*.json") do |file|
|
|
127
|
+
#tmp = file.slice! "#{directory}/"
|
|
128
|
+
output.push(file)
|
|
129
|
+
end
|
|
130
|
+
return output
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def self.read_directory( directory )
|
|
134
|
+
output = Array.new
|
|
135
|
+
Dir.glob("#{directory}/*.json") do |file|
|
|
136
|
+
output.push(Program.read_file(file))
|
|
137
|
+
end
|
|
138
|
+
return output
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
#
|
|
142
|
+
# Utility method to read output files to a directory.
|
|
143
|
+
#
|
|
144
|
+
def self.read_file( directory, name )
|
|
145
|
+
return Program.read_file("#{directory}/#{name}")
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def self.read_file( name )
|
|
149
|
+
output = ""
|
|
150
|
+
#name.gsub!(/[^0-9A-Za-z. -]/,"-")
|
|
151
|
+
f = File.open( name, 'r')
|
|
152
|
+
f.each_line do |line|
|
|
153
|
+
output += line
|
|
154
|
+
end
|
|
155
|
+
f.close
|
|
156
|
+
return output
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def self.write_csv(directory, name, content)
|
|
160
|
+
if !File.file?("#{directory}/#{name}")
|
|
161
|
+
Program.write_file(directory, name, "")
|
|
162
|
+
end
|
|
163
|
+
CSV.open("#{directory}/#{name}", "ab") do |csv|
|
|
164
|
+
csv << content
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
data/lib/rules.json
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
[{
|
|
2
|
+
"pattern": "System\\.(out|err)\\.print",
|
|
3
|
+
"message": "Remove any System.out configurations in favor of logging statements.",
|
|
4
|
+
"type": "warning"
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"pattern": "\\.printStackTrace\\(",
|
|
8
|
+
"message": "Detected instances of printStackTrace(...). Remove this reference.",
|
|
9
|
+
"type": "warning"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"pattern": "public static",
|
|
13
|
+
"message": "Remove references to 'static' in methods. This can cause unexpected behavior.",
|
|
14
|
+
"type": "warning"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"pattern": "(<Source>)((?!<\\!\\[CDATA\\[).)*\\s?$",
|
|
18
|
+
"message": "Correct tag to be <Source><![CDATA[",
|
|
19
|
+
"type": "warning"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"pattern": "^(\\s)?(\\<\\/Source\\>)",
|
|
23
|
+
"message": "Correct tag to be ]]></Source>",
|
|
24
|
+
"type": "warning"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"pattern": ">",
|
|
28
|
+
"message": "Detected instances of '>' Convert to '>'.",
|
|
29
|
+
"type": "warning"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"pattern": "<",
|
|
33
|
+
"message": "Detected instances of '<' Convert to '<'.",
|
|
34
|
+
"type": "warning"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"pattern": "&",
|
|
38
|
+
"message": "Detected instances of '&' Convert to '&'.",
|
|
39
|
+
"type": "warning"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"pattern": "context\\.decrypt(\\s)?\\(",
|
|
43
|
+
"message": "Remove references to 'decrypt'. This is not allowed.",
|
|
44
|
+
"type": "error"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"pattern": "context\\.commitTransaction(\\s)?\\(",
|
|
48
|
+
"message": "Remove references to 'commitTransaction'. This is not allowed.",
|
|
49
|
+
"type": "error"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"pattern": "context\\.saveObject(\\s)?\\(",
|
|
53
|
+
"message": "Remove references to 'saveObject'. This is not allowed.",
|
|
54
|
+
"type": "error"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"pattern": "context\\.authenticate(\\s)?\\(",
|
|
58
|
+
"message": "Remove references to 'authenticate'. This is not allowed.",
|
|
59
|
+
"type": "error"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"pattern": "context\\.close(\\s)?\\(",
|
|
63
|
+
"message": "Remove references to 'close'. This is not allowed.",
|
|
64
|
+
"type": "error"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"pattern": "context\\.decache(\\s)?\\(",
|
|
68
|
+
"message": "Remove references to 'decache'. This is not allowed.",
|
|
69
|
+
"type": "error"
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
{
|
|
73
|
+
"pattern": "context\\.encrypt(\\s)?\\(",
|
|
74
|
+
"message": "Remove references to 'encrypt'. This is not allowed.",
|
|
75
|
+
"type": "error"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"pattern": "context\\.getJdbcConnection(\\s)?\\(",
|
|
79
|
+
"message": "Remove references to 'encrypt'. This is not allowed.",
|
|
80
|
+
"type": "error"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"pattern": "context\\.impersonate(\\s)?\\(",
|
|
84
|
+
"message": "Remove references to 'impersonate'. This is not allowed.",
|
|
85
|
+
"type": "error"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"pattern": "context\\.importObject(\\s)?\\(",
|
|
89
|
+
"message": "Remove references to 'importObject'. This is not allowed.",
|
|
90
|
+
"type": "error"
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
{
|
|
94
|
+
"pattern": "XMLObjectFactory\\.getInstance()\\.toXml\\(*\\)",
|
|
95
|
+
"message": "Remove references to XMLObjectFactory.getInstance().toXml(...).",
|
|
96
|
+
"type": "error"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"pattern": "\\.toXml(\\s)?\\(*\\)",
|
|
100
|
+
"message": "Remove references to 'toXml'. This is not allowed.",
|
|
101
|
+
"type": "error"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"pattern": "Thread\\.",
|
|
105
|
+
"message": "Remove references to 'Thread'. This is not allowed.",
|
|
106
|
+
"type": "error"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"pattern": "Runnable\\.",
|
|
110
|
+
"message": "Remove references to 'Runnable'. This is not allowed.",
|
|
111
|
+
"type": "error"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"pattern": "context\\.lockObject(\\s)?\\(",
|
|
115
|
+
"message": "Remove references to 'lockObject'. This is not allowed.",
|
|
116
|
+
"type": "error"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"pattern": "context\\.lockObjectById(\\s)?\\(",
|
|
120
|
+
"message": "Remove references to 'lockObjectById'. This is not allowed.",
|
|
121
|
+
"type": "error"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"pattern": "context\\.lockObjectByName(\\s)?\\(",
|
|
125
|
+
"message": "Remove references to 'lockObjectByName'. This is not allowed.",
|
|
126
|
+
"type": "error"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"pattern": "context\\.notify(\\s)?\\(",
|
|
130
|
+
"message": "Remove references to 'notify'. This is not allowed.",
|
|
131
|
+
"type": "error"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"pattern": "context\\.notifyAll(\\s)?\\(",
|
|
135
|
+
"message": "Remove references to 'notifyAll'. This is not allowed.",
|
|
136
|
+
"type": "error"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"pattern": "context\\.printStatistics(\\s)?\\(",
|
|
140
|
+
"message": "Remove references to 'printStatistics'. This is not allowed.",
|
|
141
|
+
"type": "error"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"pattern": "context\\.reconnect(\\s)?\\(",
|
|
145
|
+
"message": "Remove references to 'reconnect'. This is not allowed.",
|
|
146
|
+
"type": "error"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"pattern": "context\\.removeObject(\\s)?\\(",
|
|
150
|
+
"message": "Remove references to 'removeObject'. This is not allowed.",
|
|
151
|
+
"type": "error"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"pattern": "context\\.removeObjects(\\s)?\\(",
|
|
155
|
+
"message": "Remove references to 'removeObjects'. This is not allowed.",
|
|
156
|
+
"type": "error"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"pattern": "context\\.rollbackTransaction\\(",
|
|
160
|
+
"message": "Remove references to 'rollbackTransaction'. This is not allowed.",
|
|
161
|
+
"type": "error"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"pattern": "context\\.runRule(\\s)?\\(",
|
|
165
|
+
"message": "Remove references to 'runRule'. This is not allowed.",
|
|
166
|
+
"type": "error"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"pattern": "context\\.runScript(\\s)?\\(",
|
|
170
|
+
"message": "Remove references to 'runScript'. This is not allowed.",
|
|
171
|
+
"type": "error"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"pattern": "context\\.sendEmailNotification(\\s)?\\(",
|
|
175
|
+
"message": "Remove references to 'sendEmailNotification'. This is not allowed.",
|
|
176
|
+
"type": "error"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"pattern": "TimeZone\\.setTimeZone\\(",
|
|
180
|
+
"message": "Setting TimeZones is not supported.",
|
|
181
|
+
"type": "error"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"pattern": "identity\\.getLinks(\\s)?\\(",
|
|
185
|
+
"message": "The function 'getLinks' is deprecated. Use an identity search instead.",
|
|
186
|
+
"type": "error"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"pattern": "^(\\s)?(<Rule)(.*?)(type=)('|\")(ResourceObjectCustomization)('|\")",
|
|
190
|
+
"message": "Unsupported Rule Type: ResourceObjectCustomization rules are not supported, and cannot be submitted.",
|
|
191
|
+
"type": "error"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"pattern": "^(\\s)?(<Rule)(.*?)(type=)('|\")(Integration)('|\")",
|
|
195
|
+
"message": "Unsupported Rule Type: Integration rules are not supported. Consider implementation of a BeforeProvisioning rule instead.",
|
|
196
|
+
"type": "error"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"pattern": "^(\\s)?(<Rule)(.*?)(type=)('|\")(?!(IdentityAttribute|AttributeGenerator|AttributeGeneratorFromTemplate|Correlation|ManagerCorrelation|BeforeProvisioning|ConnectorAfterCreate|ConnectorAfterModify|BuildMap|JDBCBuildMap|JDBCProvisioning|SAPBuildMap|SapHrOperationProvisioning|WebServiceBeforeOperation|WebServiceAfterOperation))('|\")",
|
|
200
|
+
"message": "Unsupported Rule Type: This type of rule is not supported. See the IdentityNow Rule Guide for more details on supported rules.",
|
|
201
|
+
"type": "error"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"pattern": "^(\\s)?(<Rule)(.*?)(type=)('|\")(CertificationExclusion)('|\")",
|
|
205
|
+
"message": "Deprecated Rule Type: CertificationExclusion rules are deprecated. Consider configuration via certification campaign filters instead.",
|
|
206
|
+
"type": "warning"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"pattern": "^(\\s)?(<Rule)(.*?)(type=)('|\")(IdentitySelector)('|\")",
|
|
210
|
+
"message": "Deprecated Rule Type: IdentitySelector rules are deprecated. Consider configuration via rule assignment criteria instead.",
|
|
211
|
+
"type": "warning"
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"pattern": "(context\\.)(getObjectByName|getObjectById|getObjects|getObject)(.*?)(\\s)?(\\()+(\\s)?(?!((\\s)?(sailpoint\\.object\\.)?(Identity|Link)))",
|
|
215
|
+
"message": "Cannot get objects other than sailpoint.object.Identity or sailpoint.object.Link objects.",
|
|
216
|
+
"type": "error"
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"pattern": "Log4j",
|
|
220
|
+
"message": "Do not declare your own loggers.",
|
|
221
|
+
"type": "error"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"pattern": "(context\\.search)(\\s)?(\\()+(\\s)?(?!((\\s)?(sailpoint\\.object\\.)?(Identity|Link)))",
|
|
225
|
+
"message": "Only sailpoint.object.Identity or sailpoint.object.Link objects are searchable.",
|
|
226
|
+
"type": "error"
|
|
227
|
+
}
|
|
228
|
+
]
|
metadata
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: identitynow_rule_validator
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0b
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- neil-mcglennon-sp
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain:
|
|
11
|
+
- |
|
|
12
|
+
-----BEGIN CERTIFICATE-----
|
|
13
|
+
MIIEYjCCAsqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDDCJuZWls
|
|
14
|
+
Lm1jZ2xlbm5vbi9EQz1zYWlscG9pbnQvREM9Y29tMB4XDTIwMDEyODE3MzYwNloX
|
|
15
|
+
DTIxMDEyNzE3MzYwNlowLTErMCkGA1UEAwwibmVpbC5tY2dsZW5ub24vREM9c2Fp
|
|
16
|
+
bHBvaW50L0RDPWNvbTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKqi
|
|
17
|
+
9+1E2sipSc7Iju7N6oQT1NNnRzjC0lQYh2w8XyrkNrmBDq3DrZcK08tDHSZDeII3
|
|
18
|
+
pI3wUduamXJ9fLlIp3THv01sB/PZGpcuLsJlxlCnnXrnckFqGoWApgRgtDChn5xk
|
|
19
|
+
CqQshFrk7felCJj95RmhWqgjp/jzRL8djksbxVB4wc3qCBkw2mS6v3Z516gALJrK
|
|
20
|
+
ILXwttgQoXZipvm1GAnfXBOJaXVO1yGt4D7egeNnqLZ8p92vBEI8gwhA4nsw2bgI
|
|
21
|
+
Rm7Y/eeWMuzoNBAXVZnPUB65hrS7kpSpKomWHbV91TzjcKohyjYBj4/1xuIhED31
|
|
22
|
+
jxpoIOOIdzvCxERxPS5ay5+VlTaBXxNsIz12UFUImSMjqLpa6i/SLLwLXO4pyq8q
|
|
23
|
+
6seUSqpLai6vue7pFFQSgINrpTfw2VxrhF4mSipEwgkQ479e451/tFG1Fw5jJWtz
|
|
24
|
+
o95bJWBBxH8mm8T+z/XUeY0xMyHegAN7cHXfe8wU3z2OLLop3XzB+7P/P8zYdwID
|
|
25
|
+
AQABo4GMMIGJMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ5225b
|
|
26
|
+
ZgQ6rTZpji087FmAGRc02TAnBgNVHREEIDAegRxuZWlsLm1jZ2xlbm5vbkBzYWls
|
|
27
|
+
cG9pbnQuY29tMCcGA1UdEgQgMB6BHG5laWwubWNnbGVubm9uQHNhaWxwb2ludC5j
|
|
28
|
+
b20wDQYJKoZIhvcNAQELBQADggGBAJgrmpwrIu1WO1r8WL62je6PcJdBjKHux5xU
|
|
29
|
+
D/x3oiSG+qrP2XMKHIHmo1mjQmObWviMVmgU238imT/hcelGbZnkGQ82swAECvZ2
|
|
30
|
+
SEDYx6Dpu0qisI1GliK5m/T7aGhkjxlCxcBa8/eDUwmU55sEXY0Xu1lkq5XoTUwQ
|
|
31
|
+
rEsm8j74ilJOdRf3nla3UUrxGAfWvC/Jul4CTlNt7ADQcMKUiFvkSswY2R+pQWXu
|
|
32
|
+
PKfzNu+y/GU4zwLwfbfPYh9k3s8ynqodBFbwnkh5Q+1CUgYyb//HyOmV5emphaf7
|
|
33
|
+
inuam3RWZl2R2x4o0bOrj277XWJtUoOKgEuV27tmT1TdpAnuaPIrCR/sr7w383aO
|
|
34
|
+
NLKmt0gcTRRt327KOFTls9hByUNR6uEglbaDyErVRECLYOUk19wo6vE9onjaEZTR
|
|
35
|
+
KxiqTPt+66S5Zu9TMeBdYHKYzP8OMs2AwIPrSQH1tGxuGdrjvMvRU3XPxEnuJTwE
|
|
36
|
+
1Av2VddcX+awmjPuUJVxXSyVzEbPZg==
|
|
37
|
+
-----END CERTIFICATE-----
|
|
38
|
+
date: 2020-01-28 00:00:00.000000000 Z
|
|
39
|
+
dependencies:
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: bundler
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.16'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.16'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rake
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '10.0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '10.0'
|
|
68
|
+
description: A tool to validate IdentityNow rules.
|
|
69
|
+
email:
|
|
70
|
+
- neil.mcglennon@sailpoint.com
|
|
71
|
+
executables: []
|
|
72
|
+
extensions: []
|
|
73
|
+
extra_rdoc_files: []
|
|
74
|
+
files:
|
|
75
|
+
- lib/identitynow_rule_validator.rb
|
|
76
|
+
- lib/program.rb
|
|
77
|
+
- lib/rules.json
|
|
78
|
+
homepage: http://www.sailpoint.com
|
|
79
|
+
licenses:
|
|
80
|
+
- MIT
|
|
81
|
+
metadata: {}
|
|
82
|
+
post_install_message:
|
|
83
|
+
rdoc_options: []
|
|
84
|
+
require_paths:
|
|
85
|
+
- lib
|
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - ">="
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: '0'
|
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: 1.3.1
|
|
96
|
+
requirements: []
|
|
97
|
+
rubyforge_project:
|
|
98
|
+
rubygems_version: 2.7.6
|
|
99
|
+
signing_key:
|
|
100
|
+
specification_version: 4
|
|
101
|
+
summary: IdentityNow Rule Validator
|
|
102
|
+
test_files: []
|
metadata.gz.sig
ADDED
|
Binary file
|