ui: rewrite admin templates to pf4, add some helper scripts

This commit is contained in:
Jens Langhammer 2020-02-21 14:20:16 +01:00
parent 8fd86a28ff
commit ea6a1422f7
26 changed files with 1063 additions and 956 deletions

View File

@ -3,44 +3,65 @@
{% load i18n %} {% load i18n %}
{% load utils %} {% load utils %}
{% block title %}
{% title %}
{% endblock %}
{% block content %} {% block content %}
<div class="container"> <section class="pf-c-page__main-section pf-m-light">
<h1><span class="pficon-applications"></span> {% trans "Applications" %}</h1> <div class="pf-c-content">
<span>{% trans "External Applications which use passbook as Identity-Provider, utilizing protocols like OAuth2 and SAML." %}</span> <h1>
<hr> <i class="pf-icon pf-icon-applications"></i>
<a href="{% url 'passbook_admin:application-create' %}?back={{ request.get_full_path }}" class="btn btn-primary"> {% trans 'Applications' %}
{% trans 'Create...' %} </h1>
</a> <p>{% trans "External Applications which use passbook as Identity-Provider, utilizing protocols like OAuth2 and SAML." %}</p>
<hr> </div>
<table class="table table-striped table-bordered"> </section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__action-group">
<a href="{% url 'passbook_admin:application-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-grid-xl" role="grid">
<thead> <thead>
<tr> <tr role="row">
<th>{% trans 'Name' %}</th> <th role="columnheader" scope="col">{% trans 'Name' %}</th>
<th>{% trans 'Provider' %}</th> <th role="columnheader" scope="col">{% trans 'Provider' %}</th>
<th>{% trans 'Provider Type' %}</th> <th role="columnheader" scope="col">{% trans 'Provider Type' %}</th>
<th></th> <th role="cell"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody role="rowgroup">
{% for application in object_list %} {% for application in object_list %}
<tr> <tr role="row">
<td>{{ application.name }}</td> <th role="columnheader">
<td>{{ application.get_provider }}</td> <div>
<td>{{ application.get_provider|verbose_name }}</td> <div>{{ application.name }}</div>
{% if application.meta_publisher %}
<small>{{ application.meta_publisher }}</small>
{% endif %}
</div>
</th>
<td role="cell">
<span>
{{ application.get_provider }}
</span>
</td>
<td role="cell">
<span>
{{ application.get_provider|verbose_name }}
</span>
</td>
<td> <td>
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:application-update' pk=application.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
href="{% url 'passbook_admin:application-update' pk=application.uuid %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a> <a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:application-delete' pk=application.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
<a class="btn btn-default btn-sm"
href="{% url 'passbook_admin:application-delete' pk=application.uuid %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-bottom">
{% include 'partials/pagination.html' %} {% include 'partials/pagination.html' %}
</div> </div>
</div>
</section>
{% endblock %} {% endblock %}

View File

@ -3,85 +3,66 @@
{% load i18n %} {% load i18n %}
{% load utils %} {% load utils %}
{% block title %}
{% title %}
{% endblock %}
{% block content %} {% block content %}
<h1><span class="pficon-catalog"></span> {% trans "Audit Log" %}</h1> <section class="pf-c-page__main-section pf-m-light">
<div id="pf-list-standard" class="list-group list-view-pf list-view-pf-view"> <div class="pf-c-content">
{% for entry in object_list %} <h1>
<div class="list-group-item"> <i class="pf-icon pf-icon-catalog"></i>
<div class="list-view-pf-main-info"> {% trans 'Audit Log' %}
<div class="list-view-pf-left"> </h1>
<span class="fa fa-plane list-view-pf-icon-sm"></span>
</div> </div>
<div class="list-view-pf-body"> </section>
<div class="list-view-pf-description"> <section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="list-group-item-heading"> <div class="pf-c-card">
{{ entry.action }} <div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
</div>
<div class="list-group-item-text">
{{ entry.context }}
</div>
</div>
<div class="list-view-pf-additional-info">
<div class="list-view-pf-additional-info-item">
<span class="pficon pficon-user"></span>
<strong>{{ entry.user }}</strong>
</div>
<div class="list-view-pf-additional-info-item">
<span class="pficon pficon-cluster"></span>
<strong>{{ entry.app|default:'-' }}</strong>
</div>
<div class="list-view-pf-additional-info-item">
<span class="fa fa-clock-o"></span>
<strong>{{ entry.created }}</strong>
</div>
<div class="list-view-pf-additional-info-item">
<span class="pficon pficon-screen"></span>
<strong>{{ entry.request_ip }}</strong>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
<script>
$(document).ready(function () {
// Row Checkbox Selection
$("#pf-list-standard input[type='checkbox']").change(function (e) {
if ($(this).is(":checked")) {
$(this).closest('.list-group-item').addClass("active");
} else {
$(this).closest('.list-group-item').removeClass("active");
}
});
// toggle dropdown menu
$('#pf-list-standard .list-view-pf-actions').on('show.bs.dropdown', function () {
var $this = $(this);
var $dropdown = $this.find('.dropdown');
var space = $(window).height() - $dropdown[0].getBoundingClientRect().top - $this.find('.dropdown-menu').outerHeight(true);
$dropdown.toggleClass('dropup', space < 10);
});
// allow users to select multiple list items with shift key
$('#pf-list-standard .list-group').on('click', '.list-view-pf-checkbox>input', function (event) {
var $list = $('.list-group');
var prevIndex = $list.data('preIndex');
var $listItems = $list.children('.list-group-item');
var $currentItem = $(this).closest('.list-group-item');
if (event.shiftKey && prevIndex > -1 && this.checked) {
var currentIndex = $listItems.index($currentItem);
var $selectScope = currentIndex - prevIndex > 0
? $currentItem.prevAll().not($listItems.eq(prevIndex).prevAll().addBack())
: $listItems.eq(prevIndex).prevAll().not($currentItem.prevAll().addBack());
$selectScope.addClass('active').find('.list-view-pf-checkbox').children('input').prop('checked', true);
}
$list.data('preIndex', this.checked ? $listItems.index($currentItem) : -1);
});
});
</script>
{% include 'partials/pagination.html' %} {% include 'partials/pagination.html' %}
</div> </div>
<table class="pf-c-table pf-m-grid-xl" role="grid">
<thead>
<tr role="row">
<th role="columnheader" scope="col">{% trans 'Action' %}</th>
<th role="columnheader" scope="col">{% trans 'Context' %}</th>
<th role="columnheader" scope="col">{% trans 'User' %}</th>
<th role="columnheader" scope="col">{% trans 'Creation Date' %}</th>
<th role="columnheader" scope="col">{% trans 'Client IP' %}</th>
</tr>
</thead>
<tbody role="rowgroup">
{% for entry in object_list %}
<tr role="row">
<th role="columnheader">
<div>
<div>{{ entry.action }}</div>
<small>{{ entry.app|default:'-' }}</small>
</div>
</th>
<td role="cell">
<span>
{{ entry.context }}
</span>
</td>
<td role="cell">
<span>
{{ entry.user }}
</span>
</td>
<td role="cell">
<span>
{{ entry.created }}
</span>
</td>
<td role="cell">
<span>
{{ entry.client_ip }}
</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-bottom">
{% include 'partials/pagination.html' %}
</div>
</div>
</section>
{% endblock %} {% endblock %}

View File

