bugfixes, cleanup

This commit is contained in:
TuxCoder 2022-02-06 23:57:01 +01:00
parent 1bf474045a
commit 17c30128ae
82 changed files with 216 additions and 76 deletions

View file

@ -0,0 +1,37 @@
{% extends 'base.html.j2' %}
{% block body %}
<div class="container-fluid">
<div class="row">
{% for message in get_flashed_messages() %}
<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ message }}
</div>
{% endfor %}
</div>
<div class="row">
<nav class="col-md-2 d-none d-md-block bg-light sidebar fixed-top">
<div class="sidebar-sticky active">
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.users') }}">{{ gettext('users') }}</a></li>
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.registrations') }}">{{ gettext('registrations') }}</a></li>
</div>
</nav>
<main class="col-md-9 ml-sm-auto col-lg-10 px-4" role="main">
<h1>{% block title %}{% endblock %}</h1>
<div class="card">
<div class="card-body mt-5 mb-5">
<div class="tab-content">
{% block content %}{% endblock %}
</div>
</div>
</div>
</main>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,2 @@
{% extends 'admin/base.html.j2' %}

View file

@ -0,0 +1,28 @@
{% extends 'admin/base.html.j2' %}
{% block title %}{{ gettext('registrations') }}{% endblock %}
{% block content %}
<table class="table">
<thead>
<tr>
<th>username</th>
<th>created_at</th>
<th>action<th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.username }}</td>
<td>{{ user.created_at }}</td>
<td>
<a title="{{ gettext('Reject')}}" href="{{ url_for('.registration_delete', registration_id=user.id) }}" onclick="admin.registration.delete(this.href, '{{ user.username }}'); return false;"><i class="fas fa-ban"></i></a>
<a title="{{ gettext('Reject')}}" href="{{ url_for('.registration_accept', registration_id=user.id) }}" onclick="admin.registration.accept(this.href, '{{ user.username }}'); return false;"><i class="fas fa-check"></i></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock%}

View file

@ -0,0 +1,29 @@
{% extends 'admin/base.html.j2' %}
{% block title %}{{ gettext('users') }}{% endblock %}
{% block content %}
<table class="table">
<thead>
<tr>
<th>username</th>
<th>created_at</th>
<th>modified_at</th>
<th>last_login</th>
<th>action</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.username }}</td>
<td>{{ user.created_at }}</td>
<td>{{ user.modified_at }}</td>
<td>{{ user.last_login }}</td>
<td> </td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock%}

View file

@ -0,0 +1,28 @@
{% extends 'base.html.j2' %}
{% block body %}
<div class="container-fluid">
<div class="row">
{% for message in get_flashed_messages() %}
<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ message }}
</div>
{% endfor %}
</div>
<div class="row">
<main class="col-md-9 ml-sm-auto col-lg-10 px-4" role="main">
<h1>{% block title %}{% endblock %}</h1>
<div class="card">
<div class="card-body mt-5 mb-5">
<div class="tab-content">
{% block content %}{% endblock %}
</div>
</div>
</div>
</main>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,14 @@
{% extends 'auth/base.html.j2' %}
{% block title %}{{ gettext('Consent') }}{% endblock %}
{% block content %}
<p>
The application "{{ client.client_id }}" requested the following scopes: {{ requested_scope }}
</p>
<p> Allow this app to access that data?</p>
{{ render_form(form) }}
{% endblock %}

View file

@ -0,0 +1,13 @@
{% extends 'auth/base.html.j2' %}
{% block title %}{{ gettext('Login') }}{% endblock %}
{% block content %}
{{ render_form(form) }}
<a href="{{ url_for('.sign_up') }}" class="btn btn-primary">Sign Up</a>
{% endblock %}

View file

