add translation to german
This commit is contained in:
parent
fcb6a8f6ca
commit
8db179d07c
12 changed files with 497 additions and 53 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
.venv/
|
*.mo
|
||||||
*.pyc
|
*.pyc
|
||||||
|
.venv/
|
||||||
config.json
|
config.json
|
||||||
|
|
18
README.md
18
README.md
|
@ -2,8 +2,26 @@
|
||||||
|
|
||||||
Licenced under [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/). See [LICENCE](LICENCE) file for full licence text.
|
Licenced under [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/). See [LICENCE](LICENCE) file for full licence text.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
All instructions assume you have the requirements already installed.
|
||||||
|
|
||||||
|
## Adding translations
|
||||||
|
|
||||||
|
Replace `<LANG>` with your intended language.
|
||||||
|
|
||||||
|
1. run `pybabel init -i messages.pot -d translations -l <LANG>`
|
||||||
|
2. edit `translations/<LANG>/LC_MESSAGES/messages.po`
|
||||||
|
3. For testing, run `pybabel compile -d translations`
|
||||||
|
|
||||||
|
If you changed the translation strings, make sure to run `pybabel extract -F babel.cfg -o messages.pot .` and
|
||||||
|
`pybabel update -i messages.pot -d translations` first.
|
||||||
|
|
||||||
## Setting it up
|
## Setting it up
|
||||||
|
|
||||||
|
After deploying the repository, change to `ldap_frontend` directory, then
|
||||||
|
run `pybabel compile -d translations`.
|
||||||
|
|
||||||
### config.json
|
### config.json
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,8 @@ from json import load
|
||||||
from os import environ
|
from os import environ
|
||||||
|
|
||||||
from flask import Flask, flash, redirect, request, session, url_for
|
from flask import Flask, flash, redirect, request, session, url_for
|
||||||
from flask_wtf.csrf import CSRFProtect, CSRFError
|
from flask_babel import Babel, gettext
|
||||||
|
from flask_wtf.csrf import CSRFError, CSRFProtect
|
||||||
from ldap3 import ALL_ATTRIBUTES, MODIFY_ADD, MODIFY_DELETE
|
from ldap3 import ALL_ATTRIBUTES, MODIFY_ADD, MODIFY_DELETE
|
||||||
from ldap3.core.exceptions import LDAPException
|
from ldap3.core.exceptions import LDAPException
|
||||||
from ldap3.utils.dn import escape_rdn
|
from ldap3.utils.dn import escape_rdn
|
||||||
|
@ -19,16 +20,25 @@ from .helpers.ldap import (
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = environ.get("FLASK_SECRET_KEY", default="test")
|
app.secret_key = environ.get("FLASK_SECRET_KEY", default="test")
|
||||||
|
app.config["LANGUAGES"] = {"en": "English", "de": "Deutsch"}
|
||||||
|
|
||||||
|
babel = Babel(app)
|
||||||
csrf = CSRFProtect(app)
|
csrf = CSRFProtect(app)
|
||||||
|
|
||||||
with open(environ["APP_CONFIG"]) as f:
|
with open(environ["APP_CONFIG"]) as f:
|
||||||
APP_CONFIG = load(f)
|
APP_CONFIG = load(f)
|
||||||
|
|
||||||
|
|
||||||
|
@babel.localeselector
|
||||||
|
def get_locale():
|
||||||
|
return request.accept_languages.best_match(app.config["LANGUAGES"].keys())
|
||||||
|
|
||||||
|
|
||||||
@app.errorhandler(CSRFError)
|
@app.errorhandler(CSRFError)
|
||||||
def handle_csrf_error(e):
|
def handle_csrf_error(e):
|
||||||
flash("CRSF validation error. For your own safety, you have been logged out.")
|
flash(
|
||||||
|
gettext("CRSF validation error. For your own safety, you have been logged out.")
|
||||||
|
)
|
||||||
|
|
||||||
session["is_logged_in"] = False
|
session["is_logged_in"] = False
|
||||||
session["username"] = ""
|
session["username"] = ""
|
||||||
|
@ -39,7 +49,7 @@ def handle_csrf_error(e):
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def slash():
|
def slash():
|
||||||
if session.get('is_logged_in'):
|
if session.get("is_logged_in"):
|
||||||
return redirect(url_for("selfservice"))
|
return redirect(url_for("selfservice"))
|
||||||
return redirect(url_for("login"))
|
return redirect(url_for("login"))
|
||||||
|
|
||||||
|
@ -57,11 +67,11 @@ def login():
|
||||||
session["username"] = escape_rdn(request.form["username"])
|
session["username"] = escape_rdn(request.form["username"])
|
||||||
session["password"] = request.form["password"]
|
session["password"] = request.form["password"]
|
||||||
|
|
||||||
flash("logged in")
|
flash(gettext("logged in"))
|
||||||
|
|
||||||
return redirect(url_for("selfservice"))
|
return redirect(url_for("selfservice"))
|
||||||
else:
|
else:
|
||||||
flash("username or password is wrong")
|
flash(gettext("username or password is wrong"))
|
||||||
|
|
||||||
return template(None, "login.html")
|
return template(None, "login.html")
|
||||||
|
|
||||||
|
@ -72,7 +82,7 @@ def logout():
|
||||||
session["username"] = ""
|
session["username"] = ""
|
||||||
session["password"] = ""
|
session["password"] = ""
|
||||||
|
|
||||||
flash("logged out")
|
flash(gettext("you have been logged out"))
|
||||||
|
|
||||||
return redirect(url_for("login"))
|
return redirect(url_for("login"))
|
||||||
|
|
||||||
|
@ -96,7 +106,7 @@ def selfservice(ldap):
|
||||||
"mail": request.form["mail"],
|
"mail": request.form["mail"],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
flash("data updated")
|
flash(gettext("user data was updated"))
|
||||||
except LDAPException as e:
|
except LDAPException as e:
|
||||||
app.logger.error(
|
app.logger.error(
|
||||||
"Updating {} failed: {}\n{}".format(
|
"Updating {} failed: {}\n{}".format(
|
||||||
|
@ -113,15 +123,15 @@ def selfservice(ldap):
|
||||||
request.form["current"],
|
request.form["current"],
|
||||||
):
|
):
|
||||||
validated = False
|
validated = False
|
||||||
flash("current password does not match")
|
flash(gettext("current password does not match the one stored"))
|
||||||
|
|
||||||
if request.form["new"] != request.form["repeat"]:
|
if request.form["new"] != request.form["repeat"]:
|
||||||
validated = False
|
validated = False
|
||||||
flash("new passwords do not match")
|
flash(gettext("new passwords do not match"))
|
||||||
|
|
||||||
if len(request.form["new"]) < 12:
|
if len(request.form["new"]) < 12:
|
||||||
validated = False
|
validated = False
|
||||||
flash("new password must be atleast 12 characters")
|
flash(gettext("new password must be atleast 12 characters long"))
|
||||||
|
|
||||||
if validated:
|
if validated:
|
||||||
try:
|
try:
|
||||||
|
@ -131,7 +141,7 @@ def selfservice(ldap):
|
||||||
request.form["new"],
|
request.form["new"],
|
||||||
)
|
)
|
||||||
session["password"] = request.form["new"]
|
session["password"] = request.form["new"]
|
||||||
flash("password changed")
|
flash(gettext("your password was changed"))
|
||||||
except LDAPException as e:
|
except LDAPException as e:
|
||||||
app.logger.error(
|
app.logger.error(
|
||||||
"Updating {} failed: {}".format(
|
"Updating {} failed: {}".format(
|
||||||
|
@ -184,7 +194,13 @@ def group_edit(ldap, ou):
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
flash(f"{request.form['remove']} was removed from {ou}")
|
flash(
|
||||||
|
gettext(
|
||||||
|
"%(user)s was removed from %(ou)s",
|
||||||
|
user=request.form["remove"],
|
||||||
|
ou=ou,
|
||||||
|
)
|
||||||
|
)
|
||||||
elif request.form.get("add"):
|
elif request.form.get("add"):
|
||||||
ldap.modify(
|
ldap.modify(
|
||||||
APP_CONFIG["template"]["group_dn"].format(ou),
|
APP_CONFIG["template"]["group_dn"].format(ou),
|
||||||
|
@ -199,7 +215,11 @@ def group_edit(ldap, ou):
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
flash(f"{request.form['add']} was added to {ou}")
|
flash(
|
||||||
|
gettext(
|
||||||
|
"%(user)s was added to %(ou)s", user=request.form["remove"], ou=ou
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return redirect(url_for("group_edit", ou=ou))
|
return redirect(url_for("group_edit", ou=ou))
|
||||||
|
|
||||||
|
|
3
ldap_frontend/babel.cfg
Normal file
3
ldap_frontend/babel.cfg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[python: **.py]
|
||||||
|
[jinja2: **/templates/**.html]
|
||||||
|
extensions=jinja2.ext.autoescape,jinja2.ext.with_
|
199
ldap_frontend/messages.pot
Normal file
199
ldap_frontend/messages.pot
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
# Translations template for PROJECT.
|
||||||
|
# Copyright (C) 2021 ORGANIZATION
|
||||||
|
# This file is distributed under the same license as the PROJECT project.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2021.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
|
"POT-Creation-Date: 2021-12-23 09:11+0100\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Generated-By: Babel 2.9.1\n"
|
||||||
|
|
||||||
|
#: __init__.py:40
|
||||||
|
msgid "CRSF validation error. For your own safety, you have been logged out."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: __init__.py:69
|
||||||
|
msgid "logged in"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: __init__.py:73
|
||||||
|
msgid "username or password is wrong"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: __init__.py:84
|
||||||
|
msgid "you have been logged out"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: __init__.py:108
|
||||||
|
msgid "user data was updated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: __init__.py:125
|
||||||
|
msgid "current password does not match the one stored"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: __init__.py:129
|
||||||
|
msgid "new passwords do not match"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: __init__.py:133
|
||||||
|
msgid "new password must be atleast 12 characters long"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: __init__.py:143
|
||||||
|
msgid "your password was changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: __init__.py:196
|
||||||
|
#, python-format
|
||||||
|
msgid "%(user)s was removed from %(ou)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: __init__.py:211
|
||||||
|
#, python-format
|
||||||
|
msgid "%(user)s was added to %(ou)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/login.html:2 templates/login.html:7 templates/login.html:19
|
||||||
|
msgid "Login"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/login.html:10
|
||||||
|
msgid "Username"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/login.html:15
|
||||||
|
msgid "Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/layout/default.html:23 templates/selfservice.html:2
|
||||||
|
msgid "self service"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:7
|
||||||
|
msgid "Edit User Data"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/members.html:7 templates/selfservice.html:10
|
||||||
|
msgid "uid"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:13
|
||||||
|
msgid "Contact an administrator if you want to change this."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:18
|
||||||
|
msgid "name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:21
|
||||||
|
msgid "This field gets adjusted automatically based on the fields below."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:26
|
||||||
|
msgid "surname"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:33
|
||||||
|
msgid "given name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:40
|
||||||
|
msgid "e-mail address"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:46
|
||||||
|
msgid "Update"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:53 templates/selfservice.html:77
|
||||||
|
msgid "change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:56
|
||||||
|
msgid "current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:63
|
||||||
|
msgid "new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:66
|
||||||
|
msgid "Your new password must be atleast 12 characters long."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/selfservice.html:71
|
||||||
|
msgid "repeat new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/list.html:2
|
||||||
|
msgid "group list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/list.html:7
|
||||||
|
msgid "group name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/list.html:8
|
||||||
|
msgid "group description"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/list.html:9
|
||||||
|
msgid "member?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/list.html:10
|
||||||
|
msgid "member count"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/members.html:2
|
||||||
|
#, python-format
|
||||||
|
msgid "group %(ou)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/members.html:8
|
||||||
|
msgid "cn"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/members.html:9
|
||||||
|
msgid "remove member"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/members.html:21
|
||||||
|
msgid "remove"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/members.html:31 templates/groups/members.html:45
|
||||||
|
msgid "add user to group"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/groups/members.html:37
|
||||||
|
msgid "select user"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/layout/default.html:26
|
||||||
|
msgid "groups"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/layout/default.html:30
|
||||||
|
msgid "Other Sites"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/layout/default.html:39
|
||||||
|
#, python-format
|
||||||
|
msgid "Signed in as <em>%(uid)s</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/layout/default.html:39
|
||||||
|
msgid "logout"
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
{% extends "layout/default.html" %}
|
{% extends "layout/default.html" %}
|
||||||
{% block title %}groups{% endblock %}
|
{% block title %}{% trans %}group list{% endtrans %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<table class="table table-hover align-middle">
|
<table class="table table-hover align-middle">
|
||||||
<thead class="table-light">
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">group name</th>
|
<th scope="col">{% trans %}group name{% endtrans %}</th>
|
||||||
<th scope="col">group description</th>
|
<th scope="col">{% trans %}group description{% endtrans %}</th>
|
||||||
<th scope="col">member?</th>
|
<th scope="col">{% trans %}member?{% endtrans %}</th>
|
||||||
<th scope="col">member count</th>
|
<th scope="col">{% trans %}member count{% endtrans %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{% extends "layout/default.html" %}
|
{% extends "layout/default.html" %}
|
||||||
{% block title %}group {{ ou }}{% endblock %}
|
{% block title %}{% trans ou=ou %}group {{ ou }}{% endtrans %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<table class="table table-hover align-middle">
|
<table class="table table-hover align-middle">
|
||||||
<thead class="table-light">
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">uid</th>
|
<th scope="col">{% trans %}uid{% endtrans %}</th>
|
||||||
<th scope="col">cn</th>
|
<th scope="col">{% trans %}cn{% endtrans %}</th>
|
||||||
<th scope="col">remove</th>
|
<th scope="col">{% trans %}remove member{% endtrans %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
<form action="{{ url_for("group_edit", ou=ou) }}" method="post">
|
<form action="{{ url_for("group_edit", ou=ou) }}" method="post">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
<input type="hidden" name="remove" value="{{ member["uid"] }}">
|
<input type="hidden" name="remove" value="{{ member["uid"] }}">
|
||||||
<input type="submit" value="remove" class="btn btn-danger">
|
<input type="submit" value="{% trans %}remove{% endtrans %}" class="btn btn-danger">
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -28,13 +28,13 @@
|
||||||
<form action="{{ url_for("group_edit", ou=ou) }}" method="post" class="row g-3 needs-validation">
|
<form action="{{ url_for("group_edit", ou=ou) }}" method="post" class="row g-3 needs-validation">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>add user to group</legend>
|
<legend>{% trans %}add user to group{% endtrans %}</legend>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="add" class="form-label col-sm-2">user</label>
|
<label for="add" class="form-label col-sm-2">user</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select name="add" id="add" class="form-select">
|
<select name="add" id="add" class="form-select">
|
||||||
<option value="" selected>select user ...</option>
|
<option value="" selected>{% trans %}select user{% endtrans %}</option>
|
||||||
{% for user in other_users|sort %}
|
{% for user in other_users|sort %}
|
||||||
<option value="{{ user["uid"] }}">{{ user["cn"] }} ({{ user["uid"] }})</option>
|
<option value="{{ user["uid"] }}">{{ user["cn"] }} ({{ user["uid"] }})</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="submit" value="add user" class="btn btn-primary mb-3"><br>
|
<input type="submit" value="{% trans %}add user to group{% endtrans %}" class="btn btn-primary mb-3"><br>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -20,16 +20,14 @@
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{{ url_for("selfservice") }}">self service</a>
|
<a class="nav-link" href="{{ url_for("selfservice") }}">{% trans %}self service{% endtrans %}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{{ url_for("groups") }}">groups</a>
|
<a class="nav-link" href="{{ url_for("groups") }}">{% trans %}groups{% endtrans %}</a>
|
||||||
</li>
|
</li>
|
||||||
{% if APP_CONFIG.external_links %}
|
{% if APP_CONFIG.external_links %}
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">{% trans %}Other Sites{% endtrans %}</a>
|
||||||
Other Sites
|
|
||||||
</a>
|
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||||
{% for text, link in APP_CONFIG.external_links.items()|sort %}
|
{% for text, link in APP_CONFIG.external_links.items()|sort %}
|
||||||
<a class="dropdown-item" href="{{ link }}">{{ text }}</a>
|
<a class="dropdown-item" href="{{ link }}">{{ text }}</a>
|
||||||
|
@ -38,7 +36,7 @@
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
<span class="navbar-text navbar-right">Signed in as <em>{{ CURRENT_USER["uid"] }}</em> - <a href="{{ url_for("logout") }}">logout</a></span>
|
<span class="navbar-text navbar-right">{% trans uid=CURRENT_USER["uid"] %}Signed in as <em>{{ uid }}</em>{% endtrans %} - <a href="{{ url_for("logout") }}">{% trans %}logout{% endtrans %}</a></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
{% extends "layout/default.html" %}
|
{% extends "layout/default.html" %}
|
||||||
|
{% block title %}{% trans %}Login{% endtrans %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form action="{{ url_for("login") }}" method="post">
|
<form action="{{ url_for("login") }}" method="post">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Login</legend>
|
<legend>{% trans %}Login{% endtrans %}</legend>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="username" class="form-label">Username</label>
|
<label for="username" class="form-label">{% trans %}Username{% endtrans %}</label>
|
||||||
<input type="text" name="username" id="username" required class="form-control">
|
<input type="text" name="username" id="username" required class="form-control">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="password" class="form-label">Password</label>
|
<label for="password" class="form-label">{% trans %}Password{% endtrans %}</label>
|
||||||
<input type="password" name="password" id="password" required class="form-control">
|
<input type="password" name="password" id="password" required class="form-control">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="submit" value="Login" class="btn btn-primary mb-3">
|
<input type="submit" value="{% trans %}Login{% endtrans %}" class="btn btn-primary mb-3">
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,79 +1,80 @@
|
||||||
{% extends "layout/default.html" %}
|
{% extends "layout/default.html" %}
|
||||||
{% block title %}self service{% endblock %}
|
{% block title %}{% trans %}self service{% endtrans %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form action="{{ url_for("selfservice") }}" method="post" class="row g-3 needs-validation">
|
<form action="{{ url_for("selfservice") }}" method="post" class="row g-3 needs-validation">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>user data</legend>
|
<legend>{% trans %}Edit User Data{% endtrans %}</legend>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="uid" class="form-label col-sm-2">uid</label>
|
<label for="uid" class="form-label col-sm-2">{% trans %}uid{% endtrans %}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" name="uid" id="uid" value="{{ CURRENT_USER["uid"]|e }}" disabled readonly class="form-control" aria-describedby="uidHelp">
|
<input type="text" name="uid" id="uid" value="{{ CURRENT_USER["uid"]|e }}" disabled readonly class="form-control" aria-describedby="uidHelp">
|
||||||
<div id="uidHelp" class="form-text">contact an administrator if you want to change this</div>
|
<div id="uidHelp" class="form-text">{% trans %}Contact an administrator if you want to change this.{% endtrans %}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="cn" class="form-label col-sm-2">common name</label>
|
<label for="cn" class="form-label col-sm-2">{% trans commonName %}name{% endtrans %}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" name="cn" id="cn" value="{{ CURRENT_USER["cn"]|e }}" disabled readonly class="form-control" aria-describedby="cnHelp">
|
<input type="text" name="cn" id="cn" value="{{ CURRENT_USER["cn"]|e }}" disabled readonly class="form-control" aria-describedby="cnHelp">
|
||||||
<div id="cnHelp" class="form-text">gets adjusted automatically</div>
|
<div id="cnHelp" class="form-text">{% trans %}This field gets adjusted automatically based on the fields below.{% endtrans %}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="sn" class="form-label col-sm-2">surname</label>
|
<label for="sn" class="form-label col-sm-2">{% trans sn %}surname{% endtrans %}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" name="sn" id="sn" value="{{ CURRENT_USER["sn"]|e }}" required class="form-control">
|
<input type="text" name="sn" id="sn" value="{{ CURRENT_USER["sn"]|e }}" required class="form-control">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="givenName" class="form-label col-sm-2">given name</label>
|
<label for="givenName" class="form-label col-sm-2">{% trans givenName %}given name{% endtrans %}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" name="givenName" id="givenName" value="{{ CURRENT_USER["givenName"]|e }}" required class="form-control">
|
<input type="text" name="givenName" id="givenName" value="{{ CURRENT_USER["givenName"]|e }}" required class="form-control">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="mail" class="form-label col-sm-2">email address</label>
|
<label for="mail" class="form-label col-sm-2">{% trans email %}e-mail address{% endtrans %}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="email" name="mail" id="mail" value="{{ CURRENT_USER["mail"]|e }}" required class="form-control">
|
<input type="email" name="mail" id="mail" value="{{ CURRENT_USER["mail"]|e }}" required class="form-control">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="submit" name="userdata" value="update" class="btn btn-primary mb-3"><br>
|
<input type="submit" name="userdata" value="{% trans %}Update{% endtrans %}" class="btn btn-primary mb-3"><br>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form action="{{ url_for("selfservice") }}" method="post">
|
<form action="{{ url_for("selfservice") }}" method="post">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>password</legend>
|
<legend>{% trans %}change password{% endtrans %}</legend>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="current" class="form-label col-sm-2">current password</label>
|
<label for="current" class="form-label col-sm-2">{% trans %}current password{% endtrans %}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="password" name="current" id="current" value="" class="form-control">
|
<input type="password" name="current" id="current" value="" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="new" class="form-label col-sm-2">new password</label>
|
<label for="new" class="form-label col-sm-2">{% trans %}new password{% endtrans %}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="password" name="new" id="new" value="" class="form-control">
|
<input type="password" name="new" id="new" value="" class="form-control" aria-describedby="newHelp">
|
||||||
|
<div id="newHelp" class="form-text">{% trans %}Your new password must be atleast 12 characters long.{% endtrans %}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="repeat" class="form-label col-sm-2">repeat new password</label>
|
<label for="repeat" class="form-label col-sm-2">{% trans %}repeat new password{% endtrans %}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="password" name="repeat" id="repeat" value="" class="form-control">
|
<input type="password" name="repeat" id="repeat" value="" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="submit" name="passwordchange" value="change password" class="btn btn-primary mb-3"><br>
|
<input type="submit" name="passwordchange" value="{% trans %}change password{% endtrans %}" class="btn btn-primary mb-3"><br>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
200
ldap_frontend/translations/de/LC_MESSAGES/messages.po
Normal file
200
ldap_frontend/translations/de/LC_MESSAGES/messages.po
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
# German translations for qzwi-ldap-frontend.
|
||||||
|
# Copyright (C) 2021 Franziska Kunsmann
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: qzwi-ldap-frontend\n"
|
||||||
|
"Report-Msgid-Bugs-To: qzwi@kunsmann.eu\n"
|
||||||
|
"POT-Creation-Date: 2021-12-23 09:11+0100\n"
|
||||||
|
"PO-Revision-Date: 2021-12-23 08:41+0100\n"
|
||||||
|
"Last-Translator: Franziska Kunsmann <qzwi@kunsmann.eu>\n"
|
||||||
|
"Language: de\n"
|
||||||
|
"Language-Team: de <LL@li.org>\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Generated-By: Babel 2.9.1\n"
|
||||||
|
|
||||||
|
#: __init__.py:40
|
||||||
|
msgid "CRSF validation error. For your own safety, you have been logged out."
|
||||||
|
msgstr ""
|
||||||
|
"Formularvalidierung fehlgeschlagen. Zu deiner Sicherheit wurdest du "
|
||||||
|
"abgemeldet."
|
||||||
|
|
||||||
|
#: __init__.py:69
|
||||||
|
msgid "logged in"
|
||||||
|
msgstr "Erfolgreich angemeldet"
|
||||||
|
|
||||||
|
#: __init__.py:73
|
||||||
|
msgid "username or password is wrong"
|
||||||
|
msgstr "Der eingegebene Benutzername existiert nicht oder das Passwort ist falsch."
|
||||||
|
|
||||||
|
#: __init__.py:84
|
||||||
|
msgid "you have been logged out"
|
||||||
|
msgstr "Du wurdest abgemeldet."
|
||||||
|
|
||||||
|
#: __init__.py:108
|
||||||
|
msgid "user data was updated"
|
||||||
|
msgstr "Die Benutzerdaten wurden geändert."
|
||||||
|
|
||||||
|
#: __init__.py:125
|
||||||
|
msgid "current password does not match the one stored"
|
||||||
|
msgstr "Das eingegebene Passwort stimmt nicht mit dem bisherigen überein."
|
||||||
|
|
||||||
|
#: __init__.py:129
|
||||||
|
msgid "new passwords do not match"
|
||||||
|
msgstr "Das neue Passwort stimmt nicht mit der Wiederholung überein."
|
||||||
|
|
||||||
|
#: __init__.py:133
|
||||||
|
msgid "new password must be atleast 12 characters long"
|
||||||
|
msgstr "Dein neues Passwort muss mindestens 12 Zeichen lang sein."
|
||||||
|
|
||||||
|
#: __init__.py:143
|
||||||
|
msgid "your password was changed"
|
||||||
|
msgstr "Dein Passwort wurde geändert."
|
||||||
|
|
||||||
|
#: __init__.py:196
|
||||||
|
#, python-format
|
||||||
|
msgid "%(user)s was removed from %(ou)s"
|
||||||
|
msgstr "%(user)s wurde aus %(ou)s entfernt."
|
||||||
|
|
||||||
|
#: __init__.py:211
|
||||||
|
#, python-format
|
||||||
|
msgid "%(user)s was added to %(ou)s"
|
||||||
|
msgstr "%(user)s wurde zu %(ou)s hinzugefügt."
|
||||||
|
|
||||||
|
#: templates/login.html:2 templates/login.html:7 templates/login.html:19
|
||||||
|
msgid "Login"
|
||||||
|
msgstr "Anmelden"
|
||||||
|
|
||||||
|
#: templates/login.html:10
|
||||||
|
msgid "Username"
|
||||||
|
msgstr "Benutzername"
|
||||||
|
|
||||||
|
#: templates/login.html:15
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Passwort"
|
||||||
|
|
||||||
|
#: templates/layout/default.html:23 templates/selfservice.html:2
|
||||||
|
msgid "self service"
|
||||||
|
msgstr "Daten ändern"
|
||||||
|
|
||||||
|
#: templates/selfservice.html:7
|
||||||
|
msgid "Edit User Data"
|
||||||
|
msgstr "Benutzer*innen-Daten ändern"
|
||||||
|
|
||||||
|
#: templates/groups/members.html:7 templates/selfservice.html:10
|
||||||
|
msgid "uid"
|
||||||
|
msgstr "Login-Name"
|
||||||
|
|
||||||
|
#: templates/selfservice.html:13
|
||||||
|
msgid "Contact an administrator if you want to change this."
|
||||||
|
msgstr "Kontaktiere einen Administrator, wenn du diesen Wert ändern möchtest."
|
||||||
|
|
||||||
|
#: templates/selfservice.html:18
|
||||||
|
msgid "name"
|
||||||
|
msgstr "Name"
|
||||||
|
|
||||||
|
#: templates/selfservice.html:21
|
||||||
|
msgid "This field gets adjusted automatically based on the fields below."
|
||||||
|
msgstr "Dieser Wert wird automatisch basierend auf den Feldern darunter geändert."
|
||||||
|
|
||||||
|
#: templates/selfservice.html:26
|
||||||
|
msgid "surname"
|
||||||
|
msgstr "Nachname"
|
||||||
|
|
||||||
|
#: templates/selfservice.html:33
|
||||||
|
msgid "given name"
|
||||||
|
msgstr "Vorname"
|
||||||
|
|
||||||
|
#: templates/selfservice.html:40
|
||||||
|
msgid "e-mail address"
|
||||||
|
msgstr "E-Mail-Adresse"
|
||||||
|
|
||||||
|
#: templates/selfservice.html:46
|
||||||
|
msgid "Update"
|
||||||
|
msgstr "Daten ändern"
|
||||||
|
|
||||||
|
#: templates/selfservice.html:53 templates/selfservice.html:77
|
||||||
|
msgid "change password"
|
||||||
|
msgstr "Passwort ändern"
|
||||||
|
|
||||||
|
#: templates/selfservice.html:56
|
||||||
|
msgid "current password"
|
||||||
|
msgstr "Aktuelles Passwort"
|
||||||
|
|
||||||
|
#: templates/selfservice.html:63
|
||||||
|
msgid "new password"
|
||||||
|
msgstr "Neues Passwort"
|
||||||
|
|
||||||
|
#: templates/selfservice.html:66
|
||||||
|
msgid "Your new password must be atleast 12 characters long."
|
||||||
|
msgstr "Dein neues Passwort muss mindestens 12 Zeichen lang sein."
|
||||||
|
|
||||||
|
#: templates/selfservice.html:71
|
||||||
|
msgid "repeat new password"
|
||||||
|
msgstr "Neues Passwort (Wiederholung)"
|
||||||
|
|
||||||
|
#: templates/groups/list.html:2
|
||||||
|
msgid "group list"
|
||||||
|
msgstr "Gruppen-Übersicht"
|
||||||
|
|
||||||
|
#: templates/groups/list.html:7
|
||||||
|
msgid "group name"
|
||||||
|
msgstr "Gruppen-Name"
|
||||||
|
|
||||||
|
#: templates/groups/list.html:8
|
||||||
|
msgid "group description"
|
||||||
|
msgstr "Gruppen-Beschreibung"
|
||||||
|
|
||||||
|
#: templates/groups/list.html:9
|
||||||
|
msgid "member?"
|
||||||
|
msgstr "Mitglied?"
|
||||||
|
|
||||||
|
#: templates/groups/list.html:10
|
||||||
|
msgid "member count"
|
||||||
|
msgstr "Anzahl der Mitglieder"
|
||||||
|
|
||||||
|
#: templates/groups/members.html:2
|
||||||
|
#, python-format
|
||||||
|
msgid "group %(ou)s"
|
||||||
|
msgstr "Gruppe %(ou)s"
|
||||||
|
|
||||||
|
#: templates/groups/members.html:8
|
||||||
|
msgid "cn"
|
||||||
|
msgstr "Name"
|
||||||
|
|
||||||
|
#: templates/groups/members.html:9
|
||||||
|
msgid "remove member"
|
||||||
|
msgstr "Mitglied entfernen"
|
||||||
|
|
||||||
|
#: templates/groups/members.html:21
|
||||||
|
msgid "remove"
|
||||||
|
msgstr "Entfernen"
|
||||||
|
|
||||||
|
#: templates/groups/members.html:31 templates/groups/members.html:45
|
||||||
|
msgid "add user to group"
|
||||||
|
msgstr "Mitglied zur Gruppe hinzufügen"
|
||||||
|
|
||||||
|
#: templates/groups/members.html:37
|
||||||
|
msgid "select user"
|
||||||
|
msgstr "Benutzer auswählen"
|
||||||
|
|
||||||
|
#: templates/layout/default.html:26
|
||||||
|
msgid "groups"
|
||||||
|
msgstr "Gruppen"
|
||||||
|
|
||||||
|
#: templates/layout/default.html:30
|
||||||
|
msgid "Other Sites"
|
||||||
|
msgstr "Links"
|
||||||
|
|
||||||
|
#: templates/layout/default.html:39
|
||||||
|
#, python-format
|
||||||
|
msgid "Signed in as <em>%(uid)s</em>"
|
||||||
|
msgstr "Angemeldet als <em>%(uid)s</em>\n"
|
||||||
|
|
||||||
|
#: templates/layout/default.html:39
|
||||||
|
msgid "logout"
|
||||||
|
msgstr "Abmelden"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
Babel==2.9.1
|
||||||
click==8.0.3
|
click==8.0.3
|
||||||
Flask==2.0.2
|
Flask==2.0.2
|
||||||
|
Flask-Babel==2.0.0
|
||||||
Flask-WTF==1.0.0
|
Flask-WTF==1.0.0
|
||||||
gunicorn==20.1.0
|
gunicorn==20.1.0
|
||||||
itsdangerous==2.0.1
|
itsdangerous==2.0.1
|
||||||
|
@ -7,5 +9,6 @@ Jinja2==3.0.3
|
||||||
ldap3==2.9.1
|
ldap3==2.9.1
|
||||||
MarkupSafe==2.0.1
|
MarkupSafe==2.0.1
|
||||||
pyasn1==0.4.8
|
pyasn1==0.4.8
|
||||||
|
pytz==2021.3
|
||||||
Werkzeug==2.0.2
|
Werkzeug==2.0.2
|
||||||
WTForms==3.0.0
|
WTForms==3.0.0
|
||||||
|
|
Loading…
Reference in a new issue