@ -3,29 +3,34 @@
{% load i18n %} {% load i18n %}
{% load utils %} {% load utils %}
{% block title %}
{% title %}
{% endblock %}
{% block content %} {% block content %}
<div class="container"> <section class="pf-c-page__main-section pf-m-light">
<h1><span class="pficon-applications"></span> {% trans "Request" %}</h1> <div class="pf-c-content">
<hr> <h1>
<table class="table table-striped table-bordered"> <i class="pf-icon pf-icon-applications"></i>
{% trans 'Request' %}
</h1>
</div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<table class="pf-c-table pf-m-grid-xl" role="grid">
<thead> <thead>
<tr> <tr role="row">
<th>{% trans 'Key' %}</th> <th role="columnheader" scope="col" style="min-width: 150px;">{% trans 'Key' %}</th>
<th>{% trans 'Value' %}</th> <th role="columnheader" scope="col">{% trans 'Value' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody role="rowgroup">
{% for key, value in request_dict.items %} {% for key, value in request_dict.items %}
<tr> <tr role="row">
<td>{{ key }}</td> <td role="cell">{{ key }}</td>
<td>{{ value }}</td> <td role="cell">{{ value }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div>
</section>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -4,60 +4,80 @@
{% load utils %} {% load utils %}
{% load admin_reflection %} {% load admin_reflection %}
{% block title %}
{% title %}
{% endblock %}
{% block content %} {% block content %}
<div class="container"> <section class="pf-c-page__main-section pf-m-light">
<h1><span class="pficon-plugged"></span> {% trans "Factors" %}</h1> <div class="pf-c-content">
<span>{% trans "Factors required for a user to successfully authenticate." %}</span> <h1>
<hr> <i class="pf-icon pf-icon-plugged"></i>
<div class="dropdown"> {% trans 'Factors' %}
<button class="btn btn-primary dropdown-toggle" type="button" id="createDropdown" data-toggle="dropdown"> </h1>
{% trans 'Create...' %} <p>{% trans "Factors required for a user to successfully authenticate." %}
<span class="caret"></span> </p>
</div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__action-group">
<div class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">{% trans 'Create' %}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button> </button>
<ul class="dropdown-menu" role="menu" aria-labelledby="createDropdown"> <ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %} {% for type, name in types.items %}
<li role="presentation"><a role="menuitem" tabindex="-1" <li>
href="{% url 'passbook_admin:factor-create' %}?type={{ type }}&back={{ request.get_full_path }}">{{ name }}</a></li> <a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:factor-create' %}?type={{ type }}&back={{ request.get_full_path }}">{{ name }}</a>
</li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
<hr> </div>
<table class="table table-striped table-bordered"> {% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-grid-xl" role="grid">
<thead> <thead>
<tr> <tr role="row">
<th>{% trans 'Name' %}</th> <th role="columnheader" scope="col">{% trans 'Name' %}</th>
<th>{% trans 'Type' %}</th> <th role="columnheader" scope="col">{% trans 'Order' %}</th>
<th>{% trans 'Order' %}</th> <th role="columnheader" scope="col">{% trans 'Enabled' %}</th>
<th>{% trans 'Enabled?' %}</th> <th role="cell"></th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody role="rowgroup">
{% for factor in object_list %} {% for factor in object_list %}
<tr> <tr role="row">
<td>{{ factor.name }} ({{ factor.slug }})</td> <th role="columnheader">
<td>{{ factor|verbose_name }}</td> <div>
<td>{{ factor.order }}</td> <div>{{ factor.name }} ({{ factor.slug }})</div>
<td>{{ factor.enabled }}</td> <small>{{ factor|verbose_name }}</small>
</div>
</th>
<td role="cell">
<span>
{{ factor.order }}
</span>
</td>
<td role="cell">
<span>
{{ factor.enabled }}
</span>
</td>
<td> <td>
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:factor-update' pk=factor.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
href="{% url 'passbook_admin:factor-update' pk=factor.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a> <a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:factor-delete' pk=factor.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
<a class="btn btn-default btn-sm"
href="{% url 'passbook_admin:factor-delete' pk=factor.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
{% get_links factor as links %} {% get_links factor as links %}
{% for name, href in links.items %} {% for name, href in links.items %}
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-tertiary" href="{{ href }}?back={{ request.get_full_path }}">{% trans name %}</a>
href="{{ href }}?back={{ request.get_full_path }}">{% trans name %}</a>
{% endfor %} {% endfor %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-bottom">
{% include 'partials/pagination.html' %} {% include 'partials/pagination.html' %}
</div> </div>
</div>
</section>
{% endblock %} {% endblock %}

View File

@ -3,44 +3,64 @@
{% load i18n %} {% load i18n %}
{% load utils %} {% load utils %}
{% block title %}
{% title %}
{% endblock %}
{% block content %} {% block content %}
<div class="container"> <section class="pf-c-page__main-section pf-m-light">
<h1><span class="pficon-users"></span> {% trans "Groups" %}</h1> <div class="pf-c-content">
<span>{% trans "Group users together and give them permissions based on the membership." %}</span> <h1>
<hr> <i class="pf-icon pf-icon-users"></i>
<a href="{% url 'passbook_admin:group-create' %}?back={{ request.get_full_path }}" class="btn btn-primary"> {% trans 'Groups' %}
{% trans 'Create...' %} </h1>
</a> <p>{% trans "Group users together and give them permissions based on the membership." %}
<hr> </p>
<table class="table table-striped table-bordered"> </div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__action-group">
<a href="{% url 'passbook_admin:group-create' %}?back={{ request.get_full_path }}"
class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-grid-xl" role="grid">
<thead> <thead>
<tr> <tr role="row">
<th>{% trans 'Name' %}</th> <th role="columnheader" scope="col">{% trans 'Name' %}</th>
<th>{% trans 'Parent' %}</th> <th role="columnheader" scope="col">{% trans 'Parent' %}</th>
<th>{% trans 'Members' %}</th> <th role="columnheader" scope="col">{% trans 'Members' %}</th>
<th></th> <th role="cell"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody role="rowgroup">
{% for group in object_list %} {% for group in object_list %}
<tr> <tr role="row">
<td>{{ group.name }}</td> <td role="cell">
<td>{{ group.parent }}</td> <span>
<td>{{ group.user_set.all|length }}</td> {{ group.name }}
</span>
</td>
<td role="cell">
<span>
{{ group.parent }}
</span>
</td>
<td role="cell">
<span>
{{ group.user_set.all|length }}
</span>
</td>
<td> <td>
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:group-update' pk=group.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
href="{% url 'passbook_admin:group-update' pk=group.uuid %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a> <a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:group-delete' pk=group.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
<a class="btn btn-default btn-sm"
href="{% url 'passbook_admin:group-delete' pk=group.uuid %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-bottom">
{% include 'partials/pagination.html' %} {% include 'partials/pagination.html' %}
</div> </div>
</div>
</section>
{% endblock %} {% endblock %}

View File

@ -3,42 +3,57 @@
{% load i18n %} {% load i18n %}
{% load utils %} {% load utils %}
{% block title %}
{% title %}
{% endblock %}
{% block content %} {% block content %}
<div class="container"> <section class="pf-c-page__main-section pf-m-light">
<h1><span class="pficon-migration"></span> {% trans "Invitations" %}</h1> <div class="pf-c-content">
<span>{% trans "Create Invitation Links which optionally force a username or expire on a set date." %}</span> <h1>
<hr> <i class="pf-icon pf-icon-migration"></i>
<a href="{% url 'passbook_admin:invitation-create' %}?back={{ request.get_full_path }}" class="btn btn-primary"> {% trans 'Invitations' %}
{% trans 'Create...' %} </h1>
</a> <p>{% trans "Create Invitation Links to enroll Users, and optionally force a username or expire on a set date." %}
<hr> </p>
<table class="table table-striped table-bordered"> </div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__action-group">
<a href="{% url 'passbook_admin:invitation-create' %}?back={{ request.get_full_path }}"
class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-grid-xl" role="grid">
<thead> <thead>
<tr> <tr role="row">
<th>{% trans 'Expiry' %}</th> <th role="columnheader" scope="col">{% trans 'Expiry' %}</th>
<th>{% trans 'Link' %}</th> <th role="columnheader" scope="col">{% trans 'Link' %}</th>
<th></th> <th role="cell"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody role="rowgroup">
{% for invitation in object_list %} {% for invitation in object_list %}
<tr> <tr role="row">
<td>{{ invitation.expires|default:"Never" }}</td> <td role="cell">
<td> <span>
<pre>{{ invitation.link }}</pre> {{ invitation.expiry }}
</span>
</td>
<td role="cell">
<span>
{{ invitation.Link }}
</span>
</td> </td>
<td> <td>
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:invitation-delete' pk=invitation.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
href="{% url 'passbook_admin:invitation-delete' pk=invitation.uuid %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-bottom">
{% include 'partials/pagination.html' %} {% include 'partials/pagination.html' %}
</div> </div>
</div>
</section>
{% endblock %} {% endblock %}

View File

@ -3,204 +3,157 @@
{% load i18n %} {% load i18n %}
{% block content %} {% block content %}
<section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content">
<h1>{% trans 'System Overview' %}</h1>
</div>
</section>
<section class="pf-c-page__main-section"> <section class="pf-c-page__main-section">
<div class="pf-l-gallery pf-m-gutter"> <div class="pf-l-gallery pf-m-gutter">
<a href="{% url 'passbook_admin:applications' %}" class="pf-c-card pf-m-hoverable pf-m-compact" id="card-1"> <a href="{% url 'passbook_admin:applications' %}" class="pf-c-card pf-m-hoverable pf-m-compact">
<div class="pf-c-card__head"> <div class="pf-c-card__head">
<div class="pf-c-card__head-main">
<i class="pf-icon pf-icon-applications"></i> {% trans 'Applications' %} <i class="pf-icon pf-icon-applications"></i> {% trans 'Applications' %}
</div> </div>
</div>
<div class="pf-c-card__body"> <div class="pf-c-card__body">
<i class="pf-icon pf-icon-ok"></i> {{ application_count }} <i class="pf-icon pf-icon-ok"></i> {{ application_count }}
</div> </div>
</a> </a>
<a href="{% url 'passbook_admin:sources' %}" class="pf-c-card pf-m-hoverable pf-m-compact" id="card-1"> <a href="{% url 'passbook_admin:sources' %}" class="pf-c-card pf-m-hoverable pf-m-compact">
<div class="pf-c-card__head"> <div class="pf-c-card__head">
<i class="pf-icon pf-icon-resource-pool"></i> {% trans 'Sources' %} <div class="pf-c-card__head-main">
<i class="pf-icon pf-icon-middleware"></i> {% trans 'Sources' %}
</div>
</div> </div>
<div class="pf-c-card__body"> <div class="pf-c-card__body">
<i class="pf-icon pf-icon-ok"></i> {{ source_count }} <i class="pf-icon pf-icon-ok"></i> {{ source_count }}
</div> </div>
</a> </a>
<a href="{% url 'passbook_admin:providers' %}" class="pf-c-card pf-m-hoverable pf-m-compact" id="card-1"> <a href="{% url 'passbook_admin:providers' %}" class="pf-c-card pf-m-hoverable pf-m-compact">
<div class="pf-c-card__head"> <div class="pf-c-card__head">
<div class="pf-c-card__head-main">
<i class="pf-icon pf-icon-plugged"></i> {% trans 'Providers' %} <i class="pf-icon pf-icon-plugged"></i> {% trans 'Providers' %}
</div> </div>
</div>
<div class="pf-c-card__body"> <div class="pf-c-card__body">
{% if providers_without_application.exists %} {% if providers_without_application.exists %}
<i class="pf-icon pf-icon-warning-triangle"></i> {{ provider_count }} <i class="pf-icon pf-icon-warning-triangle"></i> {{ provider_count }}
<div class="pf-c-tooltip pf-m-top" role="tooltip"> <p>{% trans 'Warning: At least one Provider has no application assigned.' %}</p>
<div class="pf-c-tooltip__arrow"></div>
<div class="pf-c-tooltip__content" id="tooltip-top-content">
{% trans 'Warning: At least one Provider has no application assigned.' %}
</div>
</div>
{% else %} {% else %}
<i class="pf-icon pf-icon-ok"></i> {{ provider_count }} <i class="pf-icon pf-icon-ok"></i> {{ provider_count }}
{% endif %} {% endif %}
</div> </div>
</a> </a>
<a href="{% url 'passbook_admin:factors' %}" class="pf-c-card pf-m-hoverable pf-m-compact">
<div class="pf-c-card__head">
<div class="pf-c-card__head-main">
<i class="pf-icon pf-icon-plugged"></i> {% trans 'Factors' %}
</div> </div>
</section> </div>
<div class="col-xs-6 col-sm-2 col-md-2"> <div class="pf-c-card__body">
<div class="card-pf card-pf-accented card-pf-aggregate-status">
<h2 class="card-pf-title">
<a href="{% url 'passbook_admin:factors' %}">
<span class="pficon-plugged"></span>
<span class="card-pf-aggregate-status-count"></span> {% trans 'Factors' %}
</a>
</h2>
<div class="card-pf-body">
<p class="card-pf-aggregate-status-notifications">
<span class="card-pf-aggregate-status-notification">
{% if factor_count < 1 %} {% if factor_count < 1 %}
<span class="pficon-error-circle-o" data-toggle="tooltip" data-placement="right" <i class="pficon-error-circle-o"></i> {{ factor_count }}
title="{% trans 'No Factors configured. No Users will be able to login.' %}"></span> <p>{% trans 'No Factors configured. No Users will be able to login.' %}"></p>
{{ factor_count }}
{% else %} {% else %}
<i class="pf-icon pf-icon-ok"></i>{{ factor_count }} <i class="pf-icon pf-icon-ok"></i> {{ factor_count }}
{% endif %} {% endif %}
</span>
</p>
</div> </div>
</div>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<div class="card-pf card-pf-accented card-pf-aggregate-status">
<h2 class="card-pf-title">
<a href="{% url 'passbook_admin:policies' %}">
<span class="pficon-infrastructure"></span>
<span class="card-pf-aggregate-status-count"></span> {% trans 'Policies' %}
</a> </a>
</h2>
<div class="card-pf-body"> <a href="{% url 'passbook_admin:policies' %}" class="pf-c-card pf-m-hoverable pf-m-compact">
<p class="card-pf-aggregate-status-notifications"> <div class="pf-c-card__head">
<span class="card-pf-aggregate-status-notification"> <div class="pf-c-card__head-main">
{% if policies_without_attachment > 0 %} <i class="pf-icon pf-icon-infrastructure"></i> {% trans 'Policies' %}
<span class="pficon-warning-triangle-o" data-toggle="tooltip" data-placement="right" </div>
title="{% trans 'Policies without attachment exist.' %}"></span> </div>
{{ policy_count }} <div class="pf-c-card__body">
{% if policies_without_binding %}
<i class="pf-icon pf-icon-warning-triangle"></i> {{ policy_count }}
<p>{% trans 'Policies without binding exist.' %}</p>
{% else %} {% else %}
<i class="pf-icon pf-icon-ok"></i>{{ policy_count }} <i class="pf-icon pf-icon-ok"></i> {{ policy_count }}
{% endif %} {% endif %}
</span>
</p>
</div> </div>
</div>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<div class="card-pf card-pf-accented card-pf-aggregate-status">
<h2 class="card-pf-title">
<a href="{% url 'passbook_admin:invitations' %}">
<span class="pficon-migration"></span>
<span class="card-pf-aggregate-status-count"></span> {% trans 'Invitation' %}
</a> </a>
</h2>
<div class="card-pf-body"> <a href="{% url 'passbook_admin:invitations' %}" class="pf-c-card pf-m-hoverable pf-m-compact">
<p class="card-pf-aggregate-status-notifications"> <div class="pf-c-card__head">
<span class="card-pf-aggregate-status-notification"> <div class="pf-c-card__head-main">
<a href="{% url 'passbook_admin:invitations' %}"> <i class="pf-icon pf-icon-migration"></i> {% trans 'Invitation' %}
<i class="pf-icon pf-icon-ok"></i>{{ invitation_count }} </div>
</div>
<div class="pf-c-card__body">
<i class="pf-icon pf-icon-ok"></i> {{ invitation_count }}
</div>
</a> </a>
</span>
</p> <a href="{% url 'passbook_admin:users' %}" class="pf-c-card pf-m-hoverable pf-m-compact">
<div class="pf-c-card__head">
<div class="pf-c-card__head-main">
<i class="pf-icon pf-icon-user"></i> {% trans 'Users' %}
</div> </div>
</div> </div>
<div class="pf-c-card__body">
<i class="pf-icon pf-icon-ok"></i> {{ user_count }}
</div> </div>
<div class="col-xs-6 col-sm-2 col-md-2">
<div class="card-pf card-pf-accented card-pf-aggregate-status">
<h2 class="card-pf-title">
<a href="{% url 'passbook_admin:users' %}">
<span class="pficon-users"></span>
<span class="card-pf-aggregate-status-count"></span> {% trans 'Users' %}
</a> </a>
</h2>
<div class="card-pf-body"> <div class="pf-c-card pf-m-hoverable pf-m-compact">
<p class="card-pf-aggregate-status-notifications"> <div class="pf-c-card__head">
<span class="card-pf-aggregate-status-notification"> <div class="pf-c-card__head-main">
<a href="{% url 'passbook_admin:users' %}"> <i class="pf-icon pf-icon-bundle"></i> {% trans 'Version' %}
<i class="pf-icon pf-icon-ok"></i>{{ user_count }}
</a>
</span>
</p>
</div> </div>
</div> </div>
</div> <div class="pf-c-card__body">
<div class="col-xs-6 col-sm-2 col-md-2"> <i class="pf-icon pf-icon-ok"></i> {{ version }}
<div class="card-pf card-pf-accented card-pf-aggregate-status">
<h2 class="card-pf-title">
<span class="pficon-bundle"></span>
<span class="card-pf-aggregate-status-count"></span> {% trans 'Version' %}
</h2>
<div class="card-pf-body">
<p class="card-pf-aggregate-status-notifications">
<span class="card-pf-aggregate-status-notification">
<a href="#">
{{ version }}
</a>
</span>
</p>
</div> </div>
</div> </div>
<div class="pf-c-card pf-m-hoverable pf-m-compact">
<div class="pf-c-card__head">
<div class="pf-c-card__head-main">
<i class="pf-icon pf-icon-server"></i> {% trans 'Workers' %}
</div> </div>
<div class="col-xs-6 col-sm-2 col-md-2"> </div>
<div class="card-pf card-pf-accented card-pf-aggregate-status"> <div class="pf-c-card__body">
<h2 class="card-pf-title"> {% if worker_count < 1 %}
<a href="#"> <i class="pf-icon pf-icon-warning-triangle"></i> {{ worker_count }}
<span class="pficon-server"></span> <p>{% trans 'No workers connected.' %}</p>
<span class="card-pf-aggregate-status-count"></span> {% trans 'Worker(s)' %}
</a>
</h2>
<div class="card-pf-body">
<p class="card-pf-aggregate-status-notifications">
<span class="card-pf-aggregate-status-notification">
<a href="#">
{% if worker_count < 1%}
<span class="pficon-warning-triangle-o" data-toggle="tooltip" data-placement="right"
title="{% trans 'No workers connected.' %}"></span> {{ worker_count }}
{% else %} {% else %}
<i class="pf-icon pf-icon-ok"></i>{{ worker_count }} <i class="pf-icon pf-icon-ok"></i> {{ worker_count }}
{% endif %} {% endif %}
</a>
</span>
</p>
</div> </div>
</div> </div>
<a class="pf-c-card pf-m-hoverable pf-m-compact" data-target="modal" data-modal="clearCacheModalRoot">
<div class="pf-c-card__head">
<div class="pf-c-card__head-main">
<i class="pf-icon pf-icon-server"></i> {% trans 'Cached Policies' %}
</div> </div>
<div class="col-xs-6 col-sm-2 col-md-2"> </div>
<div class="card-pf card-pf-accented card-pf-aggregate-status"> <div class="pf-c-card__body">
<h2 class="card-pf-title">
<span class="pficon-server"></span>
<span class="card-pf-aggregate-status-count"></span> {% trans 'Cached Policies' %}
</h2>
<div class="card-pf-body">
<p class="card-pf-aggregate-status-notifications">
<span class="card-pf-aggregate-status-notification">
<a href="#" data-toggle="modal" data-target="#clearCacheMOdal">
{% if cached_policies < 1 %} {% if cached_policies < 1 %}
<span class="pficon-warning-triangle-o" data-toggle="tooltip" data-placement="right" <i class="pf-icon pf-icon-warning-triangle"></i> {{ cached_policies }}
title="{% trans 'No policies cached. Users may experience slow response times.' %}"></span> {{ cached_policies }} <p>{% trans 'No policies cached. Users may experience slow response times.' %}</p>
{% else %} {% else %}
<i class="pf-icon pf-icon-ok"></i>{{ cached_policies }} <i class="pf-icon pf-icon-ok"></i> {{ cached_policies }}
{% endif %} {% endif %}
</div>
</a> </a>
</span> </section>
</p>
</div>
</div>
</div>
</div> </div>
<div class="modal fade" id="clearCacheMOdal" tabindex="-1" role="dialog" aria-labelledby="clearCacheMOdalLabel" aria-hidden="true"> <div class="pf-c-backdrop" id="clearCacheModalRoot" hidden>
<div class="modal-dialog"> <div class="pf-l-bullseye">
<div class="modal-content"> <div class="pf-c-modal-box pf-m-sm" role="dialog">
<div class="modal-header"> <button data-modal-close class="pf-c-button pf-m-plain" type="button" aria-label="Close dialog">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"> <i class="fas fa-times" aria-hidden="true"></i>
<span class="pficon pficon-close"></span>
</button> </button>
<h4 class="modal-title" id="clearCacheMOdalLabel">{% trans 'Clear Cache' %}</h4> <h1 class="pf-c-title pf-m-2xl" id="modal-title">{% trans 'Clear Cache' %}?</h1>
</div> <div class="pf-c-modal-box__body" id="modal-description">
<div class="modal-body">
<form method="post" id="clearForm"> <form method="post" id="clearForm">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="clear"> <input type="hidden" name="clear">
@ -216,10 +169,10 @@
</h3> </h3>
</form> </form>
</div> </div>
<div class="modal-footer"> <footer class="pf-c-modal-box__footer pf-m-align-left">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> <button form="clearForm" class="pf-c-button pf-m-primary" type="submit">{% trans 'Clear' %}</button>
<button form="clearForm" type="submit" type="button" class="btn btn-danger">{% trans 'Clear' %}</button> <button data-modal-close class="pf-c-button pf-m-link" type="button">{% trans 'Cancel' %}</button>
</div> </footer>
</div> </div>
</div> </div>
</div> </div>

View File

@ -3,61 +3,76 @@
{% load i18n %} {% load i18n %}
{% load utils %} {% load utils %}
{% block title %}
{% title %}
{% endblock %}
{% block content %} {% block content %}
<div class="container"> <section class="pf-c-page__main-section pf-m-light">
<h1><span class="pficon-infrastructure"></span> {% trans "Policies" %}</h1> <div class="pf-c-content">
<span>{% trans "Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Factors." %}</span> <h1>
<hr> <i class="pf-icon pf-icon-infrastructure"></i>
<div class="dropdown"> {% trans 'Policies' %}
<button class="btn btn-primary dropdown-toggle" type="button" id="createDropdown" data-toggle="dropdown"> </h1>
{% trans 'Create...' %} <p>{% trans "Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Factors." %}</p>
<span class="caret"></span> </div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__action-group">
<div class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">{% trans 'Create' %}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button> </button>
<ul class="dropdown-menu" role="menu" aria-labelledby="createDropdown"> <ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %} {% for type, name in types.items %}
<li role="presentation"><a role="menuitem" tabindex="-1" <li>
href="{% url 'passbook_admin:policy-create' %}?type={{ type }}&back={{ request.get_full_path }}">{{ name }}</a></li> <a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:policy-create' %}?type={{ type }}&back={{ request.get_full_path }}">{{ name }}</a>
</li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
<hr> </div>
<table class="table table-striped table-bordered"> {% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-grid-xl" role="grid">
<thead> <thead>
<tr> <tr role="row">
<th></th> <th role="columnheader" scope="col">{% trans 'Name' %}</th>
<th>{% trans 'Name' %}</th> <th role="columnheader" scope="col">{% trans 'Type' %}</th>
<th>{% trans 'Type' %}</th> <th role="cell"></th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody role="rowgroup">
{% for policy in object_list %} {% for policy in object_list %}
<tr {% if not policy.policymodel_set.exists %} class="warning" {% endif %}> <tr role="row">
<th> <th role="columnheader">
<div>
<div>{{ policy.name }}</div>
{% if not policy.policymodel_set.exists %} {% if not policy.policymodel_set.exists %}
<span class="pficon-warning-triangle-o" data-toggle="tooltip" data-placement="right" title="{% trans 'Warning: Policy is not assigned.' %}"></span> <i class="pf-icon pf-icon-warning-triangle"></i>
<small>{% trans 'Warning: Policy is not assigned.' %}</small>
{% else %} {% else %}
<span class="pficon-ok" data-toggle="tooltip" data-placement="right" title="{% blocktrans with objects=policy.policymodel_set.all|join:', ' %}Assigned to objects {{ objects }}{% endblocktrans %}"></span> <i class="pf-icon pf-icon-ok"></i>
<small>{% blocktrans with objects=policy.policymodel_set.all|join:', ' %}Assigned to objects {{ objects }}{% endblocktrans %}</small>
{% endif %} {% endif %}
</div>
</th> </th>
<td>{{ policy.name }}</td> <td role="cell">
<td>{{ policy|verbose_name }}</td> <span>
{{ policy|verbose_name }}
</span>
</td>
<td> <td>
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:policy-update' pk=policy.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
href="{% url 'passbook_admin:policy-update' pk=policy.uuid %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a> <a class="pf-c-button pf-m-tertiary" href="{% url 'passbook_admin:policy-test' pk=policy.pk %}?back={{ request.get_full_path }}">{% trans 'Test' %}</a>
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:policy-delete' pk=policy.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
href="{% url 'passbook_admin:policy-test' pk=policy.uuid %}?back={{ request.get_full_path }}">{% trans 'Test' %}</a>
<a class="btn btn-default btn-sm"
href="{% url 'passbook_admin:policy-delete' pk=policy.uuid %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-bottom">
{% include 'partials/pagination.html' %} {% include 'partials/pagination.html' %}
</div> </div>
</div>
</section>
{% endblock %} {% endblock %}

View File

@ -3,51 +3,70 @@
{% load i18n %} {% load i18n %}
{% load utils %} {% load utils %}
{% block title %}
{% title %}
{% endblock %}
{% block content %} {% block content %}
<div class="container"> <section class="pf-c-page__main-section pf-m-light">
<h1><span class="fa fa-table"></span> {% trans "Property Mappings" %}</h1> <div class="pf-c-content">
<span>{% trans "Property Mappings allow you expose provider-specific attributes." %}</span> <h1>
<hr> <i class="pf-icon pf-icon-blueprint"></i>
<div class="dropdown"> {% trans 'Property Mappings' %}
<button class="btn btn-primary dropdown-toggle" type="button" id="createDropdown" data-toggle="dropdown"> </h1>
{% trans 'Create...' %} <p>{% trans "Control how passbook exposes and interprets information." %}
<span class="caret"></span> </p>
</div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__action-group">
<div class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">{% trans 'Create' %}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button> </button>
<ul class="dropdown-menu" role="menu" aria-labelledby="createDropdown"> <ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %} {% for type, name in types.items %}
<li role="presentation"><a role="menuitem" tabindex="-1" <li>
href="{% url 'passbook_admin:property-mapping-create' %}?type={{ type }}&back={{ request.get_full_path }}">{{ name }}</a></li> <a class="pf-c-dropdown__menu-item"
href="{% url 'passbook_admin:property-mapping-create' %}?type={{ type }}&back={{ request.get_full_path }}">{{ name }}</a>
</li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
<hr> </div>
<table class="table table-striped table-bordered"> {% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-grid-xl" role="grid">
<thead> <thead>
<tr> <tr role="row">
<th>{% trans 'Name' %}</th> <th role="columnheader" scope="col">{% trans 'Name' %}</th>
<th>{% trans 'Type' %}</th> <th role="columnheader" scope="col">{% trans 'Type' %}</th>
<th></th> <th role="cell"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody role="rowgroup">
{% for property_mapping in object_list %} {% for property_mapping in object_list %}
<tr> <tr role="row">
<td>{{ property_mapping.name }}</td> <td role="cell">
<td>{{ property_mapping|verbose_name }}</td> <span>
{{ property_mapping.name }}
</span>
</td>
<td role="cell">
<span>
{{ property_mapping|verbose_name }}
</span>
</td>
<td> <td>
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:property-mapping-update' pk=property_mapping.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
href="{% url 'passbook_admin:property-mapping-update' pk=property_mapping.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a> <a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:property-mapping-delete' pk=property_mapping.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
<a class="btn btn-default btn-sm"
href="{% url 'passbook_admin:property-mapping-delete' pk=property_mapping.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-bottom">
{% include 'partials/pagination.html' %} {% include 'partials/pagination.html' %}
</div> </div>
</div>
</section>
{% endblock %} {% endblock %}

View File

@ -4,58 +4,75 @@
{% load utils %} {% load utils %}
{% load admin_reflection %} {% load admin_reflection %}
{% block title %}
{% title %}
{% endblock %}
{% block content %} {% block content %}
<div class="container"> <section class="pf-c-page__main-section pf-m-light">
<h1><span class="pficon-integration"></span> {% trans "Providers" %}</h1> <div class="pf-c-content">
<span>{% trans "Authentication Protocol Provider, used as Protocol behind an Application." %}</span> <h1>
<hr> <i class="pf-icon pf-icon-integration"></i>
<div class="dropdown"> {% trans 'Providers' %}
<button class="btn btn-primary dropdown-toggle" type="button" id="createDropdown" data-toggle="dropdown"> </h1>
{% trans 'Create...' %} <p>{% trans "Provide support for protocols like SAML and OAuth to assigned applications." %}
<span class="caret"></span> </p>
</div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__action-group">
<div class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">{% trans 'Create' %}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button> </button>
<ul class="dropdown-menu" role="menu" aria-labelledby="createDropdown"> <ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %} {% for type, name in types.items %}
<li role="presentation"><a role="menuitem" tabindex="-1" <li>
href="{% url 'passbook_admin:provider-create' %}?type={{ type }}&back={{ request.get_full_path }}">{{ name }}</a></li> <a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:provider-create' %}?type={{ type }}&back={{ request.get_full_path }}">{{ name }}</a>
</li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
<hr> </div>
<table class="table table-striped table-bordered"> {% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-grid-xl" role="grid">
<thead> <thead>
<tr> <tr role="row">
<th></th> <th role="columnheader" scope="col">{% trans 'Name' %}</th>
<th>{% trans 'Name' %}</th> <th role="columnheader" scope="col">{% trans 'Type' %}</th>
<th>{% trans 'Type' %}</th> <th role="cell"></th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody role="rowgroup">
{% for provider in object_list %} {% for provider in object_list %}
<tr {% if not provider.application %} class="warning" {% endif %}> <tr role="row">
<th> <th role="columnheader">
<div>
<div>{{ provider.name }}</div>
{% if not provider.application %} {% if not provider.application %}
<span class="pficon-warning-triangle-o" data-toggle="tooltip" data-placement="right" title="{% trans 'Warning: Provider has no application assigned.' %}"></span> <i class="pf-icon pf-icon-warning-triangle"></i>
<small>{% trans 'Warning: Provider not assigned to any application.' %}</small>
{% else %} {% else %}
<span class="pficon-ok" data-toggle="tooltip" data-placement="right" title="{% blocktrans with app=provider.application %}Assigned to Application {{ app }}{% endblocktrans %}"></span> <i class="pf-icon pf-icon-ok"></i>
<small>
{% blocktrans with app=provider.application %}
Assigned to application {{ app }}.
{% endblocktrans %}
</small>
{% endif %} {% endif %}
</div>
</th> </th>
<td>{{ provider.name }}</td> <td role="cell">
<td>{{ provider|verbose_name }}</td> <span>
{{ provider|verbose_name }}
</span>
</td>
<td> <td>
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:provider-update' pk=provider.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
href="{% url 'passbook_admin:provider-update' pk=provider.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a> <a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:provider-delete' pk=provider.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
<a class="btn btn-default btn-sm"
href="{% url 'passbook_admin:provider-delete' pk=provider.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
{% get_links provider as links %} {% get_links provider as links %}
{% for name, href in links.items %} {% for name, href in links.items %}
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-tertiary" href="{{ href }}?back={{ request.get_full_path }}">{% trans name %}</a>
href="{{ href }}?back={{ request.get_full_path }}">{% trans name %}</a>
{% endfor %} {% endfor %}
{% get_htmls provider as htmls %} {% get_htmls provider as htmls %}
{% for html in htmls %} {% for html in htmls %}
@ -66,6 +83,9 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-bottom">
{% include 'partials/pagination.html' %} {% include 'partials/pagination.html' %}
</div> </div>
</div>
</section>
{% endblock %} {% endblock %}

View File

@ -5,53 +5,81 @@
{% load admin_reflection %} {% load admin_reflection %}
{% block content %} {% block content %}
<div class="container"> <section class="pf-c-page__main-section pf-m-light">
<h1><span class="pficon-resource-pool"></span> {% trans "Sources" %}</h1> <div class="pf-c-content">
<span>{% trans "External Sources which can be used to get Identities into passbook, for example Social Providers like Twiter and GitHub or Enterprise Providers like ADFS and LDAP." %}</span> <h1>
<hr> <i class="pf-icon pf-icon-middleware"></i>
<div class="dropdown"> {% trans 'Source' %}
<button class="btn btn-primary dropdown-toggle" type="button" id="createDropdown" data-toggle="dropdown"> </h1>
{% trans 'Create...' %} <p>{% trans "External Sources which can be used to get Identities into passbook, for example Social Providers like Twiter and GitHub or Enterprise Providers like ADFS and LDAP." %}
<span class="caret"></span> </p>
</div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__action-group">
<div class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">{% trans 'Create' %}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button> </button>
<ul class="dropdown-menu" role="menu" aria-labelledby="createDropdown"> <ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %} {% for type, name in types.items %}
<li role="presentation"><a role="menuitem" tabindex="-1" <li>
href="{% url 'passbook_admin:source-create' %}?type={{ type }}&back={{ request.get_full_path }}">{{ name }}</a></li> <a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:source-create' %}?type={{ type }}&back={{ request.get_full_path }}">{{ name }}</a>
</li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
<hr> </div>
<table class="table table-striped table-bordered"> {% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-grid-xl" role="grid">
<thead> <thead>
<tr> <tr role="row">
<th>{% trans 'Name' %}</th> <th role="columnheader" scope="col">{% trans 'Name' %}</th>
<th>{% trans 'Class' %}</th> <th role="columnheader" scope="col">{% trans 'Type' %}</th>
<th>{% trans 'Additional Info' %}</th> <th role="columnheader" scope="col">{% trans 'Additional Info' %}</th>
<th></th> <th role="cell"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody role="rowgroup">
{% for source in object_list %} {% for source in object_list %}
<tr> <tr role="row">
<td>{{ source.name }}</td> <th role="columnheader">
<td>{{ source|fieldtype }}</td> <div>
<td>{{ source.ui_additional_info|safe|default:"" }}</td> <div>{{ source.name }}</div>
{% if not source.enabled %}
<small>{% trans 'Disabled' %}</small>
{% endif %}
</div>
</th>
<td role="cell">
<span>
{{ source|fieldtype }}
</span>
</td>
<td role="cell">
<span>
{{ source.ui_additional_info|default:""|safe }}
</span>
</td>
<td> <td>
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:source-update' pk=source.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
href="{% url 'passbook_admin:source-update' pk=source.uuid %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a> <a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:source-delete' pk=source.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
<a class="btn btn-default btn-sm"
href="{% url 'passbook_admin:source-delete' pk=source.uuid %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
{% get_links source as links %} {% get_links source as links %}
{% for name, href in links %} {% for name, href in links %}
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-tertiary" href="{{ href }}?back={{ request.get_full_path }}">{% trans name %}</a>
href="{{ href }}?back={{ request.get_full_path }}">{% trans name %}</a>
{% endfor %} {% endfor %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-bottom">
{% include 'partials/pagination.html' %} {% include 'partials/pagination.html' %}
</div> </div>
</div>
</section>
{% endblock %} {% endblock %}

View File

@ -4,44 +4,63 @@
{% load utils %} {% load utils %}
{% block content %} {% block content %}
<div class="container"> <section class="pf-c-page__main-section pf-m-light">
<h1><span class="pficon-users"></span> {% trans "Users" %}</h1> <div class="pf-c-content">
<hr> <h1>
<a href="{% url 'passbook_admin:user-create' %}?back={{ request.get_full_path }}" class="btn btn-primary"> <i class="pf-icon pf-icon-user"></i>
{% trans 'Create...' %} {% trans 'Users' %}
</a> </h1>
<hr> </div>
<table class="table table-striped table-bordered"> </section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__action-group">
<a href="{% url 'passbook_admin:user-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-grid-xl" role="grid">
<thead> <thead>
<tr> <tr role="row">
<th>{% trans 'Username' %}</th> <th role="columnheader" scope="col">{% trans 'Name' %}</th>
<th>{% trans 'Name' %}</th> <th role="columnheader" scope="col">{% trans 'Active' %}</th>
<th>{% trans 'Active' %}</th> <th role="columnheader" scope="col">{% trans 'Last Login' %}</th>
<th>{% trans 'Last Login' %}</th> <th role="cell"></th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody role="rowgroup">
{% for user in object_list %} {% for user in object_list %}
<tr> <tr role="row">
<td>{{ user.username }}</td> <th role="columnheader">
<td>{{ user.name|default:'-' }}</td> <div>
<td>{{ user.is_active }}</td> <div>{{ user.username }}</div>
<td>{{ user.last_login }}</td> <small>{{ user.name }}</small>
</div>
</th>
<td role="cell">
<span>
{{ user.is_active }}
</span>
</td>
<td role="cell">
<span>
{{ user.last_login }}
</span>
</td>
<td> <td>
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-secondary" href="{% url 'passbook_admin:user-update' pk=user.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>
href="{% url 'passbook_admin:user-update' pk=user.pk %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a> <a class="pf-c-button pf-m-danger" href="{% url 'passbook_admin:user-delete' pk=user.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a>
<a class="btn btn-default btn-sm" <a class="pf-c-button pf-m-tertiary" href="{% url 'passbook_admin:user-password-reset' pk=user.pk %}?back={{ request.get_full_path }}">{% trans 'Reset Password' %}</a>
href="{% url 'passbook_admin:user-delete' pk=user.pk %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a> <a class="pf-c-button pf-m-tertiary" href="{% url 'passbook_core:overview' %}?__impersonate={{ user.pk }}">{% trans 'Impersonate' %}</a>
<a class="btn btn-default btn-sm"
href="{% url 'passbook_admin:user-password-reset' pk=user.pk %}?back={{ request.get_full_path }}">{% trans 'Reset Password' %}</a>
<a class="btn btn-default btn-sm"
href="{% url 'passbook_core:overview' %}?__impersonate={{ user.pk }}">{% trans 'Impersonate' %}</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-bottom">
{% include 'partials/pagination.html' %} {% include 'partials/pagination.html' %}
</div> </div>
</div>
</section>
{% endblock %} {% endblock %}

View File

@ -42,7 +42,7 @@ class AdministrationOverviewView(AdminRequiredMixin, TemplateView):
kwargs["providers_without_application"] = Provider.objects.filter( kwargs["providers_without_application"] = Provider.objects.filter(
application=None application=None
) )
kwargs["policies_without_attachment"] = len( kwargs["policies_without_binding"] = len(
Policy.objects.filter(policymodel__isnull=True) Policy.objects.filter(policymodel__isnull=True)
) )
kwargs["cached_policies"] = len(cache.keys("policy_*")) kwargs["cached_policies"] = len(cache.keys("policy_*"))

View File

@ -3,33 +3,21 @@
{% load utils %} {% load utils %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" class="layout-pf layout-pf-fixed transitions">
<head> <html lang="en">
<head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title> <title>{% block title %}{% title %}{% endblock %}</title>
{% block title %} <link rel="icon" type="image/png" href="{% static 'passbook/logo.png' %}">
{% title %} <link rel="shortcut icon" type="image/png" href="{% static 'passbook/logo.png' %}">
{% endblock %} <link rel="stylesheet" type="text/css" href="{% static 'node_modules/@patternfly/patternfly/patternfly.css' %}">
</title> <link rel="stylesheet" type="text/css" href="{% static 'node_modules/@patternfly/patternfly/patternfly-addons.css' %}">
<link rel="icon" type="image/png" href="{% static 'img/logo.png' %}"> <link rel="stylesheet" type="text/css" href="{% static 'passbook/pf.css' %}">
<link rel="shortcut icon" type="image/png" href="{% static 'img/logo.png' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/patternfly.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/patternfly-additions.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/passbook.css' %}">
<style>
.login-pf {
background-attachment: fixed;
scroll-behavior: smooth;
background-size: cover;
}
</style>
{% block head %} {% block head %}
{% endblock %} {% endblock %}
</head> </head>
<body>
<body {% if is_login %} class="login-pf" {% endif %}>
{% if 'impersonate_id' in request.session %} {% if 'impersonate_id' in request.session %}
<div class="experimental-pf-bar"> <div class="experimental-pf-bar">
<span id="experimentalBar" class="experimental-pf-text"> <span id="experimentalBar" class="experimental-pf-text">
@ -40,12 +28,8 @@
{% endif %} {% endif %}
{% block body %} {% block body %}
{% endblock %} {% endblock %}
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="{% static 'js/patternfly.min.js' %}"></script>
<script src="{% static 'js/passbook.js' %}"></script>
{% block scripts %} {% block scripts %}
{% endblock %} {% endblock %}
</body> <script src="{% static 'passbook/pf.js' %}"></script>
</body>
</html> </html>

View File

@ -1,33 +0,0 @@
{% load static %}
{% load i18n %}
{% load utils %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{% block title %}{% title %}{% endblock %}</title>
<link rel="icon" type="image/png" href="{% static 'passbook/logo.png' %}">
<link rel="shortcut icon" type="image/png" href="{% static 'passbook/logo.png' %}">
<link rel="stylesheet" type="text/css" href="{% static 'node_modules/@patternfly/patternfly/patternfly.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'node_modules/@patternfly/patternfly/patternfly-addons.css' %}">
{% block head %}
{% endblock %}
</head>
<body>
{% if 'impersonate_id' in request.session %}
<div class="experimental-pf-bar">
<span id="experimentalBar" class="experimental-pf-text">
{% blocktrans with user=user %}You're currently impersonating {{ user }}.{% endblocktrans %}
<a href="?__unimpersonate=True" id="acceptMessage">{% trans 'Stop impersonation' %}</a>
</span>
</div>
{% endif %}
{% block body %}
{% endblock %}
{% block scripts %}
{% endblock %}
</body>
</html>

View File

@ -1,4 +1,4 @@
{% extends 'base/skeleton_pf4.html' %} {% extends 'base/skeleton.html' %}
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}

View File

@ -1,4 +1,4 @@
{% extends "base/skeleton_pf4.html" %} {% extends "base/skeleton.html" %}
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
@ -123,16 +123,3 @@
</main> </main>
</div> </div>
{% endblock %} {% endblock %}
{% block scripts %}
{{ block.super }}
<script>
$(document).ready(function () {
// initialize tooltips
$('[data-toggle="tooltip"]').tooltip();
// Initialize the vertical navigation
$().setupVerticalNavigation(true);
});
</script>
{% endblock %}

View File

@ -14,7 +14,10 @@
{% block content %} {% block content %}
<section class="pf-c-page__main-section pf-m-light"> <section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content"> <div class="pf-c-content">
<h1>{% trans 'Applications' %}</h1> <h1>
<i class="pf-icon pf-icon-applications"></i>
{% trans 'Applications' %}
</h1>
</div> </div>
</section> </section>
<section class="pf-c-page__main-section"> <section class="pf-c-page__main-section">

View File

@ -1,22 +1,43 @@
{% load i18n %} {% load i18n %}
<div class="btn-group"> <div class="pf-c-pagination">
<div class="pf-c-pagination__total-items">
<b>{{ page_obj.start_index }} - {{ page_obj.end_index }}</b>of
<b>{{ page_obj.count }}</b>
</div>
{% with param=get_param|default:'page' %} {% with param=get_param|default:'page' %}
<nav class="pf-c-pagination__nav" aria-label="Pagination">
<a class="pf-c-button pf-m-plain" type="button" aria-label="Go to first page"
href="?{{ param }}=1">
<i class="fas fa-angle-double-left" aria-hidden="true"></i>
</a>
<a class="pf-c-button pf-m-plain" type="button" aria-label="Go to previous page"
{% if page_obj.has_previous %} {% if page_obj.has_previous %}
<a class="btn btn-default" href="?{{ param }}={{ page_obj.previous_page_number }}"><span class="fa fa-angle-left"></span></a> href="?{{ param }}={{ page_obj.previous_page_number }}"
{% else %} {% else %}
<a class="btn btn-default disabled" href=""><span class="fa fa-angle-left"></span></a> disabled
{% endif %} {% endif %}>
<span class="btn btn-default"> <i class="fas fa-angle-left" aria-hidden="true"></i>
</a>
<div class="pf-c-pagination__nav-page-select">
<span>
{% blocktrans with current=page_obj.number total=page_obj.paginator.num_pages %} {% blocktrans with current=page_obj.number total=page_obj.paginator.num_pages %}
Page {{ current }} of {{ total }} {{ current }} of {{ total }}
{% endblocktrans %} {% endblocktrans %}
</span> </span>
</div>
<a class="pf-c-button pf-m-plain" type="button" aria-label="Go to next page"
{% if page_obj.has_next %} {% if page_obj.has_next %}
<a class="btn btn-default" href="?{{ param }}={{ page_obj.next_page_number }}"><span class="fa fa-angle-right"></span></a> href="?{{ param }}={{ page_obj.next_page_number }}"
{% else %} {% else %}
<a class="btn btn-default disabled" href=""><span class="fa fa-angle-right"></span></a> disabled
{% endif %} {% endif %}>
<i class="fas fa-angle-right" aria-hidden="true"></i>
</a>
<a class="pf-c-button pf-m-plain" type="button" aria-label="Go to last page"
href="?{{ param }}={{ page_obj.num_pages }}">
<i class="fas fa-angle-double-right" aria-hidden="true"></i>
</a>
</nav>
{% endwith %} {% endwith %}
</div> </div>
<hr>

View File

@ -0,0 +1,15 @@
version: "3.5"
services:
passbook_gatekeeper:
container_name: gatekeeper
image: beryju/passbook-gatekeeper:{{ version }}
ports:
- 4180:4180
environment:
OAUTH2_PROXY_CLIENT_ID: {{ provider.client.client_id }}
OAUTH2_PROXY_CLIENT_SECRET: {{ provider.client.client_secret }}
OAUTH2_PROXY_REDIRECT_URL: https://{{ provider.external_host }}/oauth2/callback
OAUTH2_PROXY_OIDC_ISSUER_URL: https://{{ request.META.HTTP_HOST }}/application/oidc
OAUTH2_PROXY_COOKIE_SECRET: {{ cookie_secret }}
OAUTH2_PROXY_UPSTREAMS: http://{{ provider.internal_host }}

View File

@ -55,7 +55,7 @@ metadata:
namespace: kube-system namespace: kube-system
spec: spec:
rules: rules:
- host: {{ provider.host }} - host: {{ provider.external_host }}
http: http:
paths: paths:
- backend: - backend:

View File

@ -7,78 +7,65 @@
<link rel="stylesheet" href="{% static 'codemirror/theme/monokai.css' %}"> <link rel="stylesheet" href="{% static 'codemirror/theme/monokai.css' %}">
<script src="{% static 'codemirror/mode/yaml/yaml.js' %}"></script> <script src="{% static 'codemirror/mode/yaml/yaml.js' %}"></script>
<div class="dropdown" style="display: inline-block;"> <div class="pf-c-dropdown">
<button class="btn btn-default btn-sm dropdown-toggle" type="button" id="setupDropdown-{{ provider.pk }}" data-toggle="dropdown"> <button class="pf-c-button pf-m-tertiary pf-c-dropdown__toggle" type="button">
{% trans 'Setup with...' %} <span class="pf-c-dropdown__toggle-text">{% trans 'Setup with...' %}</span>
<span class="caret"></span> <i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button> </button>
<ul class="dropdown-menu" role="menu" aria-labelledby="setupDropdown-{{ provider.pk }}"> <ul class="pf-c-dropdown__menu" hidden>
<li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#docker-compose-{{ provider.pk }}">{% trans 'docker-compose' %}</a></li> <li>
<li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#k8s-{{ provider.pk }}">{% trans 'Kubernetes' %}</a></li> <button class="pf-c-dropdown__menu-item" data-target="modal" data-modal="docker-compose-{{ provider.pk }}">{% trans 'docker-compose' %}</button>
</li>
<li>
<button class="pf-c-dropdown__menu-item" data-target="modal" data-modal="k8s-{{ provider.pk }}">{% trans 'Kubernetes' %}</button>
</li>
</ul> </ul>
</div> </div>
<div class="modal fade" id="docker-compose-{{ provider.pk }}" tabindex="-1" role="dialog" aria-labelledby="{{ provider.pk }}Label" aria-hidden="true"> <div class="pf-c-backdrop" id="docker-compose-{{ provider.pk }}" hidden>
<div class="modal-dialog modal-lg"> <div class="pf-l-bullseye">
<div class="modal-content"> <div class="pf-c-modal-box pf-m-lg" role="dialog">
<div class="modal-header"> <button data-modal-close class="pf-c-button pf-m-plain" type="button" aria-label="Close dialog">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close"> <i class="fas fa-times" aria-hidden="true"></i>
<span class="pficon pficon-close"></span>
</button> </button>
<h4 class="modal-title" id="{{ provider.pk }}Label">{% trans 'Setup with docker-compose' %}</h4> <h1 class="pf-c-title pf-m-2xl">{% trans 'Setup with docker-compose' %}</h1>
</div> <div class="pf-c-modal-box__body">
<div class="modal-body">
{% trans 'Add the following snippet to your docker-compose file.' %} {% trans 'Add the following snippet to your docker-compose file.' %}
<textarea class="codemirror">version: "3.5" <textarea class="codemirror">{% include 'app_gw/docker-compose.yml' %}</textarea>
services:
passbook_gatekeeper:
container_name: gatekeeper
image: beryju/passbook-gatekeeper:{{ version }}
ports:
- 4180:4180
environment:
OAUTH2_PROXY_CLIENT_ID: {{ provider.client.client_id }}
OAUTH2_PROXY_CLIENT_SECRET: {{ provider.client.client_secret }}
OAUTH2_PROXY_REDIRECT_URL: https://{{ provider.external_host }}/oauth2/callback
OAUTH2_PROXY_OIDC_ISSUER_URL: https://{{ request.META.HTTP_HOST }}/application/oidc
OAUTH2_PROXY_COOKIE_SECRET: {{ cookie_secret }}
OAUTH2_PROXY_UPSTREAMS: http://{{ provider.internal_host }}</textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">{% trans 'Close' %}</button>
</div> </div>
<footer class="pf-c-modal-box__footer pf-m-align-left">
<button data-modal-close class="pf-c-button pf-m-primary" type="button">{% trans 'Close' %}</button>
</footer>
</div> </div>
</div> </div>
</div> </div>
<div class="modal fade" id="k8s-{{ provider.pk }}" tabindex="-1" role="dialog" aria-labelledby="{{ provider.pk }}Label" aria-hidden="true">
<div class="modal-dialog modal-lg"> <div class="pf-c-backdrop" id="k8s-{{ provider.pk }}" hidden>
<div class="modal-content"> <div class="pf-l-bullseye">
<div class="modal-header"> <div class="pf-c-modal-box pf-m-lg" role="dialog">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close"> <button data-modal-close class="pf-c-button pf-m-plain" type="button" aria-label="Close dialog">
<span class="pficon pficon-close"></span> <i class="fas fa-times" aria-hidden="true"></i>
</button> </button>
<h4 class="modal-title" id="{{ provider.pk }}Label">{% trans 'Setup with Kubernetes' %}</h4> <h1 class="pf-c-title pf-m-2xl">{% trans 'Setup with Kubernetes' %}</h1>
</div> <div class="pf-c-modal-box__body">
<div class="modal-body">
<p>{% trans 'Download the manifest to create the Gatekeeper deployment and service:' %}</p> <p>{% trans 'Download the manifest to create the Gatekeeper deployment and service:' %}</p>
<a href="{% url 'passbook_providers_app_gw:k8s-manifest' provider=provider.pk %}">{% trans 'Here' %}</a> <a href="{% url 'passbook_providers_app_gw:k8s-manifest' provider=provider.pk %}">{% trans 'Here' %}</a>
<p>{% trans 'Afterwards, add the following annotations to the Ingress you want to secure:' %}</p> <p>{% trans 'Afterwards, add the following annotations to the Ingress you want to secure:' %}</p>
<textarea class="codemirror"> <textarea class="codemirror">
nginx.ingress.kubernetes.io/auth-url: "https://{{ provider.host }}/oauth2/auth" nginx.ingress.kubernetes.io/auth-url: "https://{{ provider.external_host }}/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://{{ provider.host }}/oauth2/start?rd=$escaped_request_uri" nginx.ingress.kubernetes.io/auth-signin: "https://{{ provider.external_host }}/oauth2/start?rd=$escaped_request_uri"
</textarea> </textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">{% trans 'Close' %}</button>
</div> </div>
<footer class="pf-c-modal-box__footer pf-m-align-left">
<button data-modal-close class="pf-c-button pf-m-primary" type="button">{% trans 'Close' %}</button>
</footer>
</div> </div>
</div> </div>
</div> </div>
<script> <script>
let attributes = document.getElementsByClassName('codemirror'); let attributes = document.getElementsByClassName('codemirror');
for (let attrib of attributes) { for (let attrib of attributes) {
let myCodeMirror = CodeMirror.fromTextArea(attrib, { let myCodeMirror = CodeMirror.fromTextArea(attrib, {
mode: 'yaml', mode: 'yaml',
theme: 'monokai', theme: 'monokai',
@ -86,5 +73,5 @@ for (let attrib of attributes) {
readOnly: true, readOnly: true,
autoRefresh: true, autoRefresh: true,
}); });
} }
</script> </script>

View File

@ -1,49 +1,46 @@
{% load i18n %} {% load i18n %}
<button class="btn btn-default btn-sm" data-toggle="modal" data-target="#{{ provider.pk }}">{% trans 'View Setup URLs' %}</button> <button class="pf-c-button pf-m-tertiary" data-target="modal" data-modal="provider-{{ provider.pk }}">{% trans 'View Setup URLs' %}</button>
<div class="modal fade" id="{{ provider.pk }}" tabindex="-1" role="dialog" aria-labelledby="{{ provider.pk }}Label" aria-hidden="true">
<div class="modal-dialog"> <div class="pf-c-backdrop" id="provider-{{ provider.pk }}" hidden>
<div class="modal-content"> <div class="pf-l-bullseye">
<div class="modal-header"> <div class="pf-c-modal-box pf-m-sm" role="dialog">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close"> <button data-modal-close class="pf-c-button pf-m-plain" type="button" aria-label="Close dialog">
<span class="pficon pficon-close"></span> <i class="fas fa-times" aria-hidden="true"></i>
</button> </button>
<h4 class="modal-title" id="{{ provider.pk }}Label">{% trans 'Setup URLs' %}</h4> <h1 class="pf-c-title pf-m-2xl" id="modal-title">{% trans 'Setup URLs' %}</h1>
<div class="pf-c-modal-box__body" id="modal-description">
<form class="pf-c-form">
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="help-text-simple-form-name">
<span class="pf-c-form__label-text">{% trans 'Authorize URL' %}</span>
</label>
<input class="pf-c-form-control" readonly type="text" value="{{ authorize }}" />
</div> </div>
<div class="modal-body"> <div class="pf-c-form__group">
<form class="form-horizontal"> <label class="pf-c-form__label" for="help-text-simple-form-name">
<div class="form-group"> <span class="pf-c-form__label-text">{% trans 'Token URL' %}</span>
<label class="col-sm-3 control-label">{% trans 'Authorize URL' %}</label> </label>
<div class="col-sm-9"> <input class="pf-c-form-control" readonly type="text" value="{{ token }}" />
<input type="text"class="form-control" readonly value="{{ authorize }}">
</div> </div>
<div class="pf-c-form__group">
<label class="pf-c-form__label" for="help-text-simple-form-name">
<span class="pf-c-form__label-text">{% trans 'Userinfo Endpoint' %}</span>
</label>
<input class="pf-c-form-control" readonly type="text" value="{{ userinfo }}" />
</div> </div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans 'Token URL' %}</label>
<div class="col-sm-9">
<input type="text" class="form-control" readonly value="{{ token }}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans 'Userinfo Endpoint' %}</label>
<div class="col-sm-9">
<input type="text" class="form-control" readonly value="{{ userinfo }}">
</div>
</div>
</form>
<hr> <hr>
<form class="form-horizontal"> <div class="pf-c-form__group">
<div class="form-group"> <label class="pf-c-form__label" for="help-text-simple-form-name">
<label class="col-sm-3 control-label">{% trans 'OpenID Configuration URL' %}</label> <span class="pf-c-form__label-text">{% trans 'OpenID Configuration URL' %}</span>
<div class="col-sm-9"> </label>
<input type="text"class="form-control" readonly value="{{ provider_info }}"> <input class="pf-c-form-control" readonly type="text" value="{{ provider_info }}" />
</div>
</div> </div>
</form> </form>
</div> </div>
<div class="modal-footer"> <footer class="pf-c-modal-box__footer pf-m-align-left">
<button type="button" class="btn btn-primary" data-dismiss="modal">{% trans 'Close' %}</button> <button data-modal-close class="pf-c-button pf-m-primary" type="button">{% trans 'Close' %}</button>
</div> </footer>
</div> </div>
</div> </div>
</div> </div>

View File

@ -7,35 +7,35 @@
<link rel="stylesheet" href="{% static 'codemirror/theme/monokai.css' %}"> <link rel="stylesheet" href="{% static 'codemirror/theme/monokai.css' %}">
<script src="{% static 'codemirror/mode/xml/xml.js' %}"></script> <script src="{% static 'codemirror/mode/xml/xml.js' %}"></script>
<button class="btn btn-default btn-sm" data-toggle="modal" data-target="#{{ provider.pk }}">{% trans 'View Metadata' %}</button> <button class="pf-c-button pf-m-tertiary" data-target="modal" data-modal="{{ provider.pk }}">{% trans 'View Metadata' %}</button>
<div class="modal fade" id="{{ provider.pk }}" tabindex="-1" role="dialog" aria-labelledby="{{ provider.pk }}Label" aria-hidden="true">
<div class="modal-dialog modal-lg"> <div class="pf-c-backdrop" id="{{ provider.pk }}" hidden>
<div class="modal-content"> <div class="pf-l-bullseye">
<div class="modal-header"> <div class="pf-c-modal-box pf-m-sm" role="dialog">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close"> <button data-modal-close class="pf-c-button pf-m-plain" type="button" aria-label="Close dialog">
<span class="pficon pficon-close"></span> <i class="fas fa-times" aria-hidden="true"></i>
</button> </button>
<h4 class="modal-title" id="{{ provider.pk }}Label">{% trans 'Metadata' %}</h4> <h1 class="pf-c-title pf-m-2xl" id="modal-title">{% trans 'Metadata' %}</h1>
</div> <div class="pf-c-modal-box__body" id="modal-description">
<div class="modal-body"> <form method="post">
<form class="form-horizontal">
<textarea class="codemirror" id="{{ provider.pk }}-textarea"> <textarea class="codemirror" id="{{ provider.pk }}-textarea">
{{ metadata }} {{ metadata }}
</textarea> </textarea>
</form> </form>
</div> </div>
<div class="modal-footer"> <footer class="pf-c-modal-box__footer pf-m-align-left">
<button type="button" class="btn btn-primary" data-dismiss="modal">{% trans 'Close' %}</button> <button data-modal-close class="pf-c-button pf-m-primary" type="button">{% trans 'Close' %}</button>
</div> </footer>
</div> </div>
</div> </div>
</div> </div>
<script> <script>
CodeMirror.fromTextArea(document.getElementById("{{ provider.pk }}-textarea"), { CodeMirror.fromTextArea(document.getElementById("{{ provider.pk }}-textarea"), {
mode: 'xml', mode: 'xml',
theme: 'monokai', theme: 'monokai',
lineNumbers: false, lineNumbers: false,
readOnly: true, readOnly: true,
autoRefresh: true, autoRefresh: true,
}); });
</script> </script>

View File

@ -0,0 +1,7 @@
.pf-c-page__sidebar {
z-index: 0;
}
.pf-c-page__header {
z-index: 0;
}

View File

@ -0,0 +1,23 @@
// Button Dropdowns
document.querySelectorAll("button.pf-c-dropdown__toggle").forEach((b) => {
b.addEventListener('click', (e) => {
const parent = e.target.closest('.pf-c-dropdown');
const menu = parent.querySelector('.pf-c-dropdown__menu');
menu.hidden = !menu.hidden;
});
});
// Modal
document.querySelectorAll("[data-target='modal']").forEach((m) => {
m.addEventListener("click", (e) => {
const parentContainer = e.target.closest('[data-target="modal"]');
const modalId = parentContainer.attributes['data-modal'].value;
document.querySelector(`#${modalId}`).removeAttribute("hidden");
});
});
document.querySelectorAll(".pf-c-modal-box [data-modal-close]").forEach(b => {
b.addEventListener("click", (e) => {
const parentContainer = e.target.closest('.pf-c-backdrop');
parentContainer.setAttribute("hidden", true);
});
});