Hopefully provided a reliable fix to the settings type conversion issues brought upon with the authentication settings editor overhaul.

This commit is contained in:
Matt Scott 2023-04-11 18:50:47 -04:00
parent feb62cf39f
commit c98c174c23
No known key found for this signature in database
GPG Key ID: A9A0AFFC0E079001
3 changed files with 192 additions and 51 deletions

View File

@ -13,7 +13,130 @@ class Setting(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True, index=True) name = db.Column(db.String(64), unique=True, index=True)
value = db.Column(db.Text()) value = db.Column(db.Text())
types = {
'maintenance': bool,
'fullscreen_layout': bool,
'record_helper': bool,
'login_ldap_first': bool,
'default_record_table_size': int,
'default_domain_table_size': int,
'auto_ptr': bool,
'record_quick_edit': bool,
'pretty_ipv6_ptr': bool,
'dnssec_admins_only': bool,
'allow_user_create_domain': bool,
'allow_user_remove_domain': bool,
'allow_user_view_history': bool,
'custom_history_header': str,
'delete_sso_accounts': bool,
'bg_domain_updates': bool,
'enable_api_rr_history': bool,
'preserve_history': bool,
'site_name': str,
'site_url': str,
'session_timeout': int,
'warn_session_timeout': bool,
'pdns_api_url': str,
'pdns_api_key': str,
'pdns_api_timeout': int,
'pdns_version': str,
'verify_ssl_connections': bool,
'verify_user_email': bool,
'enforce_api_ttl': bool,
'ttl_options': str,
'otp_field_enabled': bool,
'custom_css': str,
'otp_force': bool,
'max_history_records': int,
'deny_domain_override': bool,
'account_name_extra_chars': bool,
'gravatar_enabled': bool,
'forward_records_allow_edit': dict,
'reverse_records_allow_edit': dict,
'local_db_enabled': bool,
'signup_enabled': bool,
'pwd_enforce_characters': bool,
'pwd_min_len': int,
'pwd_min_lowercase': int,
'pwd_min_uppercase': int,
'pwd_min_digits': int,
'pwd_min_special': int,
'pwd_enforce_complexity': bool,
'pwd_min_complexity': int,
'ldap_enabled': bool,
'ldap_type': str,
'ldap_uri': str,
'ldap_base_dn': str,
'ldap_admin_username': str,
'ldap_admin_password': str,
'ldap_domain': str,
'ldap_filter_basic': str,
'ldap_filter_username': str,
'ldap_filter_group': str,
'ldap_filter_groupname': str,
'ldap_sg_enabled': bool,
'ldap_admin_group': str,
'ldap_operator_group': str,
'ldap_user_group': str,
'autoprovisioning': bool,
'autoprovisioning_attribute': str,
'urn_value': str,
'purge': bool,
'google_oauth_enabled': bool,
'google_oauth_client_id': str,
'google_oauth_client_secret': str,
'google_oauth_scope': str,
'google_base_url': str,
'google_oauth_auto_configure': bool,
'google_oauth_metadata_url': str,
'google_token_url': str,
'google_authorize_url': str,
'github_oauth_enabled': bool,
'github_oauth_key': str,
'github_oauth_secret': str,
'github_oauth_scope': str,
'github_oauth_api_url': str,
'github_oauth_auto_configure': bool,
'github_oauth_metadata_url': str,
'github_oauth_token_url': str,
'github_oauth_authorize_url': str,
'azure_oauth_enabled': bool,
'azure_oauth_key': str,
'azure_oauth_secret': str,
'azure_oauth_scope': str,
'azure_oauth_api_url': str,
'azure_oauth_auto_configure': bool,
'azure_oauth_metadata_url': str,
'azure_oauth_token_url': str,
'azure_oauth_authorize_url': str,
'azure_sg_enabled': bool,
'azure_admin_group': str,
'azure_operator_group': str,
'azure_user_group': str,
'azure_group_accounts_enabled': bool,
'azure_group_accounts_name': str,
'azure_group_accounts_name_re': str,
'azure_group_accounts_description': str,
'azure_group_accounts_description_re': str,
'oidc_oauth_enabled': bool,
'oidc_oauth_key': str,
'oidc_oauth_secret': str,
'oidc_oauth_scope': str,
'oidc_oauth_api_url': str,
'oidc_oauth_auto_configure': bool,
'oidc_oauth_metadata_url': str,
'oidc_oauth_token_url': str,
'oidc_oauth_authorize_url': str,
'oidc_oauth_logout_url': str,
'oidc_oauth_username': str,
'oidc_oauth_email': str,
'oidc_oauth_firstname': str,
'oidc_oauth_last_name': str,
'oidc_oauth_account_name_property': str,
'oidc_oauth_account_description_property': str,
}
defaults = { defaults = {
# General Settings # General Settings
'maintenance': False, 'maintenance': False,
@ -334,6 +457,34 @@ class Setting(db.Model):
self.name = name self.name = name
self.value = value self.value = value
def convert_type(self, name, value):
import json
if name in self.types:
var_type = self.types[name]
# Handle boolean values
if var_type == bool:
if value == 'True' or value == 'true' or value == '1' or value == True:
return True
else:
return False
# Handle float values
if var_type == float:
return float(value)
# Handle integer values
if var_type == int:
return int(value)
if var_type == dict or var_type == list:
return json.loads(value)
if var_type == str:
return str(value)
return value
def set_maintenance(self, mode): def set_maintenance(self, mode):
maintenance = Setting.query.filter( maintenance = Setting.query.filter(
Setting.name == 'maintenance').first() Setting.name == 'maintenance').first()
@ -386,7 +537,7 @@ class Setting(db.Model):
current_setting = Setting(name=setting, value=None) current_setting = Setting(name=setting, value=None)
db.session.add(current_setting) db.session.add(current_setting)
value = str(value) value = str(self.convert_type(setting, value))
try: try:
current_setting.value = value current_setting.value = value
@ -410,16 +561,15 @@ class Setting(db.Model):
if result is not None: if result is not None:
if hasattr(result, 'value'): if hasattr(result, 'value'):
result = result.value result = result.value
return strtobool(result) if result in [
'True', 'False', 'true', 'false', '1', '0' return self.convert_type(setting, result)
] else result
else: else:
return self.defaults[setting] return self.defaults[setting]
else: else:
current_app.logger.error('Unknown setting queried: {0}'.format(setting)) current_app.logger.error('Unknown setting queried: {0}'.format(setting))
def get_group(self, group): def get_group(self, group):
if isinstance(group, str): if not isinstance(group, list):
group = self.groups[group] group = self.groups[group]
result = {} result = {}
@ -427,16 +577,7 @@ class Setting(db.Model):
for record in records: for record in records:
if record.name in group: if record.name in group:
value = record.value result[record.name] = self.convert_type(record.name, record.value)
if value in ['True', 'False']:
value = strtobool(value)
elif value.isdecimal() and '.' in value:
value = float(value)
elif value.isnumeric():
value = int(value)
result[record.name] = value
return result return result

View File

@ -15,8 +15,8 @@ let AuthenticationSettingsModel = function (user_data, api_url, csrf_token, sele
let defaults = { let defaults = {
// Local Authentication Settings // Local Authentication Settings
local_db_enabled: 1, local_db_enabled: true,
signup_enabled: 1, signup_enabled: true,
pwd_enforce_characters: 0, pwd_enforce_characters: 0,
pwd_min_len: 10, pwd_min_len: 10,
pwd_min_lowercase: 3, pwd_min_lowercase: 3,
@ -27,7 +27,7 @@ let AuthenticationSettingsModel = function (user_data, api_url, csrf_token, sele
pwd_min_complexity: 11, pwd_min_complexity: 11,
// LDAP Authentication Settings // LDAP Authentication Settings
ldap_enabled: 0, ldap_enabled: false,
ldap_type: 'ldap', ldap_type: 'ldap',
ldap_uri: '', ldap_uri: '',
ldap_base_dn: '', ldap_base_dn: '',
@ -38,64 +38,64 @@ let AuthenticationSettingsModel = function (user_data, api_url, csrf_token, sele
ldap_filter_username: '', ldap_filter_username: '',
ldap_filter_group: '', ldap_filter_group: '',
ldap_filter_groupname: '', ldap_filter_groupname: '',
ldap_sg_enabled: 0, ldap_sg_enabled: false,
ldap_admin_group: '', ldap_admin_group: '',
ldap_operator_group: '', ldap_operator_group: '',
ldap_user_group: '', ldap_user_group: '',
autoprovisioning: 0, autoprovisioning: false,
autoprovisioning_attribute: '', autoprovisioning_attribute: '',
urn_value: '', urn_value: '',
purge: 0, purge: 0,
// Google OAuth2 Settings // Google OAuth2 Settings
google_oauth_enabled: 0, google_oauth_enabled: false,
google_oauth_client_id: '', google_oauth_client_id: '',
google_oauth_client_secret: '', google_oauth_client_secret: '',
google_oauth_scope: '', google_oauth_scope: '',
google_base_url: '', google_base_url: '',
google_oauth_auto_configure: 1, google_oauth_auto_configure: true,
google_oauth_metadata_url: '', google_oauth_metadata_url: '',
google_token_url: '', google_token_url: '',
google_authorize_url: '', google_authorize_url: '',
// GitHub OAuth2 Settings // GitHub OAuth2 Settings
github_oauth_enabled: 0, github_oauth_enabled: false,
github_oauth_key: '', github_oauth_key: '',
github_oauth_secret: '', github_oauth_secret: '',
github_oauth_scope: '', github_oauth_scope: '',
github_oauth_api_url: '', github_oauth_api_url: '',
github_oauth_auto_configure: 0, github_oauth_auto_configure: false,
github_oauth_metadata_url: '', github_oauth_metadata_url: '',
github_oauth_token_url: '', github_oauth_token_url: '',
github_oauth_authorize_url: '', github_oauth_authorize_url: '',
// Azure AD OAuth2 Settings // Azure AD OAuth2 Settings
azure_oauth_enabled: 0, azure_oauth_enabled: false,
azure_oauth_key: '', azure_oauth_key: '',
azure_oauth_secret: '', azure_oauth_secret: '',
azure_oauth_scope: '', azure_oauth_scope: '',
azure_oauth_api_url: '', azure_oauth_api_url: '',
azure_oauth_auto_configure: 1, azure_oauth_auto_configure: true,
azure_oauth_metadata_url: '', azure_oauth_metadata_url: '',
azure_oauth_token_url: '', azure_oauth_token_url: '',
azure_oauth_authorize_url: '', azure_oauth_authorize_url: '',
azure_sg_enabled: 0, azure_sg_enabled: false,
azure_admin_group: '', azure_admin_group: '',
azure_operator_group: '', azure_operator_group: '',
azure_user_group: '', azure_user_group: '',
azure_group_accounts_enabled: 0, azure_group_accounts_enabled: false,
azure_group_accounts_name: '', azure_group_accounts_name: '',
azure_group_accounts_name_re: '', azure_group_accounts_name_re: '',
azure_group_accounts_description: '', azure_group_accounts_description: '',
azure_group_accounts_description_re: '', azure_group_accounts_description_re: '',
// OIDC OAuth2 Settings // OIDC OAuth2 Settings
oidc_oauth_enabled: 0, oidc_oauth_enabled: false,
oidc_oauth_key: '', oidc_oauth_key: '',
oidc_oauth_secret: '', oidc_oauth_secret: '',
oidc_oauth_scope: '', oidc_oauth_scope: '',
oidc_oauth_api_url: '', oidc_oauth_api_url: '',
oidc_oauth_auto_configure: 1, oidc_oauth_auto_configure: true,
oidc_oauth_metadata_url: '', oidc_oauth_metadata_url: '',
oidc_oauth_token_url: '', oidc_oauth_token_url: '',
oidc_oauth_authorize_url: '', oidc_oauth_authorize_url: '',

View File

@ -450,15 +450,15 @@
<div class="radio"> <div class="radio">
<label> <label>
<input type="radio" name="ldap_sg_enabled" <input type="radio" name="ldap_sg_enabled"
id="ldap_sg_off" value="0" id="ldap_sg_off" value="false"
data-bind="enable: ldap_enabled, checked: ldap_sg_enabled, checkedValue: 0"> data-bind="enable: ldap_enabled, checked: ldap_sg_enabled, checkedValue: false">
OFF OFF
</label> </label>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
<label> <label>
<input type="radio" name="ldap_sg_enabled" <input type="radio" name="ldap_sg_enabled"
id="ldap_sg_on" value="1" id="ldap_sg_on" value="true"
data-bind="enable: ldap_enabled, checked: ldap_sg_enabled, checkedValue: 1"> data-bind="enable: ldap_enabled, checked: ldap_sg_enabled, checkedValue: true">
ON ON
</label> </label>
</div> </div>
@ -497,15 +497,15 @@
<div class="radio"> <div class="radio">
<label> <label>
<input type="radio" name="autoprovisioning" <input type="radio" name="autoprovisioning"
id="autoprovisioning_off" value="0" id="autoprovisioning_off" value="false"
data-bind="enable: ldap_enabled, checked: autoprovisioning, checkedValue: 0"> data-bind="enable: ldap_enabled, checked: autoprovisioning, checkedValue: false">
OFF OFF
</label> </label>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
<label> <label>
<input type="radio" name="autoprovisioning" <input type="radio" name="autoprovisioning"
id="autoprovisioning_on" value="1" id="autoprovisioning_on" value="true"
data-bind="enable: ldap_enabled, checked: autoprovisioning, checkedValue: 1"> data-bind="enable: ldap_enabled, checked: autoprovisioning, checkedValue: true">
ON ON
</label> </label>
</div> </div>
@ -540,16 +540,16 @@
<label> <label>
<input type="radio" name="purge" <input type="radio" name="purge"
id="purge_off" id="purge_off"
value="0" value="false"
data-bind="enable: ldap_enabled() && autoprovisioning(), checked: purge, checkedValue: 0"> data-bind="enable: ldap_enabled() && autoprovisioning(), checked: purge, checkedValue: false">
OFF OFF
</label> </label>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
<label> <label>
<input type="radio" name="purge" <input type="radio" name="purge"
id="purge_on" id="purge_on"
value="1" value="true"
data-bind="enable: ldap_enabled() && autoprovisioning(), checked: purge, checkedValue: 1"> data-bind="enable: ldap_enabled() && autoprovisioning(), checked: purge, checkedValue: true">
ON ON
</label> </label>
</div> </div>
@ -1112,15 +1112,15 @@
<div class="radio"> <div class="radio">
<label> <label>
<input type="radio" name="azure_sg_enabled" <input type="radio" name="azure_sg_enabled"
id="azure_sg_off" value="0" id="azure_sg_off" value="false"
data-bind="enable: azure_oauth_enabled, checked: azure_sg_enabled, checkedValue: 0"> data-bind="enable: azure_oauth_enabled, checked: azure_sg_enabled, checkedValue: false">
OFF OFF
</label> </label>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
<label> <label>
<input type="radio" name="azure_sg_enabled" <input type="radio" name="azure_sg_enabled"
id="azure_sg_on" value="1" id="azure_sg_on" value="true"
data-bind="enable: azure_oauth_enabled, checked: azure_sg_enabled, checkedValue: 1"> data-bind="enable: azure_oauth_enabled, checked: azure_sg_enabled, checkedValue: true">
ON ON
</label> </label>
</div> </div>
@ -1163,8 +1163,8 @@
<input type="radio" <input type="radio"
name="azure_group_accounts_enabled" name="azure_group_accounts_enabled"
id="azure_group_accounts_off" id="azure_group_accounts_off"
value="0" value="false"
data-bind="enable: azure_oauth_enabled, checked: azure_group_accounts_enabled, checkedValue: 0"> data-bind="enable: azure_oauth_enabled, checked: azure_group_accounts_enabled, checkedValue: false">
OFF OFF
</label> </label>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
@ -1172,8 +1172,8 @@
<input type="radio" <input type="radio"
name="azure_group_accounts_enabled" name="azure_group_accounts_enabled"
id="azure_group_accounts_on" id="azure_group_accounts_on"
value="1" value="true"
data-bind="enable: azure_oauth_enabled, checked: azure_group_accounts_enabled, checkedValue: 1"> data-bind="enable: azure_oauth_enabled, checked: azure_group_accounts_enabled, checkedValue: true">
ON ON
</label> </label>
</div> </div>