[Web] improve identity-provider template

This commit is contained in:
FreddleSpl0it 2023-07-06 15:59:16 +02:00
parent b11ee45ba1
commit 45544311f1
No known key found for this signature in database
GPG Key ID: 00E14E7634F4BEC5
3 changed files with 182 additions and 109 deletions

View File

@ -1956,7 +1956,7 @@ function identity_provider($_action, $_data = null, $_extra = null) {
$_data['mailpassword_flow'] = isset($_data['mailpassword_flow']) ? intval($_data['mailpassword_flow']) : 0; $_data['mailpassword_flow'] = isset($_data['mailpassword_flow']) ? intval($_data['mailpassword_flow']) : 0;
$_data['periodic_sync'] = isset($_data['periodic_sync']) ? intval($_data['periodic_sync']) : 0; $_data['periodic_sync'] = isset($_data['periodic_sync']) ? intval($_data['periodic_sync']) : 0;
$_data['import_users'] = isset($_data['import_users']) ? intval($_data['import_users']) : 0; $_data['import_users'] = isset($_data['import_users']) ? intval($_data['import_users']) : 0;
$required_settings = array('authsource', 'server_url', 'realm', 'client_id', 'client_secret', 'redirect_url', 'version', 'mailpassword_flow', 'periodic_sync', 'import_users'); $required_settings = array('authsource', 'server_url', 'realm', 'client_id', 'client_secret', 'redirect_url', 'version', 'mailpassword_flow', 'periodic_sync', 'import_users', 'sync_interval');
} else if ($_data['authsource'] == "generic-oidc") { } else if ($_data['authsource'] == "generic-oidc") {
$required_settings = array('authsource', 'authorize_url', 'token_url', 'client_id', 'client_secret', 'redirect_url', 'userinfo_url'); $required_settings = array('authsource', 'authorize_url', 'token_url', 'client_id', 'client_secret', 'redirect_url', 'userinfo_url');
} }

View File

