Working on Knockout model integration into existing authentication settings editor view.

Settings are now loading via new backend API.
This commit is contained in:
Matt Scott 2023-04-10 07:39:21 -04:00
parent 827da59ae2
commit 0912dd2805
No known key found for this signature in database
GPG Key ID: A9A0AFFC0E079001
5 changed files with 244 additions and 58 deletions

View File

@ -226,6 +226,103 @@ class Setting(db.Model):
},
}
groups = {
'authentication': [
# Local Authentication Settings
'local_db_enabled',
'signup_enabled',
'pwd_enforce_characters',
'pwd_min_len',
'pwd_min_lowercase',
'pwd_min_uppercase',
'pwd_min_digits',
'pwd_min_special',
'pwd_enforce_complexity',
'pwd_min_complexity',
# LDAP Authentication Settings
'ldap_enabled',
'ldap_type',
'ldap_uri',
'ldap_base_dn',
'ldap_admin_username',
'ldap_admin_password',
'ldap_domain',
'ldap_filter_basic',
'ldap_filter_username',
'ldap_filter_group',
'ldap_filter_groupname',
'ldap_sg_enabled',
'ldap_admin_group',
'ldap_operator_group',
'ldap_user_group',
'autoprovisioning',
'autoprovisioning_attribute',
'urn_value',
'purge',
# Google OAuth2 Settings
'google_oauth_enabled',
'google_oauth_client_id',
'google_oauth_client_secret',
'google_oauth_scope',
'google_base_url',
'google_oauth_auto_configure',
'google_oauth_metadata_url',
'google_token_url',
'google_authorize_url',
# GitHub OAuth2 Settings
'github_oauth_enabled',
'github_oauth_key',
'github_oauth_secret',
'github_oauth_scope',
'github_oauth_api_url',
'github_oauth_auto_configure',
'github_oauth_metadata_url',
'github_oauth_token_url',
'github_oauth_authorize_url',
# Azure OAuth2 Settings
'azure_oauth_enabled',
'azure_oauth_key',
'azure_oauth_secret',
'azure_oauth_scope',
'azure_oauth_api_url',
'azure_oauth_auto_configure',
'azure_oauth_metadata_url',
'azure_oauth_token_url',
'azure_oauth_authorize_url',
'azure_sg_enabled',
'azure_admin_group',
'azure_operator_group',
'azure_user_group',
'azure_group_accounts_enabled',
'azure_group_accounts_name',
'azure_group_accounts_name_re',
'azure_group_accounts_description',
'azure_group_accounts_description_re',
# OIDC OAuth2 Settings
'oidc_oauth_enabled',
'oidc_oauth_key',
'oidc_oauth_secret',
'oidc_oauth_scope',
'oidc_oauth_api_url',
'oidc_oauth_auto_configure',
'oidc_oauth_metadata_url',
'oidc_oauth_token_url',
'oidc_oauth_authorize_url',
'oidc_oauth_logout_url',
'oidc_oauth_username',
'oidc_oauth_email',
'oidc_oauth_firstname',
'oidc_oauth_last_name',
'oidc_oauth_account_name_property',
'oidc_oauth_account_description_property',
]
}
def __init__(self, id=None, name=None, value=None):
self.id = id
self.name = name
@ -321,6 +418,24 @@ class Setting(db.Model):
else:
current_app.logger.error('Unknown setting queried: {0}'.format(setting))
def get_group(self, group):
if isinstance(group, str):
group = self.groups[group]
result = {}
records = self.query.all()
for record in records:
if record.name in group:
value = record.value
if value in ['True', 'False']:
value = strtobool(value)
result[record.name] = value
return result
def get_records_allow_to_edit(self):
return list(
set(self.get_forward_records_allow_to_edit() +

View File

@ -1829,6 +1829,13 @@ def setting_authentication():
result=result)
@admin_bp.route('/setting/authentication/api', methods=['GET', 'POST'])
@login_required
@admin_role_required
def setting_authentication_api():
return Setting().get_group('authentication')
@admin_bp.route('/templates', methods=['GET', 'POST'])
@admin_bp.route('/templates/list', methods=['GET', 'POST'])
@login_required

View File

@ -1,7 +1,11 @@
let model;
let AuthenticationSettingsModel = function (user_data, csrf_token, selector) {
let AuthenticationSettingsModel = function (user_data, api_url, csrf_token, selector) {
let self = this;
self.api_url = api_url;
self.csrf_token = csrf_token;
self.selector = selector;
self.loading = false;
let defaults = {
tab_active: '',
@ -31,14 +35,14 @@ let AuthenticationSettingsModel = function (user_data, csrf_token, selector) {
ldap_filter_username: '',
ldap_filter_group: '',
ldap_filter_groupname: '',
ldap_sg_enabled: false,
ldap_sg_enabled: 0,
ldap_admin_group: '',
ldap_operator_group: '',
ldap_user_group: '',
autoprovisioning: false,
autoprovisioning: 0,
autoprovisioning_attribute: '',
urn_value: '',
purge: false,
purge: 0,
// Google OAuth2 Settings
google_oauth_enabled: false,
@ -104,6 +108,7 @@ let AuthenticationSettingsModel = function (user_data, csrf_token, selector) {
self.data = {};
self.setupObservables = function () {
self.loading = ko.observable(self.loading);
self.tab_active = ko.observable(self.data.tab_active);
self.tab_default = ko.observable(self.data.tab_default);
@ -201,6 +206,25 @@ let AuthenticationSettingsModel = function (user_data, csrf_token, selector) {
self.oidc_oauth_account_description_property = ko.observable(self.data.oidc_oauth_account_description_property);
}
self.initTabs = function () {
if (self.hasHash()) {
self.activateTab(self.getHash());
} else {
self.activateDefaultTab();
}
}
self.loadData = function () {
self.loading = true;
$.ajax({
url: self.api_url,
type: 'POST',
data: {_csrf_token: csrf_token},
dataType: 'json',
success: self.onDataLoaded
});
}
self.updateWithDefaults = function (instance) {
self.data = $.extend(defaults, instance)
}
@ -215,14 +239,6 @@ let AuthenticationSettingsModel = function (user_data, csrf_token, selector) {
self.activateTab(self.tab_default());
}
self.initTabs = function() {
if (self.hasHash()) {
self.activateTab(self.getHash());
} else {
self.activateDefaultTab();
}
}
self.getHash = function () {
return window.location.hash.substring(1);
}
@ -243,6 +259,26 @@ let AuthenticationSettingsModel = function (user_data, csrf_token, selector) {
}
}
self.onDataLoaded = function (data) {
self.updateWithDefaults(data);
self.setupObservables();
self.loading = false;
let el = null;
if (typeof selector !== 'undefined') {
el = $(selector)
}
if (el !== null && el.length > 0) {
ko.applyBindings(self, el[0]);
} else {
ko.applyBindings(self);
}
self.initTabs();
self.setupListeners();
}
self.onTabClick = function (model, event) {
self.activateTab($(event.target).data('tab'));
return false;
@ -257,17 +293,11 @@ let AuthenticationSettingsModel = function (user_data, csrf_token, selector) {
}
}
self.updateWithDefaults(user_data);
self.setupObservables();
ko.applyBindings(self);
self.initTabs();
self.setupListeners();
self.loadData();
}
$(function () {
// TODO: Load the data from the server and pass it to the model instantiation
loaded_data = {};
model = new AuthenticationSettingsModel(loaded_data, CSRF_TOKEN, '#settings-editor');
model = new AuthenticationSettingsModel(loaded_data, API_URL, CSRF_TOKEN, '#settings-editor');
})

View File

@ -12,6 +12,7 @@
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Home</a></li>
<li class="breadcrumb-item">Settings</li>
<li class="breadcrumb-item active">Authentication Settings</li>
</ol>
</div>
@ -31,6 +32,12 @@
</div>
<!-- /.card-header -->
<div class="card-body">
<div class="overlay-wrapper" data-bind="visible: loading">
<div class="overlay">
<i class="fas fa-3x fa-sync-alt fa-spin"></i>
<div class="text-bold pt-2 pl-2">Loading settings...</div>
</div>
</div>
{% if result %}
<div
class="alert {% if result['status'] %}alert-success{% else %}alert-danger{% endif %} alert-dismissible">
@ -351,7 +358,8 @@
<span class="help-block with-errors"></span>
</div>
<div id="ldap_openldap_fields">
<div class="form-group" data-bind="visible: ldap_type() == 'ldap'">
<div class="form-group"
data-bind="visible: ldap_type() == 'ldap'">
<label for="ldap_admin_username">LDAP admin
username</label>
<input type="text" class="form-control"
@ -362,7 +370,8 @@
data-bind="enable: ldap_enabled() && ldap_type() == 'ldap', value: ldap_admin_username, valueUpdate: 'afterkeydown'">
<span class="help-block with-errors"></span>
</div>
<div class="form-group" data-bind="visible: ldap_type() == 'ldap'">
<div class="form-group"
data-bind="visible: ldap_type() == 'ldap'">
<label for="ldap_admin_password">LDAP admin
password</label>
<input type="password" class="form-control"
@ -375,7 +384,8 @@
</div>
</div>
<div id="ldap_ad_fields">
<div class="form-group" data-bind="visible: ldap_type() == 'ad'">
<div class="form-group"
data-bind="visible: ldap_type() == 'ad'">
<label for="ldap_domain">Active Directory
domain</label>
<input type="text" class="form-control"
@ -443,14 +453,14 @@
<label>
<input type="radio" name="ldap_sg_enabled"
id="ldap_sg_off" value="0"
data-bind="enable: ldap_enabled, checked: ldap_sg_enabled, checkedValue: false">
data-bind="enable: ldap_enabled, checked: ldap_sg_enabled, checkedValue: 0">
OFF
</label>
&nbsp;&nbsp;&nbsp;
<label>
<input type="radio" name="ldap_sg_enabled"
id="ldap_sg_on" value="1"
data-bind="enable: ldap_enabled, checked: ldap_sg_enabled, checkedValue: true">
data-bind="enable: ldap_enabled, checked: ldap_sg_enabled, checkedValue: 1">
ON
</label>
</div>
@ -493,14 +503,14 @@
<label>
<input type="radio" name="autoprovisioning"
id="autoprovisioning_off" value="0"
data-bind="enable: ldap_enabled, checked: autoprovisioning, checkedValue: false">
data-bind="enable: ldap_enabled, checked: autoprovisioning, checkedValue: 0">
OFF
</label>
&nbsp;&nbsp;&nbsp;
<label>
<input type="radio" name="autoprovisioning"
id="autoprovisioning_on" value="1"
data-bind="enable: ldap_enabled, checked: autoprovisioning, checkedValue: true">
data-bind="enable: ldap_enabled, checked: autoprovisioning, checkedValue: 1">
ON
</label>
</div>
@ -538,7 +548,7 @@
<input type="radio" name="purge"
id="purge_off"
value="0"
data-bind="enable: ldap_enabled() && autoprovisioning(), checked: purge, checkedValue: false">
data-bind="enable: ldap_enabled() && autoprovisioning(), checked: purge, checkedValue: 0">
OFF
</label>
&nbsp;&nbsp;&nbsp;
@ -546,7 +556,7 @@
<input type="radio" name="purge"
id="purge_on"
value="1"
data-bind="enable: ldap_enabled() && autoprovisioning(), checked: purge, checkedValue: true">
data-bind="enable: ldap_enabled() && autoprovisioning(), checked: purge, checkedValue: 1">
ON
</div>
</div>
@ -798,13 +808,17 @@
<span class="help-block with-errors"></span>
</div>
<div class="form-group">
<input type="checkbox" id="google_oauth_auto_configure"
name="google_oauth_auto_configure" class="checkbox"
<input type="checkbox"
id="google_oauth_auto_configure"
name="google_oauth_auto_configure"
class="checkbox"
data-bind="checked: google_oauth_auto_configure">
<label for="google_oauth_auto_configure">Enable Google
<label for="google_oauth_auto_configure">Enable
Google
OAuth Auto-Configuration</label>
</div>
<div class="form-group" data-bind="visible: google_oauth_auto_configure">
<div class="form-group"
data-bind="visible: google_oauth_auto_configure">
<label for="google_oauth_metadata_url">Metadata
URL</label>
<input type="text" class="form-control"
@ -815,7 +829,8 @@
data-bind="enable: google_oauth_enabled() && google_oauth_auto_configure(), value: google_oauth_metadata_url, valueUpdate: 'afterkeydown'">
<span class="help-block with-errors"></span>
</div>
<div class="form-group" data-bind="hidden: google_oauth_auto_configure">
<div class="form-group"
data-bind="hidden: google_oauth_auto_configure">
<label for="google_token_url">Token URL</label>
<input type="text" class="form-control"
name="google_token_url" id="google_token_url"
@ -824,7 +839,8 @@
data-bind="enable: google_oauth_enabled() && !google_oauth_auto_configure(), value: google_token_url, valueUpdate: 'afterkeydown'">
<span class="help-block with-errors"></span>
</div>
<div class="form-group" data-bind="hidden: google_oauth_auto_configure">
<div class="form-group"
data-bind="hidden: google_oauth_auto_configure">
<label for="google_authorize_url">Authorize
URL</label>
<input type="text" class="form-control"
@ -934,13 +950,17 @@
<span class="help-block with-errors"></span>
</div>
<div class="form-group">
<input type="checkbox" id="github_oauth_auto_configure"
name="github_oauth_auto_configure" class="checkbox"
<input type="checkbox"
id="github_oauth_auto_configure"
name="github_oauth_auto_configure"
class="checkbox"
data-bind="checked: github_oauth_auto_configure">
<label for="github_oauth_auto_configure">Enable GitHub
<label for="github_oauth_auto_configure">Enable
GitHub
OAuth Auto-Configuration</label>
</div>
<div class="form-group" data-bind="visible: github_oauth_auto_configure">
<div class="form-group"
data-bind="visible: github_oauth_auto_configure">
<label for="github_oauth_metadata_url">Metadata
URL</label>
<input type="text" class="form-control"
@ -951,7 +971,8 @@
data-bind="enable: github_oauth_enabled() && github_oauth_auto_configure(), value: github_oauth_metadata_url, valueUpdate: 'afterkeydown'">
<span class="help-block with-errors"></span>
</div>
<div class="form-group" data-bind="hidden: github_oauth_auto_configure">
<div class="form-group"
data-bind="hidden: github_oauth_auto_configure">
<label for="github_oauth_token_url">Token
URL</label>
<input type="text" class="form-control"
@ -962,7 +983,8 @@
data-bind="enable: github_oauth_enabled() && !github_oauth_auto_configure(), value: github_oauth_token_url, valueUpdate: 'afterkeydown'">
<span class="help-block with-errors"></span>
</div>
<div class="form-group" data-bind="hidden: github_oauth_auto_configure">
<div class="form-group"
data-bind="hidden: github_oauth_auto_configure">
<label for="github_oauth_authorize_url">Authorize
URL</label>
<input type="text" class="form-control"
@ -1070,13 +1092,16 @@
<span class="help-block with-errors"></span>
</div>
<div class="form-group">
<input type="checkbox" id="azure_oauth_auto_configure"
name="azure_oauth_auto_configure" class="checkbox"
<input type="checkbox"
id="azure_oauth_auto_configure"
name="azure_oauth_auto_configure"
class="checkbox"
data-bind="checked: azure_oauth_auto_configure">
<label for="azure_oauth_auto_configure">Enable Azure
OAuth Auto-Configuration</label>
</div>
<div class="form-group" data-bind="visible: azure_oauth_auto_configure">
<div class="form-group"
data-bind="visible: azure_oauth_auto_configure">
<label for="azure_oauth_metadata_url">Metadata
URL</label>
<input type="text" class="form-control"
@ -1087,7 +1112,8 @@
data-bind="enable: azure_oauth_enabled() && azure_oauth_auto_configure(), value: azure_oauth_metadata_url, valueUpdate: 'afterkeydown'">
<span class="help-block with-errors"></span>
</div>
<div class="form-group" data-bind="hidden: azure_oauth_auto_configure">
<div class="form-group"
data-bind="hidden: azure_oauth_auto_configure">
<label for="azure_oauth_token_url">Token URL</label>
<input type="text" class="form-control"
name="azure_oauth_token_url"
@ -1097,7 +1123,8 @@
data-bind="enable: azure_oauth_enabled() && !azure_oauth_auto_configure(), value: azure_oauth_token_url, valueUpdate: 'afterkeydown'">
<span class="help-block with-errors"></span>
</div>
<div class="form-group" data-bind="hidden: azure_oauth_auto_configure">
<div class="form-group"
data-bind="hidden: azure_oauth_auto_configure">
<label for="azure_oauth_authorize_url">Authorize
URL</label>
<input type="text" class="form-control"
@ -1117,14 +1144,14 @@
<label>
<input type="radio" name="azure_sg_enabled"
id="azure_sg_off" value="0"
data-bind="enable: azure_oauth_enabled, checked: azure_sg_enabled, checkedValue: false">
data-bind="enable: azure_oauth_enabled, checked: azure_sg_enabled, checkedValue: 0">
OFF
</label>
&nbsp;&nbsp;&nbsp;
<label>
<input type="radio" name="azure_sg_enabled"
id="azure_sg_on" value="1"
data-bind="enable: azure_oauth_enabled, checked: azure_sg_enabled, checkedValue: true">
data-bind="enable: azure_oauth_enabled, checked: azure_sg_enabled, checkedValue: 1">
ON
</label>
</div>
@ -1171,7 +1198,7 @@
name="azure_group_accounts_enabled"
id="azure_group_accounts_off"
value="0"
data-bind="enable: azure_oauth_enabled, checked: azure_group_accounts_enabled, checkedValue: false">
data-bind="enable: azure_oauth_enabled, checked: azure_group_accounts_enabled, checkedValue: 0">
OFF
</label>
&nbsp;&nbsp;&nbsp;
@ -1180,7 +1207,7 @@
name="azure_group_accounts_enabled"
id="azure_group_accounts_on"
value="1"
data-bind="enable: azure_oauth_enabled, checked: azure_group_accounts_enabled, checkedValue: true">
data-bind="enable: azure_oauth_enabled, checked: azure_group_accounts_enabled, checkedValue: 1">
ON
</label>
</div>
@ -1383,13 +1410,16 @@
<span class="help-block with-errors"></span>
</div>
<div class="form-group">
<input type="checkbox" id="oidc_oauth_auto_configure"
name="oidc_oauth_auto_configure" class="checkbox"
<input type="checkbox"
id="oidc_oauth_auto_configure"
name="oidc_oauth_auto_configure"
class="checkbox"
data-bind="checked: oidc_oauth_auto_configure">
<label for="oidc_oauth_auto_configure">Enable OIDC
OAuth Auto-Configuration</label>
</div>
<div class="form-group" data-bind="visible: oidc_oauth_auto_configure">
<div class="form-group"
data-bind="visible: oidc_oauth_auto_configure">
<label for="oidc_oauth_metadata_url">Metadata
URL</label>
<input type="text" class="form-control"
@ -1400,7 +1430,8 @@
data-bind="enable: oidc_oauth_enabled() && oidc_oauth_auto_configure(), value: oidc_oauth_metadata_url, valueUpdate: 'afterkeydown'">
<span class="help-block with-errors"></span>
</div>
<div class="form-group" data-bind="hidden: oidc_oauth_auto_configure">
<div class="form-group"
data-bind="hidden: oidc_oauth_auto_configure">
<label for="oidc_oauth_token_url">Token URL</label>
<input type="text" class="form-control"
name="oidc_oauth_token_url"
@ -1410,7 +1441,8 @@
data-bind="enable: oidc_oauth_enabled() && !oidc_oauth_auto_configure(), value: oidc_oauth_token_url, valueUpdate: 'afterkeydown'">
<span class="help-block with-errors"></span>
</div>
<div class="form-group" data-bind="hidden: oidc_oauth_auto_configure">
<div class="form-group"
data-bind="hidden: oidc_oauth_auto_configure">
<label for="oidc_oauth_authorize_url">Authorize
URL</label>
<input type="text" class="form-control"
@ -1557,10 +1589,12 @@
{%- endassets %}
<script>
let CSRF_TOKEN = '{{ csrf_token() }}';
let API_URL = '{{ url_for('admin.setting_authentication_api') }}';
let CSRF_TOKEN = '{{ csrf_token() }}';
</script>
<script type="text/javascript" src="{{ url_for('static', filename='custom/js/app-authentication-settings-editor.js') }}"></script>
<script type="text/javascript"
src="{{ url_for('static', filename='custom/js/app-authentication-settings-editor.js') }}"></script>
<script>
/*

View File

@ -228,7 +228,7 @@
<footer class="main-footer">
<strong><a href="https://github.com/PowerDNS-Admin/PowerDNS-Admin">PowerDNS-Admin</a></strong> - A PowerDNS web
interface with advanced features.
<span class="float-right">Version 0.4.0</span>
<span class="float-right">Version 0.4.1</span>
</footer>
</div>
<!-- ./wrapper -->