Completed first-found updates for the API key add/edit view.

This commit is contained in:
Matt Scott 2023-02-20 09:56:26 -05:00
parent db70e34c98
commit 5a4279d7b8

View File

@ -1,303 +1,338 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "admin_keys" %} {% set active_page = "admin_keys" %}
{% if create %}
{% if (key is not none and key.role.name != "User") %}{% set hide_opts = True %}{%else %}{% set hide_opts = False %}{% endif %} {% set action_label = 'Create' %}
{% set form_action = url_for('admin.edit_key') %}
{% block title %} {% else %}
<title> {% set action_label = 'Edit' %}
Edit Key - {{ SITE_NAME }} {% set form_action = url_for('admin.edit_key', key_id=key.id) %}
</title> {% endif %}
{% endblock %} {% if (key is not none and key.role.name != "User") %}{% set hide_opts = True %}{% else %}
{% set hide_opts = False %}{% endif %}
{% block title %}<title>{{ action_label }} API Key - {{ SITE_NAME }}</title>{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<div class="content-header"> <div class="content-header">
<div class="container-fluid"> <div class="container-fluid">
<div class="row mb-2"> <div class="row mb-2">
<div class="col-sm-6"> <div class="col-sm-6">
<h1 class="m-0 text-dark"> <h1 class="m-0 text-dark">{{ action_label }} API Key</h1>
API Keys </div>
<small>{% if create %}Add API Key{% else %}Edit API Key - {{ key.id }}{% endif %}</small> <div class="col-sm-6">
</h1> <ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{{ url_for('admin.manage_keys') }}">API Keys</a></li>
<li class="breadcrumb-item active">{{ action_label }} API Key</li>
</ol>
</div>
</div>
</div> </div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{ url_for('dashboard.dashboard') }}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{{ url_for('admin.manage_keys') }}">API Keys</a></li>
<li class="breadcrumb-item active">{% if create %}Add API Key{% else %}Edit API Key - {% endif %}{{ key.id }}</li>
</ol>
</div>
</div>
</div> </div>
</div>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-4"> <div class="col-12 col-sm-6 col-lg-4">
<div class="card "> <form role="form" method="post" action="{{ form_action }}">
<div class="card-header"> <input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
<h3 class="card-title">{% if create %}Add{% else %}Edit{% endif %} Key</h3> <input type="hidden" name="create" value="{{ create }}">
</div> <div class="card card-outline card-primary shadow">
<form role="form" method="post" <div class="card-header">
action="{% if create %}{{ url_for('admin.edit_key') }}{% else %}{{ url_for('admin.edit_key', key_id=key.id) }}{% endif %}"> <h3 class="card-title">API Key Editor</h3>
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}"> </div>
<input type="hidden" name="create" value="{{ create }}"> <!-- /.card-header -->
<div class="card-body"> <div class="card-body">
<div class="form-group has-feedback"> <div class="form-group has-feedback">
<label class="control-label" for="role">Role</label> <label class="control-label" for="role">Role</label>
<select class="key_role form-control" id="key_role" name="key_role"> <select class="key_role form-control" id="key_role" name="key_role">
{% for role in roles %} {% for role in roles %}
<option value="{{ role.name }}" <option value="{{ role.name }}"
{% if (key is not none) and (role.id==key.role.id) %}selected{% endif %} {% if (key is not none) and (role.id==key.role.id) %}selected{% endif %}
{% if (key is none) and (role.name=="User") %}selected{% endif %}> {% if (key is none) and (role.name=="User") %}selected{% endif %}>
{{ role.name }} {{ role.name }}
</option> </option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
<div class="form-group has-feedback"> <!-- /.form-group -->
<label class="control-label" for="description">Description</label> <div class="form-group has-feedback">
<input type="text" class="form-control" placeholder="Description" name="description" <label class="control-label" for="description">Description</label>
{% if key is not none %} value="{{ key.description }}" {% endif %}> <input type="text" class="form-control" placeholder="Description" name="description"
<span class="glyphicon glyphicon-pencil form-control-feedback"></span> {% if key is not none %} value="{{ key.description }}" {% endif %}>
</div> <span class="glyphicon glyphicon-pencil form-control-feedback"></span>
</div> </div>
<div class="card-header key-opts"{% if hide_opts %} style="display: none;"{% endif %}> <!-- /.form-group -->
<h3 class="card-title">Accounts Access Control</h3> </div>
</div> <!-- /.card-body -->
<div class="card-body key-opts"{% if hide_opts %} style="display: none;"{% endif %}> <div class="card-header key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
<p>This key will be linked to the accounts on the right,</p> <h3 class="card-title">Accounts Access Control</h3>
<p>thus granting access to domains owned by the selected accounts.</p> </div>
<p>Click on accounts to move between the columns.</p> <!-- /.card-header -->
<div class="form-group col-2"> <div class="card-body key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
<select multiple="multiple" class="form-control" id="key_multi_account" name="key_multi_account"> <p>This key will be linked to the accounts on the right,</p>
{% for account in accounts %} <p>thus granting access to domains owned by the selected accounts.</p>
<option {% if key and account in key.accounts %}selected{% endif %} value="{{ account.name }}">{{ account.name }}</option> <p>Click on accounts to move between the columns.</p>
{% endfor %} <div class="form-group col-2">
</select> <select multiple="multiple" class="form-control" id="key_multi_account"
</div> name="key_multi_account">
</div> {% for account in accounts %}
<div class="card-header key-opts"{% if hide_opts %} style="display: none;"{% endif %}> <option {% if key and account in key.accounts %}selected{% endif %}
<h3 class="card-title">Domain Access Control</h3> value="{{ account.name }}">{{ account.name }}</option>
</div> {% endfor %}
<div class="card-body key-opts"{% if hide_opts %} style="display: none;"{% endif %}> </select>
<p>This key will have acess to the domains on the right.</p> </div>
<p>Click on domains to move between the columns.</p> <!-- /.form-group -->
<div class="form-group col-2"> </div>
<select multiple="multiple" class="form-control" id="key_multi_domain" <!-- /.card-body -->
name="key_multi_domain"> <div class="card-header key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
{% for domain in domains %} <h3 class="card-title">Domain Access Control</h3>
<option {% if key and domain in key.domains %}selected{% endif %} value="{{ domain.name }}">{{ domain.name }}</option> </div>
{% endfor %} <!-- /.card-header -->
</select> <div class="card-body key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
<p>This key will have access to the domains on the right.</p>
<p>Click on domains to move between the columns.</p>
<div class="form-group col-2">
<select multiple="multiple" class="form-control" id="key_multi_domain"
name="key_multi_domain">
{% for domain in domains %}
<option {% if key and domain in key.domains %}selected{% endif %}
value="{{ domain.name }}">{{ domain.name }}</option>
{% endfor %}
</select>
</div>
</div>
<!-- /.card-body -->
<div class="card-footer">
<button type="button" class="btn btn-secondary float-left" title="Cancel"
onclick="window.location.href='{{ url_for('admin.manage_keys') }}'">
<i class="fa-solid fa-window-close"></i>&nbsp;Cancel
</button>
<button type="submit" class="btn btn-primary float-right"
title="{{ action_label }} API Key" id="key_submit">
<i class="fa-solid fa-save"></i>&nbsp;{{ action_label }} API Key
</button>
</div>
<!-- /.card-footer -->
</div> </div>
</div> <!-- /.card -->
<div class="card-footer"> </form>
<button type="button" class="btn btn-secondary float-left" onclick="window.location.href='{{ url_for('admin.manage_keys') }}'">
<i class="fa-solid fa-window-close"></i>&nbsp;Cancel
</button>
<button type="submit" class="btn btn-primary float-right" id="key_submit">
<i class="fa-solid fa-save"></i>&nbsp;{% if create %}Create{% else %}Update{% endif %} Key
</button>
</div>
</form>
</div>
</div>
<div class="col-8">
<div class="card">
<div class="card-header">
<h3 class="card-title">Help with {% if create %}creating a new{% else%}updating a{% endif %} key
</h3>
</div> </div>
<div class="card-body"> <!-- /.col -->
<p>Fill in all the fields in the form to the left.</p>
<p><strong>Role</strong> The role of the key.</p> <div class="col-12 col-sm-6 col-lg-8">
<p><strong>Description</strong> The key description.</p> <div class="card card-outline card-secondary shadow">
<p><strong>Access Control</strong> The domains or accounts which the key has access to.</p> <div class="card-header">
<h3 class="card-title">API Key Editor Help</h3>
</div>
<!-- /.card-header -->
<div class="card-body">
<p>Fill in all the fields in the form to the left.</p>
<p><strong>Role</strong> The role of the key.</p>
<p><strong>Description</strong> The key description.</p>
<p><strong>Access Control</strong> The domains or accounts which the key has access to.</p>
</div>
<!-- /.card-body -->
</div>
<!-- /.card -->
</div> </div>
<!-- /.col -->
</div> </div>
<!-- /.row -->
</div> </div>
</div> <!-- /.container-fluid -->
</div> </section>
</section>
{% endblock %} {% endblock %}
{% block extrascripts %} {% block extrascripts %}
<script> <script>
$('form').submit(function (e) { $('form').submit(function (e) {
var selectedRole = $("#key_role").val(); var selectedRole = $("#key_role").val();
var selectedDomains = $("#key_multi_domain option:selected").length; var selectedDomains = $("#key_multi_domain option:selected").length;
var selectedAccounts = $("#key_multi_account option:selected").length; var selectedAccounts = $("#key_multi_account option:selected").length;
var warn_modal = $("#modal_warning"); var warn_modal = $("#modal_warning");
if (selectedRole != "User" && selectedDomains > 0 && selectedAccounts > 0){ if (selectedRole != "User" && selectedDomains > 0 && selectedAccounts > 0) {
var warning = "Administrator and Operators have access to all domains. Your domain an account selection won't be saved."; var warning = "Administrator and Operators have access to all domains. Your domain an account selection won't be saved.";
e.preventDefault(e); e.preventDefault(e);
warn_modal.modal('show'); warn_modal.modal('show');
}
if (selectedRole == "User" && selectedDomains == 0 && selectedAccounts == 0) {
var warning = "User role must have at least one account or one domain bound. None selected.";
e.preventDefault(e);
warn_modal.modal('show');
}
warn_modal.find('.modal-body p').text(warning);
warn_modal.find('#button_key_confirm_warn').click(clearModal);
});
function clearModal() {
$("#modal_warning").modal('hide');
} }
if (selectedRole == "User" && selectedDomains == 0 && selectedAccounts == 0){ $('#key_role').on('change', function (e) {
var warning = "User role must have at least one account or one domain bound. None selected."; var optionSelected = $("option:selected", this);
e.preventDefault(e); if (this.value != "User") {
warn_modal.modal('show'); // Clear the visible list
} $('#ms-key_multi_domain .ms-selection li').each(function () {
$(this).css('display', 'none');
})
$('#ms-key_multi_domain .ms-selectable li').each(function () {
$(this).css('display', '');
})
$('#ms-key_multi_account .ms-selection li').each(function () {
$(this).css('display', 'none');
})
$('#ms-key_multi_account .ms-selectable li').each(function () {
$(this).css('display', '');
})
// Deselect invisible selectbox
$('#key_multi_domain option:selected').each(function () {
$(this).prop('selected', false);
})
$('#key_multi_account option:selected').each(function () {
$(this).prop('selected', false);
})
// Hide the lists
$(".key-opts").hide();
} else {
$(".key-opts").show();
}
});
$("#key_multi_domain").multiSelect({
selectableHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Domain Name'>",
selectionHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Domain Name'>",
afterInit: function (ms) {
var that = this,
$selectableSearch = that.$selectableUl.prev(),
$selectionSearch = that.$selectionUl.prev(),
selectableSearchString = '#' + that.$container.attr('id') + ' .ms-elem-selectable:not(.ms-selected)',
selectionSearchString = '#' + that.$container.attr('id') + ' .ms-elem-selection.ms-selected';
warn_modal.find('.modal-body p').text(warning); that.qs1 = $selectableSearch.quicksearch(selectableSearchString)
warn_modal.find('#button_key_confirm_warn').click(clearModal); .on('keydown', function (e) {
}); if (e.which === 40) {
function clearModal(){ that.$selectableUl.focus();
$("#modal_warning").modal('hide'); return false;
} }
$('#key_role').on('change', function (e) { });
var optionSelected = $("option:selected", this);
if (this.value != "User") {
// Clear the visible list
$('#ms-key_multi_domain .ms-selection li').each(function(){ $(this).css('display', 'none');})
$('#ms-key_multi_domain .ms-selectable li').each(function(){ $(this).css('display', '');})
$('#ms-key_multi_account .ms-selection li').each(function(){ $(this).css('display', 'none');})
$('#ms-key_multi_account .ms-selectable li').each(function(){ $(this).css('display', '');})
// Deselect invisible selectbox
$('#key_multi_domain option:selected').each(function(){ $(this).prop('selected', false);})
$('#key_multi_account option:selected').each(function(){ $(this).prop('selected', false);})
// Hide the lists
$(".key-opts").hide();
}
else {
$(".key-opts").show();
}
});
$("#key_multi_domain").multiSelect({
selectableHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Domain Name'>",
selectionHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Domain Name'>",
afterInit: function (ms) {
var that = this,
$selectableSearch = that.$selectableUl.prev(),
$selectionSearch = that.$selectionUl.prev(),
selectableSearchString = '#' + that.$container.attr('id') + ' .ms-elem-selectable:not(.ms-selected)',
selectionSearchString = '#' + that.$container.attr('id') + ' .ms-elem-selection.ms-selected';
that.qs1 = $selectableSearch.quicksearch(selectableSearchString) that.qs2 = $selectionSearch.quicksearch(selectionSearchString)
.on('keydown', function (e) { .on('keydown', function (e) {
if (e.which === 40) { if (e.which == 40) {
that.$selectableUl.focus(); that.$selectionUl.focus();
return false; return false;
} }
}); });
},
afterSelect: function () {
this.qs1.cache();
this.qs2.cache();
},
afterDeselect: function () {
this.qs1.cache();
this.qs2.cache();
}
});
$("#key_multi_account").multiSelect({
selectableHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Account Name'>",
selectionHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Account Name'>",
afterInit: function (ms) {
var that = this,
$selectableSearch = that.$selectableUl.prev(),
$selectionSearch = that.$selectionUl.prev(),
selectableSearchString = '#' + that.$container.attr('id') + ' .ms-elem-selectable:not(.ms-selected)',
selectionSearchString = '#' + that.$container.attr('id') + ' .ms-elem-selection.ms-selected';
that.qs2 = $selectionSearch.quicksearch(selectionSearchString) that.qs1 = $selectableSearch.quicksearch(selectableSearchString)
.on('keydown', function (e) { .on('keydown', function (e) {
if (e.which == 40) { if (e.which === 40) {
that.$selectionUl.focus(); that.$selectableUl.focus();
return false; return false;
} }
}); });
},
afterSelect: function () {
this.qs1.cache();
this.qs2.cache();
},
afterDeselect: function () {
this.qs1.cache();
this.qs2.cache();
}
});
$("#key_multi_account").multiSelect({
selectableHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Account Name'>",
selectionHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Account Name'>",
afterInit: function (ms) {
var that = this,
$selectableSearch = that.$selectableUl.prev(),
$selectionSearch = that.$selectionUl.prev(),
selectableSearchString = '#' + that.$container.attr('id') + ' .ms-elem-selectable:not(.ms-selected)',
selectionSearchString = '#' + that.$container.attr('id') + ' .ms-elem-selection.ms-selected';
that.qs1 = $selectableSearch.quicksearch(selectableSearchString) that.qs2 = $selectionSearch.quicksearch(selectionSearchString)
.on('keydown', function (e) { .on('keydown', function (e) {
if (e.which === 40) { if (e.which == 40) {
that.$selectableUl.focus(); that.$selectionUl.focus();
return false; return false;
} }
}); });
},
afterSelect: function () {
this.qs1.cache();
this.qs2.cache();
},
afterDeselect: function () {
this.qs1.cache();
this.qs2.cache();
}
});
{% if plain_key %}
$(document.body).ready(function () {
var modal = $("#modal_show_key");
var info = "Please copy this key to a secure location. You will be unable to view it again once you close this window: {{ plain_key }}";
modal.find('.modal-body p').text(info);
modal.find('#button_key_confirm').click(redirect_modal);
modal.find('#button_close_modal').click(redirect_modal);
modal.modal('show');
});
that.qs2 = $selectionSearch.quicksearch(selectionSearchString) function redirect_modal() {
.on('keydown', function (e) { window.location.href = '{{ url_for('admin.manage_keys') }}';
if (e.which == 40) { modal.modal('hide');
that.$selectionUl.focus(); }
return false; {% endif %}
} </script>
});
},
afterSelect: function () {
this.qs1.cache();
this.qs2.cache();
},
afterDeselect: function () {
this.qs1.cache();
this.qs2.cache();
}
});
{% if plain_key %}
$(document.body).ready(function () {
var modal = $("#modal_show_key");
var info = "Please copy this key to a secure location. You will be unable to view it again once you close this window: {{ plain_key }}";
modal.find('.modal-body p').text(info);
modal.find('#button_key_confirm').click(redirect_modal);
modal.find('#button_close_modal').click(redirect_modal);
modal.modal('show');
});
function redirect_modal() {
window.location.href = '{{ url_for('admin.manage_keys') }}';
modal.modal('hide');
}
{% endif %}
</script>
{% endblock %} {% endblock %}
{% block modals %} {% block modals %}
<div class="modal fade" id="modal_show_key"> <div class="modal fade" id="modal_show_key">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title">New API Key</h5> <h5 class="modal-title">New API Key</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="button_close_modal"> <button type="button" class="close" data-dismiss="modal" aria-label="Close" id="button_close_modal">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<p></p> <p></p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-primary" id="button_key_confirm"> <button type="button" class="btn btn-primary" id="button_key_confirm">
Confirm Confirm
</button> </button>
</div> </div>
</div>
</div>
</div> </div>
</div> <div class="modal fade" id="modal_warning">
</div> <div class="modal-dialog">
<div class="modal fade" id="modal_warning"> <div class="modal-content">
<div class="modal-dialog"> <div class="modal-header">
<div class="modal-content"> <h5 class="modal-title">WARNING</h5>
<div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"
<h5 class="modal-title">WARNING</h5> id="button_close_warn_modal">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="button_close_warn_modal"> <span aria-hidden="true">&times;</span>
<span aria-hidden="true">&times;</span> </button>
</button> </div>
</div> <div class="modal-body">
<div class="modal-body"> <p></p>
<p></p> </div>
</div> <div class="modal-footer">
<div class="modal-footer"> <button type="button" class="btn btn-secondary close" data-dismiss="modal" id="button_close_modal">
<button type="button" class="btn btn-secondary close" data-dismiss="modal" id="button_close_modal"> Close
Close </button>
</button> <button type="button" class="btn btn-primary" id="button_key_confirm_warn">
<button type="button" class="btn btn-primary" id="button_key_confirm_warn"> OK
OK </button>
</button> </div>
</div> </div>
</div>
</div> </div>
</div>
</div>
{% endblock %} {% endblock %}