@ -0,0 +1,25 @@
{% extends 'auth/base.html.j2' %}
{% block title %}{{ gettext('Login') }}{% endblock %}
{% block content %}
<ul class="nav nav-tabs" id="myTab" role="tablist">
{% for auth_name in forms.keys() %}
<li class="nav-item">
<a class="nav-link{{' active' if loop.first else ''}}" id="home-tab" data-toggle="tab" href="#{{ auth_name }}" role="tab" aria-controls="home" aria-selected="true">{{ gettext(auth_name) }}</a>
</li>
{% endfor %}
</ul>
<div class="tab-content" id="myTabContent">
{% for auth_name, form in forms.items() %}
<div class="tab-pane fade{{ ' show active' if loop.first else '' }}" id="{{ auth_name }}" role="tabpanel" aria-labelledby="{{ auth_name }}-tab">
{{ render_form(form) }}
</div>
{% endfor %}
</div>
{% endblock %}

View file

@ -0,0 +1,11 @@
{% extends 'auth/base.html.j2' %}
{% block title %}{{ gettext('Sign Up') }}{% endblock %}
{% block content %}
{{ render_form(form, onsubmit="return auth.sign_up.submit(this)", action_url=url_for('auth.sign_up_submit')) }}
{% endblock %}

View file

@ -0,0 +1,163 @@
{% extends 'skelet.html.j2' %}
{# Renders field for bootstrap 3 standards.
Params:
field - WTForm field
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_
Example usage:
{{ macros.render_field(form.email, placeholder='Input email', type='email') }}
#}
{% macro render_field(field, label_visible=true, horizontal=false) -%}
<div class="form-group {% if field.errors %}has-error{% endif %} {{ 'row' if horizontal }} {{ kwargs.pop('class_', '') }}">
{% if (field.type != 'HiddenField' and field.type !='CSRFTokenField') and label_visible %}
<label for="{{ field.id }}" class="control-label {{ 'col-sm-2 col-form-label' if horizontal }}">{{ field.label.text }}</label>
{% endif %}
<div class="{{ 'col-sm-10' if horizontal }}">
{{ field(class_='form-control', **kwargs) }}
</div>
{% if field.errors %}
{% for e in field.errors %}
<p class="alert alert-danger">{{ e }}</p>
{% endfor %}
{% endif %}
</div>
{%- endmacro %}
{# Renders checkbox fields since they are represented differently in bootstrap
Params:
field - WTForm field (there are no check, but you should put here only BooleanField.
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_
Example usage:
{{ macros.render_checkbox_field(form.remember_me) }}
#}
{% macro render_checkbox_field(field) -%}
<div class="checkbox">
<label>
{{ field(type='checkbox', **kwargs) }} {{ field.label }}
</label>
</div>
{%- endmacro %}
{# Renders radio field
Params:
field - WTForm field (there are no check, but you should put here only BooleanField.
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_
Example usage:
{{ macros.render_radio_field(form.answers) }}
#}
{% macro render_radio_field(field) -%}
{% for value, label, _ in field.iter_choices() %}
<div class="radio">
<label>
<input type="radio" name="{{ field.id }}" id="{{ field.id }}" value="{{ value }}">{{ label }}
</label>
</div>
{% endfor %}
{%- endmacro %}
{# Renders submit field
Params:
field - WTForm field (there are no check, but you should put here only BooleanField.
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_
Example usage:
{{ macros.render_submit_field(form.answers) }}
#}
{% macro render_submit_field(field, btn_class='btn btn-primary') -%}
<input type="submit" class="{{ btn_class }}" value="{{ field.label.text }}" />
{%- endmacro %}
{# Renders form field
Params:
field - WTForm field (there are no check, but you should put here only BooleanField.
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_
Example usage:
{{ macros.render_submit_field(form.answers) }}
#}
{% macro render_form_field(field) -%}
<fieldset>
{#<legend>{{field.label}}</legend>#}
{{ _render_form(field, horizontal=true) }}
</fieldset>
{%- endmacro %}
{% macro render_list_field(field) -%}
<fieldset>
<legend>{{ field.label.text }}</legend>
<template id='{{field.name}}-template'>
<li class="list-group-item">
{{ _render_form(field.get_template(), horizontal=true) }}
<a class="btn btn-danger" onclick="fieldlist.remove(this)">Remove</a>
</li>
</template>
<ul class="list-group">
{% for _field in field %}
<li class="list-group-item">
{{ _render_field(_field) }}
<a class="btn btn-danger" onclick="fieldlist.remove(this)">Remove</a>
</li>
{% endfor %}
</ul>
<a class="btn btn-success" onclick="fieldlist.add('{{ field.name }}')">Add</a>
</fieldset>
{%- endmacro %}
{% macro _render_field(f) %}
{% if f.type == 'BooleanField' %}
{{ render_checkbox_field(f, **kwargs) }}
{% elif f.type == 'RadioField' %}
{{ render_radio_field(f, **kwargs) }}
{% elif f.type == 'SubmitField' %}
{{ render_submit_field(f, **kwargs) }}
{% elif f.type == 'FormField' %}
{{ render_form_field(f, **kwargs) }}
{% elif f.type == 'ModelFieldList' %}
{{ render_list_field(f, **kwargs) }}
{% elif f.type == 'FieldList' %}
{{ render_list_field(f, **kwargs) }}
{% else %}
{{ render_field(f, **kwargs) }}
{% endif %}
{% endmacro %}
{% macro _render_form(form) -%}
{% if caller %}
{{ caller() }}
{% else %}
{% for f in form %}
{{ _render_field(f, **kwargs) }}
{% endfor %}
{% endif %}
{%- endmacro %}
{# Renders WTForm in bootstrap way. There are two ways to call function:
- as macros: it will render all field forms using cycle to iterate over them
- as call: it will insert form fields as you specify:
e.g. {% call macros.render_form(form, action_url=url_for('login_view'), action_text='Login',
class_='login-form') %}
{{ macros.render_field(form.email, placeholder='Input email', type='email') }}
{{ macros.render_field(form.password, placeholder='Input password', type='password') }}
{{ macros.render_checkbox_field(form.remember_me, type='checkbox') }}
{% endcall %}
Params:
form - WTForm class
action_url - url where to submit this form
action_text - text of submit button
class_ - sets a class for form
#}
{% macro render_form(form, action_url='', class_='', method='post', onsubmit='') -%}
<form method="{{ method }}" {% if action_url %}action="{{ action_url }}" {% endif %}role="form" class="{{ class_ }}" {% if onsubmit %}onsubmit="{{ onsubmit }}"{% endif %}>
<input name="form" type="hidden" value="{{ form.__class__.__name__ }}">
{{ _render_form(form) }}
</form>
{%- endmacro %}

View file

@ -0,0 +1,42 @@
{% extends 'base.html.j2' %}
{% block body %}
<div class="container-fluid">
<div class="row">
{% for message in get_flashed_messages() %}
<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert">&times;</button>
{{ message }}
</div>
{% endfor %}
</div>
<div class="row">
<nav class="col-md-2 d-none d-md-block bg-light sidebar fixed-top">
<div class="sidebar-sticky active">
{#<a href="/"><img alt="logo" class="container-fluid" src="/static/images/dog_main_small.png"></a>#}
<li class="nav-item"><a class="nav-link" href="{{ url_for('frontend.index') }}">{{ gettext('Account') }}</a></li>
<li class="nav-item"><a class="nav-link" href="{{ url_for('frontend.client_cert') }}">{{ gettext('Client Cert') }}</a></li>
<li class="nav-item"><a class="nav-link" href="{{ url_for('frontend.totp') }}">{{ gettext('2FA - TOTP') }}</a></li>
<li class="nav-item"><a class="nav-link" href="{{ url_for('frontend.oauth2_tokens') }}">{{ gettext('Oauth2 Tokens') }}</a></li>
<li class="nav-item"><a class="nav-link" href="{{ url_for('frontend.password_change') }}">{{ gettext('Password Change') }}</a></li>
<li class="nav-item"><a class="nav-link" href="{{ url_for('frontend.logout') }}">{{ gettext('Logout') }}</a></li>
</div>
</nav>
<main class="col-md-9 ml-sm-auto col-lg-10 px-4" role="main">
<h1>{% block title %}{% endblock %}</h1>
<div class="card">
<div class="card-body mt-5 mb-5">
<div class="tab-content">
{% block content %}{% endblock %}
</div>
</div>
</div>
</main>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,60 @@
{% extends 'frontend/base.html.j2' %}
{% block title %}{{ gettext('client certs') }}{% endblock %}
{% block content %}
<ul class="nav nav-tabs" id="myTab" role="tablist">
{% for service in services.values() %}
<li class="nav-item">
<a class="nav-link{{' active' if loop.first else ''}}" id="home-tab" data-toggle="tab" href="#{{ service.name }}" role="tab" aria-controls="home" aria-selected="true">{{ service.name }}</a>
</li>
{% endfor %}
</ul>
<div class="tab-content" id="myTabContent">
{% for service in services.values() if service.client_cert %}
<div class="tab-pane fade{{ ' show active' if loop.first else '' }}" id="{{ service.name }}" role="tabpanel" aria-labelledby="{{ service.name }}-tab">
<table class="table">
<thead>
<tr>
<th>not valid before</th>
<th>not valid after</th>
<th>serial_number<th>
<th> <th>
</tr>
</thead>
<tbody>
{% for cert in client_certs[service.name] %}
<tr {{ 'class="table-warning"' if not cert.is_valid else ''}}>
<td>{{ cert.not_valid_before }}</td>
<td>{{ cert.not_valid_after }}</td>
<td>{{ cert.serial_number_hex }}</td>
<td>
<a title="{{ gettext('Download') }}" href="{{ url_for('.get_client_cert', service_name=service.name, serial_number=cert.serial_number_hex) }}"><i class="fas fa-file-download"></i></a>
&nbsp;
{% if cert.is_valid %}
<a title="{{ gettext('Revoke')}}" href="{{ url_for('.revoke_client_cert', service_name=service.name, serial_number=cert.serial_number_hex) }}" onclick="client_cert.revoke_certificate(this.href, '{{ cert.serial_number_hex }}'); return false;"><i class="fas fa-ban"></i></a>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<a class="btn btn-primary" href="{{ url_for('frontend.client_cert_new', service_name=service.name) }}">
New Certificate
</a>
</div>
{% endfor %}
</div>
{% endblock %}
{% block script_js %}
client_cert.init_list();
{% endblock %}

View file

@ -0,0 +1,45 @@
{% extends 'frontend/base.html.j2' %}
{% block title %}{{ gettext('new client cert - {service_name}').format(service_name=service.name) }}{% endblock %}
{% block content %}
<div id="sign-key">
<h4>Sign Public Key</h4>
{{ render_form(form) }}
</div>
<div id="gen-key">
<h4>Generate new key in the browser</h4>
<div id="gen-key-sign" style="display: none">
{{ render_form(form) }}
</div>
<form id="gen-key-form">
<div class="form-group">
<label for="valid_time" class="control-label ">Key Password for .p12 (optional)</label>
<div class="">
<input class="form-control" id="cert-password" type="password" name="password"/>
</div>
</div>
<div class="form-group">
<label for="valid_time" class="control-label ">Key Size</label>
<div class="">
<select id="key-size" class="custom-select">
<option value="4096" selected>4096</option>
<option value="2048">2048</option>
</select>
</div>
</div>
<div class="form-group ">
<label for="valid_time" class="control-label ">valid time in days</label>
<div class="">
<input class="form-control" name="valid_time" required type="text" value="365">
</div>
</div>
</form>
<button id="generate-key" class="btn btn-primary" onclick="client_cert.generate_private_key()">Generate Key</button>
<a style="display: none" id="save-button" download="lenticular_cloud_{{ service.name }}.p12" class="btn btn-primary">Save Keypair</a>
{% endblock %}

View file

@ -0,0 +1,2 @@
{% extends 'frontend/base.html.j2' %}

View file

@ -0,0 +1,31 @@
{% extends 'frontend/base.html.j2' %}
{% block title %}{{ gettext('Oauth2 tokens') }}{% endblock %}
{% block content %}
<table class="table">
<thead>
<tr>
<th>{{ gettext('Client ID') }}</th>
<th>{{ gettext('Remember') }}</th>
<th>{{ gettext('Created at') }}
<th>{{ gettext('Action') }}
</tr>
</thead>
<tbody>
{% for consent_session in consent_sessions %}
<tr>
<td>{{ consent_session.consent_request.client.client_id }}</td>
<td>{{ consent_session.remember }}</td>
<td>{{ consent_session.handled_at }}</td>
<td>
<a title="{{ gettext('Revoke')}}" href="{{ url_for('.oauth2_token_revoke', client_id=consent_session.consent_request.client.client_id) }}" onclick="oauth2_token.revoke(this.href, '{{ consent_session.consent_request.client.client_id }}'); return false;"><i class="fas fa-ban"></i></a>
</td>
</tr>
</tbody>
{% endfor %}
</table>
{% endblock %}

View file

@ -0,0 +1,21 @@
{% extends 'frontend/base.html.j2' %}
{% block title %}{{ gettext('Oauth2 Request') }}{% endblock %}
{% block content %}
<div class="container">
<p>
A service ask for access to your account data.<br>
</p>
<p>
<b> Requested Scopes: {{ auth_req['scope'] }}</b>
</p>
<p>
You can confirm this pressing "Continue"
</p>
{{ render_form(form) }}
</div>
{% endblock %}

View file

@ -0,0 +1,16 @@
{% extends 'frontend/base.html.j2' %}
{% block title %}{{ gettext('Password Change') }}{% endblock %}
{% block content %}
{{ render_form(form)}}
{% endblock %}
{% block script_js %}
password_change.init();
{% endblock %}

View file

@ -0,0 +1,35 @@
{% extends 'frontend/base.html.j2' %}
{% block title %}{{ gettext('2FA - TOTP') }}{% endblock %}
{% block content %}
<table class="table">
<thead>
<tr>
<th>name</th>
<th>created_at</th>
<th>action<th>
</tr>
</thead>
<tbody>
{% for totp in current_user.totps %}
<tr>
<td>{{ totp.name }}</td>
<td>{{ totp.created_at }}</td>
<td>{{ render_form(delete_form, action_url=url_for('frontend.totp_delete', totp_name=totp.name)) }}</td>
{% endfor %}
</table>
<a class="btn btn-default" href="{{ url_for('frontend.totp_new') }}">
New TOTP
</a>
{% endblock %}
{% block script_js %}
totp.init_list();
{% endblock %}

View file

@ -0,0 +1,20 @@
{% extends 'frontend/base.html.j2' %}
{% block title %}{{ gettext('2FA - TOTP - New') }}{% endblock %}
{% block content %}
{{ render_form(form) }}
<div id="svg-container">
</div>
{% endblock %}
{% block script_js %}
totp.init_new();
{% endblock %}

View file

@ -0,0 +1,8 @@
<!doctype html>
<title>Logout</title>
Do you really want to logout?
<form method="POST">
<button type="submit" name="logout" value="logout">Yes, logout</button>
<button type="submit" name="no_logout" value="no_logout">No, cancel logout</button>
</form>

View file

@ -0,0 +1,40 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{% block title %}{% endblock %} - Lenticular Cloud</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="/static/main.css?v={{ GIT_HASH }}" />
{% block head %}{% endblock %}
</head>
<body>
<div class='messages-box'>
</div>
<nav class="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
{% if current_user.is_authenticated %}
<a class="nav-link" href="{{ url_for('frontend.logout') }}">{{ gettext('Logout') }}</a>
Hallo {{ current_user.username }}
{% endif %}
<div class="col-xs-1"><button id="sidebarCollapse" class="btn btn-primary d-xs-block d-md-none" ><i class="fa fa-bars fa-2x"></i></button></div>
<div class="col-xs-11"><a class="navbar-brand col-xs-11 col-sm-3 col-md-2 mr-0" href="/">Lenticular Cloud</a></div>
</nav>
<div style="height: 40px"></div>
{% block body %}{% endblock %}
<div class='container'>
<div class="mt-5 row justify-content-center">
<footer>
<span class="text-muted">Render Time: {{ g.request_time() }}</span> | <span class="text-muted">{{ gettext('All right reserved. &copy;') + '2020' }}</span>
</footer>
</div>
</div>
<script type="application/javascript" src="/static/main.js?v={{ GIT_HASH }}" ></script>
<script type="application/javascript" >
{% block script_js %}{% endblock %}
</script>
</body>
</html>