mirror of
https://github.com/lucaspalomodevelop/eventcally.git
synced 2026-03-13 00:07:22 +00:00
Merge pull request #474 from eventcally/issues/473
User.tos_accepted_at #473
This commit is contained in:
commit
b874550a64
@ -13,13 +13,13 @@ Cypress.Commands.add("logexec", (command) => {
|
||||
|
||||
Cypress.Commands.add("setup", () => {
|
||||
cy.logexec("flask test reset --seed");
|
||||
cy.logexec("flask user create test@test.de password --confirm");
|
||||
cy.logexec("flask user create test@test.de password --confirm --accept-tos");
|
||||
});
|
||||
|
||||
Cypress.Commands.add(
|
||||
"createUser",
|
||||
(email = "test@test.de", password = "password", admin = false) => {
|
||||
let cmd = 'flask user create "' + email + '" "' + password + '" --confirm';
|
||||
let cmd = 'flask user create "' + email + '" "' + password + '" --confirm --accept-tos';
|
||||
if (admin) {
|
||||
cmd += " --admin";
|
||||
}
|
||||
|
||||
103
messages.pot
103
messages.pot
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2023-05-09 22:22+0200\n"
|
||||
"POT-Creation-Date: 2023-05-11 11:19+0200\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"
|
||||
@ -229,21 +229,29 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:21 project/forms/admin_unit_member.py:14
|
||||
#: project/forms/admin.py:22
|
||||
msgid "Reset for all users"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:24
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:28 project/forms/admin_unit_member.py:14
|
||||
#: project/forms/admin_unit_member.py:34
|
||||
msgid "Roles"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:22 project/templates/admin/update_user.html:4
|
||||
#: project/forms/admin.py:29 project/templates/admin/update_user.html:4
|
||||
#: project/templates/admin/update_user.html:8
|
||||
msgid "Update user"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:26 project/templates/admin/delete_user.html:6
|
||||
#: project/forms/admin.py:33 project/templates/admin/delete_user.html:6
|
||||
msgid "Delete user"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:27 project/forms/admin_unit.py:53
|
||||
#: project/forms/admin.py:34 project/forms/admin_unit.py:53
|
||||
#: project/forms/admin_unit_member.py:12 project/forms/admin_unit_member.py:25
|
||||
#: project/forms/admin_unit_member.py:30 project/forms/event.py:107
|
||||
#: project/forms/event_suggestion.py:38 project/forms/organizer.py:33
|
||||
@ -255,60 +263,60 @@ msgstr ""
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:32
|
||||
#: project/forms/admin.py:39
|
||||
msgid "Incoming reference requests allowed"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:33
|
||||
#: project/forms/admin.py:40
|
||||
msgid ""
|
||||
"If set, other organizations can ask this organization to reference their "
|
||||
"event."
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:39
|
||||
#: project/forms/admin.py:46
|
||||
msgid "Suggestions enabled"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:40
|
||||
#: project/forms/admin.py:47
|
||||
msgid "If set, the organization can work with suggestions."
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:44
|
||||
#: project/forms/admin.py:51
|
||||
msgid "Create other organizations"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:45
|
||||
#: project/forms/admin.py:52
|
||||
msgid "If set, members of the organization can create other organizations."
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:51
|
||||
#: project/forms/admin.py:58
|
||||
msgid "Invite other organizations"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:52
|
||||
#: project/forms/admin.py:59
|
||||
msgid "If set, members of the organization can invite other organizations."
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:58
|
||||
#: project/forms/admin.py:65
|
||||
msgid "Verify other organizations"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:59
|
||||
#: project/forms/admin.py:66
|
||||
msgid "If set, members of the organization can verify other organizations."
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:64 project/templates/admin/update_admin_unit.html:4
|
||||
#: project/forms/admin.py:71 project/templates/admin/update_admin_unit.html:4
|
||||
#: project/templates/admin/update_admin_unit.html:8
|
||||
msgid "Update organization"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:68 project/templates/admin/delete_admin_unit.html:6
|
||||
#: project/forms/admin.py:75 project/templates/admin/delete_admin_unit.html:6
|
||||
#: project/templates/admin_unit/request_deletion.html:6
|
||||
#: project/templates/admin_unit/update.html:93
|
||||
msgid "Delete organization"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:69 project/forms/admin_unit.py:34
|
||||
#: project/forms/admin.py:76 project/forms/admin_unit.py:34
|
||||
#: project/forms/admin_unit.py:142 project/forms/admin_unit.py:147
|
||||
#: project/forms/admin_unit.py:152 project/forms/event.py:85
|
||||
#: project/forms/event.py:114 project/forms/event_place.py:30
|
||||
@ -323,27 +331,27 @@ msgstr ""
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:73 project/forms/admin.py:80
|
||||
#: project/forms/admin.py:80 project/forms/admin.py:87
|
||||
msgid "Recipient"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:75
|
||||
#: project/forms/admin.py:82
|
||||
msgid "Send test mail synchronously"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:82 project/forms/admin.py:88
|
||||
#: project/forms/admin.py:89 project/forms/admin.py:95
|
||||
msgid "Test recipient"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:83
|
||||
#: project/forms/admin.py:90
|
||||
msgid "All users with enabled newsletter setting"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:89
|
||||
#: project/forms/admin.py:96
|
||||
msgid "Message"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:90
|
||||
#: project/forms/admin.py:97
|
||||
msgid "Send newsletter"
|
||||
msgstr ""
|
||||
|
||||
@ -1243,6 +1251,10 @@ msgstr ""
|
||||
msgid "Deny"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/security.py:79
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/user.py:9 project/templates/admin/admin.html:31
|
||||
#: project/templates/admin/newsletter.html:4
|
||||
#: project/templates/admin/newsletter.html:93
|
||||
@ -1337,7 +1349,7 @@ msgstr ""
|
||||
#: project/templates/_macros.html:590 project/templates/_macros.html:633
|
||||
#: project/templates/_macros.html:765
|
||||
#: project/templates/admin/admin_units.html:36
|
||||
#: project/templates/admin/users.html:34
|
||||
#: project/templates/admin/users.html:36
|
||||
#: project/templates/manage/events.html:116
|
||||
#: project/templates/manage/members.html:35
|
||||
#: project/templates/manage/organizers.html:33
|
||||
@ -1725,7 +1737,7 @@ msgid "View"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/admin/admin_units.html:37
|
||||
#: project/templates/admin/users.html:35
|
||||
#: project/templates/admin/users.html:37
|
||||
#: project/templates/manage/events.html:117
|
||||
#: project/templates/manage/members.html:21
|
||||
#: project/templates/manage/members.html:36
|
||||
@ -1742,7 +1754,7 @@ msgstr ""
|
||||
msgid "User"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/admin/email.html:47 project/views/admin.py:144
|
||||
#: project/templates/admin/email.html:47 project/views/admin.py:165
|
||||
msgid "Mail sent successfully"
|
||||
msgstr ""
|
||||
|
||||
@ -1758,6 +1770,13 @@ msgstr ""
|
||||
msgid "Mails sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/admin/reset_tos_accepted.html:4
|
||||
#: project/templates/admin/reset_tos_accepted.html:8
|
||||
#: project/templates/admin/settings.html:28
|
||||
#: project/templates/admin/users.html:48
|
||||
msgid "Reset acceptance of terms of service and privacy"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/admin_unit/create.html:58
|
||||
#: project/templates/admin_unit/update.html:66
|
||||
#: project/templates/event/create.html:347
|
||||
@ -2293,6 +2312,10 @@ msgstr ""
|
||||
msgid "Register for free"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/user/accept_tos.html:6
|
||||
msgid "Confirmation required"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/user/request_deletion.html:8
|
||||
msgid ""
|
||||
"The account is not deleted immediately. After a period of time, the "
|
||||
@ -2319,43 +2342,43 @@ msgstr ""
|
||||
msgid "Preview"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:63
|
||||
#: project/views/admin.py:64
|
||||
msgid "Organization successfully updated"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:85 project/views/admin_unit.py:187
|
||||
#: project/views/admin.py:86 project/views/admin_unit.py:187
|
||||
#: project/views/admin_unit.py:220 project/views/manage.py:316
|
||||
msgid "Entered name does not match organization name"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:89
|
||||
#: project/views/admin.py:90
|
||||
msgid "Organization successfully deleted"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:113 project/views/manage.py:486
|
||||
#: project/views/user.py:41
|
||||
#: project/views/admin.py:134 project/views/manage.py:486
|
||||
#: project/views/user.py:63
|
||||
msgid "Settings successfully updated"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:133
|
||||
#: project/views/admin.py:154
|
||||
#, python-format
|
||||
msgid "Test mail from %(site_name)s"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:162
|
||||
#: project/views/admin.py:183
|
||||
#, python-format
|
||||
msgid "Newsletter from %(site_name)s"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:212
|
||||
#: project/views/admin.py:233
|
||||
msgid "User successfully updated"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:232
|
||||
#: project/views/admin.py:253
|
||||
msgid "Entered email does not match user email"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:236
|
||||
#: project/views/admin.py:257
|
||||
msgid "User successfully deleted"
|
||||
msgstr ""
|
||||
|
||||
@ -2576,17 +2599,17 @@ msgid ""
|
||||
"verified automatically."
|
||||
msgstr ""
|
||||
|
||||
#: project/views/user.py:85
|
||||
#: project/views/user.py:107
|
||||
msgid ""
|
||||
"You are administrator of at least one organization. Cancel your "
|
||||
"membership to delete your account."
|
||||
msgstr ""
|
||||
|
||||
#: project/views/user.py:92 project/views/user.py:119
|
||||
#: project/views/user.py:114 project/views/user.py:141
|
||||
msgid "Entered email does not match your email"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/user.py:138
|
||||
#: project/views/user.py:160
|
||||
msgid "User deletion requested"
|
||||
msgstr ""
|
||||
|
||||
|
||||
27
migrations/versions/becc71f97606_.py
Normal file
27
migrations/versions/becc71f97606_.py
Normal file
@ -0,0 +1,27 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: becc71f97606
|
||||
Revises: cceaf9b28134
|
||||
Create Date: 2023-05-10 14:25:57.157442
|
||||
|
||||
"""
|
||||
import sqlalchemy as sa
|
||||
import sqlalchemy_utils
|
||||
from alembic import op
|
||||
|
||||
from project import dbtypes
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "becc71f97606"
|
||||
down_revision = "cceaf9b28134"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column("user", sa.Column("tos_accepted_at", sa.DateTime(), nullable=True))
|
||||
op.execute("UPDATE public.user SET tos_accepted_at = CURRENT_TIMESTAMP;")
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_column("user", "tos_accepted_at")
|
||||
@ -1,6 +1,6 @@
|
||||
import logging
|
||||
import os
|
||||
from datetime import timedelta
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from flask import Flask
|
||||
from flask_babel import Babel
|
||||
@ -9,7 +9,7 @@ from flask_gzip import Gzip
|
||||
from flask_mail import Mail, email_dispatched
|
||||
from flask_migrate import Migrate
|
||||
from flask_qrcode import QRcode
|
||||
from flask_security import Security, SQLAlchemySessionUserDatastore
|
||||
from flask_security import Security, SQLAlchemySessionUserDatastore, user_registered
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_wtf.csrf import CSRFProtect
|
||||
from sqlalchemy import MetaData
|
||||
@ -228,6 +228,16 @@ security = Security(
|
||||
)
|
||||
app.session_interface = CustomSessionInterface()
|
||||
|
||||
|
||||
@user_registered.connect_via(app)
|
||||
def user_registered_sighandler(app, user, confirm_token, confirmation_token, form_data):
|
||||
if "accept_tos" in form_data and form_data["accept_tos"]:
|
||||
from project.services.user import set_user_accepted_tos
|
||||
|
||||
set_user_accepted_tos(user)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
# OAuth2
|
||||
from project.oauth2 import config_oauth
|
||||
|
||||
@ -276,9 +286,9 @@ from project.views import (
|
||||
reference_request,
|
||||
reference_request_review,
|
||||
root,
|
||||
user,
|
||||
widget,
|
||||
)
|
||||
from project.views import user as user_view
|
||||
from project.views import widget
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
app.run()
|
||||
|
||||
@ -35,7 +35,12 @@ from project.services.event_suggestion import insert_event_suggestion
|
||||
from project.services.oauth2_client import complete_oauth2_client
|
||||
from project.services.organizer import get_event_organizer, upsert_event_organizer
|
||||
from project.services.place import get_event_places, upsert_event_place
|
||||
from project.services.user import create_user, find_user_by_email, get_user
|
||||
from project.services.user import (
|
||||
create_user,
|
||||
find_user_by_email,
|
||||
get_user,
|
||||
set_user_accepted_tos,
|
||||
)
|
||||
|
||||
test_cli = AppGroup("test")
|
||||
|
||||
@ -61,13 +66,19 @@ def _get_default_organizer_id(admin_unit_id):
|
||||
|
||||
|
||||
def _create_user(
|
||||
email="test@test.de", password="MeinPasswortIstDasBeste", confirm=True
|
||||
email="test@test.de",
|
||||
password="MeinPasswortIstDasBeste",
|
||||
confirm=True,
|
||||
tos_accepted=True,
|
||||
):
|
||||
user = create_user(email, password)
|
||||
|
||||
if confirm:
|
||||
confirm_user(user)
|
||||
|
||||
if tos_accepted:
|
||||
set_user_accepted_tos(user)
|
||||
|
||||
db.session.commit()
|
||||
return user.id
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ from project.services.user import (
|
||||
add_admin_roles_to_user,
|
||||
create_user,
|
||||
find_user_by_email,
|
||||
set_user_accepted_tos,
|
||||
)
|
||||
|
||||
user_cli = AppGroup("user")
|
||||
@ -27,7 +28,8 @@ def add_admin_roles(email):
|
||||
@click.argument("password")
|
||||
@click.option("--confirm/--no-confirm", default=False)
|
||||
@click.option("--admin/--no-admin", default=False)
|
||||
def create(email, password, confirm, admin):
|
||||
@click.option("--accept-tos/--no-accept-tos", default=False)
|
||||
def create(email, password, confirm, admin, accept_tos):
|
||||
user = create_user(email, password)
|
||||
|
||||
if confirm:
|
||||
@ -36,6 +38,9 @@ def create(email, password, confirm, admin):
|
||||
if admin:
|
||||
add_admin_roles_to_user(email)
|
||||
|
||||
if accept_tos:
|
||||
set_user_accepted_tos(user)
|
||||
|
||||
db.session.commit()
|
||||
result = {"user_id": user.id}
|
||||
click.echo(json.dumps(result))
|
||||
|
||||
@ -17,6 +17,13 @@ class AdminSettingsForm(FlaskForm):
|
||||
submit = SubmitField(lazy_gettext("Save"))
|
||||
|
||||
|
||||
class ResetTosAceptedForm(FlaskForm):
|
||||
reset_for_users = BooleanField(
|
||||
lazy_gettext("Reset for all users"), validators=[DataRequired()]
|
||||
)
|
||||
submit = SubmitField(lazy_gettext("Reset"))
|
||||
|
||||
|
||||
class UpdateUserForm(FlaskForm):
|
||||
roles = MultiCheckboxField(lazy_gettext("Roles"))
|
||||
submit = SubmitField(lazy_gettext("Update user"))
|
||||
|
||||
@ -72,3 +72,12 @@ class ExtendedForgotPasswordForm(ForgotPasswordForm):
|
||||
class AuthorizeForm(FlaskForm):
|
||||
allow = SubmitField(lazy_gettext("Allow"))
|
||||
deny = SubmitField(lazy_gettext("Deny"))
|
||||
|
||||
|
||||
class AcceptTosForm(FlaskForm):
|
||||
accept_tos = BooleanField(validators=[DataRequired()])
|
||||
submit = SubmitField(lazy_gettext("Confirm"))
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(AcceptTosForm, self).__init__(**kwargs)
|
||||
self._fields["accept_tos"].label.text = get_accept_tos_markup()
|
||||
|
||||
@ -59,7 +59,10 @@ class User(db.Model, UserMixin):
|
||||
server_default="1",
|
||||
)
|
||||
)
|
||||
created_at = Column(DateTime, default=datetime.datetime.utcnow)
|
||||
tos_accepted_at = Column(
|
||||
DateTime(),
|
||||
nullable=True,
|
||||
)
|
||||
created_at = deferred(Column(DateTime, default=datetime.datetime.utcnow))
|
||||
deletion_requested_at = deferred(Column(DateTime, nullable=True))
|
||||
|
||||
|
||||
@ -1,11 +1,29 @@
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from flask import g, request
|
||||
from flask import g, redirect, request, url_for
|
||||
from flask_login.utils import encode_cookie
|
||||
from flask_security import current_user
|
||||
|
||||
from project import app
|
||||
|
||||
|
||||
@app.after_request
|
||||
def check_tos_accepted(response):
|
||||
if (
|
||||
response.status_code == 200
|
||||
and request.endpoint
|
||||
and not request.endpoint.startswith("api_")
|
||||
and not request.endpoint.startswith("widget_")
|
||||
and request.endpoint not in ["static", "user_accept_tos"]
|
||||
and current_user
|
||||
and current_user.is_authenticated
|
||||
and not current_user.tos_accepted_at
|
||||
):
|
||||
return redirect(url_for("user_accept_tos", next=request.url))
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@app.after_request
|
||||
def set_manage_admin_unit_cookie(response):
|
||||
admin_unit = getattr(g, "manage_admin_unit", None)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
from sqlalchemy import exists, func
|
||||
from sqlalchemy import exists, func, update
|
||||
|
||||
from project import db
|
||||
from project.models import Settings
|
||||
from project.models import Settings, User
|
||||
|
||||
|
||||
def upsert_settings():
|
||||
@ -17,3 +17,8 @@ def has_tos():
|
||||
return db.session.scalar(
|
||||
exists().where(func.coalesce(Settings.tos, "") != "").select()
|
||||
)
|
||||
|
||||
|
||||
def reset_tos_accepted_for_users():
|
||||
db.session.execute(update(User).values(tos_accepted_at=None))
|
||||
db.session.commit()
|
||||
|
||||
@ -122,3 +122,7 @@ def is_user_admin_member(user: User) -> bool:
|
||||
).first()
|
||||
is not None
|
||||
)
|
||||
|
||||
|
||||
def set_user_accepted_tos(user: User):
|
||||
user.tos_accepted_at = datetime.datetime.utcnow()
|
||||
|
||||
16
project/templates/admin/reset_tos_accepted.html
Normal file
16
project/templates/admin/reset_tos_accepted.html
Normal file
@ -0,0 +1,16 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_field_with_errors, render_field %}
|
||||
{%- block title -%}
|
||||
{{ _('Reset acceptance of terms of service and privacy') }}
|
||||
{%- endblock -%}
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ _('Reset acceptance of terms of service and privacy') }}</h1>
|
||||
|
||||
<form action="" method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
{{ render_field_with_errors(form.reset_for_users, ri="checkbox") }}
|
||||
{{ render_field(form.submit) }}
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
@ -24,4 +24,8 @@
|
||||
{{ render_field(form.submit) }}
|
||||
</form>
|
||||
|
||||
<div class="my-4">
|
||||
<a class="btn btn-outline-danger m-1" href="{{ url_for('admin_reset_tos_accepted') }}" role="button">{{ _('Reset acceptance of terms of service and privacy') }}…</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -19,6 +19,7 @@
|
||||
<th>{{ _('Email') }}</th>
|
||||
<th>created_at</th>
|
||||
<th>confirmed_at</th>
|
||||
<th>tos_accepted_at</th>
|
||||
<th>deletion_requested_at</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@ -29,6 +30,7 @@
|
||||
<td>{{ user.email }}</td>
|
||||
<td>{% if user.created_at %}{{ user.created_at | dateformat }}{% endif %}</td>
|
||||
<td>{% if user.confirmed_at %}{{ user.confirmed_at | dateformat }}{% endif %}</td>
|
||||
<td>{% if user.tos_accepted_at %}{{ user.tos_accepted_at | dateformat }}{% endif %}</td>
|
||||
<td>{% if user.deletion_requested_at %}{{ user.deletion_requested_at | dateformat }}{% endif %}</td>
|
||||
<td>
|
||||
<a href="{{ url_for('admin_user_update', id=user.id) }}">{{ _('Edit') }}</a>
|
||||
@ -42,4 +44,9 @@
|
||||
|
||||
<div class="my-4">{{ render_pagination(pagination) }}</div>
|
||||
|
||||
<div class="my-4">
|
||||
<a class="btn btn-outline-danger m-1" href="{{ url_for('admin_reset_tos_accepted') }}" role="button">{{ _('Reset acceptance of terms of service and privacy') }}…</a>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
22
project/templates/user/accept_tos.html
Normal file
22
project/templates/user/accept_tos.html
Normal file
@ -0,0 +1,22 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_field %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ _('Confirmation required') }}</h1>
|
||||
<div>
|
||||
<form action="" method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="form-group form-check">
|
||||
<div class="input-group">
|
||||
{{ form.accept_tos(class="form-check-input")|safe }}
|
||||
{{ form.accept_tos.label(class="form-check-label") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ render_field(form.submit) }}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
Binary file not shown.
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2023-05-09 22:22+0200\n"
|
||||
"POT-Creation-Date: 2023-05-11 11:19+0200\n"
|
||||
"PO-Revision-Date: 2020-06-07 18:51+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: de\n"
|
||||
@ -230,21 +230,29 @@ msgstr "Startseite"
|
||||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
|
||||
#: project/forms/admin.py:21 project/forms/admin_unit_member.py:14
|
||||
#: project/forms/admin.py:22
|
||||
msgid "Reset for all users"
|
||||
msgstr "Für alle Nutzer zurücksetzen"
|
||||
|
||||
#: project/forms/admin.py:24
|
||||
msgid "Reset"
|
||||
msgstr "Zurücksetzen"
|
||||
|
||||
#: project/forms/admin.py:28 project/forms/admin_unit_member.py:14
|
||||
#: project/forms/admin_unit_member.py:34
|
||||
msgid "Roles"
|
||||
msgstr "Rollen"
|
||||
|
||||
#: project/forms/admin.py:22 project/templates/admin/update_user.html:4
|
||||
#: project/forms/admin.py:29 project/templates/admin/update_user.html:4
|
||||
#: project/templates/admin/update_user.html:8
|
||||
msgid "Update user"
|
||||
msgstr "Nutzer aktualisieren"
|
||||
|
||||
#: project/forms/admin.py:26 project/templates/admin/delete_user.html:6
|
||||
#: project/forms/admin.py:33 project/templates/admin/delete_user.html:6
|
||||
msgid "Delete user"
|
||||
msgstr "Nutzer löschen"
|
||||
|
||||
#: project/forms/admin.py:27 project/forms/admin_unit.py:53
|
||||
#: project/forms/admin.py:34 project/forms/admin_unit.py:53
|
||||
#: project/forms/admin_unit_member.py:12 project/forms/admin_unit_member.py:25
|
||||
#: project/forms/admin_unit_member.py:30 project/forms/event.py:107
|
||||
#: project/forms/event_suggestion.py:38 project/forms/organizer.py:33
|
||||
@ -256,11 +264,11 @@ msgstr "Nutzer löschen"
|
||||
msgid "Email"
|
||||
msgstr "Email"
|
||||
|
||||
#: project/forms/admin.py:32
|
||||
#: project/forms/admin.py:39
|
||||
msgid "Incoming reference requests allowed"
|
||||
msgstr "Eingehende Empfehlungsanfragen erlauben"
|
||||
|
||||
#: project/forms/admin.py:33
|
||||
#: project/forms/admin.py:40
|
||||
msgid ""
|
||||
"If set, other organizations can ask this organization to reference their "
|
||||
"event."
|
||||
@ -268,56 +276,56 @@ msgstr ""
|
||||
"Wenn gesetzt, können andere Organisationen diese Organisation bitten, "
|
||||
"deren Veranstaltungen zu empfehlen."
|
||||
|
||||
#: project/forms/admin.py:39
|
||||
#: project/forms/admin.py:46
|
||||
msgid "Suggestions enabled"
|
||||
msgstr "Vorschläge aktiv"
|
||||
|
||||
#: project/forms/admin.py:40
|
||||
#: project/forms/admin.py:47
|
||||
msgid "If set, the organization can work with suggestions."
|
||||
msgstr "Wenn gesetzt, kann die Organisation mit Vorschlägen arbeiten."
|
||||
|
||||
#: project/forms/admin.py:44
|
||||
#: project/forms/admin.py:51
|
||||
msgid "Create other organizations"
|
||||
msgstr "Andere Organisationen erstellen"
|
||||
|
||||
#: project/forms/admin.py:45
|
||||
#: project/forms/admin.py:52
|
||||
msgid "If set, members of the organization can create other organizations."
|
||||
msgstr ""
|
||||
"Wenn gesetzt, können Mitglieder der Organisation andere Organisationen "
|
||||
"erstellen."
|
||||
|
||||
#: project/forms/admin.py:51
|
||||
#: project/forms/admin.py:58
|
||||
msgid "Invite other organizations"
|
||||
msgstr "Andere Organisationen einladen"
|
||||
|
||||
#: project/forms/admin.py:52
|
||||
#: project/forms/admin.py:59
|
||||
msgid "If set, members of the organization can invite other organizations."
|
||||
msgstr ""
|
||||
"Wenn gesetzt, können Mitglieder der Organisation andere Organisationen "
|
||||
"einladen."
|
||||
|
||||
#: project/forms/admin.py:58
|
||||
#: project/forms/admin.py:65
|
||||
msgid "Verify other organizations"
|
||||
msgstr "Andere Organisationen verifizieren"
|
||||
|
||||
#: project/forms/admin.py:59
|
||||
#: project/forms/admin.py:66
|
||||
msgid "If set, members of the organization can verify other organizations."
|
||||
msgstr ""
|
||||
"Wenn gesetzt, können Mitglieder der Organisation andere Organisationen "
|
||||
"verifizieren."
|
||||
|
||||
#: project/forms/admin.py:64 project/templates/admin/update_admin_unit.html:4
|
||||
#: project/forms/admin.py:71 project/templates/admin/update_admin_unit.html:4
|
||||
#: project/templates/admin/update_admin_unit.html:8
|
||||
msgid "Update organization"
|
||||
msgstr "Organisation aktualisieren"
|
||||
|
||||
#: project/forms/admin.py:68 project/templates/admin/delete_admin_unit.html:6
|
||||
#: project/forms/admin.py:75 project/templates/admin/delete_admin_unit.html:6
|
||||
#: project/templates/admin_unit/request_deletion.html:6
|
||||
#: project/templates/admin_unit/update.html:93
|
||||
msgid "Delete organization"
|
||||
msgstr "Organisation löschen"
|
||||
|
||||
#: project/forms/admin.py:69 project/forms/admin_unit.py:34
|
||||
#: project/forms/admin.py:76 project/forms/admin_unit.py:34
|
||||
#: project/forms/admin_unit.py:142 project/forms/admin_unit.py:147
|
||||
#: project/forms/admin_unit.py:152 project/forms/event.py:85
|
||||
#: project/forms/event.py:114 project/forms/event_place.py:30
|
||||
@ -332,27 +340,27 @@ msgstr "Organisation löschen"
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: project/forms/admin.py:73 project/forms/admin.py:80
|
||||
#: project/forms/admin.py:80 project/forms/admin.py:87
|
||||
msgid "Recipient"
|
||||
msgstr "Empfänger"
|
||||
|
||||
#: project/forms/admin.py:75
|
||||
#: project/forms/admin.py:82
|
||||
msgid "Send test mail synchronously"
|
||||
msgstr "Test-Mail synchron senden"
|
||||
|
||||
#: project/forms/admin.py:82 project/forms/admin.py:88
|
||||
#: project/forms/admin.py:89 project/forms/admin.py:95
|
||||
msgid "Test recipient"
|
||||
msgstr "Test-Empfänger"
|
||||
|
||||
#: project/forms/admin.py:83
|
||||
#: project/forms/admin.py:90
|
||||
msgid "All users with enabled newsletter setting"
|
||||
msgstr "Alle Nutzer mit aktiviertem Newsletter"
|
||||
|
||||
#: project/forms/admin.py:89
|
||||
#: project/forms/admin.py:96
|
||||
msgid "Message"
|
||||
msgstr "Nachricht"
|
||||
|
||||
#: project/forms/admin.py:90
|
||||
#: project/forms/admin.py:97
|
||||
msgid "Send newsletter"
|
||||
msgstr "Newsletter senden"
|
||||
|
||||
@ -561,9 +569,8 @@ msgstr ""
|
||||
#, python-format
|
||||
msgid "I read and accept %(privacy_open)sPrivacy%(privacy_close)s."
|
||||
msgstr ""
|
||||
"Ich habe die "
|
||||
"%(privacy_open)sDatenschutzerklärung%(privacy_close)s gelesen und "
|
||||
"akzeptiere diese."
|
||||
"Ich habe die %(privacy_open)sDatenschutzerklärung%(privacy_close)s "
|
||||
"gelesen und akzeptiere diese."
|
||||
|
||||
#: project/forms/common.py:95
|
||||
msgid "0 (Little relevant)"
|
||||
@ -1301,6 +1308,10 @@ msgstr "Erlauben"
|
||||
msgid "Deny"
|
||||
msgstr "Ablehnen"
|
||||
|
||||
#: project/forms/security.py:79
|
||||
msgid "Confirm"
|
||||
msgstr "Bestätigen"
|
||||
|
||||
#: project/forms/user.py:9 project/templates/admin/admin.html:31
|
||||
#: project/templates/admin/newsletter.html:4
|
||||
#: project/templates/admin/newsletter.html:93
|
||||
@ -1397,7 +1408,7 @@ msgstr "Merkzettel"
|
||||
#: project/templates/_macros.html:590 project/templates/_macros.html:633
|
||||
#: project/templates/_macros.html:765
|
||||
#: project/templates/admin/admin_units.html:36
|
||||
#: project/templates/admin/users.html:34
|
||||
#: project/templates/admin/users.html:36
|
||||
#: project/templates/manage/events.html:116
|
||||
#: project/templates/manage/members.html:35
|
||||
#: project/templates/manage/organizers.html:33
|
||||
@ -1785,7 +1796,7 @@ msgid "View"
|
||||
msgstr "Anzeigen"
|
||||
|
||||
#: project/templates/admin/admin_units.html:37
|
||||
#: project/templates/admin/users.html:35
|
||||
#: project/templates/admin/users.html:37
|
||||
#: project/templates/manage/events.html:117
|
||||
#: project/templates/manage/members.html:21
|
||||
#: project/templates/manage/members.html:36
|
||||
@ -1802,7 +1813,7 @@ msgstr "Löschen"
|
||||
msgid "User"
|
||||
msgstr "Nutzer"
|
||||
|
||||
#: project/templates/admin/email.html:47 project/views/admin.py:144
|
||||
#: project/templates/admin/email.html:47 project/views/admin.py:165
|
||||
msgid "Mail sent successfully"
|
||||
msgstr "Mail erfolgreich gesendet"
|
||||
|
||||
@ -1818,6 +1829,13 @@ msgstr "Test-Mail asynchron senden"
|
||||
msgid "Mails sent successfully"
|
||||
msgstr "Mails erfolgreich gesendet"
|
||||
|
||||
#: project/templates/admin/reset_tos_accepted.html:4
|
||||
#: project/templates/admin/reset_tos_accepted.html:8
|
||||
#: project/templates/admin/settings.html:28
|
||||
#: project/templates/admin/users.html:48
|
||||
msgid "Reset acceptance of terms of service and privacy"
|
||||
msgstr "Akzeptanz der Nutzungsbedingungen und des Datenschutzes zurücksetzen"
|
||||
|
||||
#: project/templates/admin_unit/create.html:58
|
||||
#: project/templates/admin_unit/update.html:66
|
||||
#: project/templates/event/create.html:347
|
||||
@ -2366,6 +2384,10 @@ msgstr "Du hast noch keinen Account? Kein Problem!"
|
||||
msgid "Register for free"
|
||||
msgstr "Kostenlos registrieren"
|
||||
|
||||
#: project/templates/user/accept_tos.html:6
|
||||
msgid "Confirmation required"
|
||||
msgstr "Bestätigung erforderlich"
|
||||
|
||||
#: project/templates/user/request_deletion.html:8
|
||||
msgid ""
|
||||
"The account is not deleted immediately. After a period of time, the "
|
||||
@ -2394,43 +2416,43 @@ msgstr "Optionale Details"
|
||||
msgid "Preview"
|
||||
msgstr "Vorschau"
|
||||
|
||||
#: project/views/admin.py:63
|
||||
#: project/views/admin.py:64
|
||||
msgid "Organization successfully updated"
|
||||
msgstr "Organisation erfolgreich aktualisiert"
|
||||
|
||||
#: project/views/admin.py:85 project/views/admin_unit.py:187
|
||||
#: project/views/admin.py:86 project/views/admin_unit.py:187
|
||||
#: project/views/admin_unit.py:220 project/views/manage.py:316
|
||||
msgid "Entered name does not match organization name"
|
||||
msgstr "Der eingegebene Name entspricht nicht dem Namen der Organisation"
|
||||
|
||||
#: project/views/admin.py:89
|
||||
#: project/views/admin.py:90
|
||||
msgid "Organization successfully deleted"
|
||||
msgstr "Organisation erfolgreich gelöscht"
|
||||
|
||||
#: project/views/admin.py:113 project/views/manage.py:486
|
||||
#: project/views/user.py:41
|
||||
#: project/views/admin.py:134 project/views/manage.py:486
|
||||
#: project/views/user.py:63
|
||||
msgid "Settings successfully updated"
|
||||
msgstr "Einstellungen erfolgreich aktualisiert"
|
||||
|
||||
#: project/views/admin.py:133
|
||||
#: project/views/admin.py:154
|
||||
#, python-format
|
||||
msgid "Test mail from %(site_name)s"
|
||||
msgstr "Test-Mail von %(site_name)s"
|
||||
|
||||
#: project/views/admin.py:162
|
||||
#: project/views/admin.py:183
|
||||
#, python-format
|
||||
msgid "Newsletter from %(site_name)s"
|
||||
msgstr "Newsletter von %(site_name)s"
|
||||
|
||||
#: project/views/admin.py:212
|
||||
#: project/views/admin.py:233
|
||||
msgid "User successfully updated"
|
||||
msgstr "Nutzer erfolgreich aktualisiert"
|
||||
|
||||
#: project/views/admin.py:232
|
||||
#: project/views/admin.py:253
|
||||
msgid "Entered email does not match user email"
|
||||
msgstr "Die eingegebene Email passt nicht zur Email des Nutzers"
|
||||
|
||||
#: project/views/admin.py:236
|
||||
#: project/views/admin.py:257
|
||||
msgid "User successfully deleted"
|
||||
msgstr "Nutzer erfolgreich gelöscht"
|
||||
|
||||
@ -2660,7 +2682,7 @@ msgstr ""
|
||||
"Ob alle zukünftigen Empfehlungsanfragen von %(admin_unit_name)s "
|
||||
"automatisch verifiziert werden sollen."
|
||||
|
||||
#: project/views/user.py:85
|
||||
#: project/views/user.py:107
|
||||
msgid ""
|
||||
"You are administrator of at least one organization. Cancel your "
|
||||
"membership to delete your account."
|
||||
@ -2668,11 +2690,11 @@ msgstr ""
|
||||
"Du bist Administrator von mindestens einer Organisation. Beende deine "
|
||||
"Mitgliedschaft, um deinen Account zu löschen."
|
||||
|
||||
#: project/views/user.py:92 project/views/user.py:119
|
||||
#: project/views/user.py:114 project/views/user.py:141
|
||||
msgid "Entered email does not match your email"
|
||||
msgstr "Die eingegebene Email entspricht nicht deiner Email"
|
||||
|
||||
#: project/views/user.py:138
|
||||
#: project/views/user.py:160
|
||||
msgid "User deletion requested"
|
||||
msgstr "Löschung des Nutzers beantragt"
|
||||
|
||||
|
||||
Binary file not shown.
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2023-05-09 22:22+0200\n"
|
||||
"POT-Creation-Date: 2023-05-11 11:19+0200\n"
|
||||
"PO-Revision-Date: 2021-04-30 15:04+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: en\n"
|
||||
@ -230,21 +230,29 @@ msgstr ""
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:21 project/forms/admin_unit_member.py:14
|
||||
#: project/forms/admin.py:22
|
||||
msgid "Reset for all users"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:24
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:28 project/forms/admin_unit_member.py:14
|
||||
#: project/forms/admin_unit_member.py:34
|
||||
msgid "Roles"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:22 project/templates/admin/update_user.html:4
|
||||
#: project/forms/admin.py:29 project/templates/admin/update_user.html:4
|
||||
#: project/templates/admin/update_user.html:8
|
||||
msgid "Update user"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:26 project/templates/admin/delete_user.html:6
|
||||
#: project/forms/admin.py:33 project/templates/admin/delete_user.html:6
|
||||
msgid "Delete user"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:27 project/forms/admin_unit.py:53
|
||||
#: project/forms/admin.py:34 project/forms/admin_unit.py:53
|
||||
#: project/forms/admin_unit_member.py:12 project/forms/admin_unit_member.py:25
|
||||
#: project/forms/admin_unit_member.py:30 project/forms/event.py:107
|
||||
#: project/forms/event_suggestion.py:38 project/forms/organizer.py:33
|
||||
@ -256,60 +264,60 @@ msgstr ""
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:32
|
||||
#: project/forms/admin.py:39
|
||||
msgid "Incoming reference requests allowed"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:33
|
||||
#: project/forms/admin.py:40
|
||||
msgid ""
|
||||
"If set, other organizations can ask this organization to reference their "
|
||||
"event."
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:39
|
||||
#: project/forms/admin.py:46
|
||||
msgid "Suggestions enabled"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:40
|
||||
#: project/forms/admin.py:47
|
||||
msgid "If set, the organization can work with suggestions."
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:44
|
||||
#: project/forms/admin.py:51
|
||||
msgid "Create other organizations"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:45
|
||||
#: project/forms/admin.py:52
|
||||
msgid "If set, members of the organization can create other organizations."
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:51
|
||||
#: project/forms/admin.py:58
|
||||
msgid "Invite other organizations"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:52
|
||||
#: project/forms/admin.py:59
|
||||
msgid "If set, members of the organization can invite other organizations."
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:58
|
||||
#: project/forms/admin.py:65
|
||||
msgid "Verify other organizations"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:59
|
||||
#: project/forms/admin.py:66
|
||||
msgid "If set, members of the organization can verify other organizations."
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:64 project/templates/admin/update_admin_unit.html:4
|
||||
#: project/forms/admin.py:71 project/templates/admin/update_admin_unit.html:4
|
||||
#: project/templates/admin/update_admin_unit.html:8
|
||||
msgid "Update organization"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:68 project/templates/admin/delete_admin_unit.html:6
|
||||
#: project/forms/admin.py:75 project/templates/admin/delete_admin_unit.html:6
|
||||
#: project/templates/admin_unit/request_deletion.html:6
|
||||
#: project/templates/admin_unit/update.html:93
|
||||
msgid "Delete organization"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:69 project/forms/admin_unit.py:34
|
||||
#: project/forms/admin.py:76 project/forms/admin_unit.py:34
|
||||
#: project/forms/admin_unit.py:142 project/forms/admin_unit.py:147
|
||||
#: project/forms/admin_unit.py:152 project/forms/event.py:85
|
||||
#: project/forms/event.py:114 project/forms/event_place.py:30
|
||||
@ -324,27 +332,27 @@ msgstr ""
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:73 project/forms/admin.py:80
|
||||
#: project/forms/admin.py:80 project/forms/admin.py:87
|
||||
msgid "Recipient"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:75
|
||||
#: project/forms/admin.py:82
|
||||
msgid "Send test mail synchronously"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:82 project/forms/admin.py:88
|
||||
#: project/forms/admin.py:89 project/forms/admin.py:95
|
||||
msgid "Test recipient"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:83
|
||||
#: project/forms/admin.py:90
|
||||
msgid "All users with enabled newsletter setting"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:89
|
||||
#: project/forms/admin.py:96
|
||||
msgid "Message"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/admin.py:90
|
||||
#: project/forms/admin.py:97
|
||||
msgid "Send newsletter"
|
||||
msgstr ""
|
||||
|
||||
@ -1251,6 +1259,10 @@ msgstr ""
|
||||
msgid "Deny"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/security.py:79
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#: project/forms/user.py:9 project/templates/admin/admin.html:31
|
||||
#: project/templates/admin/newsletter.html:4
|
||||
#: project/templates/admin/newsletter.html:93
|
||||
@ -1345,7 +1357,7 @@ msgstr ""
|
||||
#: project/templates/_macros.html:590 project/templates/_macros.html:633
|
||||
#: project/templates/_macros.html:765
|
||||
#: project/templates/admin/admin_units.html:36
|
||||
#: project/templates/admin/users.html:34
|
||||
#: project/templates/admin/users.html:36
|
||||
#: project/templates/manage/events.html:116
|
||||
#: project/templates/manage/members.html:35
|
||||
#: project/templates/manage/organizers.html:33
|
||||
@ -1733,7 +1745,7 @@ msgid "View"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/admin/admin_units.html:37
|
||||
#: project/templates/admin/users.html:35
|
||||
#: project/templates/admin/users.html:37
|
||||
#: project/templates/manage/events.html:117
|
||||
#: project/templates/manage/members.html:21
|
||||
#: project/templates/manage/members.html:36
|
||||
@ -1750,7 +1762,7 @@ msgstr ""
|
||||
msgid "User"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/admin/email.html:47 project/views/admin.py:144
|
||||
#: project/templates/admin/email.html:47 project/views/admin.py:165
|
||||
msgid "Mail sent successfully"
|
||||
msgstr ""
|
||||
|
||||
@ -1766,6 +1778,13 @@ msgstr ""
|
||||
msgid "Mails sent successfully"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/admin/reset_tos_accepted.html:4
|
||||
#: project/templates/admin/reset_tos_accepted.html:8
|
||||
#: project/templates/admin/settings.html:28
|
||||
#: project/templates/admin/users.html:48
|
||||
msgid "Reset acceptance of terms of service and privacy"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/admin_unit/create.html:58
|
||||
#: project/templates/admin_unit/update.html:66
|
||||
#: project/templates/event/create.html:347
|
||||
@ -2301,6 +2320,10 @@ msgstr ""
|
||||
msgid "Register for free"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/user/accept_tos.html:6
|
||||
msgid "Confirmation required"
|
||||
msgstr ""
|
||||
|
||||
#: project/templates/user/request_deletion.html:8
|
||||
msgid ""
|
||||
"The account is not deleted immediately. After a period of time, the "
|
||||
@ -2327,43 +2350,43 @@ msgstr ""
|
||||
msgid "Preview"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:63
|
||||
#: project/views/admin.py:64
|
||||
msgid "Organization successfully updated"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:85 project/views/admin_unit.py:187
|
||||
#: project/views/admin.py:86 project/views/admin_unit.py:187
|
||||
#: project/views/admin_unit.py:220 project/views/manage.py:316
|
||||
msgid "Entered name does not match organization name"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:89
|
||||
#: project/views/admin.py:90
|
||||
msgid "Organization successfully deleted"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:113 project/views/manage.py:486
|
||||
#: project/views/user.py:41
|
||||
#: project/views/admin.py:134 project/views/manage.py:486
|
||||
#: project/views/user.py:63
|
||||
msgid "Settings successfully updated"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:133
|
||||
#: project/views/admin.py:154
|
||||
#, python-format
|
||||
msgid "Test mail from %(site_name)s"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:162
|
||||
#: project/views/admin.py:183
|
||||
#, python-format
|
||||
msgid "Newsletter from %(site_name)s"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:212
|
||||
#: project/views/admin.py:233
|
||||
msgid "User successfully updated"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:232
|
||||
#: project/views/admin.py:253
|
||||
msgid "Entered email does not match user email"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/admin.py:236
|
||||
#: project/views/admin.py:257
|
||||
msgid "User successfully deleted"
|
||||
msgstr ""
|
||||
|
||||
@ -2584,17 +2607,17 @@ msgid ""
|
||||
"verified automatically."
|
||||
msgstr ""
|
||||
|
||||
#: project/views/user.py:85
|
||||
#: project/views/user.py:107
|
||||
msgid ""
|
||||
"You are administrator of at least one organization. Cancel your "
|
||||
"membership to delete your account."
|
||||
msgstr ""
|
||||
|
||||
#: project/views/user.py:92 project/views/user.py:119
|
||||
#: project/views/user.py:114 project/views/user.py:141
|
||||
msgid "Entered email does not match your email"
|
||||
msgstr ""
|
||||
|
||||
#: project/views/user.py:138
|
||||
#: project/views/user.py:160
|
||||
msgid "User deletion requested"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ from project.forms.admin import (
|
||||
AdminTestEmailForm,
|
||||
DeleteAdminUnitForm,
|
||||
DeleteUserForm,
|
||||
ResetTosAceptedForm,
|
||||
UpdateAdminUnitForm,
|
||||
UpdateUserForm,
|
||||
)
|
||||
@ -99,6 +100,26 @@ def admin_admin_unit_delete(id):
|
||||
)
|
||||
|
||||
|
||||
@app.route("/admin/reset-tos-accepted", methods=("GET", "POST"))
|
||||
@roles_required("admin")
|
||||
def admin_reset_tos_accepted():
|
||||
from project.services.admin import reset_tos_accepted_for_users
|
||||
|
||||
form = ResetTosAceptedForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
try:
|
||||
reset_tos_accepted_for_users()
|
||||
return redirect(url_for("admin"))
|
||||
except SQLAlchemyError as e: # pragma: no cover
|
||||
db.session.rollback()
|
||||
flash(handleSqlError(e), "danger")
|
||||
else:
|
||||
flash_errors(form)
|
||||
|
||||
return render_template("admin/reset_tos_accepted.html", form=form)
|
||||
|
||||
|
||||
@app.route("/admin/settings", methods=("GET", "POST"))
|
||||
@roles_required("admin")
|
||||
def admin_settings():
|
||||
|
||||
@ -3,16 +3,18 @@ import datetime
|
||||
from flask import flash, redirect, render_template, url_for
|
||||
from flask_babel import gettext
|
||||
from flask_security import auth_required, current_user
|
||||
from flask_security.utils import get_post_login_redirect
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from project import app, db
|
||||
from project.forms.security import AcceptTosForm
|
||||
from project.forms.user import (
|
||||
CancelUserDeletionForm,
|
||||
NotificationForm,
|
||||
RequestUserDeletionForm,
|
||||
)
|
||||
from project.models import AdminUnitInvitation, User
|
||||
from project.services.user import is_user_admin_member
|
||||
from project.services.user import is_user_admin_member, set_user_accepted_tos
|
||||
from project.views.utils import (
|
||||
flash_errors,
|
||||
get_invitation_access_result,
|
||||
@ -28,6 +30,26 @@ def profile():
|
||||
return render_template("profile.html")
|
||||
|
||||
|
||||
@app.route("/user/accept-tos", methods=("GET", "POST"))
|
||||
@auth_required()
|
||||
def user_accept_tos():
|
||||
form = AcceptTosForm()
|
||||
|
||||
if current_user.tos_accepted_at: # pragma: no cover
|
||||
return redirect(get_post_login_redirect())
|
||||
|
||||
if form.validate_on_submit():
|
||||
try:
|
||||
set_user_accepted_tos(current_user)
|
||||
db.session.commit()
|
||||
return redirect(get_post_login_redirect())
|
||||
except SQLAlchemyError as e: # pragma: no cover
|
||||
db.session.rollback()
|
||||
flash(handleSqlError(e), "danger")
|
||||
|
||||
return render_template("user/accept_tos.html", form=form)
|
||||
|
||||
|
||||
@app.route("/user/notifications", methods=("GET", "POST"))
|
||||
@auth_required()
|
||||
def user_notifications():
|
||||
|
||||
@ -2,6 +2,8 @@ import base64
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.seeder import Seeder
|
||||
|
||||
|
||||
def test_read(client, app, db, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
@ -412,7 +414,7 @@ def test_put_invalidDateFormat(client, seeder, utils, app):
|
||||
utils.assert_response_unprocessable_entity(response)
|
||||
|
||||
|
||||
def test_put_startAfterEnd(client, seeder, utils, app):
|
||||
def test_put_startAfterEnd(client, seeder: Seeder, utils, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
|
||||
@ -37,7 +37,15 @@ def test_create(client, seeder, app):
|
||||
|
||||
runner = app.test_cli_runner()
|
||||
result = runner.invoke(
|
||||
args=["user", "create", "test@test.de", "password", "--confirm", "--admin"]
|
||||
args=[
|
||||
"user",
|
||||
"create",
|
||||
"test@test.de",
|
||||
"password",
|
||||
"--confirm",
|
||||
"--admin",
|
||||
"--accept-tos",
|
||||
]
|
||||
)
|
||||
assert "user_id" in result.output
|
||||
|
||||
@ -46,6 +54,7 @@ def test_create(client, seeder, app):
|
||||
|
||||
user = find_user_by_email("test@test.de")
|
||||
assert user.confirmed_at is not None
|
||||
assert user.tos_accepted_at is not None
|
||||
|
||||
|
||||
def test_confirm(client, seeder, app):
|
||||
|
||||
@ -34,6 +34,7 @@ class Seeder(object):
|
||||
password="MeinPasswortIstDasBeste",
|
||||
admin=False,
|
||||
confirm=True,
|
||||
tos_accepted=True,
|
||||
):
|
||||
from flask_security.confirmable import confirm_user
|
||||
|
||||
@ -41,6 +42,7 @@ class Seeder(object):
|
||||
add_admin_roles_to_user,
|
||||
create_user,
|
||||
find_user_by_email,
|
||||
set_user_accepted_tos,
|
||||
)
|
||||
|
||||
with self._app.app_context():
|
||||
@ -52,6 +54,9 @@ class Seeder(object):
|
||||
if confirm:
|
||||
confirm_user(user)
|
||||
|
||||
if tos_accepted:
|
||||
set_user_accepted_tos(user)
|
||||
|
||||
if admin:
|
||||
add_admin_roles_to_user(email)
|
||||
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import pytest
|
||||
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_normal_user(client, seeder, utils):
|
||||
seeder.create_user()
|
||||
@ -285,3 +288,23 @@ def test_admin_unit_delete(client, seeder, utils, app, db, mocker, db_error, non
|
||||
|
||||
admin_unit = db.session.get(AdminUnit, admin_unit_id)
|
||||
assert admin_unit is None
|
||||
|
||||
|
||||
def test_admin_reset_tos_accepted(client, app, db, seeder: Seeder, utils: UtilActions):
|
||||
seeder.setup_base(admin=True)
|
||||
|
||||
response = utils.get_endpoint_ok("admin_reset_tos_accepted")
|
||||
response = utils.post_form(
|
||||
response.request.url,
|
||||
response,
|
||||
{
|
||||
"reset_for_users": "y",
|
||||
"submit": "Reset",
|
||||
},
|
||||
)
|
||||
utils.assert_response_redirect(response, "admin")
|
||||
|
||||
with app.app_context():
|
||||
from project.models.user import User
|
||||
|
||||
assert len(User.query.filter(User.tos_accepted_at.isnot(None)).all()) == 0
|
||||
|
||||
@ -4,7 +4,7 @@ from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_index_noCookie(client, seeder, utils):
|
||||
def test_index_noCookie(client, seeder: Seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
|
||||
response = utils.get_endpoint("manage")
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_profile(client, seeder, utils):
|
||||
@ -245,3 +246,28 @@ def test_user_cancel_deletion(
|
||||
|
||||
user = db.session.get(User, user_id)
|
||||
assert user.deletion_requested_at is None
|
||||
|
||||
|
||||
def test_user_accept_tos(client, app, db, seeder: Seeder, utils: UtilActions):
|
||||
seeder.setup_base()
|
||||
|
||||
with app.app_context():
|
||||
from project.services.admin import reset_tos_accepted_for_users
|
||||
|
||||
reset_tos_accepted_for_users()
|
||||
|
||||
response = utils.get_endpoint("profile")
|
||||
utils.assert_response_redirect(
|
||||
response, "user_accept_tos", next="http://localhost/profile"
|
||||
)
|
||||
|
||||
response = utils.get_endpoint_ok("user_accept_tos", next="/profile")
|
||||
response = utils.post_form(
|
||||
response.request.url,
|
||||
response,
|
||||
{
|
||||
"accept_tos": "y",
|
||||
"submit": "Confirm",
|
||||
},
|
||||
)
|
||||
utils.assert_response_redirect(response, "profile")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user