mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-11-14 09:30:27 +00:00
5ad384bfe9
This commit adds support for the `oidc_oauth_metadata_url` configuration option. This option specifies the URL of the OIDC server's metadata endpoint, which contains information about the OIDC server's endpoints, supported scopes, and other configuration details. By using this option, we can ensure compatibility with different OIDC servers and reduce the risk of errors due to manual endpoint configuration.
1780 lines
140 KiB
HTML
1780 lines
140 KiB
HTML
{% extends "base.html" %}
|
|
{% set active_page = "admin_settings" %}
|
|
{% block title %}<title>Authentication Settings - {{ SITE_NAME }}</title>{% endblock %}
|
|
|
|
{% block dashboard_stat %}
|
|
<div class="content-header">
|
|
<div class="container-fluid">
|
|
<div class="row mb-2">
|
|
<div class="col-sm-6">
|
|
<h1 class="m-0 text-dark">Authentication Settings</h1>
|
|
</div>
|
|
<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 active">Authentication Settings</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<section class="content">
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card card-outline card-primary shadow">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Settings Editor</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
{% if result %}
|
|
<div
|
|
class="alert {% if result['status'] %}alert-success{% else %}alert-danger{% endif %} alert-dismissible">
|
|
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">
|
|
×
|
|
</button>
|
|
{{ result['msg'] }}
|
|
</div>
|
|
{% endif %}
|
|
<div class="nav-tabs-custom">
|
|
<ul class="nav nav-tabs" role="tablist">
|
|
<li class="nav-item">
|
|
<a class="nav-link active" href="#tabs-general" data-toggle="pill" role="tab">General</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="#tabs-ldap" data-toggle="pill" role="tab">LDAP</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="#tabs-google" data-toggle="pill" role="tab">Google
|
|
OAuth</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="#tabs-github" data-toggle="pill" role="tab">GitHub
|
|
OAuth</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="#tabs-azure" data-toggle="pill" role="tab">Microsoft
|
|
OAuth</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="#tabs-oidc" data-toggle="pill" role="tab">OpenID
|
|
Connect OAuth</a>
|
|
</li>
|
|
</ul>
|
|
<div class="tab-content">
|
|
|
|
<div class="tab-pane active" id="tabs-general">
|
|
<div class="row">
|
|
<div class="col-12 col-sm-6 col-lg-4">
|
|
<form role="form" method="post">
|
|
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
|
<input type="hidden" value="general" name="config_tab"/>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Basic Settings</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<div class="form-group">
|
|
<input type="checkbox" id="local_db_enabled"
|
|
name="local_db_enabled"
|
|
class="checkbox"
|
|
{% if SETTING.get('local_db_enabled') %}checked{% endif %}>
|
|
<label for="local_db_enabled">Local DB
|
|
Authentication</label>
|
|
</div>
|
|
<div class="form-group">
|
|
<input type="checkbox" id="signup_enabled"
|
|
name="signup_enabled"
|
|
class="checkbox"
|
|
{% if SETTING.get('signup_enabled') %}checked{% endif %}>
|
|
<label for="signup_enabled">Allow users to sign
|
|
up</label>
|
|
</div>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
<div class="card-footer">
|
|
<button type="submit" class="btn btn-primary"
|
|
title="Save Settings">
|
|
<i class="fa-solid fa-save"></i> Save Settings
|
|
</button>
|
|
</div>
|
|
<!-- /.card-footer -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</form>
|
|
</div>
|
|
<!-- /.col -->
|
|
|
|
<div class="col-12 col-sm-6 col-lg-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Settings Help</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<p>Fill in all the fields in the left form.</p>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</div>
|
|
<!-- /.col -->
|
|
</div>
|
|
<!-- /.row -->
|
|
</div>
|
|
<!-- /.tab-pane -->
|
|
|
|
<div class="tab-pane" id="tabs-ldap">
|
|
<div class="row">
|
|
<div class="col-12 col-sm-6 col-lg-4">
|
|
{% if error %}
|
|
<div class="alert alert-danger alert-dismissible">
|
|
<button type="button" class="close" data-dismiss="alert"
|
|
aria-hidden="true">×
|
|
</button>
|
|
<h4><i class="icon fa fa-ban"></i> Error!</h4>
|
|
{{ error }}
|
|
</div>
|
|
{% endif %}
|
|
<form role="form" method="post" data-toggle="validator">
|
|
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
|
<input type="hidden" value="ldap" name="config_tab"/>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">LDAP Settings</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<fieldset>
|
|
<div class="form-group">
|
|
<input type="checkbox" id="ldap_enabled"
|
|
name="ldap_enabled"
|
|
class="checkbox"
|
|
{% if SETTING.get('ldap_enabled') %}checked{% endif %}>
|
|
<label for="ldap_enabled">Enable LDAP
|
|
Authentication</label>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Type</label>
|
|
<div class="radio">
|
|
<label>
|
|
<input type="radio" name="ldap_type"
|
|
id="ldap"
|
|
onclick="javascript:ldapSelection();"
|
|
value="ldap"
|
|
{% if SETTING.get('ldap_type')=='ldap' %}checked{% endif %}>
|
|
OpenLDAP
|
|
</label>
|
|
|
|
<label>
|
|
<input type="radio" name="ldap_type" id="ad"
|
|
onclick="javascript:ldapSelection();"
|
|
value="ad"
|
|
{% if SETTING.get('ldap_type')=='ad' %}checked{% endif %}>
|
|
Active Directory
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>ADMINISTRATOR INFO</legend>
|
|
<div class="form-group">
|
|
<label for="ldap_uri">LDAP URI</label>
|
|
<input type="text" class="form-control"
|
|
name="ldap_uri"
|
|
id="ldap_uri"
|
|
placeholder="e.g. ldaps://your-ldap-server:636"
|
|
data-error="Please input LDAP URI"
|
|
value="{{ SETTING.get('ldap_uri') }}">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="ldap_base_dn">LDAP Base DN</label>
|
|
<input type="text" class="form-control"
|
|
name="ldap_base_dn"
|
|
id="ldap_base_dn"
|
|
placeholder="e.g. dc=mydomain,dc=com"
|
|
data-error="Please input LDAP Base DN"
|
|
value="{{ SETTING.get('ldap_base_dn') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div id="ldap_openldap_fields">
|
|
<div class="form-group">
|
|
<label for="ldap_admin_username">LDAP admin
|
|
username</label>
|
|
<input type="text" class="form-control"
|
|
name="ldap_admin_username"
|
|
id="ldap_admin_username"
|
|
placeholder="e.g. cn=admin,dc=mydomain,dc=com"
|
|
data-error="Please input LDAP admin username"
|
|
value="{{ SETTING.get('ldap_admin_username') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="ldap_admin_password">LDAP admin
|
|
password</label>
|
|
<input type="password" class="form-control"
|
|
name="ldap_admin_password"
|
|
id="ldap_admin_password"
|
|
placeholder="LDAP Admin password"
|
|
data-error="Please input LDAP admin password"
|
|
value="{{ SETTING.get('ldap_admin_password') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</div>
|
|
<div id="ldap_ad_fields">
|
|
<div class="form-group">
|
|
<label for="ldap_domain">Active Directory
|
|
domain</label>
|
|
<input type="text" class="form-control"
|
|
name="ldap_domain" id="ldap_domain"
|
|
placeholder="Active Directory domain"
|
|
data-error="Please input Actve Directory domain value"
|
|
value="{{ SETTING.get('ldap_domain') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>FILTERS</legend>
|
|
<div class="form-group">
|
|
<label for="ldap_filter_basic">Basic filter</label>
|
|
<input type="text" class="form-control"
|
|
name="ldap_filter_basic"
|
|
id="ldap_filter_basic"
|
|
placeholder="e.g. (objectClass=inetorgperson)"
|
|
data-error="Please input LDAP filter"
|
|
value="{{ SETTING.get('ldap_filter_basic') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="ldap_filter_username">Username
|
|
field</label>
|
|
<input type="text" class="form-control"
|
|
name="ldap_filter_username"
|
|
id="ldap_filter_username"
|
|
placeholder="e.g. uid"
|
|
data-error="Please input field for username filtering"
|
|
value="{{ SETTING.get('ldap_filter_username') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div id="ldap_openldap_group_filters">
|
|
<div class="form-group">
|
|
<label for="ldap_filter_group">Group
|
|
filter</label>
|
|
<input type="text" class="form-control"
|
|
name="ldap_filter_group"
|
|
id="ldap_filter_group"
|
|
placeholder="e.g. (objectclass=groupOfNames)"
|
|
data-error="Please input LDAP filter"
|
|
value="{{ SETTING.get('ldap_filter_group') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="ldap_filter_groupname">Group name
|
|
field</label>
|
|
<input type="text" class="form-control"
|
|
name="ldap_filter_groupname"
|
|
id="ldap_filter_groupname"
|
|
placeholder="e.g. member"
|
|
data-error="Please input field for group name filtering"
|
|
value="{{ SETTING.get('ldap_filter_groupname') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>GROUP SECURITY</legend>
|
|
<div class="form-group">
|
|
<label>Status</label>
|
|
<div class="radio">
|
|
<label>
|
|
<input type="radio" name="ldap_sg_enabled"
|
|
id="ldap_sg_off" value="OFF"
|
|
{% if not SETTING.get('ldap_sg_enabled') %}checked{% endif %}>
|
|
OFF
|
|
</label>
|
|
|
|
<label>
|
|
<input type="radio" name="ldap_sg_enabled"
|
|
id="ldap_sg_on" value="ON"
|
|
{% if SETTING.get('ldap_sg_enabled') %}checked{% endif %}>
|
|
ON
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="ldap_admin_group">Admin group</label>
|
|
<input type="text" class="form-control"
|
|
name="ldap_admin_group" id="ldap_admin_group"
|
|
placeholder="e.g. cn=sysops,dc=mydomain,dc=com"
|
|
data-error="Please input LDAP DN for Admin group"
|
|
value="{{ SETTING.get('ldap_admin_group') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="ldap_operator_group">Operator
|
|
group</label>
|
|
<input type="text" class="form-control"
|
|
name="ldap_operator_group"
|
|
id="ldap_operator_group"
|
|
placeholder="e.g. cn=operators,dc=mydomain,dc=com"
|
|
data-error="Please input LDAP DN for Operator group"
|
|
value="{{ SETTING.get('ldap_operator_group') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="ldap_user_group">User group</label>
|
|
<input type="text" class="form-control"
|
|
name="ldap_user_group" id="ldap_user_group"
|
|
placeholder="e.g. cn=users,dc=mydomain,dc=com"
|
|
data-error="Please input LDAP DN for User group"
|
|
value="{{ SETTING.get('ldap_user_group') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>ADVANCE</legend>
|
|
<div class="form-group">
|
|
<label>Roles Autoprovisioning</label>
|
|
<div class="radio">
|
|
<label>
|
|
<input type="radio" name="autoprovisioning"
|
|
id="autoprovisioning_off" value="OFF"
|
|
{% if not SETTING.get('autoprovisioning') %}checked{% endif %}>
|
|
OFF
|
|
</label>
|
|
|
|
<label>
|
|
<input type="radio" name="autoprovisioning"
|
|
id="autoprovisioning_on" value="ON"
|
|
|
|
{% if SETTING.get('autoprovisioning') %}checked{% endif %}>
|
|
ON
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="autoprovisioning_attribute">Roles
|
|
provisioning
|
|
field</label>
|
|
<input type="text" class="form-control"
|
|
name="autoprovisioning_attribute"
|
|
id="autoprovisioning_attribute"
|
|
placeholder="e.g. eduPersonEntitlement"
|
|
data-error=" Please input field responsible for autoprovisioning"
|
|
value="{{ SETTING.get('autoprovisioning_attribute') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
|
|
<div
|
|
class="form-group {% if error %}has-error{% endif %}">
|
|
<label for="urn_value">Urn prefix</label>
|
|
<input type="text" class="form-control"
|
|
name="urn_value"
|
|
id="urn_value"
|
|
placeholder="e.g. urn:mace:<yourOrganization>"
|
|
data-error="Please fill this field"
|
|
value="{{ SETTING.get('urn_value') }}">
|
|
{% if error %}
|
|
<span class="help-block with-errors">Please input the correct prefix for your urn value</span>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Purge Roles If Empty</label>
|
|
<div class="radio">
|
|
<label>
|
|
<input type="radio" name="purge"
|
|
id="purge_off"
|
|
value="OFF"
|
|
{% if not SETTING.get('purge') %}checked{% endif %}>
|
|
OFF
|
|
</label>
|
|
|
|
<label>
|
|
<input type="radio" name="purge"
|
|
id="purge_on"
|
|
value="ON"
|
|
{% if SETTING.get('purge') %}checked{% endif %}>
|
|
ON
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
<div class="card-footer">
|
|
<button type="submit" class="btn btn-primary"
|
|
title="Save Settings">
|
|
<i class="fa-solid fa-save"></i> Save Settings
|
|
</button>
|
|
</div>
|
|
<!-- /.card-footer -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</form>
|
|
</div>
|
|
<!-- /.col -->
|
|
|
|
<div class="col-12 col-sm-6 col-lg-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Settings Help</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<dl class="dl-horizontal">
|
|
<dt>Enable LDAP Authentication</dt>
|
|
<dd>Turn on / off the LDAP authentication.</dd>
|
|
<dt>Type</dt>
|
|
<dd>Select your current directory service type.
|
|
<ul>
|
|
<li>
|
|
OpenLDAP - Open source implementation of the
|
|
Lightweight
|
|
Directory Access Protocol.
|
|
</li>
|
|
<li>
|
|
Active Directory - Active Directory is a
|
|
directory
|
|
service that Microsoft developed for the Windows
|
|
domain
|
|
networks.
|
|
</li>
|
|
</ul>
|
|
</dd>
|
|
<dt>ADMINISTRATOR INFO</dt>
|
|
<dd>Your LDAP connection string and admin credential used by
|
|
PDA to
|
|
query user information.
|
|
<ul>
|
|
<li>
|
|
LDAP URI - The fully qualified domain names of
|
|
your
|
|
directory servers. (e.g. ldap://127.0.0.1:389)
|
|
</li>
|
|
<li>
|
|
LDAP Base DN - The point from where a PDA will
|
|
search
|
|
for users.
|
|
</li>
|
|
<li>
|
|
LDAP admin username - Your LDAP administrator
|
|
user which
|
|
has permission to query information in the Base
|
|
DN
|
|
above. Not needed for Active Directory
|
|
authentication.
|
|
</li>
|
|
<li>
|
|
LDAP admin password - The password of LDAP
|
|
administrator
|
|
user. Not needed for Active Directory
|
|
authentication.
|
|
</li>
|
|
<li>
|
|
Active Directory domain - Active Directory
|
|
domain used.
|
|
</li>
|
|
</ul>
|
|
</dd>
|
|
<dt>FILTERS</dt>
|
|
<dd>Define how you want to filter your user in LDAP query.
|
|
<ul>
|
|
<li>
|
|
Basic filter - The filter that will be applied
|
|
to all
|
|
LDAP query by PDA. (e.g.
|
|
<i>(objectClass=inetorgperson)</i> for OpenLDAP
|
|
and <i>(objectClass=organizationalPerson)</i>
|
|
for Active Directory)
|
|
</li>
|
|
<li>
|
|
Username field - The field PDA will look for
|
|
user's
|
|
username. (e.g. <i>uid</i> for OpenLDAP and <i>sAMAccountName</i>
|
|
for Active Directory)
|
|
</li>
|
|
<li>
|
|
Group filter - The filter that will be applied
|
|
to all
|
|
LDAP group queries by PDA. (e.g. <i>(objectClass=groupOfNames)</i>
|
|
for OpenLDAP)
|
|
</li>
|
|
<li>
|
|
Group name field - The field PDA will look for
|
|
group
|
|
names. (e.g. <i>member</i> for OpenLDAP)
|
|
</li>
|
|
</ul>
|
|
</dd>
|
|
<dt>GROUP SECURITY</dt>
|
|
<dd>User can be assigned to PDA's User or Admin group by
|
|
matching
|
|
following LDAP Group.
|
|
<ul>
|
|
<li>
|
|
Status - Turn on / off group security feature.
|
|
</li>
|
|
<li>
|
|
Admin group - Your LDAP admin group.
|
|
</li>
|
|
<li>
|
|
Operator group - Your LDAP operator group.
|
|
</li>
|
|
<li>
|
|
User group - Your LDAP user group.
|
|
</li>
|
|
</ul>
|
|
</dd>
|
|
<dt>ADVANCE</dt>
|
|
<dd> Provision PDA user privileges based on LDAP Object
|
|
Attributes.
|
|
Alternative to Group Security Role Management.
|
|
<ul>
|
|
<li>
|
|
Roles Autoprovisioning - If toggled on, the PDA
|
|
Role and
|
|
the associations of users found in the local db,
|
|
will be
|
|
instantly updated from the LDAP server every
|
|
time they
|
|
log in.
|
|
</li>
|
|
<li>
|
|
Roles provisioning field - The attribute in the
|
|
ldap
|
|
server populated by the urn values where PDA
|
|
will look
|
|
for a new Role and/or new associations to
|
|
domains/accounts.
|
|
</li>
|
|
<li>
|
|
Urn prefix - The prefix used before the static
|
|
keyword
|
|
"powerdns-admin" for your entitlements in the
|
|
ldap
|
|
server. Must comply with RFC no.8141.
|
|
</li>
|
|
<li>
|
|
Purge Roles If Empty - If toggled on, ldap
|
|
entries that
|
|
have no valid "powerdns-admin" records to their
|
|
autoprovisioning field, will lose all their
|
|
associations
|
|
with any domain or account, also reverting to a
|
|
User in
|
|
the process, despite their current role in the
|
|
local db.<br>
|
|
If toggled off, in the same scenario they get to
|
|
keep
|
|
their existing associations and their current
|
|
Role.
|
|
</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</div>
|
|
<!-- /.col -->
|
|
</div>
|
|
<!-- /.row -->
|
|
</div>
|
|
<!-- /.tab-pane -->
|
|
|
|
<div class="tab-pane" id="tabs-google">
|
|
<div class="row">
|
|
<div class="col-12 col-sm-6 col-lg-4">
|
|
<form role="form" method="post" data-toggle="validator">
|
|
<input type="hidden" name="_csrf_token"
|
|
value="{{ csrf_token() }}">
|
|
<input type="hidden" value="google" name="config_tab"/>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Google OAuth Settings</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<fieldset>
|
|
<div class="form-group">
|
|
<input type="checkbox" id="google_oauth_enabled"
|
|
name="google_oauth_enabled" class="checkbox"
|
|
{% if SETTING.get('google_oauth_enabled') %}checked{% endif %}>
|
|
<label for="google_oauth_enabled">Enable Google
|
|
OAuth</label>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="google_oauth_client_id">Client
|
|
ID</label>
|
|
<input type="text" class="form-control"
|
|
name="google_oauth_client_id"
|
|
id="google_oauth_client_id"
|
|
placeholder="Google OAuth client ID"
|
|
data-error="Please input Client ID"
|
|
value="{{ SETTING.get('google_oauth_client_id') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="google_oauth_client_secret">Client
|
|
secret</label>
|
|
<input type="text" class="form-control"
|
|
name="google_oauth_client_secret"
|
|
id="google_oauth_client_secret"
|
|
placeholder="Google OAuth client secret"
|
|
data-error="Please input Client secret"
|
|
value="{{ SETTING.get('google_oauth_client_secret') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>ADVANCE</legend>
|
|
<div class="form-group">
|
|
<label for="google_token_url">Token URL</label>
|
|
<input type="text" class="form-control"
|
|
name="google_token_url" id="google_token_url"
|
|
placeholder="e.g. https://accounts.google.com/o/oauth2/token"
|
|
data-error="Please input token URL"
|
|
value="{{ SETTING.get('google_token_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="google_oauth_scope">Scope</label>
|
|
<input type="text" class="form-control"
|
|
name="google_oauth_scope"
|
|
id="google_oauth_scope"
|
|
placeholder="e.g. email profile"
|
|
data-error="Please input scope"
|
|
value="{{ SETTING.get('google_oauth_scope') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="google_authorize_url">Authorize
|
|
URL</label>
|
|
<input type="text" class="form-control"
|
|
name="google_authorize_url"
|
|
id="google_authorize_url"
|
|
placeholder="e.g. https://accounts.google.com/o/oauth2/auth"
|
|
data-error="Please input Authorize URL"
|
|
value="{{ SETTING.get('google_authorize_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="google_base_url">Base URL</label>
|
|
<input type="text" class="form-control"
|
|
name="google_base_url" id="google_base_url"
|
|
placeholder="e.g. https://www.googleapis.com/oauth2/v1/"
|
|
data-error="Please input base URL"
|
|
value="{{ SETTING.get('google_base_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
<div class="card-footer">
|
|
<button type="submit" class="btn btn-primary"
|
|
title="Save Settings">
|
|
<i class="fa-solid fa-save"></i> Save Settings
|
|
</button>
|
|
</div>
|
|
<!-- /.card-footer -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</form>
|
|
</div>
|
|
<!-- /.col -->
|
|
|
|
<div class="col-12 col-sm-6 col-lg-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Settings Help</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<p>Fill in all the fields in the left form.</p>
|
|
<p>Make sure you add PDA redirection URI (e.g
|
|
http://localhost:9191/google/authorized) to your Google App
|
|
Credentials Restriction.</p>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</div>
|
|
<!-- /.col -->
|
|
</div>
|
|
<!-- /.row -->
|
|
</div>
|
|
<!-- /.tab-pane -->
|
|
|
|
<div class="tab-pane" id="tabs-github">
|
|
<div class="row">
|
|
<div class="col-12 col-sm-6 col-lg-4">
|
|
<form role="form" method="post" data-toggle="validator">
|
|
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
|
<input type="hidden" value="github" name="config_tab"/>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">GitHub OAuth Settings</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<fieldset>
|
|
<div class="form-group">
|
|
<input type="checkbox" id="github_oauth_enabled"
|
|
name="github_oauth_enabled" class="checkbox"
|
|
{% if SETTING.get('github_oauth_enabled') %}checked{% endif %}>
|
|
<label for="github_oauth_enabled">Enable Github
|
|
OAuth</label>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="github_oauth_key">Client key</label>
|
|
<input type="text" class="form-control"
|
|
name="github_oauth_key" id="github_oauth_key"
|
|
placeholder="Github OAuth client ID"
|
|
data-error="Please input Client key"
|
|
value="{{ SETTING.get('github_oauth_key') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="github_oauth_secret">Client
|
|
secret</label>
|
|
<input type="text" class="form-control"
|
|
name="github_oauth_secret"
|
|
id="github_oauth_secret"
|
|
placeholder="Github OAuth client secret"
|
|
data-error="Please input Client secret"
|
|
value="{{ SETTING.get('github_oauth_secret') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>ADVANCE</legend>
|
|
<div class="form-group">
|
|
<label for="github_oauth_scope">Scope</label>
|
|
<input type="text" class="form-control"
|
|
name="github_oauth_scope"
|
|
id="github_oauth_scope"
|
|
placeholder="e.g. email"
|
|
data-error="Please input scope"
|
|
value="{{ SETTING.get('github_oauth_scope') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="github_oauth_api_url">API URL</label>
|
|
<input type="text" class="form-control"
|
|
name="github_oauth_api_url"
|
|
id="github_oauth_api_url"
|
|
placeholder="e.g. https://api.github.com/user"
|
|
data-error="Please input API URL"
|
|
value="{{ SETTING.get('github_oauth_api_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="github_oauth_token_url">Token
|
|
URL</label>
|
|
<input type="text" class="form-control"
|
|
name="github_oauth_token_url"
|
|
id="github_oauth_token_url"
|
|
placeholder="e.g. https://github.com/login/oauth/access_token"
|
|
data-error="Please input Token URL"
|
|
value="{{ SETTING.get('github_oauth_token_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="github_oauth_authorize_url">Authorize
|
|
URL</label>
|
|
<input type="text" class="form-control"
|
|
name="github_oauth_authorize_url"
|
|
id="github_oauth_authorize_url"
|
|
placeholder="e.g. https://github.com/login/oauth/authorize"
|
|
data-error="Plesae input Authorize URL"
|
|
value="{{ SETTING.get('github_oauth_authorize_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
<div class="card-footer">
|
|
<button type="submit" class="btn btn-primary"
|
|
title="Save Settings">
|
|
<i class="fa-solid fa-save"></i> Save Settings
|
|
</button>
|
|
</div>
|
|
<!-- /.card-footer -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</form>
|
|
</div>
|
|
<!-- /.col -->
|
|
|
|
<div class="col-12 col-sm-6 col-lg-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Settings Help</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<p>Fill in all the fields in the left form.</p>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</div>
|
|
<!-- /.col -->
|
|
</div>
|
|
<!-- /.row -->
|
|
</div>
|
|
<!-- /.tab-pane -->
|
|
|
|
<div class="tab-pane" id="tabs-azure">
|
|
<div class="row">
|
|
<div class="col-12 col-sm-6 col-lg-4">
|
|
<form role="form" method="post" data-toggle="validator">
|
|
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
|
<input type="hidden" value="azure" name="config_tab"/>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Microsoft OAuth Settings</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<fieldset>
|
|
<div class="form-group">
|
|
<input type="checkbox" id="azure_oauth_enabled"
|
|
name="azure_oauth_enabled" class="checkbox"
|
|
{% if SETTING.get('azure_oauth_enabled') %}checked{% endif %}>
|
|
<label for="azure_oauth_enabled">Enable Microsoft
|
|
Azure
|
|
OAuth</label>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_oauth_key">Client key</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_oauth_key" id="azure_oauth_key"
|
|
placeholder="Azure OAuth client ID"
|
|
data-error="Please input Client key"
|
|
value="{{ SETTING.get('azure_oauth_key') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_oauth_secret">Client
|
|
secret</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_oauth_secret"
|
|
id="azure_oauth_secret"
|
|
placeholder="Azure OAuth client secret"
|
|
data-error="Please input Client secret"
|
|
value="{{ SETTING.get('azure_oauth_secret') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>ADVANCED</legend>
|
|
<div class="form-group">
|
|
<label for="azure_oauth_scope">Scope</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_oauth_scope"
|
|
id="azure_oauth_scope"
|
|
placeholder="e.g. email"
|
|
data-error="Please input scope - e.g. User.Read"
|
|
value="{{ SETTING.get('azure_oauth_scope') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_oauth_api_url">API URL</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_oauth_api_url"
|
|
id="azure_oauth_api_url"
|
|
placeholder="e.g. https://graph.microsoft.com/v1.0/"
|
|
data-error="Please input API URL"
|
|
value="{{ SETTING.get('azure_oauth_api_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_oauth_token_url">Token URL</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_oauth_token_url"
|
|
id="azure_oauth_token_url"
|
|
placeholder="e.g. https://login.microsoftonline.com/[tenancyID]/oauth2/v2.0/token"
|
|
data-error="Please input Token URL"
|
|
value="{{ SETTING.get('azure_oauth_token_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_oauth_authorize_url">Authorize
|
|
URL</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_oauth_authorize_url"
|
|
id="azure_oauth_authorize_url"
|
|
placeholder="e.g. https://login.microsoftonline.com/[tenancyID]/oauth2/v2.0/authorize"
|
|
data-error="Please input Authorize URL"
|
|
value="{{ SETTING.get('azure_oauth_authorize_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>GROUP SECURITY</legend>
|
|
<div class="form-group">
|
|
<label>Status</label>
|
|
<div class="radio">
|
|
<label>
|
|
<input type="radio" name="azure_sg_enabled"
|
|
id="azure_sg_off" value="OFF"
|
|
{% if not SETTING.get('azure_sg_enabled') %}checked{% endif %}>
|
|
OFF
|
|
</label>
|
|
|
|
<label>
|
|
<input type="radio" name="azure_sg_enabled"
|
|
id="azure_sg_on" value="ON"
|
|
{% if SETTING.get('azure_sg_enabled') %}checked{% endif %}>
|
|
ON
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_admin_group">Admin group</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_admin_group"
|
|
id="azure_admin_group"
|
|
placeholder="e.g. 00000000-0000-0000-0000-000000000000"
|
|
data-error="Please input the ID for Admin group"
|
|
value="{{ SETTING.get('azure_admin_group') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_operator_group">Operator
|
|
group</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_operator_group"
|
|
id="azure_operator_group"
|
|
placeholder="e.g. 00000000-0000-0000-0000-000000000000"
|
|
data-error="Please input the ID for Operator group"
|
|
value="{{ SETTING.get('azure_operator_group') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_user_group">User group</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_user_group" id="azure_user_group"
|
|
placeholder="e.g. 00000000-0000-0000-0000-000000000000"
|
|
data-error="Please input the ID for User group"
|
|
value="{{ SETTING.get('azure_user_group') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>AZURE GROUP ACCOUNT SYNC/CREATION</legend>
|
|
<div class="form-group">
|
|
<label
|
|
for="azure_group_accounts_enabled">Status</label>
|
|
<div class="radio">
|
|
<label>
|
|
<input type="radio"
|
|
name="azure_group_accounts_enabled"
|
|
id="azure_group_accounts_off"
|
|
value="OFF"
|
|
{% if not SETTING.get('azure_group_accounts_enabled') %}checked{% endif %}>
|
|
OFF
|
|
</label>
|
|
|
|
<label>
|
|
<input type="radio"
|
|
name="azure_group_accounts_enabled"
|
|
id="azure_group_accounts_on"
|
|
value="ON"
|
|
{% if SETTING.get('azure_group_accounts_enabled') %}checked{% endif %}>
|
|
ON
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_group_accounts_name">Azure group
|
|
name
|
|
claim</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_group_accounts_name"
|
|
id="azure_group_accounts_name"
|
|
placeholder="e.g. displayName"
|
|
data-error="Please input the Claim for Azure group name"
|
|
value="{{ SETTING.get('azure_group_accounts_name') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_group_accounts_name_re">Azure
|
|
group name
|
|
claim regex</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_group_accounts_name_re"
|
|
id="azure_group_accounts_name_re"
|
|
placeholder="e.g. (.*)"
|
|
data-error="Please input the regex for Azure group name"
|
|
value="{{ SETTING.get('azure_group_accounts_name_re') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_group_accounts_description">Azure
|
|
group
|
|
description claim</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_group_accounts_description"
|
|
id="azure_group_accounts_description"
|
|
placeholder="e.g. description. If empty uses whole string"
|
|
data-error="Please input the Claim for Azure group description"
|
|
value="{{ SETTING.get('azure_group_accounts_description') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="azure_group_accounts_description_re">Azure
|
|
group name
|
|
description regex</label>
|
|
<input type="text" class="form-control"
|
|
name="azure_group_accounts_description_re"
|
|
id="azure_group_accounts_description_re"
|
|
placeholder="e.g. (.*). If empty uses whole string"
|
|
data-error="Please input the regex for Azure group description"
|
|
value="{{ SETTING.get('azure_group_accounts_description_re') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
<div class="card-footer">
|
|
<button type="submit" class="btn btn-primary"
|
|
title="Save Settings">
|
|
<i class="fa-solid fa-save"></i> Save Settings
|
|
</button>
|
|
</div>
|
|
<!-- /.card-footer -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</form>
|
|
</div>
|
|
<!-- /.col -->
|
|
|
|
<div class="col-12 col-sm-6 col-lg-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Settings Help</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<p>Fill in all the fields in the left form.</p>
|
|
<p>You first need to define an Application Registration in your
|
|
Azure
|
|
Active Directory, with the appropriate HTTPS URL for this
|
|
endpoint,
|
|
and with the appropriate rights, as explained in the
|
|
documentation.</p>
|
|
<p>
|
|
<ul>
|
|
<li>Under the Azure Active Directory, select App
|
|
Registrations, and
|
|
create a new one. Give it any name you want, and the
|
|
Redirect
|
|
URI shoule be type 'Web' and of the format <b>https://powerdnsadmin/azure/authorized</b>
|
|
(replace the host name approriately).
|
|
</li>
|
|
<li>Select the newly-created registration</li>
|
|
<li>On the Overview page, the Application ID is your new
|
|
Client ID
|
|
to use with PowerDNS-Admin
|
|
</li>
|
|
<li>On the Overview page, make a note of your
|
|
Directory/Tenant ID -
|
|
you need it for the API URLs later
|
|
</li>
|
|
<li>Ensure Access Tokens are enabled in the Authentication
|
|
section
|
|
</li>
|
|
<li>Under Certificates and Secrets, create a new Client
|
|
Secret. Note
|
|
this secret as it is the new Client Secret to use with
|
|
PowerDNS-Admin
|
|
</li>
|
|
<li>Under API Permissions, you need to add permissions. Add
|
|
permissions for Graph API, Delegated. Add: email,
|
|
openid,
|
|
profile, GroupMember.Read, User.Read and possibly
|
|
User.Read.All.
|
|
You then need to grant admin approval for your
|
|
organisation.
|
|
</li>
|
|
<li>For the Scope, use <b>User.Read openid mail profile</b>
|
|
</li>
|
|
<li>Replace the [tenantID] in the default URLs for authorize
|
|
and
|
|
token with your Tenant ID.
|
|
</li>
|
|
</ul>
|
|
</p>
|
|
<p>If <b>AZURE GROUP ACCOUNT SYNC/CREATION</b> is enabled,
|
|
Accounts will
|
|
be created automatically based on group membership. If an
|
|
Account
|
|
exists, an authenticated user with group membership is added
|
|
to the
|
|
Account</p>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</div>
|
|
<!-- /.col -->
|
|
</div>
|
|
<!-- /.row -->
|
|
</div>
|
|
<!-- /.tab-pane -->
|
|
|
|
<div class="tab-pane" id="tabs-oidc">
|
|
<div class="row">
|
|
<div class="col-12 col-sm-6 col-lg-4">
|
|
<form role="form" method="post" data-toggle="validator">
|
|
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
|
<input type="hidden" value="oidc" name="config_tab"/>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">OpenID Connect OAuth Settings</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<fieldset>
|
|
<div class="form-group">
|
|
<input type="checkbox" id="oidc_oauth_enabled"
|
|
name="oidc_oauth_enabled" class="checkbox"
|
|
{% if SETTING.get('oidc_oauth_enabled') %}checked{% endif %}>
|
|
<label for="oidc_oauth_enabled">Enable OpenID
|
|
Connect
|
|
OAuth</label>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_key">Client key</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_key" id="oidc_oauth_key"
|
|
placeholder="OIDC OAuth client ID"
|
|
data-error="Please input Client key"
|
|
value="{{ SETTING.get('oidc_oauth_key') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_secret">Client secret</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_secret"
|
|
id="oidc_oauth_secret"
|
|
placeholder="OIDC OAuth client secret"
|
|
data-error="Please input Client secret"
|
|
value="{{ SETTING.get('oidc_oauth_secret') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_scope">Scope</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_scope" id="oidc_oauth_scope"
|
|
placeholder="e.g. email"
|
|
data-error="Please input scope"
|
|
value="{{ SETTING.get('oidc_oauth_scope') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_api_url">API URL</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_api_url"
|
|
id="oidc_oauth_api_url"
|
|
placeholder="e.g. https://api.oidc.com/user"
|
|
data-error="Please input API URL"
|
|
value="{{ SETTING.get('oidc_oauth_api_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_token_url">Token URL</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_token_url"
|
|
id="oidc_oauth_token_url"
|
|
placeholder="e.g. https://oidc.com/login/oauth/access_token"
|
|
data-error="Please input Token URL"
|
|
value="{{ SETTING.get('oidc_oauth_token_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_authorize_url">Authorize
|
|
URL</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_authorize_url"
|
|
id="oidc_oauth_authorize_url"
|
|
placeholder="e.g. https://oidc.com/login/oauth/authorize"
|
|
data-error="Plesae input Authorize URL"
|
|
value="{{ SETTING.get('oidc_oauth_authorize_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_metadata_url">Metadata
|
|
URL</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_metadata_url"
|
|
id="oidc_oauth_metadata_url"
|
|
placeholder="e.g. https://oidc.com/login/oauth/.well-known/openid-configuration"
|
|
data-error="Plesae input Metadata URL"
|
|
value="{{ SETTING.get('oidc_oauth_metadata_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_logout_url">Logout
|
|
URL</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_logout_url"
|
|
id="oidc_oauth_logout_url"
|
|
placeholder="e.g. https://oidc.com/login/oauth/logout"
|
|
data-error="Please input Logout URL"
|
|
value="{{ SETTING.get('oidc_oauth_logout_url') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>CLAIMS</legend>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_username">Username</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_username"
|
|
id="oidc_oauth_username"
|
|
placeholder="e.g. preferred_username"
|
|
data-error="Please input Username claim"
|
|
value="{{ SETTING.get('oidc_oauth_username') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_firstname">First Name</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_firstname"
|
|
id="oidc_oauth_firstname"
|
|
placeholder="e.g. given_name"
|
|
data-error="Please input First Name claim"
|
|
value="{{ SETTING.get('oidc_oauth_firstname') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_last_name">Last Name</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_last_name"
|
|
id="oidc_oauth_last_name"
|
|
placeholder="e.g. family_name"
|
|
data-error="Please input Last Name claim"
|
|
value="{{ SETTING.get('oidc_oauth_last_name') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_email">Email</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_email" id="oidc_oauth_email"
|
|
placeholder="e.g. email"
|
|
data-error="Plesae input Email claim"
|
|
value="{{ SETTING.get('oidc_oauth_email') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>ADVANCE</legend>
|
|
<div class="form-group">
|
|
<label for="oidc_oauth_account_name_property">Autoprovision
|
|
Account Name property</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_account_name_property"
|
|
id="oidc_oauth_account_name_property"
|
|
placeholder="e.g. account_name"
|
|
data-error="Please input property containing account_name"
|
|
value="{{ SETTING.get('oidc_oauth_account_name_property') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
<div class="form-group">
|
|
<label
|
|
for="oidc_oauth_account_description_property">Autoprovision
|
|
Account Description property</label>
|
|
<input type="text" class="form-control"
|
|
name="oidc_oauth_account_description_property"
|
|
id="oidc_oauth_account_description_property"
|
|
placeholder="e.g. account_description"
|
|
data-error="Please input property containing account_description"
|
|
value="{{ SETTING.get('oidc_oauth_account_description_property') }}">
|
|
<span class="help-block with-errors"></span>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
<div class="card-footer">
|
|
<button type="submit" class="btn btn-primary"
|
|
title="Save Settings">
|
|
<i class="fa-solid fa-save"></i> Save Settings
|
|
</button>
|
|
</div>
|
|
<!-- /.card-footer -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</form>
|
|
</div>
|
|
<!-- /.col -->
|
|
<div class="col-12 col-sm-6 col-lg-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Settings Help</h3>
|
|
</div>
|
|
<!-- /.card-header -->
|
|
<div class="card-body">
|
|
<p>Fill in all the fields in the left form.</p>
|
|
</div>
|
|
<!-- /.card-body -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</div>
|
|
<!-- /.col -->
|
|
</div>
|
|
<!-- /.row -->
|
|
</div>
|
|
<!-- /.tab-pane -->
|
|
|
|
</div>
|
|
<!-- /.tab-content -->
|
|
</div>
|
|
<!-- /.nav-tabs-custom -->
|
|
</div>
|
|
<!-- /.card-body -->
|
|
</div>
|
|
<!-- /.card -->
|
|
</div>
|
|
<!-- /.col -->
|
|
</div>
|
|
<!-- /.row -->
|
|
</div>
|
|
<!-- /.container-fluid -->
|
|
</section>
|
|
{% endblock %}
|
|
|
|
{% block extrascripts %}
|
|
{% assets "js_validation" -%}
|
|
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
|
|
{%- endassets %}
|
|
|
|
<script>
|
|
function ldapSelection() {
|
|
if (document.getElementById('ldap').checked) {
|
|
document.getElementById('ldap_openldap_fields').style.display = 'block';
|
|
document.getElementById('ldap_openldap_group_filters').style.display = 'block';
|
|
document.getElementById('ldap_ad_fields').style.display = 'none';
|
|
} else {
|
|
document.getElementById('ldap_openldap_fields').style.display = 'none';
|
|
document.getElementById('ldap_openldap_group_filters').style.display = 'none';
|
|
document.getElementById('ldap_ad_fields').style.display = 'block';
|
|
}
|
|
}
|
|
|
|
window.onload = function () {
|
|
ldapSelection();
|
|
}
|
|
|
|
$(function () {
|
|
$('#tabs').tabs({
|
|
// add url anchor tags
|
|
activate: function (event, ui) {
|
|
window.location.hash = ui.newPanel.attr('id');
|
|
}
|
|
});
|
|
// re-set active tab (ui)
|
|
var activeTabIdx = $('#tabs').tabs('option', 'active');
|
|
$('#tabs li:eq(' + activeTabIdx + ')').tab('show')
|
|
});
|
|
|
|
// START: General tab js
|
|
$('#local_db_enabled').iCheck({
|
|
checkboxClass: 'icheckbox_square-blue',
|
|
increaseArea: '20%'
|
|
})
|
|
|
|
$('#signup_enabled').iCheck({
|
|
checkboxClass: 'icheckbox_square-blue',
|
|
increaseArea: '20%'
|
|
})
|
|
|
|
$('#autoprovisioning').iCheck({
|
|
checkboxClass: 'icheckbox_square-blue',
|
|
increaseArea: '20%'
|
|
})
|
|
// END: General tab js
|
|
|
|
// START: LDAP tab js
|
|
// update validation requirement when checkbox is togged
|
|
$('#ldap_enabled').iCheck({
|
|
checkboxClass: 'icheckbox_square-blue',
|
|
increaseArea: '20%'
|
|
}).on('ifChanged', function (e) {
|
|
var is_enabled = e.currentTarget.checked;
|
|
if (is_enabled) {
|
|
$('#ldap_uri').prop('required', true);
|
|
$('#ldap_base_dn').prop('required', true);
|
|
if ($('#ldap').is(":checked")) {
|
|
$('#ldap_admin_username').prop('required', true);
|
|
$('#ldap_admin_password').prop('required', true);
|
|
$('#ldap_domain').prop('required', false);
|
|
$('#ldap_filter_group').prop('required', true);
|
|
$('#ldap_filter_groupname').prop('required', true);
|
|
} else {
|
|
$('#ldap_admin_username').prop('required', false);
|
|
$('#ldap_admin_password').prop('required', false);
|
|
$('#ldap_domain').prop('required', true);
|
|
$('#ldap_filter_group').prop('required', false);
|
|
$('#ldap_filter_groupname').prop('required', false);
|
|
}
|
|
$('#ldap_filter_basic').prop('required', true);
|
|
$('#ldap_filter_username').prop('required', true);
|
|
|
|
if ($('#ldap_sg_on').is(":checked")) {
|
|
$('#ldap_admin_group').prop('required', true);
|
|
$('#ldap_operator_group').prop('required', true);
|
|
$('#ldap_user_group').prop('required', true);
|
|
}
|
|
if ($('#autoprovisioning').is(":checked")) {
|
|
$('#autoprovisioning_attribute').prop('required', true);
|
|
$('#urn_value').prop('required', true);
|
|
}
|
|
} else {
|
|
$('#ldap_uri').prop('required', false);
|
|
$('#ldap_base_dn').prop('required', false);
|
|
$('#ldap_admin_username').prop('required', false);
|
|
$('#ldap_admin_password').prop('required', false);
|
|
$('#ldap_filter_basic').prop('required', false);
|
|
$('#ldap_filter_group').prop('required', false);
|
|
$('#ldap_filter_username').prop('required', false);
|
|
$('#ldap_filter_groupname').prop('required', false);
|
|
|
|
if ($('#ldap_sg_on').is(":checked")) {
|
|
$('#ldap_admin_group').prop('required', false);
|
|
$('#ldap_operator_group').prop('required', false);
|
|
$('#ldap_user_group').prop('required', false);
|
|
}
|
|
if ($('#autoprovisioning').is(":checked")) {
|
|
$('#autoprovisioning_attribute').prop('required', false);
|
|
$('#urn_value').prop('required', true);
|
|
}
|
|
}
|
|
});
|
|
|
|
$("input[name='ldap_sg_enabled']").change(function () {
|
|
if ($('#ldap_sg_on').is(":checked") && $('#ldap_enabled').is(":checked")) {
|
|
$('#ldap_admin_group').prop('required', true);
|
|
$('#ldap_operator_group').prop('required', true);
|
|
$('#ldap_user_group').prop('required', true);
|
|
} else {
|
|
$('#ldap_admin_group').prop('required', false);
|
|
$('#ldap_operator_group').prop('required', false);
|
|
$('#ldap_user_group').prop('required', false);
|
|
}
|
|
|
|
if ($('#ldap_sg_on').is(":checked") && $('#autoprovisioning_on').is(":checked")) {
|
|
document.getElementById('ldap_sg_on').checked = false;
|
|
document.getElementById('ldap_sg_off').checked = true;
|
|
var modal = $("#modal_warning");
|
|
|
|
var info = "Group Security:Status and Advance:Autoprovisioning can not be both enabled at the same time. Please turn off Advance:Autoprovisioning first";
|
|
modal.find('.modal-body p').text(info);
|
|
modal.find('#button_warning_confirm').click(function () {
|
|
modal.modal('hide');
|
|
})
|
|
modal.find('#warning_X').click(function () {
|
|
modal.modal('hide');
|
|
})
|
|
modal.modal('show');
|
|
}
|
|
});
|
|
|
|
$("input[name='autoprovisioning']").change(function () {
|
|
if ($('#autoprovisioning_on').is(":checked") && $('#ldap_enabled').is(":checked")) {
|
|
$('#autoprovisioning_attribute').prop('required', true);
|
|
$('#urn_value').prop('required', true);
|
|
$('#purge').prop('required', true);
|
|
} else {
|
|
$('#autoprovisioning_attribute').prop('required', false);
|
|
$('#urn_value').prop('required', false);
|
|
$('#purge').prop('required', false);
|
|
}
|
|
if ($('#ldap_sg_on').is(":checked") && $('#autoprovisioning_on').is(":checked")) {
|
|
document.getElementById('autoprovisioning_on').checked = false;
|
|
document.getElementById('autoprovisioning_off').checked = true;
|
|
var modal = $("#modal_warning");
|
|
var info = "Group Security:Status and Advance:Autoprovisioning can not be both enabled at the same time. Please turn off Group Security:Status first";
|
|
modal.find('.modal-body p').text(info);
|
|
modal.find('#button_warning_confirm').click(function () {
|
|
|
|
modal.modal('hide');
|
|
})
|
|
modal.find('#warning_X').click(function () {
|
|
modal.modal('hide');
|
|
})
|
|
modal.modal('show');
|
|
|
|
}
|
|
});
|
|
|
|
$("input[name='purge']").change(function () {
|
|
if ($("#purge_on").is(":checked")) {
|
|
document.getElementById('purge_on').checked = false;
|
|
document.getElementById('purge_off').checked = true;
|
|
var modal = $("#modal_confirm");
|
|
var info = "Are you sure you want to do this? Users will lose their associated domains unless they already have their autoprovisioning field prepopulated.";
|
|
modal.find('.modal-body p').text(info);
|
|
modal.find('#button_confirm').click(function () {
|
|
document.getElementById('purge_on').checked = true;
|
|
document.getElementById('purge_off').checked = false;
|
|
modal.modal('hide');
|
|
})
|
|
modal.find('#button_cancel').click(function () {
|
|
modal.modal('hide');
|
|
})
|
|
modal.find('#X').click(function () {
|
|
modal.modal('hide');
|
|
})
|
|
modal.modal('show');
|
|
}
|
|
});
|
|
|
|
$("input[name='ldap_type']").change(function () {
|
|
if ($('#ldap').is(":checked") && $('#ldap_enabled').is(":checked")) {
|
|
$('#ldap_admin_group').prop('required', true);
|
|
$('#ldap_operator_group').prop('required', true);
|
|
$('#ldap_user_group').prop('required', true);
|
|
$('#ldap_domain').prop('required', false);
|
|
} else {
|
|
$('#ldap_admin_group').prop('required', false);
|
|
$('#ldap_operator_group').prop('required', false);
|
|
$('#ldap_user_group').prop('required', false);
|
|
$('#ldap_domain').prop('required', true);
|
|
}
|
|
});
|
|
|
|
// init validation requirement at first time page load
|
|
{% if SETTING.get('ldap_enabled') %}
|
|
$('#ldap_uri').prop('required', true);
|
|
$('#ldap_base_dn').prop('required', true);
|
|
if ($('#ldap').is(":checked")) {
|
|
$('#ldap_admin_username').prop('required', true);
|
|
$('#ldap_admin_password').prop('required', true);
|
|
$('#ldap_domain').prop('required', false);
|
|
} else {
|
|
$('#ldap_admin_username').prop('required', false);
|
|
$('#ldap_admin_password').prop('required', false);
|
|
$('#ldap_domain').prop('required', true);
|
|
}
|
|
$('#ldap_filter_basic').prop('required', true);
|
|
$('#ldap_filter_group').prop('required', true);
|
|
$('#ldap_filter_username').prop('required', true);
|
|
$('#ldap_filter_groupname').prop('required', true);
|
|
|
|
if ($('#ldap_sg_on').is(":checked")) {
|
|
$('#ldap_admin_group').prop('required', true);
|
|
$('#ldap_operator_group').prop('required', true);
|
|
$('#ldap_user_group').prop('required', true);
|
|
}
|
|
|
|
if ($('#autoprovisioning_on').is(":checked")) {
|
|
$('#autoprovisioning_attribute').prop('required', true);
|
|
$('#urn_value').prop('required', true);
|
|
}
|
|
|
|
{% endif %}
|
|
|
|
// END: LDAP tab js
|
|
|
|
// START: Google tab js
|
|
// update validation requirement when checkbox is togged
|
|
$('#google_oauth_enabled').iCheck({
|
|
checkboxClass: 'icheckbox_square-blue',
|
|
increaseArea: '20%'
|
|
}).on('ifChanged', function (e) {
|
|
var is_enabled = e.currentTarget.checked;
|
|
if (is_enabled) {
|
|
$('#google_oauth_client_id').prop('required', true);
|
|
$('#google_oauth_client_secret').prop('required', true);
|
|
$('#google_token_url').prop('required', true);
|
|
$('#google_oauth_scope').prop('required', true);
|
|
$('#google_authorize_url').prop('required', true);
|
|
$('#google_base_url').prop('required', true);
|
|
} else {
|
|
$('#google_oauth_client_id').prop('required', false);
|
|
$('#google_oauth_client_secret').prop('required', false);
|
|
$('#google_token_url').prop('required', false);
|
|
$('#google_oauth_scope').prop('required', false);
|
|
$('#google_authorize_url').prop('required', false);
|
|
$('#google_base_url').prop('required', false);
|
|
}
|
|
});
|
|
|
|
// init validation requirement at first time page load
|
|
{% if SETTING.get('google_oauth_enabled') %}
|
|
$('#google_oauth_client_id').prop('required', true);
|
|
$('#google_oauth_client_secret').prop('required', true);
|
|
$('#google_token_url').prop('required', true);
|
|
$('#google_oauth_scope').prop('required', true);
|
|
$('#google_authorize_url').prop('required', true);
|
|
$('#google_base_url').prop('required', true);
|
|
{% endif %}
|
|
// END: Google tab js
|
|
|
|
// START: Github tab js
|
|
// update validation requirement when checkbox is togged
|
|
$('#github_oauth_enabled').iCheck({
|
|
checkboxClass: 'icheckbox_square-blue',
|
|
increaseArea: '20%'
|
|
}).on('ifChanged', function (e) {
|
|
var is_enabled = e.currentTarget.checked;
|
|
if (is_enabled) {
|
|
$('#github_oauth_key').prop('required', true);
|
|
$('#github_oauth_secret').prop('required', true);
|
|
$('#github_oauth_scope').prop('required', true);
|
|
$('#github_oauth_api_url').prop('required', true);
|
|
$('#github_oauth_token_url').prop('required', true);
|
|
$('#github_oauth_authorize_url').prop('required', true);
|
|
} else {
|
|
$('#github_oauth_key').prop('required', false);
|
|
$('#github_oauth_secret').prop('required', false);
|
|
$('#github_oauth_scope').prop('required', false);
|
|
$('#github_oauth_api_url').prop('required', false);
|
|
$('#github_oauth_token_url').prop('required', false);
|
|
$('#github_oauth_authorize_url').prop('required', false);
|
|
}
|
|
});
|
|
// init validation requirement at first time page load
|
|
{% if SETTING.get('github_oauth_enabled') %}
|
|
$('#github_oauth_key').prop('required', true);
|
|
$('#github_oauth_secret').prop('required', true);
|
|
$('#github_oauth_scope').prop('required', true);
|
|
$('#github_oauth_api_url').prop('required', true);
|
|
$('#github_oauth_token_url').prop('required', true);
|
|
$('#github_oauth_authorize_url').prop('required', true);
|
|
{% endif %}
|
|
// END: Github tab js
|
|
|
|
// START: Azure tab js
|
|
// update validation requirement when checkbox is togged
|
|
$('#azure_oauth_enabled').iCheck({
|
|
checkboxClass: 'icheckbox_square-blue',
|
|
increaseArea: '20%'
|
|
}).on('ifChanged', function (e) {
|
|
var is_enabled = e.currentTarget.checked;
|
|
if (is_enabled) {
|
|
$('#azure_oauth_key').prop('required', true);
|
|
$('#azure_oauth_secret').prop('required', true);
|
|
$('#azure_oauth_scope').prop('required', true);
|
|
$('#azure_oauth_api_url').prop('required', true);
|
|
$('#azure_oauth_token_url').prop('required', true);
|
|
$('#azure_oauth_authorize_url').prop('required', true);
|
|
} else {
|
|
$('#azure_oauth_key').prop('required', false);
|
|
$('#azure_oauth_secret').prop('required', false);
|
|
$('#azure_oauth_scope').prop('required', false);
|
|
$('#azure_oauth_api_url').prop('required', false);
|
|
$('#azure_oauth_token_url').prop('required', false);
|
|
$('#azure_oauth_authorize_url').prop('required', false);
|
|
}
|
|
});
|
|
// init validation requirement at first time page load
|
|
{% if SETTING.get('azure_oauth_enabled') %}
|
|
$('#azure_oauth_key').prop('required', true);
|
|
$('#azure_oauth_secret').prop('required', true);
|
|
$('#azure_oauth_scope').prop('required', true);
|
|
$('#azure_oauth_api_url').prop('required', true);
|
|
$('#azure_oauth_token_url').prop('required', true);
|
|
$('#azure_oauth_authorize_url').prop('required', true);
|
|
{% endif %}
|
|
// END: Azure tab js
|
|
|
|
// START: OIDC tab js
|
|
$('#oidc_oauth_enabled').iCheck({
|
|
checkboxClass: 'icheckbox_square-blue',
|
|
increaseArea: '20%'
|
|
}).on('ifChanged', function (e) {
|
|
var is_enabled = e.currentTarget.checked;
|
|
if (is_enabled) {
|
|
$('#oidc_oauth_key').prop('required', true);
|
|
$('#oidc_oauth_secret').prop('required', true);
|
|
$('#oidc_oauth_scope').prop('required', true);
|
|
$('#oidc_oauth_api_url').prop('required', true);
|
|
$('#oidc_oauth_token_url').prop('required', true);
|
|
$('#oidc_oauth_authorize_url').prop('required', true);
|
|
$('#oidc_oauth_username').prop('required', true);
|
|
$('#oidc_oauth_firstname').prop('required', true);
|
|
$('#oidc_oauth_last_name').prop('required', true);
|
|
$('#oidc_oauth_email').prop('required', true);
|
|
} else {
|
|
$('#oidc_oauth_key').prop('required', false);
|
|
$('#oidc_oauth_secret').prop('required', false);
|
|
$('#oidc_oauth_scope').prop('required', false);
|
|
$('#oidc_oauth_api_url').prop('required', false);
|
|
$('#oidc_oauth_token_url').prop('required', false);
|
|
$('#oidc_oauth_authorize_url').prop('required', false);
|
|
$('#oidc_oauth_username').prop('required', false);
|
|
$('#oidc_oauth_firstname').prop('required', false);
|
|
$('#oidc_oauth_last_name').prop('required', false);
|
|
$('#oidc_oauth_email').prop('required', false);
|
|
}
|
|
});
|
|
// init validation requirement at first time page load
|
|
{% if SETTING.get('oidc_oauth_enabled') %}
|
|
$('#oidc_oauth_key').prop('required', true);
|
|
$('#oidc_oauth_secret').prop('required', true);
|
|
$('#oidc_oauth_scope').prop('required', true);
|
|
$('#oidc_oauth_api_url').prop('required', true);
|
|
$('#oidc_oauth_token_url').prop('required', true);
|
|
$('#oidc_oauth_authorize_url').prop('required', true);
|
|
$('#oidc_oauth_username').prop('required', true);
|
|
$('#oidc_oauth_firstname').prop('required', true);
|
|
$('#oidc_oauth_last_name').prop('required', true);
|
|
$('#oidc_oauth_email').prop('required', true);
|
|
{% endif %}
|
|
//END: OIDC Tab JS
|
|
|
|
</script>
|
|
{% endblock %}
|
|
|
|
{% block modals %}
|
|
<div class="modal fade modal-warning" id="modal_confirm" data-keyboard="false" data-backdrop="static">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="X">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
<h4 class="modal-title">Confirmation</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p></p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default pull-left" id="button_cancel" name="purge" value="OFF"
|
|
data-dismiss="modal">Cancel
|
|
</button>
|
|
<button type="button" class="btn btn-success" id="button_confirm">Confirm</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade modal-warning" id="modal_warning" data-keyboard="false" data-backdrop="static">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="warning_X">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
<h4 class="modal-title">Warning</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p></p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-success" id="button_warning_confirm">Yes I understand</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|