autosign 0.1.4 → 1.0.0
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 +4 -4
- data/.rubocop.yml +12 -0
- data/.rubocop_todo.yml +659 -0
- data/.travis.yml +4 -4
- data/CHANGELOG.md +53 -0
- data/Gemfile.lock +66 -34
- data/README.md +37 -0
- data/Rakefile +22 -22
- data/autosign.gemspec +23 -18
- data/bin/autosign +10 -6
- data/bin/autosign-validator +5 -5
- data/lib/autosign/config.rb +66 -52
- data/lib/autosign/validator.rb +33 -196
- data/lib/autosign/{validators → validator}/jwt.rb +41 -42
- data/lib/autosign/{validators → validator}/multiplexer.rb +24 -32
- data/lib/autosign/{validators → validator}/passwordlist.rb +16 -17
- data/lib/autosign/validator/validator_base.rb +168 -0
- data/lib/autosign/version.rb +1 -1
- metadata +78 -75
- data/features/autosign.feature +0 -93
- data/features/step_definitions/autosign_steps.rb +0 -44
- data/features/support/env.rb +0 -17
- data/features/validate.feature +0 -22
- data/fixtures/i-7672fe81.pem +0 -34
- data/spec/spec_helper.rb +0 -102
- data/spec/specs/config_spec.rb +0 -20
- data/spec/specs/decoder_spec.rb +0 -24
- data/spec/specs/journal_spec.rb +0 -41
- data/spec/specs/token_spec.rb +0 -102
- data/spec/specs/validators/jwt_spec.rb +0 -69
- data/spec/specs/validators/passwordlist_spec.rb +0 -51
data/bin/autosign-validator
CHANGED
@@ -13,14 +13,14 @@ raw_csr = $stdin.read
|
|
13
13
|
@logger.add_appenders Logging.appenders.stdout
|
14
14
|
|
15
15
|
# Load config and then add logfile as a log appender
|
16
|
-
|
16
|
+
config_settings = Autosign::Config.new.settings
|
17
17
|
|
18
|
-
unless
|
18
|
+
unless config_settings['general']['logfile'].nil?
|
19
19
|
file_layout = Logging.layouts.pattern(:pattern => "%d %-5l -- %c : %m\n", :date_pattern => "%Y-%m-%dT%H:%M:%S.%s")
|
20
|
-
@logger.add_appenders Logging.appenders.file(
|
20
|
+
@logger.add_appenders Logging.appenders.file(config_settings['general']['logfile'], :layout => file_layout)
|
21
21
|
end
|
22
22
|
|
23
|
-
@logger.level =
|
23
|
+
@logger.level = config_settings['general']['loglevel'].to_sym unless config_settings['general']['loglevel'].nil?
|
24
24
|
|
25
25
|
### End logging initialization
|
26
26
|
|
@@ -41,7 +41,7 @@ exit 1 unless csr.is_a?(Hash)
|
|
41
41
|
### End Inputs
|
42
42
|
|
43
43
|
### validate token
|
44
|
-
token_validation = Autosign::Validator.any_validator(csr[:challenge_password].to_s, certname.to_s, raw_csr)
|
44
|
+
token_validation = Autosign::Validator.any_validator(csr[:challenge_password].to_s, certname.to_s, raw_csr, config_settings)
|
45
45
|
### end validation
|
46
46
|
|
47
47
|
### Exit with correct exit status
|
data/lib/autosign/config.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rbconfig'
|
2
4
|
require 'securerandom'
|
3
5
|
require 'deep_merge'
|
@@ -7,16 +9,16 @@ module Autosign
|
|
7
9
|
# Exceptions namespace for Autosign class
|
8
10
|
module Exceptions
|
9
11
|
# Exception representing a general failure during validation
|
10
|
-
class Validation <
|
12
|
+
class Validation < RuntimeError
|
11
13
|
end
|
12
14
|
# Exception representing a missing file during config validation
|
13
|
-
class NotFound <
|
15
|
+
class NotFound < RuntimeError
|
14
16
|
end
|
15
17
|
# Exception representing a permissions error during config validation
|
16
|
-
class Permissions <
|
18
|
+
class Permissions < RuntimeError
|
17
19
|
end
|
18
20
|
# Exception representing errors that Autosign does not know how to handle
|
19
|
-
class Error <
|
21
|
+
class Error < RuntimeError
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
@@ -45,11 +47,16 @@ module Autosign
|
|
45
47
|
@config_file_paths = ['/etc/puppetlabs/puppetserver/autosign.conf', '/etc/autosign.conf', '/usr/local/etc/autosign.conf']
|
46
48
|
|
47
49
|
# HOME is unset when puppet runs, so we need to only use it if it's set
|
48
|
-
|
49
|
-
|
50
|
+
unless ENV['HOME'].nil?
|
51
|
+
@config_file_paths << File.join(Dir.home, '.autosign.conf')
|
52
|
+
end
|
53
|
+
|
54
|
+
unless settings_param['config_file'].nil?
|
55
|
+
@config_file_paths = [settings_param['config_file']]
|
56
|
+
end
|
50
57
|
|
51
58
|
@settings = settings_param
|
52
|
-
@log.debug
|
59
|
+
@log.debug 'Using merged settings hash: ' + @settings.to_s
|
53
60
|
end
|
54
61
|
|
55
62
|
# Return a merged settings hash of defaults, config file settings
|
@@ -57,11 +64,11 @@ module Autosign
|
|
57
64
|
#
|
58
65
|
# @return [Hash] deep merged settings hash
|
59
66
|
def settings
|
60
|
-
@log.debug
|
67
|
+
@log.debug 'merging settings'
|
61
68
|
setting_sources = [default_settings, configfile, @settings]
|
62
|
-
merged_settings = setting_sources.inject({}) { |merged, hash| merged.deep_merge!(hash) }
|
63
|
-
@log.debug
|
64
|
-
|
69
|
+
merged_settings = setting_sources.inject({}) { |merged, hash| merged.deep_merge!(hash, {:overwrite_arrays => true}) }
|
70
|
+
@log.debug 'using merged settings: ' + merged_settings.to_s
|
71
|
+
merged_settings
|
65
72
|
end
|
66
73
|
|
67
74
|
private
|
@@ -78,12 +85,14 @@ module Autosign
|
|
78
85
|
def default_settings
|
79
86
|
{ 'general' =>
|
80
87
|
{
|
81
|
-
'loglevel'
|
88
|
+
'loglevel' => 'INFO',
|
89
|
+
'validation_order' => %w[
|
90
|
+
jwt_token password_list multiplexer
|
91
|
+
]
|
82
92
|
},
|
83
93
|
'jwt_token' => {
|
84
94
|
'validity' => 7200
|
85
|
-
}
|
86
|
-
}
|
95
|
+
} }
|
87
96
|
end
|
88
97
|
|
89
98
|
# Locate the configuration file, parse it from INI-format, and return
|
@@ -91,21 +100,21 @@ module Autosign
|
|
91
100
|
#
|
92
101
|
# @return [Hash] configuration settings loaded from INI file
|
93
102
|
def configfile
|
94
|
-
@log.debug
|
95
|
-
@config_file_paths.each
|
103
|
+
@log.debug 'Finding config file'
|
104
|
+
@config_file_paths.each do |file|
|
96
105
|
@log.debug "Checking if file '#{file}' exists"
|
97
106
|
if File.file?(file)
|
98
|
-
@log.debug
|
107
|
+
@log.debug 'Reading config file from: ' + file
|
99
108
|
config_file = File.read(file)
|
100
109
|
parsed_config_file = YAML.load(config_file)
|
101
|
-
#parsed_config_file = IniParse.parse(config_file).to_hash
|
102
|
-
@log.debug
|
110
|
+
# parsed_config_file = IniParse.parse(config_file).to_hash
|
111
|
+
@log.debug 'configuration read from config file: ' + parsed_config_file.to_s
|
103
112
|
return parsed_config_file if parsed_config_file.is_a?(Hash)
|
104
113
|
else
|
105
114
|
@log.debug "Configuration file '#{file}' not found"
|
106
115
|
end
|
107
|
-
|
108
|
-
|
116
|
+
end
|
117
|
+
{}
|
109
118
|
end
|
110
119
|
|
111
120
|
# Validate configuration file
|
@@ -114,14 +123,14 @@ module Autosign
|
|
114
123
|
# @param configfile [String] the absolute path of the config file to validate
|
115
124
|
# @return [String] the absolute path of the config file
|
116
125
|
def validate_config_file(configfile = location)
|
117
|
-
@log.debug
|
126
|
+
@log.debug 'validating config file'
|
118
127
|
unless File.file?(configfile)
|
119
128
|
@log.error "configuration file not found at: #{configfile}"
|
120
129
|
raise Autosign::Exceptions::NotFound
|
121
130
|
end
|
122
131
|
|
123
132
|
# check if file is world-readable
|
124
|
-
if File.world_readable?(configfile)
|
133
|
+
if File.world_readable?(configfile) || File.world_writable?(configfile)
|
125
134
|
@log.error "configuration file #{configfile} is world-readable or world-writable, which is a security risk"
|
126
135
|
raise Autosign::Exceptions::Permissions
|
127
136
|
end
|
@@ -137,20 +146,20 @@ module Autosign
|
|
137
146
|
case RbConfig::CONFIG['host_os']
|
138
147
|
when /darwin|mac os/
|
139
148
|
{
|
140
|
-
'logpath'
|
141
|
-
'confpath'
|
149
|
+
'logpath' => File.join(Dir.home, 'autosign.log'),
|
150
|
+
'confpath' => File.join(Dir.home, '.autosign.conf'),
|
142
151
|
'journalfile' => File.join(Dir.home, '.autosign.journal')
|
143
152
|
}
|
144
153
|
when /linux/
|
145
154
|
{
|
146
|
-
'logpath'
|
147
|
-
'confpath'
|
155
|
+
'logpath' => '/var/log/autosign.log',
|
156
|
+
'confpath' => '/etc/autosign.conf',
|
148
157
|
'journalfile' => File.join(Dir.home, '/var/autosign/autosign.journal')
|
149
158
|
}
|
150
159
|
when /bsd/
|
151
160
|
{
|
152
|
-
'logpath'
|
153
|
-
'confpath'
|
161
|
+
'logpath' => '/var/log/autosign.log',
|
162
|
+
'confpath' => '/usr/local/etc/autosign.conf',
|
154
163
|
'journalfile' => File.join(Dir.home, '/var/autosign/autosign.journal')
|
155
164
|
}
|
156
165
|
else
|
@@ -161,36 +170,41 @@ module Autosign
|
|
161
170
|
config = {
|
162
171
|
'general' => {
|
163
172
|
'loglevel' => 'warn',
|
164
|
-
'logfile' =>
|
173
|
+
'logfile' => os_defaults['logpath'],
|
174
|
+
'validation_order' => %w[
|
175
|
+
jwt_token password_list multiplexer
|
176
|
+
]
|
165
177
|
},
|
166
178
|
'jwt_token' => {
|
167
|
-
'secret' =>
|
179
|
+
'secret' => SecureRandom.base64(20),
|
168
180
|
'validity' => '7200',
|
169
181
|
'journalfile' => os_defaults['journalfile']
|
170
182
|
}
|
171
183
|
}
|
172
184
|
|
173
|
-
# config = IniParse.gen do |doc|
|
174
|
-
# doc.section("general") do |general|
|
175
|
-
# general.option("loglevel", "warn")
|
176
|
-
# general.option("logfile", os_defaults['logpath'])
|
177
|
-
# end
|
178
|
-
# doc.section("jwt_token") do |jwt_token|
|
179
|
-
# jwt_token.option("secret", SecureRandom.base64(15))
|
180
|
-
# jwt_token.option("validity", 7200)
|
181
|
-
# jwt_token.option("journalfile", os_defaults['journalfile'])
|
182
|
-
# end
|
183
|
-
# doc.section("multiplexer") do |jwt_token|
|
184
|
-
# jwt_token.option(";external_policy_executable", '/usr/local/bin/some_autosign_executable')
|
185
|
-
# jwt_token.option(";external_policy_executable", '/usr/local/bin/another_autosign_executable')
|
186
|
-
# end
|
187
|
-
# doc.section("password_list") do |jwt_token|
|
188
|
-
# jwt_token.option(";password", 'static_autosign_password_here')
|
189
|
-
# jwt_token.option(";password", 'another_static_autosign_password')
|
190
|
-
# end
|
191
|
-
# end.to_ini
|
192
|
-
config_file=settings_param['config_file'] || os_defaults['confpath']
|
193
|
-
|
185
|
+
# config = IniParse.gen do |doc|
|
186
|
+
# doc.section("general") do |general|
|
187
|
+
# general.option("loglevel", "warn")
|
188
|
+
# general.option("logfile", os_defaults['logpath'])
|
189
|
+
# end
|
190
|
+
# doc.section("jwt_token") do |jwt_token|
|
191
|
+
# jwt_token.option("secret", SecureRandom.base64(15))
|
192
|
+
# jwt_token.option("validity", 7200)
|
193
|
+
# jwt_token.option("journalfile", os_defaults['journalfile'])
|
194
|
+
# end
|
195
|
+
# doc.section("multiplexer") do |jwt_token|
|
196
|
+
# jwt_token.option(";external_policy_executable", '/usr/local/bin/some_autosign_executable')
|
197
|
+
# jwt_token.option(";external_policy_executable", '/usr/local/bin/another_autosign_executable')
|
198
|
+
# end
|
199
|
+
# doc.section("password_list") do |jwt_token|
|
200
|
+
# jwt_token.option(";password", 'static_autosign_password_here')
|
201
|
+
# jwt_token.option(";password", 'another_static_autosign_password')
|
202
|
+
# end
|
203
|
+
# end.to_ini
|
204
|
+
config_file = settings_param['config_file'] || os_defaults['confpath']
|
205
|
+
if File.file?(config_file)
|
206
|
+
raise Autosign::Exceptions::Error, "file #{config_file} already exists, aborting"
|
207
|
+
end
|
194
208
|
return config_file if File.write(config_file, config.to_yaml)
|
195
209
|
end
|
196
210
|
end
|
data/lib/autosign/validator.rb
CHANGED
@@ -1,221 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'logging'
|
2
|
-
require 'require_all'
|
3
4
|
|
4
5
|
module Autosign
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
class Validator
|
18
|
-
def initialize()
|
19
|
-
start_logging()
|
20
|
-
settings() # just run to validate settings
|
21
|
-
setup()
|
22
|
-
# call name to ensure that the class fails immediately if child classes
|
23
|
-
# do not implement it.
|
24
|
-
name()
|
25
|
-
end
|
26
|
-
|
27
|
-
# Name of the validator. This must be implemented by validators which
|
28
|
-
# inherit from the Autosign::Validator class. The name is used to identify
|
29
|
-
# the validator in friendly messages and to determine which configuration
|
30
|
-
# file section settings will be loaded from.
|
31
|
-
#
|
32
|
-
# @example set the name of a child class validator to "example"
|
33
|
-
# module Autosign
|
34
|
-
# module Validators
|
35
|
-
# class Example < Autosign::Validator
|
36
|
-
# def name
|
37
|
-
# "example"
|
38
|
-
# end
|
39
|
-
# end
|
40
|
-
# end
|
41
|
-
# end
|
42
|
-
# @return [String] name of the validator. Do not use special characters.
|
43
|
-
def name
|
44
|
-
# override this after inheriting
|
45
|
-
# should return a string with no spaces
|
46
|
-
# this is the name used to reference the validator in config files
|
47
|
-
raise NotImplementedError
|
48
|
-
end
|
49
|
-
|
50
|
-
# define how a validator actually validates the request.
|
51
|
-
# This must be implemented by validators which inherit from the
|
52
|
-
# Autosign::Validator class.
|
53
|
-
#
|
54
|
-
# @param challenge_password [String] the challenge_password OID from the certificate signing request. The challenge_password field is the same setting as the "challengePassword" field in a `csr_attributes.yaml` file when the CSR is generated. In a request using a JSON web token, this would be the serialized token.
|
55
|
-
# @param certname [String] the common name being requested in the certificate signing request. Treat the certname as untrusted. This is user-submitted data that you must validate.
|
56
|
-
# @param raw_csr [String] the encoded X509 certificate signing request, as received by the autosign policy executable. This is provided as an optional extension point, but your validator may not need to use it.
|
57
|
-
# @return [True, False] return true if the certificate should be signed, and false if you cannot validate the request successfully.
|
58
|
-
def perform_validation(challenge_password, certname, raw_csr)
|
59
|
-
# override this after inheriting
|
60
|
-
# should return true to indicate success validating
|
61
|
-
# or false to indicate that the validator was unable to validate
|
62
|
-
raise NotImplementedError
|
63
|
-
end
|
64
|
-
|
65
|
-
# wrapper method that wraps input validation and logging around the perform_validation method.
|
66
|
-
# Do not override or use this class in child classes. This is the class that gets called
|
67
|
-
# on validator objects.
|
68
|
-
def validate(challenge_password, certname, raw_csr)
|
69
|
-
@log.debug "running validate"
|
70
|
-
fail unless challenge_password.is_a?(String)
|
71
|
-
fail unless certname.is_a?(String)
|
72
|
-
|
73
|
-
case perform_validation(challenge_password, certname, raw_csr)
|
74
|
-
when true
|
75
|
-
@log.debug "validated successfully"
|
76
|
-
@log.info "Validated '#{certname}' using '#{name}' validator"
|
77
|
-
return true
|
78
|
-
when false
|
79
|
-
@log.debug "validation failed"
|
80
|
-
@log.debug "Unable to validate '#{certname}' using '#{name}' validator"
|
81
|
-
return false
|
82
|
-
else
|
83
|
-
@log.error "perform_validation returned a non-boolean result"
|
84
|
-
raise "perform_validation returned a non-boolean result"
|
6
|
+
module Validator
|
7
|
+
|
8
|
+
# @return [Array] - A list of all the validator classes
|
9
|
+
# @param list [Array] - a list of validators to use, uses the settings list by default
|
10
|
+
# This returns a list of validators that were specified by the user and the exact
|
11
|
+
# order they want the validation to procede.
|
12
|
+
def self.validation_order(settings = Autosign::Config.new.settings, list = nil)
|
13
|
+
validation_order = list || settings['general']['validation_order']
|
14
|
+
# create a key pair where the key is the name of the validator and value is the class
|
15
|
+
validator_list = validator_classes.each_with_object({}) do |klass, acc|
|
16
|
+
acc[klass::NAME] = klass
|
17
|
+
acc
|
85
18
|
end
|
19
|
+
# filter out validators that do not exist
|
20
|
+
order = validation_order.map { |v| validator_list.fetch(v, nil) }.compact
|
21
|
+
@log = Logging.logger[self.class]
|
22
|
+
@log.debug("Validator order: #{order.inspect}")
|
23
|
+
order
|
86
24
|
end
|
87
25
|
|
26
|
+
# @summary
|
88
27
|
# Class method to attempt validation of a request against all validators which inherit from this class.
|
89
28
|
# The request is considered to be validated if any one validator succeeds.
|
29
|
+
# The first validator to pass shorts the validation process so other validators are not called.
|
90
30
|
# @param challenge_password [String] the challenge_password OID from the certificate signing request
|
91
31
|
# @param certname [String] the common name being requested in the certificate signing request
|
92
32
|
# @param raw_csr [String] the encoded X509 certificate signing request, as received by the autosign policy executable
|
93
|
-
# @return [
|
94
|
-
def self.any_validator(challenge_password, certname, raw_csr)
|
33
|
+
# @return [Boolean] return true if the certificate should be signed, and false if it cannot be validated
|
34
|
+
def self.any_validator(challenge_password, certname, raw_csr, settings = Autosign::Config.new.settings)
|
95
35
|
@log = Logging.logger[self.class]
|
96
|
-
#
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
result = validator.validate(challenge_password, certname, raw_csr)
|
102
|
-
results_by_validator[validator.name] = result
|
103
|
-
@log.debug "result: #{result.to_s}"
|
104
|
-
result
|
105
|
-
}
|
106
|
-
@log.debug "validator results: " + results.to_s
|
107
|
-
@log.info "results by validator: " + results_by_validator.to_s
|
108
|
-
success = results.any?{|result| result == true}
|
109
|
-
if success
|
110
|
-
@log.info "successfully validated using one or more validators"
|
111
|
-
return true
|
36
|
+
# find the first validator that passes and return the class
|
37
|
+
validator = validation_order(settings).find { |c| c.new(settings).validate(challenge_password, certname, raw_csr) }
|
38
|
+
if validator
|
39
|
+
@log.info "Successfully validated using #{validator::NAME}"
|
40
|
+
true
|
112
41
|
else
|
113
|
-
@log.info
|
114
|
-
|
42
|
+
@log.info 'unable to validate using any validator'
|
43
|
+
false
|
115
44
|
end
|
116
45
|
end
|
117
46
|
|
118
47
|
private
|
119
48
|
|
120
|
-
# this is automatically called when the class is initialized; do not
|
121
|
-
# override it in child classes.
|
122
|
-
def start_logging
|
123
|
-
@log = Logging.logger[self.class]
|
124
|
-
@log.debug "starting autosign validator: " + self.name.to_s
|
125
|
-
end
|
126
|
-
|
127
|
-
# (optionally) override this method in validator child classes to perform any additional
|
128
|
-
# setup during class initialization prior to beginning validation.
|
129
|
-
# If you need to create a database connection, this would be a good place to do it.
|
130
|
-
# @return [True, False] return true if setup succeeded, or false if setup failed and the validation should not continue
|
131
|
-
def setup
|
132
|
-
true
|
133
|
-
end
|
134
|
-
|
135
49
|
# Find other classes that inherit from this class.
|
136
50
|
# Used to discover autosign validators. There is probably no reason to use
|
137
51
|
# this directly.
|
138
52
|
# @return [Array] of classes inheriting from Autosign::Validator
|
139
|
-
def self.
|
140
|
-
|
53
|
+
def self.validator_classes
|
54
|
+
validators = Dir.glob(File.join(__dir__, 'validator', '*')).sort.each {|k| require k }
|
55
|
+
ObjectSpace.each_object(Class).select { |klass| klass < Autosign::Validator::ValidatorBase }
|
141
56
|
end
|
142
|
-
|
143
|
-
# provide a merged settings hash of default settings for a validator,
|
144
|
-
# config file settings for the validator, and override settings defined in
|
145
|
-
# the validator.
|
146
|
-
#
|
147
|
-
# Do not override this in child classes. If you need to set
|
148
|
-
# custom config settings, override the get_override_settings method.
|
149
|
-
# The section of the config file this reads from is the same as the name
|
150
|
-
# method returns.
|
151
|
-
#
|
152
|
-
# @return [Hash] of config settings
|
153
|
-
def settings
|
154
|
-
@log.debug "merging settings"
|
155
|
-
setting_sources = [get_override_settings, load_config, default_settings]
|
156
|
-
merged_settings = setting_sources.inject({}) { |merged, hash| merged.deep_merge(hash) }
|
157
|
-
@log.debug "using merged settings: " + merged_settings.to_s
|
158
|
-
@log.debug "validating merged settings"
|
159
|
-
if validate_settings(merged_settings)
|
160
|
-
@log.debug "successfully validated merged settings"
|
161
|
-
return merged_settings
|
162
|
-
else
|
163
|
-
@log.warn "validation of merged settings failed"
|
164
|
-
@log.warn "unable to validate settings in #{self.name} validator"
|
165
|
-
raise "settings validation error"
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
# (optionally) override this from a child class to set config defaults.
|
170
|
-
# These will be overridden by config file settings.
|
171
|
-
#
|
172
|
-
# Override this when inheriting if you need to set config defaults.
|
173
|
-
# For example, if you want to pull settings from zookeeper, this would
|
174
|
-
# be a good place to do that.
|
175
|
-
#
|
176
|
-
# @return [Hash] of config settings
|
177
|
-
def default_settings
|
178
|
-
{}
|
179
|
-
end
|
180
|
-
|
181
|
-
|
182
|
-
# (optionally) override this to perform validation checks on the merged
|
183
|
-
# config hash of default settings, config file settings, and override
|
184
|
-
# settings.
|
185
|
-
# @return [True, False]
|
186
|
-
def validate_settings(settings)
|
187
|
-
settings.is_a?(Hash)
|
188
|
-
end
|
189
|
-
|
190
|
-
# load any required configuration from the config file.
|
191
|
-
# Do not override this in child classes.
|
192
|
-
# @return [Hash] configuration settings from the validator's section of the config file
|
193
|
-
def load_config
|
194
|
-
@log.debug "loading validator-specific configuration"
|
195
|
-
config = Autosign::Config.new
|
196
|
-
|
197
|
-
if config.settings.to_hash[self.name].nil?
|
198
|
-
@log.warn "Unable to load validator-specific configuration"
|
199
|
-
@log.warn "Cannot load configuration section named '#{self.name}'"
|
200
|
-
return {}
|
201
|
-
else
|
202
|
-
@log.debug "Set validator-specific settings from config file: " + config.settings.to_hash[self.name].to_s
|
203
|
-
return config.settings.to_hash[self.name]
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
# (optionally) override this from child classes to get custom configuration
|
208
|
-
# from a validator.
|
209
|
-
#
|
210
|
-
# This is how you override defaults and config file settings.
|
211
|
-
# @return [Hash] configuration settings
|
212
|
-
def get_override_settings
|
213
|
-
{}
|
214
|
-
end
|
215
|
-
|
216
57
|
end
|
217
58
|
end
|
218
|
-
|
219
|
-
# must run at the end because the validators inherit this class
|
220
|
-
# this loads all validators
|
221
|
-
require_rel 'validators'
|