@ -768,10 +768,10 @@ jQuery(function($){
return mailcow_alert_box(lang_danger.iam_test_connection, 'danger'); return mailcow_alert_box(lang_danger.iam_test_connection, 'danger');
}); });
$('.iam_rolemap_add').click(async function(e){ $('.iam_rolemap_add_keycloak').click(async function(e){
e.preventDefault(); e.preventDefault();
var parent = $('#iam_mapping_list') var parent = $('#iam_keycloak_mapping_list')
$(parent).children().last().clone().appendTo(parent); $(parent).children().last().clone().appendTo(parent);
var newChild = $(parent).children().last(); var newChild = $(parent).children().last();
$(newChild).find('input').val(''); $(newChild).find('input').val('');
@ -781,17 +781,42 @@ jQuery(function($){
$(newChild).find('select').selectpicker('destroy'); $(newChild).find('select').selectpicker('destroy');
$(newChild).find('select').selectpicker(); $(newChild).find('select').selectpicker();
$('.iam_rolemap_del').off('click'); $('.iam_keycloak_rolemap_del').off('click');
$('.iam_rolemap_del').click(async function(e){ $('.iam_keycloak_rolemap_del').click(async function(e){
e.preventDefault(); e.preventDefault();
if ($(this).parent().parent().children().length > 1) if ($(this).parent().parent().parent().parent().children().length > 1)
$(this).parent().remove(); $(this).parent().parent().parent().remove();
}); });
}); });
$('.iam_rolemap_del').click(async function(e){ $('.iam_rolemap_add_generic').click(async function(e){
e.preventDefault(); e.preventDefault();
if ($(this).parent().parent().children().length > 1)
$(this).parent().remove(); var parent = $('#iam_generic_mapping_list')
$(parent).children().last().clone().appendTo(parent);
var newChild = $(parent).children().last();
$(newChild).find('input').val('');
$(newChild).find('.dropdown-toggle').remove();
$(newChild).find('.dropdown-menu').remove();
$(newChild).find('.bs-title-option').remove();
$(newChild).find('select').selectpicker('destroy');
$(newChild).find('select').selectpicker();
$('.iam_generic_rolemap_del').off('click');
$('.iam_generic_rolemap_del').click(async function(e){
e.preventDefault();
if ($(this).parent().parent().parent().parent().children().length > 1)
$(this).parent().parent().parent().remove();
});
});
$('.iam_keycloak_rolemap_del').click(async function(e){
e.preventDefault();
if ($(this).parent().parent().parent().parent().children().length > 1)
$(this).parent().parent().parent().remove();
});
$('.iam_generic_rolemap_del').click(async function(e){
e.preventDefault();
if ($(this).parent().parent().parent().parent().children().length > 1)
$(this).parent().parent().parent().remove();
}); });
// selecting identity provider // selecting identity provider
$('#iam_provider').on('change', function(){ $('#iam_provider').on('change', function(){

View File

@ -7,10 +7,10 @@
<span class="d-none d-md-block">{{ lang.admin.iam }}</span> <span class="d-none d-md-block">{{ lang.admin.iam }}</span>
</div> </div>
<div id="collapse-tab-config-identity-provider" class="card-body collapse" data-bs-parent="#admin-content"> <div id="collapse-tab-config-identity-provider" class="card-body collapse" data-bs-parent="#admin-content">
<p class="offset-sm-3 mb-4">{{ lang.admin.iam_description }}</p> <p class="offset-sm-3 mb-4">{{ lang.admin.iam_description|raw }}</p>
<div class="row mb-4"> <div class="row mb-4">
<label class="control-label col-sm-3 text-sm-end" for="iam_realm">{{ lang.admin.iam }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_realm">{{ lang.admin.iam }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<select <select
data-style="btn btn-secondary" data-style="btn btn-secondary"
data-id="iam_provider" data-id="iam_provider"
@ -25,26 +25,26 @@
<form class="form-horizontal" autocapitalize="none" data-id="iam_keycloak" autocorrect="off" role="form" method="post"> <form class="form-horizontal" autocapitalize="none" data-id="iam_keycloak" autocorrect="off" role="form" method="post">
<input type="hidden" name="authsource" value="keycloak"> <input type="hidden" name="authsource" value="keycloak">
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end" for="iam_keycloak_url">{{ lang.admin.iam_server_url }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_keycloak_url">{{ lang.admin.iam_server_url }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<input type="text" class="form-control" id="iam_keycloak_url" name="server_url" value="{{ iam_settings.server_url }}" required> <input type="text" class="form-control" id="iam_keycloak_url" name="server_url" value="{{ iam_settings.server_url }}" required>
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end" for="iam_keycloak_realm">{{ lang.admin.iam_realm }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_keycloak_realm">{{ lang.admin.iam_realm }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<input type="text" class="form-control" id="iam_keycloak_realm" name="realm" value="{{ iam_settings.realm }}" required> <input type="text" class="form-control" id="iam_keycloak_realm" name="realm" value="{{ iam_settings.realm }}" required>
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end" for="iam_keycloak_clientid">{{ lang.admin.iam_client_id }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_keycloak_clientid">{{ lang.admin.iam_client_id }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<input type="text" class="form-control" id="iam_keycloak_clientid" name="client_id" value="{{ iam_settings.client_id }}" required> <input type="text" class="form-control" id="iam_keycloak_clientid" name="client_id" value="{{ iam_settings.client_id }}" required>
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end" for="iam_keycloak_clientsecret">{{ lang.admin.iam_client_secret }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_keycloak_clientsecret">{{ lang.admin.iam_client_secret }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<div class="reveal-password-input input-group"> <div class="reveal-password-input input-group">
<input type="password" class="password-field form-control" id="iam_keycloak_clientsecret" name="client_secret" value="{{ iam_settings.client_secret }}" required> <input type="password" class="password-field form-control" id="iam_keycloak_clientsecret" name="client_secret" value="{{ iam_settings.client_secret }}" required>
<button class="toggle-password btn btn-secondary" type="button"><i class="bi bi-eye"></i></button> <button class="toggle-password btn btn-secondary" type="button"><i class="bi bi-eye"></i></button>
@ -52,62 +52,82 @@
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end" for="iam_keycloak_redirecturl">{{ lang.admin.iam_redirect_url }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_keycloak_redirecturl">{{ lang.admin.iam_redirect_url }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<input type="text" class="form-control" id="iam_keycloak_redirecturl" name="redirect_url" value="{{ iam_settings.redirect_url }}" required> <input type="text" class="form-control" id="iam_keycloak_redirecturl" name="redirect_url" value="{{ iam_settings.redirect_url }}" required>
</div> </div>
</div> </div>
<div class="row mb-4"> <div class="row mb-4">
<label class="control-label col-sm-3 text-sm-end" for="iam_keycloak_version">{{ lang.admin.iam_version }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_keycloak_version">{{ lang.admin.iam_version }}:</label>
<div class="col-sm-4"> <div class="col-sm-4">
<input type="text" class="form-control" id="iam_keycloak_version" name="version" value="{{ iam_settings.version }}" required> <input type="text" class="form-control" id="iam_keycloak_version" name="version" value="{{ iam_settings.version }}" required>
</div> </div>
</div> </div>
<div class="row mb-4"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end">{{ lang.admin.iam_mapping }}:</label> <label class="control-label col-md-3 text-sm-end">{{ lang.admin.iam_mapping }}:</label>
<div class="col-4 d-flex mb-2"> <div class="col-12 col-md-9 col-lg-4">
<span class="w-100 me-2">Attribute</span> <div class="row px-2 align-items-center">
<span class="w-100 ms-2">Template</span> <span class="col-5 p-0 pe-2">Attribute</span>
<button class="btn btn-sm d-block d-sm-inline btn-secondary ms-2 iam_rolemap_add"><i class="bi bi-plus-lg"></i></button> <span class="col-5 p-0 pe-2">{{ lang.mailbox.template }}</span>
</div> <div class="col-2 p-0 d-flex">
<div id="iam_mapping_list"> <button class="btn btn-sm d-block d-sm-inline btn-secondary ms-auto iam_rolemap_add_keycloak"><i class="bi bi-plus-lg"></i></button>
{% for key, role in iam_settings.mappers %} </div>
<div class="offset-sm-3 col-4 d-flex mb-2">
<input type="text" class="form-control me-2" name="mappers" value="{{ iam_settings.mappers[key] }}" required>
<select data-live-search="true" name="templates" class="form-control" title="{{ lang.mailbox.template }}" required>
{% for mbox_template in mbox_templates %}
<option{% if mbox_template.template == iam_settings.templates[key] %} selected{% endif %}>
{{ mbox_template.template }}
</option>
{% endfor %}
</select>
<button class="iam_rolemap_del btn btn-sm d-block d-sm-inline btn-secondary ms-2"><i class="bi bi-x-lg"></i></button>
</div> </div>
{% endfor %}
{% if not iam_settings.mappers %}
<div class="offset-sm-3 col-4 d-flex mb-2">
<input type="text" class="form-control me-2" name="mappers" value="" required>
<select data-live-search="true" name="templates" class="form-control" title="{{ lang.mailbox.template }}" required>
{% for mbox_template in mbox_templates %}
<option>
{{ mbox_template.template }}
</option>
{% endfor %}
</select>
<button class="iam_rolemap_del btn btn-sm d-block d-sm-inline btn-secondary ms-2"><i class="bi bi-x-lg"></i></button>
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="row mb-2" id="iam_keycloak_mapping_list">
{% for key, role in iam_settings.mappers %}
<div class="offset-md-3 col-12 col-md-9 col-lg-4 mb-2">
<div class="row px-2">
<div class="col-5 p-0 pe-2">
<input type="text" class="form-control me-2" name="mappers" value="{{ iam_settings.mappers[key] }}" required>
</div>
<div class="col-5 p-0 pe-2">
<select data-live-search="true" name="templates" class="form-control" title="{{ lang.mailbox.template }}" required>
{% for mbox_template in mbox_templates %}
<option{% if mbox_template.template == iam_settings.templates[key] %} selected{% endif %}>
{{ mbox_template.template }}
</option>
{% endfor %}
</select>
</div>
<div class="col-2 p-0 d-flex">
<button class="iam_keycloak_rolemap_del btn btn-sm d-block d-sm-inline btn-secondary ms-auto"><i class="bi bi-x-lg"></i></button>
</div>
</div>
</div>
{% endfor %}
{% if not iam_settings.mappers %}
<div class="offset-md-3 col-12 col-md-9 col-lg-4 d-flex mb-2">
<div class="row px-2">
<div class="col-5 p-0 pe-2">
<input type="text" class="form-control me-2" name="mappers" value="" required>
</div>
<div class="col-5 p-0 pe-2">
<select data-live-search="true" name="templates" class="form-control" title="{{ lang.mailbox.template }}" required>
{% for mbox_template in mbox_templates %}
<option>
{{ mbox_template.template }}
</option>
{% endfor %}
</select>
</div>
<div class="col-2 p-0 d-flex">
<button class="iam_keycloak_rolemap_del btn btn-sm d-block d-sm-inline btn-secondary ms-2"><i class="bi bi-x-lg"></i></button>
</div>
</div>
</div>
{% endif %}
</div>
<div class="row mb-2 mt-4"> <div class="row mb-2 mt-4">
<label class="control-label col-sm-3 text-sm-end"></label> <label class="control-label col-md-3 text-sm-end"></label>
<div class="col-sm-9"> <div class="col-12 col-md-9">
<span>{{ lang.admin.iam_extra_permission|raw }}</span> <span>{{ lang.admin.iam_extra_permission|raw }}</span>
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end">{{ lang.admin.iam_rest_flow }}</label> <label class="control-label col-md-3 text-sm-end">{{ lang.admin.iam_rest_flow }}</label>
<div class="col-sm-9"> <div class="col-12 col-md-9">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" name="mailpassword_flow" value="1" {% if iam_settings.mailpassword_flow == 1 %}checked{% endif %}> <input class="form-check-input" type="checkbox" role="switch" name="mailpassword_flow" value="1" {% if iam_settings.mailpassword_flow == 1 %}checked{% endif %}>
</div> </div>
@ -119,28 +139,34 @@
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end">Periodic Full Sync</label> <label class="control-label col-md-3 text-sm-end">{{ lang.admin.iam_periodic_full_sync }}</label>
<div class="col-sm-9"> <div class="col-12 col-md-9">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" name="periodic_sync" value="1" {% if iam_settings.periodic_sync == 1 %}checked{% endif %}> <input class="form-check-input" type="checkbox" role="switch" name="periodic_sync" value="1" {% if iam_settings.periodic_sync == 1 %}checked{% endif %}>
</div> </div>
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end">Import Users</label> <label class="control-label col-md-3 text-sm-end">{{ lang.admin.iam_import_users }}</label>
<div class="col-sm-9"> <div class="col-12 col-md-9">
<div class="form-check form-switch"> <div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" name="import_users" value="1" {% if iam_settings.import_users == 1 %}checked{% endif %}> <input class="form-check-input" type="checkbox" role="switch" name="import_users" value="1" {% if iam_settings.import_users == 1 %}checked{% endif %}>
</div> </div>
</div> </div>
</div> </div>
<div class="row mb-2">
<label class="control-label col-md-3 text-sm-end">{{ lang.admin.iam_sync_interval }}</label>
<div class="col-12 col-md-9 col-lg-4">
<input class="form-control" type="number" name="sync_interval" style="width: 80px;" {% if iam_settings.sync_interval %}value="{{ iam_settings.sync_interval }}"{% else %}value="15"{% endif %}>
</div>
</div>
<div class="row mt-4 mb-2"> <div class="row mt-4 mb-2">
<div class="offset-sm-3 col-sm-9 d-flex"> <div class="offset-md-3 col-12 col-md-9 d-flex flex-wrap">
<div class="btn-group"> <div class="btn-group mb-2">
<button class="btn btn-sm d-block d-sm-inline btn-secondary iam_test_connection iam_test_connection" data-id="iam_keycloak"><i class="bi bi-play"></i> {{ lang.admin.iam_test_connection }}</button> <button class="btn btn-sm d-block d-sm-inline btn-secondary iam_test_connection iam_test_connection" data-id="iam_keycloak"><i class="bi bi-play"></i> {{ lang.admin.iam_test_connection }}</button>
<button class="btn btn-sm d-block d-sm-inline btn-success" data-item="identity-provider" data-action="edit_selected" data-id="iam_keycloak" data-api-url='edit/identity-provider' data-api-attr='{}'><i class="bi bi-check-lg"></i> {{ lang.admin.save }}</button> <button class="btn btn-sm d-block d-sm-inline btn-success" data-item="identity-provider" data-action="edit_selected" data-id="iam_keycloak" data-api-url='edit/identity-provider' data-api-attr='{}'><i class="bi bi-check-lg"></i> {{ lang.admin.save }}</button>
</div> </div>
<button class="btn btn-sm d-block d-sm-inline btn-danger ms-auto" data-item="identity-provider" data-action="delete_selected" data-id="iam_keycloak" data-api-url='delete/identity-provider'><i class="bi bi-trash"></i> {{ lang.mailbox.remove }}</button> <button class="btn btn-sm d-block d-sm-inline btn-danger ms-auto mb-2" data-item="identity-provider" data-action="delete_selected" data-id="iam_keycloak" data-api-url='delete/identity-provider'><i class="bi bi-trash"></i> {{ lang.mailbox.remove }}</button>
</div> </div>
</div> </div>
</form> </form>
@ -149,32 +175,32 @@
<form class="form-horizontal" autocapitalize="none" data-id="iam_generic" autocorrect="off" role="form" method="post"> <form class="form-horizontal" autocapitalize="none" data-id="iam_generic" autocorrect="off" role="form" method="post">
<input type="hidden" name="authsource" value="generic-oidc"> <input type="hidden" name="authsource" value="generic-oidc">
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end" for="iam_authorize_url">{{ lang.admin.iam_authorize_url }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_authorize_url">{{ lang.admin.iam_authorize_url }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<input type="text" class="form-control" id="iam_authorize_url" name="authorize_url" value="{{ iam_settings.authorize_url }}" required> <input type="text" class="form-control" id="iam_authorize_url" name="authorize_url" value="{{ iam_settings.authorize_url }}" required>
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end" for="iam_token_url">{{ lang.admin.iam_token_url }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_token_url">{{ lang.admin.iam_token_url }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<input type="text" class="form-control" id="iam_token_url" name="token_url" value="{{ iam_settings.token_url }}" required> <input type="text" class="form-control" id="iam_token_url" name="token_url" value="{{ iam_settings.token_url }}" required>
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end" for="iam_userinfo_url">{{ lang.admin.iam_userinfo_url }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_userinfo_url">{{ lang.admin.iam_userinfo_url }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<input type="text" class="form-control" id="iam_userinfo_url" name="userinfo_url" value="{{ iam_settings.userinfo_url }}" required> <input type="text" class="form-control" id="iam_userinfo_url" name="userinfo_url" value="{{ iam_settings.userinfo_url }}" required>
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end" for="iam_client_id">{{ lang.admin.iam_client_id }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_client_id">{{ lang.admin.iam_client_id }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<input type="text" class="form-control" id="iam_client_id" name="client_id" value="{{ iam_settings.client_id }}" required> <input type="text" class="form-control" id="iam_client_id" name="client_id" value="{{ iam_settings.client_id }}" required>
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end" for="iam_client_secret">{{ lang.admin.iam_client_secret }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_client_secret">{{ lang.admin.iam_client_secret }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<div class="reveal-password-input input-group"> <div class="reveal-password-input input-group">
<input type="password" class="password-field form-control" id="iam_client_secret" name="client_secret" value="{{ iam_settings.client_secret }}" required> <input type="password" class="password-field form-control" id="iam_client_secret" name="client_secret" value="{{ iam_settings.client_secret }}" required>
<button class="toggle-password btn btn-secondary" type="button"><i class="bi bi-eye"></i></button> <button class="toggle-password btn btn-secondary" type="button"><i class="bi bi-eye"></i></button>
@ -182,52 +208,74 @@
</div> </div>
</div> </div>
<div class="row mb-4"> <div class="row mb-4">
<label class="control-label col-sm-3 text-sm-end" for="iam_redirect_url">{{ lang.admin.iam_redirect_url }}:</label> <label class="control-label col-md-3 text-sm-end" for="iam_redirect_url">{{ lang.admin.iam_redirect_url }}:</label>
<div class="col-sm-4"> <div class="col-12 col-md-9 col-lg-4">
<input type="text" class="form-control" id="iam_redirect_url" name="redirect_url" value="{{ iam_settings.redirect_url }}" required> <input type="text" class="form-control" id="iam_redirect_url" name="redirect_url" value="{{ iam_settings.redirect_url }}" required>
</div> </div>
</div> </div>
<div class="row mb-4"> <div class="row mb-2">
<label class="control-label col-sm-3 text-sm-end">{{ lang.admin.iam_mapping }}:</label> <label class="control-label col-md-3 text-sm-end">{{ lang.admin.iam_mapping }}:</label>
<div class="col-4 d-flex mb-2"> <div class="col-12 col-md-9 col-lg-4">
<span class="w-100 me-2">Attribute</span> <div class="row px-2 align-items-center">
<span class="w-100 ms-2">Template</span> <span class="col-5 p-0 pe-2">Attribute</span>
<button class="btn btn-sm d-block d-sm-inline btn-secondary ms-2 iam_rolemap_add"><i class="bi bi-plus-lg"></i></button> <span class="col-5 p-0 pe-2">Template</span>
<div class="col-2 p-0 d-flex">
<button class="btn btn-sm d-block d-sm-inline btn-secondary ms-auto iam_rolemap_add_generic"><i class="bi bi-plus-lg"></i></button>
</div>
</div>
</div> </div>
</div>
<div class="row mb-2" id="iam_generic_mapping_list">
{% for key, role in iam_settings.mappers %} {% for key, role in iam_settings.mappers %}
<div class="offset-sm-3 col-4 d-flex mb-2"> <div class="offset-md-3 col-12 col-md-9 col-lg-4 mb-2">
<input type="text" class="form-control me-2" name="mappers" value="{{ iam_settings.mappers[key] }}" required> <div class="row px-2">
<select data-live-search="true" name="templates" class="form-control" title="{{ lang.mailbox.template }}" required> <div class="col-5 p-0 pe-2">
{% for mbox_template in mbox_templates %} <input type="text" class="form-control me-2" name="mappers" value="{{ iam_settings.mappers[key] }}" required>
<option{% if mbox_template.template == iam_settings.templates[key] %} selected{% endif %}> </div>
{{ mbox_template.template }} <div class="col-5 p-0 pe-2">
</option> <select data-live-search="true" name="templates" class="form-control" title="{{ lang.mailbox.template }}" required>
{% endfor %} {% for mbox_template in mbox_templates %}
</select> <option{% if mbox_template.template == iam_settings.templates[key] %} selected{% endif %}>
<button class="iam_rolemap_del btn btn-sm d-block d-sm-inline btn-secondary ms-2"><i class="bi bi-x-lg"></i></button> {{ mbox_template.template }}
</option>
{% endfor %}
</select>
</div>
<div class="col-2 p-0 d-flex">
<button class="iam_generic_rolemap_del btn btn-sm d-block d-sm-inline btn-secondary ms-auto"><i class="bi bi-x-lg"></i></button>
</div>
</div>
</div> </div>
{% endfor %} {% endfor %}
{% if not iam_settings.mappers %} {% if not iam_settings.mappers %}
<div class="offset-sm-3 col-4 d-flex mb-2"> <div class="offset-md-3 col-12 col-md-9 col-lg-4 d-flex mb-2">
<input type="text" class="form-control me-2" name="mappers" value="" required> <div class="row px-2">
<select data-live-search="true" name="templates" class="form-control" title="{{ lang.mailbox.template }}" required> <div class="col-5 p-0 pe-2">
{% for mbox_template in mbox_templates %} <input type="text" class="form-control me-2" name="mappers" value="" required>
<option> </div>
{{ mbox_template.template }} <div class="col-5 p-0 pe-2">
</option> <select data-live-search="true" name="templates" class="form-control" title="{{ lang.mailbox.template }}" required>
{% endfor %} {% for mbox_template in mbox_templates %}
</select> <option>
<button class="iam_rolemap_del btn btn-sm d-block d-sm-inline btn-secondary ms-2"><i class="bi bi-x-lg"></i></button> {{ mbox_template.template }}
</option>
{% endfor %}
</select>
</div>
<div class="col-2 p-0 d-flex">
<button class="iam_generic_rolemap_del btn btn-sm d-block d-sm-inline btn-secondary ms-2"><i class="bi bi-x-lg"></i></button>
</div>
</div>
</div> </div>
{% endif %} {% endif %}
</div> </div>
<div class="row mt-4 mb-2"> <div class="row mt-4 mb-2">
<div class="offset-sm-3 col-sm-9 d-flex"> <div class="offset-md-3 col-12 col-md-9 d-flex flex-wrap">
<div class="btn-group"> <div class="btn-group mb-2">
<button class="btn btn-sm d-block d-sm-inline btn-secondary iam_test_connection" data-id="iam_generic"><i class="bi bi-play"></i> {{ lang.admin.iam_test_connection }}</button> <button class="btn btn-sm d-block d-sm-inline btn-secondary iam_test_connection" data-id="iam_generic"><i class="bi bi-play"></i> {{ lang.admin.iam_test_connection }}</button>
<button class="btn btn-sm d-block d-sm-inline btn-success" data-item="identity-provider" data-action="edit_selected" data-id="iam_generic" data-api-url='edit/identity-provider' data-api-attr='{}'><i class="bi bi-check-lg"></i> {{ lang.admin.save }}</button> <button class="btn btn-sm d-block d-sm-inline btn-success" data-item="identity-provider" data-action="edit_selected" data-id="iam_generic" data-api-url='edit/identity-provider' data-api-attr='{}'><i class="bi bi-check-lg"></i> {{ lang.admin.save }}</button>
</div> </div>
<button class="btn btn-sm d-block d-sm-inline btn-danger ms-auto" data-item="identity-provider" data-action="delete_selected" data-id="iam_generic" data-api-url='delete/identity-provider'><i class="bi bi-trash"></i> {{ lang.mailbox.remove }}</button> <button class="btn btn-sm d-block d-sm-inline btn-danger ms-auto mb-2" data-item="identity-provider" data-action="delete_selected" data-id="iam_generic" data-api-url='delete/identity-provider'><i class="bi bi-trash"></i> {{ lang.mailbox.remove }}</button>
</div> </div>
</div> </div>
</form> </form>