Compare commits

..

27 Commits

Author SHA1 Message Date
1d3460b670 new release: 0.9.0-pre2 2020-06-15 19:08:17 +02:00
feba3e2430 stages/prompt: Add username type field
add autocomplete attributes for username and password
2020-06-15 19:05:18 +02:00
b49d39a685 stages/identification: improve support for password managers 2020-06-15 18:38:09 +02:00
34c1b3b68b stages/password: Improve support for password managers 2020-06-15 18:37:59 +02:00
e3d6ca6ab4 root: revert to non-prometheus db backend 2020-06-15 12:12:32 +02:00
6f0e292c43 root: add lgtm 2020-06-15 11:56:20 +02:00
9df1e7900d stages/email: add noopener noreferrer 2020-06-15 11:56:14 +02:00
9920d121e5 build(deps): bump django-prometheus from 2.1.0.dev14 to 2.1.0.dev30 (#67)
Bumps [django-prometheus](https://github.com/korfuri/django-prometheus) from 2.1.0.dev14 to 2.1.0.dev30.
- [Release notes](https://github.com/korfuri/django-prometheus/releases)
- [Changelog](https://github.com/korfuri/django-prometheus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/korfuri/django-prometheus/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-15 11:47:03 +02:00
7e77c88407 build(deps): bump boto3 from 1.14.1 to 1.14.2 (#68)
Bumps [boto3](https://github.com/boto/boto3) from 1.14.1 to 1.14.2.
- [Release notes](https://github.com/boto/boto3/releases)
- [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst)
- [Commits](https://github.com/boto/boto3/compare/1.14.1...1.14.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-15 09:05:30 +02:00
3fa982cb2a build(deps): bump boto3 from 1.13.26 to 1.14.1 (#66)
Bumps [boto3](https://github.com/boto/boto3) from 1.13.26 to 1.14.1.
- [Release notes](https://github.com/boto/boto3/releases)
- [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst)
- [Commits](https://github.com/boto/boto3/compare/1.13.26...1.14.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-12 22:49:58 +02:00
4f1e767488 build(deps): bump swagger-spec-validator from 2.7.0 to 2.7.1 (#64)
Bumps [swagger-spec-validator](https://github.com/Yelp/swagger_spec_validator) from 2.7.0 to 2.7.1.
- [Release notes](https://github.com/Yelp/swagger_spec_validator/releases)
- [Changelog](https://github.com/Yelp/swagger_spec_validator/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/Yelp/swagger_spec_validator/compare/v2.7.0...v2.7.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-11 12:47:55 +02:00
8e6b503c0d build(deps): bump signxml from 2.7.2 to 2.7.3 (#65)
Bumps [signxml](https://github.com/kislyuk/signxml) from 2.7.2 to 2.7.3.
- [Release notes](https://github.com/kislyuk/signxml/releases)
- [Changelog](https://github.com/XML-Security/signxml/blob/master/Changes.rst)
- [Commits](https://github.com/kislyuk/signxml/compare/v2.7.2...v2.7.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-11 12:44:23 +02:00
17f1cad468 build(deps): bump boto3 from 1.13.25 to 1.13.26 (#62)
Bumps [boto3](https://github.com/boto/boto3) from 1.13.25 to 1.13.26.
- [Release notes](https://github.com/boto/boto3/releases)
- [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst)
- [Commits](https://github.com/boto/boto3/compare/1.13.25...1.13.26)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-10 13:56:40 +02:00
0b8eaff874 build(deps): bump celery from 4.4.4 to 4.4.5 (#60)
Bumps [celery](https://github.com/celery/celery) from 4.4.4 to 4.4.5.
- [Release notes](https://github.com/celery/celery/releases)
- [Changelog](https://github.com/celery/celery/blob/master/Changelog.rst)
- [Commits](https://github.com/celery/celery/compare/v4.4.4...v4.4.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-09 13:48:25 +02:00
33a6d4cdeb build(deps-dev): bump pylint from 2.5.2 to 2.5.3 (#59)
Bumps [pylint](https://github.com/PyCQA/pylint) from 2.5.2 to 2.5.3.
- [Release notes](https://github.com/PyCQA/pylint/releases)
- [Changelog](https://github.com/PyCQA/pylint/blob/master/ChangeLog)
- [Commits](https://github.com/PyCQA/pylint/compare/pylint-2.5.2...pylint-2.5.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-09 13:42:34 +02:00
d3224f4ee8 build(deps): bump boto3 from 1.13.24 to 1.13.25 (#61)
Bumps [boto3](https://github.com/boto/boto3) from 1.13.24 to 1.13.25.
- [Release notes](https://github.com/boto/boto3/releases)
- [Changelog](https://github.com/boto/boto3/blob/develop/CHANGELOG.rst)
- [Commits](https://github.com/boto/boto3/compare/1.13.24...1.13.25)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-09 13:42:14 +02:00
2a3166bf7e ui: (pf4) Update pagination and toolbar 2020-06-09 13:40:03 +02:00
62fe4d617b ui: (pf4) update admin overview 2020-06-09 13:39:44 +02:00
b86b36f947 ui: (pf4) update forms 2020-06-09 13:39:35 +02:00
d6b9e67e78 ui: (pf4) fix navbar 2020-06-09 13:11:54 +02:00
f589da4e72 ui: (pf4) fix empty state 2020-06-09 09:52:25 +02:00
2e5170f631 build(deps): bump @patternfly/patternfly in /passbook/static/static (#58)
Bumps [@patternfly/patternfly](https://github.com/patternfly/patternfly) from 2.71.6 to 4.10.31.
- [Release notes](https://github.com/patternfly/patternfly/releases)
- [Changelog](https://github.com/patternfly/patternfly/blob/master/RELEASE-NOTES.md)
- [Commits](https://github.com/patternfly/patternfly/compare/v2.71.6...prerelease-v4.10.31)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-09 09:32:56 +02:00
bd312b60fc gatekeeper: update upstream docker image 2020-06-09 09:26:03 +02:00
26aa7e1fef sources/ldap: fix 'LDAPSource' object has no attribute '_connection' 2020-06-09 01:17:17 +02:00
9495956fae docs: add login credentials to kubernetes install 2020-06-08 22:13:38 +02:00
089ee86d43 docs: add initial login instructions 2020-06-08 22:11:01 +02:00
d321e2f52c docs: update docker-compose install form README 2020-06-08 22:09:04 +02:00
49 changed files with 691 additions and 641 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.9.0-pre1
current_version = 0.9.0-pre2
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-(?P<release>.*)

View File

@ -16,11 +16,11 @@ jobs:
- name: Building Docker Image
run: docker build
--no-cache
-t beryju/passbook:0.9.0-pre1
-t beryju/passbook:0.9.0-pre2
-t beryju/passbook:latest
-f Dockerfile .
- name: Push Docker Container to Registry (versioned)
run: docker push beryju/passbook:0.9.0-pre1
run: docker push beryju/passbook:0.9.0-pre2
- name: Push Docker Container to Registry (latest)
run: docker push beryju/passbook:latest
build-gatekeeper:
@ -37,11 +37,11 @@ jobs:
cd gatekeeper
docker build \
--no-cache \
-t beryju/passbook-gatekeeper:0.9.0-pre1 \
-t beryju/passbook-gatekeeper:0.9.0-pre2 \
-t beryju/passbook-gatekeeper:latest \
-f Dockerfile .
- name: Push Docker Container to Registry (versioned)
run: docker push beryju/passbook-gatekeeper:0.9.0-pre1
run: docker push beryju/passbook-gatekeeper:0.9.0-pre2
- name: Push Docker Container to Registry (latest)
run: docker push beryju/passbook-gatekeeper:latest
build-static:
@ -66,11 +66,11 @@ jobs:
run: docker build
--no-cache
--network=$(docker network ls | grep github | awk '{print $1}')
-t beryju/passbook-static:0.9.0-pre1
-t beryju/passbook-static:0.9.0-pre2
-t beryju/passbook-static:latest
-f static.Dockerfile .
- name: Push Docker Container to Registry (versioned)
run: docker push beryju/passbook-static:0.9.0-pre1
run: docker push beryju/passbook-static:0.9.0-pre2
- name: Push Docker Container to Registry (latest)
run: docker push beryju/passbook-static:latest
test-release:

49
Pipfile.lock generated
View File

@ -30,13 +30,6 @@
],
"version": "==3.2.7"
},
"asn1crypto": {
"hashes": [
"sha256:5a215cb8dc12f892244e3a113fe05397ee23c5c4ca7a69cd6e69811755efc42d",
"sha256:831d2710d3274c8a74befdddaf9f17fcbf6e350534565074818722d6d615b315"
],
"version": "==1.3.0"
},
"attrs": {
"hashes": [
"sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c",
@ -53,26 +46,26 @@
},
"boto3": {
"hashes": [
"sha256:5df1f3f84587b4d812f6f178031119b80920822b459bbb70ad49f431128655dc",
"sha256:d19fb5b7f27c29a7a036e36888e9584132e2f8edfa6ef906ea5a712e3e29962c"
"sha256:a33e465831fb95af2e57576927f33746be620ba236252f8e1291c1c31cf63625",
"sha256:caa4fbb9de8d8c229a183a551cb314fe208ec264545d4d825022d863d33e9b7b"
],
"index": "pypi",
"version": "==1.13.24"
"version": "==1.14.2"
},
"botocore": {
"hashes": [
"sha256:17bc71415186efb86a25dd674f78064cdd85139485967d5a0741c7b83d62cf5b",
"sha256:e44b11b1c47c06b0f6524b0ff1fa1cae5ddea4eb06f359e4a9730e8e881b397a"
"sha256:01788bfa280397ba96991cd74e706628620310c7d8b8b43b0818df3bad3daaeb",
"sha256:4e347b77e17c5a619afd59a5209b251107c3d7d5f842ec169694492f3820f75b"
],
"version": "==1.16.24"
"version": "==1.17.2"
},
"celery": {
"hashes": [
"sha256:9ae2e73b93cc7d6b48b56aaf49a68c91752d0ffd7dfdcc47f842ca79a6f13eae",
"sha256:c2037b6a8463da43b19969a0fc13f9023ceca6352b4dd51be01c66fbbb13647e"
"sha256:c3f4173f83ceb5a5c986c5fdaefb9456de3b0729a72a5776e46bd405fda7b647",
"sha256:d1762d6065522879f341c3d67c2b9fe4615eb79756d59acb1434601d4aca474b"
],
"index": "pypi",
"version": "==4.4.4"
"version": "==4.4.5"
},
"certifi": {
"hashes": [
@ -239,11 +232,11 @@
},
"django-prometheus": {
"hashes": [
"sha256:1a8cb752ae4181e38df00e7bd7d5f6495cde18b8b3ff697c22f9d8d2fe48bf28",
"sha256:9f024af5495447c8e309f07e5289e7bc1100c5a380ac7cd0afe3a1b2a0b3b534"
"sha256:28a77ecf9dbb419be21b020468255f8cdb918f2c29ed65023519f58748b2eba2",
"sha256:7396c528febbc17f767f9bc9dc24611769462d7da302cd0c52c5803309663ddd"
],
"index": "pypi",
"version": "==2.1.0.dev14"
"version": "==2.1.0.dev30"
},
"django-recaptcha": {
"hashes": [
@ -764,11 +757,11 @@
},
"signxml": {
"hashes": [
"sha256:2e186c117284fe5a0c543f5bcdde68f5a2341eeae219af9eb7e512dacf4bfce7",
"sha256:7d6af724542cae915bbb9000d333a52ce495d0b3cdcb4dc590c3c4a149b079ed"
"sha256:3b78b57e374d5517b4eddbbb27519208ccfbedbcabcf47ee322161f53482f174",
"sha256:e362b5eedbc785aec9ac1867f790ecf958d9640a95a34400a830350ba5bb1cc2"
],
"index": "pypi",
"version": "==2.7.2"
"version": "==2.7.3"
},
"six": {
"hashes": [
@ -794,11 +787,11 @@
},
"swagger-spec-validator": {
"hashes": [
"sha256:78c5165b0686788344f0c9f137f0e23e9b2b2b7d1947b1c10061c0984d008af1",
"sha256:ee12f97b058aadd276a53f69fb2ac4d10014d382ae70ce4722562a6fbdecb6ed"
"sha256:3bc18877a2f3f55dd8c4f3456d0dd9080ca248d8a5a07f8896868385e0d4b8fb",
"sha256:e7c928ffe676054358699f2559d665257b40f0165e7bd5f7d17f278148871115"
],
"index": "pypi",
"version": "==2.7.0"
"version": "==2.7.1"
},
"uritemplate": {
"hashes": [
@ -1039,11 +1032,11 @@
},
"pylint": {
"hashes": [
"sha256:b95e31850f3af163c2283ed40432f053acbc8fc6eba6a069cb518d9dbf71848c",
"sha256:dd506acce0427e9e08fb87274bcaa953d38b50a58207170dbf5b36cf3e16957b"
"sha256:7dd78437f2d8d019717dbf287772d0b2dbdfd13fc016aa7faa08d67bccc46adc",
"sha256:d0ece7d223fe422088b0e8f13fa0a1e8eb745ebffcb8ed53d3e95394b6101a1c"
],
"index": "pypi",
"version": "==2.5.2"
"version": "==2.5.3"
},
"pylint-django": {
"hashes": [

View File

@ -1,11 +1,11 @@
<img src="passbook/static/static/passbook/logo.svg" height="50" alt="passbook logo"><img src="passbook/static/static/passbook/brand_inverted.svg" height="50" alt="passbook">
![](https://img.shields.io/github/workflow/status/beryju/passbook/passbook-ci?style=flat-square)
![](https://img.shields.io/docker/pulls/beryju/passbook.svg?style=flat-square)
![](https://img.shields.io/docker/pulls/beryju/passbook-gatekeeper.svg?style=flat-square)
![](https://img.shields.io/docker/pulls/beryju/passbook-static.svg?style=flat-square)
![](https://img.shields.io/docker/v/beryju/passbook?sort=semver&style=flat-square)
![](https://img.shields.io/codecov/c/gh/beryju/passbook?style=flat-square)
![CI Build status](https://img.shields.io/github/workflow/status/beryju/passbook/passbook-ci?style=flat-square)
![Docker pulls](https://img.shields.io/docker/pulls/beryju/passbook.svg?style=flat-square)
![Docker pulls (gatekeeper)](https://img.shields.io/docker/pulls/beryju/passbook-gatekeeper.svg?style=flat-square)
![Latest version](https://img.shields.io/docker/v/beryju/passbook?sort=semver&style=flat-square)
![LGTM Grade](https://img.shields.io/lgtm/grade/python/github/BeryJu/passbook?style=flat-square)
![Code Coverage](https://img.shields.io/codecov/c/gh/beryju/passbook?style=flat-square)
## What is passbook?

View File

@ -9,18 +9,17 @@ This installation Method is for test-setups and small-scale productive setups.
## Install
Download the latest `docker-compose.yml` from [here](https://raw.githubusercontent.com/BeryJu/passbook/master/docker-compose.yml). Place it in a directory of your choice.
passbook needs to know it's primary URL to create links in E-Mails and set cookies, so you have to run the following command:
```
export PASSBOOK_DOMAIN=domain.tld # this can be any domain or IP, it just needs to point to passbook.
wget https://raw.githubusercontent.com/BeryJu/passbook/master/docker-compose.yml
# Optionally enable Error-reporting
# export PASSBOOK_ERROR_REPORTING=true
# Optionally deploy a different version
# export PASSBOOK_TAG=0.8.15-beta
# If this is a productive installation, set a different PostgreSQL Password
# export PG_PASS=$(pwgen 40 1)
docker-compose pull
docker-compose up -d
docker-compose exec server ./manage.py migrate
```
The compose file references the current latest version, which can be overridden with the `SERVER_TAG` Environment variable.
If you plan to use this setup for production, it is also advised to change the PostgreSQL Password by setting `PG_PASS` to a password of your choice.
Now you can pull the Docker images needed by running `docker-compose pull`. After this has finished, run `docker-compose up -d` to start passbook.
passbook will then be reachable on Port 80. You can optionally configure the packaged traefik to use Let's Encrypt for TLS Encryption.
Afterwards, you can log in using `pbadmin` as username and password.

View File

@ -2,6 +2,8 @@
For a mid to high-load Installation, Kubernetes is recommended. passbook is installed using a helm-chart.
This installation automatically applies database migrations on startup. After the installation is done, you can use `pbadmin` as username and password.
```
# Default values for passbook.
# This is a YAML-formatted file.

View File

@ -1,4 +1,4 @@
FROM quay.io/pusher/oauth2_proxy
FROM quay.io/oauth2-proxy/oauth2-proxy
COPY templates /templates

View File

@ -1,6 +1,6 @@
apiVersion: v1
appVersion: "0.9.0-pre1"
appVersion: "0.9.0-pre2"
description: A Helm chart for passbook.
name: passbook
version: "0.9.0-pre1"
version: "0.9.0-pre2"
icon: https://git.beryju.org/uploads/-/system/project/avatar/108/logo.png

View File

@ -2,7 +2,7 @@
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
image:
tag: 0.9.0-pre1
tag: 0.9.0-pre2
nameOverride: ""

View File

@ -1,2 +1,2 @@
"""passbook"""
__version__ = "0.9.0-pre1"
__version__ = "0.9.0-pre2"

View File

@ -16,11 +16,13 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<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 class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<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>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -65,14 +67,16 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Applications.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no applications exist. Click the button below to create one.' %}
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Applications.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no applications exist. Click the button below to create one.' %}
</div>
<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>
<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>
{% endif %}
</div>

View File

@ -15,8 +15,10 @@
</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">
{% include 'partials/pagination.html' %}
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
{% include 'partials/pagination.html' %}
</div>
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>

View File

@ -16,11 +16,13 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:certificatekeypair-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:certificatekeypair-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% include 'partials/pagination.html' %}
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -67,14 +69,16 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Certificates.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no certificates exist. Click the button below to create one.' %}
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Certificates.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no certificates exist. Click the button below to create one.' %}
</div>
<a href="{% url 'passbook_admin:certificatekeypair-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
<a href="{% url 'passbook_admin:certificatekeypair-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% endif %}
</div>

View File

@ -16,11 +16,13 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:flow-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:flow-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% include 'partials/pagination.html' %}
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -69,15 +71,16 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Flows.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no flows exist. Click the button below to create one.' %}
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Flows.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no flows exist. Click the button below to create one.' %}
</div>
<a href="{% url 'passbook_admin:flow-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
<a href="{% url 'passbook_admin:flow-create' %}?back={{ request.get_full_path }}"
class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% endif %}
</div>

View File

@ -17,12 +17,14 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<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 class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<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>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -64,14 +66,16 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Groups.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no group exist. Click the button below to create one.' %}
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Groups.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no group exist. Click the button below to create one.' %}
</div>
<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>
<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>
{% endif %}
</div>

View File

@ -11,8 +11,8 @@
<section class="pf-c-page__main-section">
<div class="pf-l-gallery pf-m-gutter">
<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-main">
<div class="pf-c-card__header">
<div class="pf-c-card__header-main">
<i class="pf-icon pf-icon-applications"></i> {% trans 'Applications' %}
</div>
</div>
@ -22,8 +22,8 @@
</a>
<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-main">
<div class="pf-c-card__header">
<div class="pf-c-card__header-main">
<i class="pf-icon pf-icon-middleware"></i> {% trans 'Sources' %}
</div>
</div>
@ -33,8 +33,8 @@
</a>
<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-main">
<div class="pf-c-card__header">
<div class="pf-c-card__header-main">
<i class="pf-icon pf-icon-plugged"></i> {% trans 'Providers' %}
</div>
</div>
@ -49,8 +49,8 @@
</a>
<a href="{% url 'passbook_admin:stages' %}" class="pf-c-card pf-m-hoverable pf-m-compact">
<div class="pf-c-card__head">
<div class="pf-c-card__head-main">
<div class="pf-c-card__header">
<div class="pf-c-card__header-main">
<i class="pf-icon pf-icon-plugged"></i> {% trans 'Stages' %}
</div>
</div>
@ -65,8 +65,8 @@
</a>
<a href="{% url 'passbook_admin:stages' %}" class="pf-c-card pf-m-hoverable pf-m-compact">
<div class="pf-c-card__head">
<div class="pf-c-card__head-main">
<div class="pf-c-card__header">
<div class="pf-c-card__header-main">
<i class="pf-icon pf-icon-topology"></i> {% trans 'Flows' %}
</div>
</div>
@ -76,8 +76,8 @@
</a>
<a href="{% url 'passbook_admin:policies' %}" class="pf-c-card pf-m-hoverable pf-m-compact">
<div class="pf-c-card__head">
<div class="pf-c-card__head-main">
<div class="pf-c-card__header">
<div class="pf-c-card__header-main">
<i class="pf-icon pf-icon-infrastructure"></i> {% trans 'Policies' %}
</div>
</div>
@ -92,8 +92,8 @@
</a>
<a href="{% url 'passbook_admin:stage-invitations' %}" class="pf-c-card pf-m-hoverable pf-m-compact">
<div class="pf-c-card__head">
<div class="pf-c-card__head-main">
<div class="pf-c-card__header">
<div class="pf-c-card__header-main">
<i class="pf-icon pf-icon-migration"></i> {% trans 'Invitation' %}
</div>
</div>
@ -103,8 +103,8 @@
</a>
<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">
<div class="pf-c-card__header">
<div class="pf-c-card__header-main">
<i class="pf-icon pf-icon-user"></i> {% trans 'Users' %}
</div>
</div>
@ -114,8 +114,8 @@
</a>
<div class="pf-c-card pf-m-hoverable pf-m-compact">
<div class="pf-c-card__head">
<div class="pf-c-card__head-main">
<div class="pf-c-card__header">
<div class="pf-c-card__header-main">
<i class="pf-icon pf-icon-bundle"></i> {% trans 'Version' %}
</div>
</div>
@ -125,8 +125,8 @@
</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">
<div class="pf-c-card__header">
<div class="pf-c-card__header-main">
<i class="pf-icon pf-icon-server"></i> {% trans 'Workers' %}
</div>
</div>
@ -141,8 +141,8 @@
</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">
<div class="pf-c-card__header">
<div class="pf-c-card__header-main">
<i class="pf-icon pf-icon-server"></i> {% trans 'Cached Policies' %}
</div>
</div>

View File

@ -16,28 +16,30 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:policy-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:policy-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
{% include 'partials/pagination.html' %}
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -81,31 +83,33 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Policies.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no policies exist. Click the button below to create one.' %}
</div>
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item"
href="{% url 'passbook_admin:policy-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Policies.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no policies exist. Click the button below to create one.' %}
</div>
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item"
href="{% url 'passbook_admin:policy-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endif %}

View File

@ -16,12 +16,14 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:policy-binding-create' %}?back={{ request.get_full_path }}"
class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:policy-binding-create' %}?back={{ request.get_full_path }}"
class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% include 'partials/pagination.html' %}
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -57,14 +59,16 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Policy Bindings.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no policy bindings exist. Click the button below to create one.' %}
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Policy Bindings.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no policy bindings exist. Click the button below to create one.' %}
</div>
<a href="{% url 'passbook_admin:policy-binding-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
<a href="{% url 'passbook_admin:policy-binding-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% endif %}
</div>

View File

@ -17,29 +17,31 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item"
href="{% url 'passbook_admin:property-mapping-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item"
href="{% url 'passbook_admin:property-mapping-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
{% include 'partials/pagination.html' %}
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -75,31 +77,33 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Property Mappings.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no property mappings exist. Click the button below to create one.' %}
</div>
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item"
href="{% url 'passbook_admin:property-mapping-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Property Mappings.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no property mappings exist. Click the button below to create one.' %}
</div>
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item"
href="{% url 'passbook_admin:property-mapping-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endif %}

View File

@ -18,28 +18,30 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:provider-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:provider-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
{% include 'partials/pagination.html' %}
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -94,30 +96,32 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Providers.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no providers exist. Click the button below to create one.' %}
</div>
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:provider-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Providers.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no providers exist. Click the button below to create one.' %}
</div>
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:provider-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endif %}

View File

@ -18,28 +18,30 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:source-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:source-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
{% include 'partials/pagination.html' %}
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -88,30 +90,32 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Sources.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no sources exist. Click the button below to create one.' %}
</div>
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:source-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Sources.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no sources exist. Click the button below to create one.' %}
</div>
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:source-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endif %}

View File

@ -18,28 +18,30 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:stage-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item" href="{% url 'passbook_admin:stage-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
{% include 'partials/pagination.html' %}
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -84,31 +86,33 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Stages.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no stages exist. Click the button below to create one.' %}
</div>
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item"
href="{% url 'passbook_admin:stage-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Stages.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no stages exist. Click the button below to create one.' %}
</div>
<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>
<ul class="pf-c-dropdown__menu" hidden>
{% for type, name in types.items %}
<li>
<a class="pf-c-dropdown__menu-item"
href="{% url 'passbook_admin:stage-create' %}?type={{ type }}&back={{ request.get_full_path }}">
{{ name|verbose_name }}<br>
<small>
{{ name|doc }}
</small>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endif %}

View File

@ -16,12 +16,14 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:stage-binding-create' %}?back={{ request.get_full_path }}"
class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:stage-binding-create' %}?back={{ request.get_full_path }}"
class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% include 'partials/pagination.html' %}
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -84,14 +86,16 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Flow-Stage Bindings.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no flow-stage bindings exist. Click the button below to create one.' %}
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Flow-Stage Bindings.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no flow-stage bindings exist. Click the button below to create one.' %}
</div>
<a href="{% url 'passbook_admin:certificatekeypair-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
<a href="{% url 'passbook_admin:certificatekeypair-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% endif %}
</div>

View File

@ -17,12 +17,14 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:stage-invitation-create' %}?back={{ request.get_full_path }}"
class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:stage-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>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -57,14 +59,16 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Invitations.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no invitations exist. Click the button below to create one.' %}
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Invitations.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no invitations exist. Click the button below to create one.' %}
</div>
<a href="{% url 'passbook_admin:stage-invitation-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
<a href="{% url 'passbook_admin:stage-invitation-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% endif %}
</div>

View File

@ -17,11 +17,13 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:stage-prompt-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
<div class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<a href="{% url 'passbook_admin:stage-prompt-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% include 'partials/pagination.html' %}
</div>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -83,14 +85,16 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Stage Prompts.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no stage prompts exist. Click the button below to create one.' %}
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Stage Prompts.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no stage prompts exist. Click the button below to create one.' %}
</div>
<a href="{% url 'passbook_admin:stage-prompt-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
<a href="{% url 'passbook_admin:stage-prompt-create' %}?back={{ request.get_full_path }}" class="pf-c-button pf-m-primary" type="button">{% trans 'Create' %}</a>
</div>
{% endif %}
</div>

View File

@ -15,11 +15,13 @@
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
{% if object_list %}
<div class="pf-c-toolbar" id="page-layout-table-simple-toolbar-top">
<div class="pf-c-toolbar__bulk-select">
<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 class="pf-c-toolbar">
<div class="pf-c-toolbar__content">
<div class="pf-c-toolbar__bulk-select">
<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>
{% include 'partials/pagination.html' %}
</div>
<table class="pf-c-table pf-m-compact pf-m-grid-xl" role="grid">
<thead>
@ -64,14 +66,16 @@
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Users.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no users exist. How did you even get here.' %}
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">
{% trans 'No Users.' %}
</h1>
<div class="pf-c-empty-state__body">
{% trans 'Currently no users exist. How did you even get here.' %}
</div>
<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>
<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>
{% endif %}
</div>

View File

@ -35,10 +35,12 @@
{% block beneath_form %}
{% endblock %}
<div class="pf-c-form__group pf-m-action">
<div class="pf-c-form__horizontal-group">
<div class="pf-c-form__actions">
<input class="pf-c-button pf-m-primary" type="submit" value="{% block action %}{% endblock %}" />
<a class="pf-c-button pf-m-secondary" href="{% back %}">{% trans "Cancel" %}</a>
<div class="pf-c-form__group-control">
<div class="pf-c-form__horizontal-group">
<div class="pf-c-form__actions">
<input class="pf-c-button pf-m-primary" type="submit" value="{% block action %}{% endblock %}" />
<a class="pf-c-button pf-m-secondary" href="{% back %}">{% trans "Cancel" %}</a>
</div>
</div>
</div>
</div>

View File

@ -25,8 +25,8 @@
</a>
</div>
<div class="pf-c-page__header-nav">
<nav class="pf-c-nav" aria-label="Nav">
<ul class="pf-c-nav__horizontal-list ws-top-nav">
<nav class="pf-c-nav pf-m-horizontal" aria-label="Nav">
<ul class="pf-c-nav__list ws-top-nav">
<li class="pf-c-nav__item"><a class="pf-c-nav__link {% is_active_url 'passbook_core:overview' %}"
href="{% url 'passbook_core:overview' %}">{% trans 'Access' %}</a></li>
{% if user.is_superuser %}

View File

@ -43,17 +43,19 @@
{% endfor %}
</div>
{% else %}
<div class="pf-c-empty-state">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">{% trans 'No Applications available.' %}</h1>
<div class="pf-c-empty-state__body">
{% trans "Either no applications are defined, or you don't have access to any." %}
<div class="pf-c-empty-state pf-m-full-height">
<div class="pf-c-empty-state__content">
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
<h1 class="pf-c-title pf-m-lg">{% trans 'No Applications available.' %}</h1>
<div class="pf-c-empty-state__body">
{% trans "Either no applications are defined, or you don't have access to any." %}
</div>
{% if user.is_superuser %} {# todo: use guardian permissions instead #}
<a href="{% url 'passbook_admin:application-create' %}" class="pf-c-button pf-m-primary" type="button">
{% trans 'Create Application' %}
</a>
{% endif %}
</div>
{% if user.is_superuser %} {# todo: use guardian permissions instead #}
<a href="{% url 'passbook_admin:application-create' %}" class="pf-c-button pf-m-primary" type="button">
{% trans 'Create Application' %}
</a>
{% endif %}
</div>
{% endif %}
</section>

View File

@ -10,6 +10,9 @@
</div>
{% endif %}
{% for field in form %}
{% if field.field.widget|fieldtype == 'HiddenInput' %}
{{ field }}
{% else %}
<div class="pf-c-form__group {% if field.errors %} has-error {% endif %}">
{% if field.field.widget|fieldtype == 'RadioSelect' %}
<label class="pf-c-form__label" {% if field.field.required %}class="required" {% endif %}
@ -66,4 +69,5 @@
</p>
{% endfor %}
</div>
{% endif %}
{% endfor %}

View File

@ -5,58 +5,72 @@
{% for field in form %}
<div class="pf-c-form__group {% if field.errors %} has-error {% endif %}">
{% if field.field.widget|fieldtype == 'RadioSelect' %}
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
{% for c in field %}
<div class="radio col-sm-10">
<input type="radio" id="{{ field.name }}-{{ forloop.counter0 }}"
name="{% if wizard %}{{ wizard.steps.current }}-{% endif %}{{ field.name }}" value="{{ c.data.value }}"
{% if c.data.selected %} checked {% endif %}>
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">{{ c.choice_label }}</label>
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
</div>
{% if field.help_text %}
<p class="pf-c-form__helper-text">{{ field.help_text }}</p>
{% endif %}
{% endfor %}
{% elif field.field.widget|fieldtype == 'Select' %}
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
<div class="pf-c-form__horizontal-group">
{{ field|css_class:"pf-c-form-control" }}
{% if field.help_text %}
<p class="pf-c-form__helper-text">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% elif field.field.widget|fieldtype == 'CheckboxInput' %}
<div class="pf-c-form__horizontal-group">
<div class="pf-c-check">
{{ field|css_class:"pf-c-check__input" }}
<label class="pf-c-check__label" for="{{ field.name }}-{{ forloop.counter0 }}">{{ field.label }}</label>
<div class="pf-c-form__group-control">
{% for c in field %}
<div class="radio col-sm-10">
<input type="radio" id="{{ field.name }}-{{ forloop.counter0 }}"
name="{% if wizard %}{{ wizard.steps.current }}-{% endif %}{{ field.name }}" value="{{ c.data.value }}"
{% if c.data.selected %} checked {% endif %}>
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">{{ c.choice_label }}</label>
</div>
{% if field.help_text %}
<p class="pf-c-form__helper-text">{{ field.help_text|safe }}</p>
<p class="pf-c-form__helper-text">{{ field.help_text }}</p>
{% endif %}
{% endfor %}
</div>
{% elif field.field.widget|fieldtype == 'Select' %}
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
</div>
<div class="pf-c-form__group-control">
<div class="pf-c-form__horizontal-group">
{{ field|css_class:"pf-c-form-control" }}
{% if field.help_text %}
<p class="pf-c-form__helper-text">{{ field.help_text|safe }}</p>
{% endif %}
</div>
</div>
{% elif field.field.widget|fieldtype == 'CheckboxInput' %}
<div class="pf-c-form__group-control">
<div class="pf-c-form__horizontal-group">
<div class="pf-c-check">
{{ field|css_class:"pf-c-check__input" }}
<label class="pf-c-check__label" for="{{ field.name }}-{{ forloop.counter0 }}">{{ field.label }}</label>
</div>
{% if field.help_text %}
<p class="pf-c-form__helper-text">{{ field.help_text|safe }}</p>
{% endif %}
</div>
</div>
{% else %}
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
<div class="c-form__horizontal-group">
{{ field|css_class:'pf-c-form-control' }}
{% if field.help_text %}
<p class="pf-c-form__helper-text">{{ field.help_text|safe }}</p>
{% endif %}
<div class="pf-c-form__group-label">
<label class="pf-c-form__label" for="{{ field.name }}-{{ forloop.counter0 }}">
<span class="pf-c-form__label-text">{{ field.label }}</span>
{% if field.field.required %}
<span class="pf-c-form__label-required" aria-hidden="true">&#42;</span>
{% endif %}
</label>
</div>
<div class="pf-c-form__group-control">
<div class="c-form__horizontal-group">
{{ field|css_class:'pf-c-form-control' }}
{% if field.help_text %}
<p class="pf-c-form__helper-text">{{ field.help_text|safe }}</p>
{% endif %}
</div>
</div>
{% endif %}
{% for error in field.errors %}

View File

@ -1,43 +1,43 @@
{% load i18n %}
<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' %}
<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 %}
href="?{{ param }}={{ page_obj.previous_page_number }}"
{% else %}
disabled
{% endif %}>
<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 %}
{{ current }} of {{ total }}
{% endblocktrans %}
</span>
<div class="pf-c-toolbar__item pf-m-pagination">
<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>
<a class="pf-c-button pf-m-plain" type="button" aria-label="Go to next page"
{% if page_obj.has_next %}
href="?{{ param }}={{ page_obj.next_page_number }}"
{% else %}
disabled
{% 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 %}
{% 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 %}
href="?{{ param }}={{ page_obj.previous_page_number }}"
{% else %}
disabled
{% endif %}>
<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 %}
{{ current }} of {{ total }}
{% endblocktrans %}
</span>
</div>
<a class="pf-c-button pf-m-plain" type="button" aria-label="Go to next page"
{% if page_obj.has_next %}
href="?{{ param }}={{ page_obj.next_page_number }}"
{% else %}
disabled
{% 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 %}
</div>
</div>

View File

@ -2,7 +2,6 @@ version: "3.5"
services:
passbook_gatekeeper:
container_name: gatekeeper
image: beryju/passbook-gatekeeper:{{ version }}
ports:
- 4180:4180

View File

@ -102,7 +102,7 @@ class SAMLSSOBindingRedirectView(SAMLSSOView):
"""SAML Handler for SSO/Redirect bindings, which are sent via GET"""
# pylint: disable=unused-argument
def get(
def get( # lgtm [py/similar-function]
self, request: HttpRequest, application_slug: str
) -> Optional[HttpResponse]:
"""Handle REDIRECT bindings"""

View File

@ -188,7 +188,7 @@ WSGI_APPLICATION = "passbook.root.wsgi.application"
DATABASES = {
"default": {
"ENGINE": "django_prometheus.db.backends.postgresql",
"ENGINE": "django.db.backends.postgresql",
"HOST": CONFIG.y("postgresql.host"),
"NAME": CONFIG.y("postgresql.name"),
"USER": CONFIG.y("postgresql.user"),

View File

@ -55,7 +55,7 @@ class LDAPSource(Source):
form = "passbook.sources.ldap.forms.LDAPSourceForm"
_connection: Optional[Connection]
_connection: Optional[Connection] = None
@property
def connection(self) -> Connection:

View File

@ -94,8 +94,6 @@ class OAuthClient(BaseOAuthClient):
"oauth_callback": callback,
"token": raw_token,
}
callback = request.build_absolute_uri(callback or request.path)
callback = force_text(callback)
try:
response = self.session.request(
"post",

View File

@ -18,7 +18,7 @@
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td> <a href="{{ url }}" target="_blank">{% trans 'Confirm Account' %}</a> </td>
<td> <a href="{{ url }}" rel="noopener noreferrer" target="_blank">{% trans 'Confirm Account' %}</a> </td>
</tr>
</tbody>
</table>

View File

@ -23,7 +23,7 @@
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td> <a href="{{ url }}" target="_blank">{% trans 'Reset Password' %}</a> </td>
<td> <a href="{{ url }}" rel="noopener noreferrer" target="_blank">{% trans 'Reset Password' %}</a> </td>
</tr>
</tbody>
</table>

View File

@ -39,8 +39,16 @@ class IdentificationForm(forms.Form):
super().__init__(*args, **kwargs)
if self.stage.user_fields == [UserFields.E_MAIL]:
self.fields["uid_field"] = forms.EmailField()
self.fields["uid_field"].label = human_list(
[x.title() for x in self.stage.user_fields]
label = human_list([x.title() for x in self.stage.user_fields])
self.fields["uid_field"].label = label
self.fields["uid_field"].widget.attrs.update(
{
"placeholder": _(label),
"autofocus": "autofocus",
# Autocomplete according to
# https://www.chromium.org/developers/design-documents/form-styles-that-chromium-understands
"autocomplete": "username",
}
)
def clean_uid_field(self):

View File

@ -0,0 +1,28 @@
# Generated by Django 3.0.7 on 2020-06-15 16:41
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("passbook_flows", "0005_provider_flows"),
("passbook_stages_identification", "0002_auto_20200530_2204"),
]
operations = [
migrations.AlterField(
model_name="identificationstage",
name="recovery_flow",
field=models.ForeignKey(
blank=True,
default=None,
help_text="Optional recovery flow, which is linked at the bottom of the page.",
null=True,
on_delete=django.db.models.deletion.SET_DEFAULT,
related_name="+",
to="passbook_flows.Flow",
),
),
]

View File

@ -23,6 +23,9 @@ def get_authentication_backends():
class PasswordForm(forms.Form):
"""Password authentication form"""
username = forms.CharField(
widget=forms.HiddenInput(attrs={"autocomplete": "username"}), required=False
)
password = forms.CharField(
widget=forms.PasswordInput(
attrs={

View File

@ -52,9 +52,20 @@ class PasswordStage(FormView, StageView):
form_class = PasswordForm
template_name = "stages/password/backend.html"
def get_form(self, form_class=None) -> PasswordForm:
form = super().get_form(form_class=form_class)
# If there's a pending user, update the `username` field
# this field is only used by password managers.
# If there's no user set, an error is raised later.
if PLAN_CONTEXT_PENDING_USER in self.executor.plan.context:
pending_user: User = self.executor.plan.context[PLAN_CONTEXT_PENDING_USER]
form.fields["username"].initial = pending_user.username
return form
def get_context_data(self, **kwargs):
kwargs = super().get_context_data(**kwargs)
kwargs["primary_action"] = _("Log in")
recovery_flow = Flow.objects.filter(designation=FlowDesignation.RECOVERY)
if recovery_flow.exists():
kwargs["recovery_flow"] = recovery_flow.first()

View File

@ -0,0 +1,33 @@
# Generated by Django 3.0.7 on 2020-06-15 16:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("passbook_stages_prompt", "0002_auto_20200528_2059"),
]
operations = [
migrations.AlterField(
model_name="prompt",
name="type",
field=models.CharField(
choices=[
("text", "Text"),
("username", "Username"),
("e-mail", "Email"),
("password", "Password"),
("number", "Number"),
("checkbox", "Checkbox"),
("data", "Date"),
("data-time", "Date Time"),
("separator", "Separator"),
("hidden", "Hidden"),
("static", "Static"),
],
max_length=100,
),
),
]

View File

@ -12,7 +12,10 @@ from passbook.policies.models import PolicyBindingModel
class FieldTypes(models.TextChoices):
"""Field types an Prompt can be"""
# Simple text field
TEXT = "text"
# Same as text, but has autocomplete for password managers
USERNAME = "username"
EMAIL = "e-mail"
PASSWORD = "password" # noqa # nosec
NUMBER = "number"
@ -52,8 +55,11 @@ class Prompt(models.Model):
}
if self.type == FieldTypes.EMAIL:
field_class = forms.EmailField
if self.type == FieldTypes.USERNAME:
attrs["autocomplete"] = "username"
if self.type == FieldTypes.PASSWORD:
widget = forms.PasswordInput(attrs=attrs)
attrs["autocomplete"] = "new-password"
if self.type == FieldTypes.NUMBER:
field_class = forms.IntegerField
widget = forms.NumberInput(attrs=attrs)
@ -64,6 +70,10 @@ class Prompt(models.Model):
if self.type == FieldTypes.CHECKBOX:
field_class = forms.CheckboxInput
kwargs["required"] = False
if self.type == FieldTypes.DATE:
field_class = forms.DateInput
if self.type == FieldTypes.DATE_TIME:
field_class = forms.DateTimeInput
# TODO: Implement static
# TODO: Implement separator

View File

@ -2,7 +2,7 @@
"license": "MIT",
"dependencies": {
"@fortawesome/fontawesome-free": "^5.13.0",
"@patternfly/patternfly": "^2.71.6",
"@patternfly/patternfly": "^4.10.31",
"codemirror": "^5.54.0"
}
}

View File

@ -198,120 +198,6 @@ input[data-is-monospace] {
font-family: monospace;
}
.ws-page-header {
background-color: #151515;
min-height: auto
}
@media (min-width: 992px) {
.ws-page-header .pf-c-page__header-nav {
margin-left:12px
}
}
.ws-page-header .pf-c-nav__scroll-button {
outline-offset: -4px;
height: 100%;
top: 0
}
.ws-page-header .pf-c-nav__horizontal-list .pf-c-nav__item {
margin-right: 0
}
.ws-page-header .pf-c-nav__horizontal-list .pf-c-nav__link {
padding-top: 22px;
padding-right: var(--pf-global--spacer--md);
padding-left: var(--pf-global--spacer--md);
color: var(--pf-global--Color--light-100)
}
@media (max-width: 991px) {
.ws-page-header .pf-c-nav__horizontal-list .pf-c-nav__link {
padding-top:10px
}
}
.ws-page-header .pf-c-nav__horizontal-list .pf-c-nav__link:after {
top: 0!important;
height: 4px
}
.ws-page-header .pf-c-nav__horizontal-list .pf-c-nav__link:active,.ws-page-header .pf-c-nav__horizontal-list .pf-c-nav__link:hover {
-webkit-transition: .5s;
transition: .5s
}
.ws-page-header .pf-c-nav__horizontal-list .pf-c-nav__link.pf-m-current,.ws-page-header .pf-c-nav__horizontal-list .pf-c-nav__link:active,.ws-page-header .pf-c-nav__horizontal-list .pf-c-nav__link:hover {
background-color: var(--pf-global--BackgroundColor--light-100);
color: #151515!important;
font-weight: var(--pf-global--FontWeight--normal)
}
.ws-page-header li a:after {
content: "";
position: absolute;
left: 50%!important;
bottom: 0;
-webkit-transform: translateX(-50%) scaleX(0);
transform: translateX(-50%) scaleX(0);
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
width: 100%;
height: 1px;
background-color: var(--pf-global--BackgroundColor--light-100);
color: #151515!important;
-webkit-transition: -webkit-transform .25s;
transition: -webkit-transform .25s;
transition: transform .25s;
transition: transform .25s,-webkit-transform .25s
}
.ws-page-header li a:hover:after {
-webkit-transform: translateX(-50%) scaleX(1);
transform: translateX(-50%) scaleX(1)
}
.ws-page-header li a.pf-m-current:after {
left: 0!important;
-webkit-transform: none;
transform: none
}
.ws-page-sidebar#page-sidebar {
color: #fff;
box-shadow: none
}
.ws-page-sidebar .pf-c-nav {
margin-top: 16px
}
.pf-site-search {
padding: 0 0 2px;
width: 150px;
background: transparent;
-webkit-transition: .25s;
transition: .25s
}
.ws-page-header .pf-c-page__header-brand-toggle {
display: none;
visibility: hidden
}
@media (max-width: 768px) {
.pf-site-search {
width:100px
}
.ws-page-header .pf-c-page__header-brand-toggle {
display: block;
visibility: visible
}
}
/* Form with user */
.form-control-static {
display: flex;

View File

@ -7,10 +7,10 @@
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.13.0.tgz#fcb113d1aca4b471b709e8c9c168674fbd6e06d9"
integrity sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg==
"@patternfly/patternfly@^2.71.6":
version "2.71.6"
resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-2.71.6.tgz#6385cbd5aaca2f59bf65496e0189c541a7f00a82"
integrity sha512-mqqtuCVa+/FbyyK8hSAcfEIwNX73+zbnzHpmC4NrW0kyMzSszPtBqev/ZO79ZxGqZUpLOyUBTVaH7oKn8cL35Q==
"@patternfly/patternfly@^4.10.31":
version "4.10.31"
resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-4.10.31.tgz#742852b69d90bb2efe304130f7226d2e356306cf"
integrity sha512-UxdZ/apWRowXYZ5qPz5LPfXwyB4YGpomrCJPX7c36+Zg8jFpYyVqgVYainL8Yf/GrChtC2LKyoHg7UUTtMtp4A==
codemirror@^5.54.0:
version "5.54.0"

View File

@ -6079,6 +6079,7 @@ definitions:
type: string
enum:
- text
- username
- e-mail
- password
- number