diff --git a/back.py b/back.py new file mode 100644 index 0000000000000000000000000000000000000000..05c6609aee933895396fdc69ac96dc8857555d88 --- /dev/null +++ b/back.py @@ -0,0 +1,24 @@ +# This snippet is in public domain. +# However, please retain this link in your sources: +# http://flask.pocoo.org/snippets/120/ +# Danya Alexeyevsky + +import functools +from flask import session, request, redirect as flask_redirect, url_for +import config + +cookie = getattr(config, "REDIRECT_BACK_COOKIE", "back") +default_view = getattr(config, "REDIRECT_BACK_DEFAULT", "index") + +def anchor(func, cookie=cookie): + @functools.wraps(func) + def result(*args, **kwargs): + session[cookie] = request.url + return func(*args, **kwargs) + return result + +def url(default=default_view, cookie=cookie, **url_args): + return session.get(cookie, url_for(default, **url_args)) + +def redirect(default=default_view, cookie=cookie, **url_args): + return flask_redirect(url(default, cookie, **url_args)) diff --git a/decorators.py b/decorators.py index 30fd142c8eedfdef29b4da748073397176a4ca32..ad617a968fbcefccf838b01fa5c474c4f8b93d23 100644 --- a/decorators.py +++ b/decorators.py @@ -4,6 +4,7 @@ from functools import wraps from models.database import ALL_MODELS from shared import db, current_user +import back ID_KEY = "id" KEY_NOT_PRESENT_MESSAGE = "Missing {}_id." @@ -12,10 +13,10 @@ OBJECT_DOES_NOT_EXIST_MESSAGE = "There is no {} with id {}." MISSING_VIEW_RIGHT = "Dir fehlenden die nötigen Zugriffsrechte." def default_redirect(): - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() def login_redirect(): - return redirect(request.args.get("next") or url_for("login")) + return back.redirect("login") def db_lookup(*models, check_exists=True): def _decorator(function): diff --git a/server.py b/server.py index 97554ad95477737cb3e9eb077403de3152661e7b..43e46d76d3765f69044536a32928b2919dea56fc 100755 --- a/server.py +++ b/server.py @@ -31,6 +31,7 @@ from models.database import ProtocolType, Protocol, DefaultTOP, TOP, LocalTOP, D from views.forms import LoginForm, ProtocolTypeForm, DefaultTopForm, MeetingReminderForm, NewProtocolForm, DocumentUploadForm, KnownProtocolSourceUploadForm, NewProtocolSourceUploadForm, generate_protocol_form, TopForm, LocalTopForm, SearchForm, DecisionSearchForm, ProtocolSearchForm, TodoSearchForm, NewProtocolFileUploadForm, NewTodoForm, TodoForm, TodoMailForm, DefaultMetaForm, MetaForm, MergeTodosForm, DecisionCategoryForm, DocumentEditForm from views.tables import ProtocolsTable, ProtocolTypesTable, ProtocolTypeTable, DefaultTOPsTable, MeetingRemindersTable, ErrorsTable, TodosTable, DocumentsTable, DecisionsTable, TodoTable, ErrorTable, TodoMailsTable, DefaultMetasTable, DecisionCategoriesTable from legacy import import_old_todos, import_old_protocols, import_old_todomails +import back app = Flask(__name__) app.config.from_object(config) @@ -158,6 +159,7 @@ def send_file(file_like, cache_timeout, as_attachment, attachment_filename): return response @app.route("/") +@back.anchor def index(): user = current_user() protocols = [ @@ -217,6 +219,7 @@ def index(): return render_template("index.html", open_protocols=open_protocols, protocol=protocol, todos=todos, show_private=show_private, has_public_view_right=has_public_view_right) @app.route("/documentation") +@back.anchor @login_required def documentation(): todostates = list(TodoState) @@ -224,6 +227,7 @@ def documentation(): return render_template("documentation.html", todostates=todostates, name_to_state=name_to_state) @app.route("/types/list") +@back.anchor @login_required def list_types(): is_logged_in = check_login() @@ -251,7 +255,7 @@ def new_type(): db.session.add(protocoltype) db.session.commit() flash("Der Protokolltyp {} wurde angelegt.".format(protocoltype.name), "alert-success") - return redirect(request.args.get("next") or url_for("list_types")) + return back.redirect("list_types") return render_template("type-new.html", form=form) @app.route("/type/edit/<int:protocoltype_id>", methods=["GET", "POST"]) @@ -267,10 +271,11 @@ def edit_type(protocoltype): else: form.populate_obj(protocoltype) db.session.commit() - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=protocoltype.id)) + return back.redirect("show_type", protocoltype_id=protocoltype.id) return render_template("type-edit.html", form=form, protocoltype=protocoltype) @app.route("/type/show/<int:protocoltype_id>") +@back.anchor @login_required @db_lookup(ProtocolType) @require_private_view_right() @@ -292,7 +297,7 @@ def delete_type(protocoltype): db.session.delete(protocoltype) db.session.commit() flash("Der Protokolltype {} wurde gelöscht.".format(name), "alert-success") - return redirect(request.args.get("next") or url_for("list_types")) + return back.redirect("list_types") @app.route("/type/reminders/new/<int:protocoltype_id>", methods=["GET", "POST"]) @login_required @@ -305,7 +310,7 @@ def new_reminder(protocoltype): form.populate_obj(meetingreminder) db.session.add(meetingreminder) db.session.commit() - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=protocoltype.id)) + return back.redirect("show_type", protocoltype_id=protocoltype.id) return render_template("reminder-new.html", form=form, protocoltype=protocoltype) @app.route("/type/reminder/edit/<int:meetingreminder_id>", methods=["GET", "POST"]) @@ -317,7 +322,7 @@ def edit_reminder(meetingreminder): if form.validate_on_submit(): form.populate_obj(meetingreminder) db.session.commit() - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=protocoltype.id)) + return back.redirect("show_type", protocoltype_id=protocoltype.id) return render_template("reminder-edit.html", form=form, meetingreminder=meetingreminder) @app.route("/type/reminder/delete/<int:meetingreminder_id>") @@ -328,7 +333,7 @@ def delete_reminder(meetingreminder): protocoltype = meetingreminder.protocoltype db.session.delete(meetingreminder) db.session.commit() - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=protocoltype.id)) + return back.redirect("show_type", protocoltype_id=protocoltype.id) @app.route("/type/tops/new/<int:protocoltype_id>", methods=["GET", "POST"]) @login_required @@ -348,7 +353,7 @@ def new_default_top(protocoltype): db.session.add(localtop) db.session.commit() flash("Der Standard-TOP {} wurde für dem Protokolltyp {} hinzugefügt.".format(defaulttop.name, protocoltype.name), "alert-success") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() return render_template("default-top-new.html", form=form, protocoltype=protocoltype) @app.route("/type/tops/edit/<int:protocoltype_id>/<int:defaulttop_id>", methods=["GET", "POST"]) @@ -360,7 +365,7 @@ def edit_default_top(protocoltype, defaulttop): if form.validate_on_submit(): form.populate_obj(defaulttop) db.session.commit() - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=protocoltype.id)) + return back.redirect("show_type", protocoltype_id=protocoltype.id) return render_template("default-top-edit.html", form=form, protocoltype=protocoltype, defaulttop=defaulttop) @app.route("/type/tops/delete/<int:defaulttop_id>") @@ -370,7 +375,7 @@ def edit_default_top(protocoltype, defaulttop): def delete_default_top(defaulttop): db.session.delete(defaulttop) db.session.commit() - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=defaulttop.protocoltype.id)) + return back.redirect("show_type", protocoltype_id=defaulttop.protocoltype.id) @app.route("/type/tops/move/<int:defaulttop_id>/<diff>/") @login_required @@ -382,9 +387,10 @@ def move_default_top(defaulttop, diff): db.session.commit() except ValueError: flash("Die angegebene Differenz ist keine Zahl.", "alert-error") - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=defaulttop.protocoltype.id)) + return back.redirect("show_type", protocoltype_id=defaulttop.protocoltype.id) @app.route("/protocols/list") +@back.anchor def list_protocols(): is_logged_in = check_login() user = current_user() @@ -506,10 +512,10 @@ def new_protocol(): protocoltype = ProtocolType.query.filter_by(id=form.protocoltype_id.data).first() if protocoltype is None or not protocoltype.has_modify_right(user): flash("Dir fehlen die nötigen Zugriffsrechte.", "alert-error") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() protocol = Protocol.create_new_protocol(protocoltype, form.date.data, form.start_time.data) - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) type_id = request.args.get("protocoltype_id") if type_id is not None: form.protocoltype.data = type_id @@ -517,6 +523,7 @@ def new_protocol(): return render_template("protocol-new.html", form=form, upload_form=upload_form, file_upload_form=file_upload_form, protocoltypes=protocoltypes) @app.route("/protocol/show/<int:protocol_id>") +@back.anchor @db_lookup(Protocol) def show_protocol(protocol): user = current_user() @@ -525,7 +532,7 @@ def show_protocol(protocol): flash("Dir fehlen die nötigen Zugriffsrechte.", "alert-error") if check_login(): return redirect(url_for("index")) - return redirect(request.args.get("next") or url_for("login", next=request.url)) + return redirect(url_for("login")) visible_documents = [ document for document in protocol.documents if (not document.is_private and document.protocol.has_public_view_right(user)) @@ -554,7 +561,7 @@ def delete_protocol(protocol): db.session.delete(protocol) db.session.commit() flash("Protokoll {} ist gelöscht.".format(name), "alert-success") - return redirect(request.args.get("next") or url_for("list_protocols")) + return back.redirect("list_protocols") @app.route("/protocol/etherpull/<int:protocol_id>") @login_required @@ -563,12 +570,12 @@ def delete_protocol(protocol): def etherpull_protocol(protocol): if not config.ETHERPAD_ACTIVE: flash("Die Etherpadfunktion ist nicht aktiviert.", "alert-error") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol_id)) + return back.redirect("show_protocol", protocol_id=protocol_id) protocol.source = get_etherpad_text(protocol.get_identifier()) db.session.commit() tasks.parse_protocol(protocol) flash("Das Protokoll wird kompiliert.", "alert-success") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) @app.route("/protocol/upload/known/<int:protocol_id>", methods=["POST"]) @login_required @@ -590,7 +597,7 @@ def upload_source_to_known_protocol(protocol): db.session.commit() tasks.parse_protocol(protocol) flash("Das Protokoll wird kompiliert.", "alert-success") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) @app.route("/protocol/upload/new/", methods=["POST"]) @login_required @@ -618,7 +625,7 @@ def upload_new_protocol(): db.session.add(local_top) db.session.commit() tasks.parse_protocol(protocol) - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) return redirect(request.args.get("fail") or url_for("new_protocol")) @app.route("/protocol/upload/new/file/", methods=["POST"]) @@ -655,7 +662,7 @@ def upload_new_protocol_by_file(): document.filename = internal_filename file.save(os.path.join(config.DOCUMENTS_PATH, internal_filename)) db.session.commit() - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) return redirect(request.args.get("fail") or url_for("new_protocol")) @app.route("/protocol/recompile/<int:protocol_id>") @@ -665,7 +672,7 @@ def upload_new_protocol_by_file(): @require_modify_right() def recompile_protocol(protocol): tasks.parse_protocol(protocol) - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) @app.route("/protocol/source/<int:protocol_id>") @login_required @@ -690,10 +697,10 @@ def get_protocol_template(protocol): def etherpush_protocol(protocol): if not config.ETHERPAD_ACTIVE: flash("Die Etherpadfunktion ist nicht aktiviert.", "alert-error") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol_id)) + return back.redirect("show_protocol", protocol_id=protocol_id) if not protocol.is_done(): tasks.set_etherpad_content(protocol) - return redirect(request.args.get("next") or protocol.get_etherpad_link()) + return redirect(protocol.get_etherpad_link()) @app.route("/protocol/update/<int:protocol_id>", methods=["GET", "POST"]) @login_required @@ -708,7 +715,7 @@ def update_protocol(protocol): meta.value = getattr(edit_form.metas, meta.name).data db.session.commit() tasks.push_tops_to_calendar(protocol) - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) for meta in protocol.metas: getattr(edit_form.metas, meta.name).data = meta.value return render_template("protocol-update.html", upload_form=upload_form, edit_form=edit_form, protocol=protocol) @@ -720,7 +727,7 @@ def update_protocol(protocol): def publish_protocol(protocol): protocol.public = True db.session.commit() - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) @app.route("/prococol/send/private/<int:protocol_id>") @login_required @@ -729,10 +736,10 @@ def publish_protocol(protocol): def send_protocol_private(protocol): if not config.MAIL_ACTIVE: flash("Die Mailfunktion ist nicht aktiviert.", "alert-error") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol_id)) + return back.redirect("show_protocol", protocol_id=protocol_id) tasks.send_protocol_private(protocol) flash("Das Protokoll wurde versandt.", "alert-success") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) @app.route("/prococol/send/public/<int:protocol_id>") @login_required @@ -741,10 +748,10 @@ def send_protocol_private(protocol): def send_protocol_public(protocol): if not config.MAIL_ACTIVE: flash("Die Mailfunktion ist nicht aktiviert.", "alert-error") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol_id)) + return back.redirect("show_protocol", protocol_id=protocol_id) tasks.send_protocol_public(protocol) flash("Das Protokoll wurde versandt.", "alert-success") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) @app.route("/protocol/reminder/<int:protocol_id>") @login_required @@ -753,11 +760,11 @@ def send_protocol_public(protocol): def send_protocol_reminder(protocol): if not config.MAIL_ACTIVE: flash("Die Mailfunktion ist nicht aktiviert.", "alert-error") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol_id)) + return back.redirect("show_protocol", protocol_id=protocol_id) meetingreminders = MeetingReminder.query.filter_by(protocoltype_id=protocol.protocoltype.id).all() if len(meetingreminders) == 0: flash("Für diesen Protokolltyp sind keine Einladungsmails konfiguriert.", "alert-error") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol_id)) + return back.redirect("show_protocol", protocol_id=protocol_id) day_difference = (protocol.date - datetime.now().date()).days past_reminders = [ meetingreminder for meetingreminder in meetingreminders @@ -770,7 +777,7 @@ def send_protocol_reminder(protocol): choosen_reminder = past_reminders[0] tasks.send_reminder(choosen_reminder, protocol) flash("Einladungsmail ist versandt.", "alert-success") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) @app.route("/protocol/tops/new/<int:protocol_id>", methods=["GET", "POST"]) @@ -785,7 +792,7 @@ def new_top(protocol): db.session.add(top) db.session.commit() tasks.push_tops_to_calendar(top.protocol) - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) else: current_numbers = list(map(lambda t: t.number, protocol.tops)) suggested_number = get_first_unused_int(current_numbers) @@ -802,7 +809,7 @@ def edit_top(top): form.populate_obj(top) db.session.commit() tasks.push_tops_to_calendar(top.protocol) - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=top.protocol.id)) + return back.redirect("show_protocol", protocol_id=top.protocol.id) return render_template("top-edit.html", form=form, top=top) @app.route("/protocol/top/delete/<int:top_id>") @@ -816,7 +823,7 @@ def delete_top(top): db.session.commit() tasks.push_tops_to_calendar(protocol) flash("Der TOP {} wurde gelöscht.".format(name), "alert-success") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) @app.route("/protocol/top/move/<int:top_id>/<diff>") @login_required @@ -829,7 +836,7 @@ def move_top(top, diff): tasks.push_tops_to_calendar(top.protocol) except ValueError: flash("Die angegebene Differenz ist keine Zahl.", "alert-error") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=top.protocol.id)) + return back.redirect("show_protocol", protocol_id=top.protocol.id) @app.route("/protocol/localtop/edit/<int:localtop_id>", methods=["GET", "POST"]) @login_required @@ -840,7 +847,7 @@ def edit_localtop(localtop): if form.validate_on_submit(): form.populate_obj(localtop) db.session.commit() - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=localtop.protocol.id)) + return back.redirect("show_protocol", protocol_id=localtop.protocol.id) return render_template("localtop-edit.html", form=form, localtop=localtop) def _get_page(): @@ -862,6 +869,7 @@ def _get_page_length(): return config.PAGE_LENGTH @app.route("/todos/list") +@back.anchor @login_required def list_todos(): user = current_user() @@ -933,7 +941,7 @@ def new_todo(): if protocoltype is not None and protocol is not None: if protocol.protocoltype != protocoltype: flash("Ungültige Protokoll-Typ-Kombination", "alert-error") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() if protocoltype is None and protocol is not None: protocoltype = protocol.protocoltype protocoltypes = ProtocolType.get_modifiable_protocoltypes(user) @@ -942,7 +950,7 @@ def new_todo(): added_protocoltype = ProtocolType.query.filter_by(id=form.protocoltype_id.data).first() if added_protocoltype is None or not added_protocoltype.has_modify_right(user): flash("Invalider Protokolltyp.") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() todo = Todo() form.populate_obj(todo) if protocol is not None: @@ -953,9 +961,9 @@ def new_todo(): db.session.commit() flash("Todo wurde angelegt.", "alert-success") if protocol is not None: - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) else: - return redirect(request.args.get("next") or url_for("list_todos", protocoltype_id=protocoltype_id)) + return back.redirect("list_todos", protocoltype_id=protocoltype_id) else: if protocoltype is not None: form.protocoltype_id.data = protocoltype.id @@ -970,10 +978,11 @@ def edit_todo(todo): if form.validate_on_submit(): form.populate_obj(todo) db.session.commit() - return redirect(request.args.get("next") or url_for("list_todos", protocoltype_id=todo.protocoltype.id)) + return back.redirect("list_todos", protocoltype_id=todo.protocoltype.id) return render_template("todo-edit.html", form=form, todo=todo) @app.route("/todo/show/<int:todo_id>") +@back.anchor @login_required @db_lookup(Todo) @require_private_view_right() @@ -990,7 +999,7 @@ def delete_todo(todo): db.session.delete(todo) db.session.commit() flash("Todo gelöscht.", "alert-success") - return redirect(request.args.get("next") or url_for("list_todos", protocoltype_id=type_id)) + return back.redirect("list_todos", protocoltype_id=type_id) @app.route("/todo/merge", methods=["GET", "POST"]) @login_required @@ -1012,10 +1021,11 @@ def merge_todos(): db.session.delete(todo2) db.session.commit() flash("Merged todos {} and {}.".format(id1, id2), "alert-success") - return redirect(request.args.get("next") or url_for("list_todos")) - return render_template("todos-merge.html", form=form, next_url=request.args.get("next")) + return back.redirect("list_todos") + return render_template("todos-merge.html", form=form) @app.route("/decisions/list") +@back.anchor def list_decisions(): is_logged_In = check_login() user = current_user() @@ -1090,7 +1100,7 @@ def download_document(document): or (not document.is_private and not document.protocol.has_public_view_right(user))): flash("Dir fehlen die nötigen Zugriffsrechte.", "alert-error") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() return send_file(document.as_file_like(), cache_timeout=1, as_attachment=True, attachment_filename=document.name) @app.route("/document/upload/<int:protocol_id>", methods=["POST"]) @@ -1101,11 +1111,11 @@ def upload_document(protocol): form = DocumentUploadForm() if form.document.data is None: flash("Es wurde keine Datei ausgewählt.", "alert-error") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() file = form.document.data if file.filename == "": flash("Es wurde keine Datei ausgewählt.", "alert-error") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() # todo: Dateitypen einschränken? if file: filename = secure_filename(file.filename) @@ -1120,7 +1130,7 @@ def upload_document(protocol): if datetime.now().date() >= protocol.date: protocol.done = True db.session.commit() - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) @app.route("/document/edit/<int:document_id>", methods=["GET", "POST"]) @login_required @@ -1131,7 +1141,7 @@ def edit_document(document): if form.validate_on_submit(): form.populate_obj(document) db.session.commit() - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=document.protocol.id)) + return back.redirect("show_protocol", protocol_id=document.protocol.id) return render_template("document-edit.html", document=document, form=form) @app.route("/document/delete/<int:document_id>") @@ -1145,7 +1155,7 @@ def delete_document(document): db.session.delete(document) db.session.commit() flash("Das Dokument {} wurde gelöscht.".format(name), "alert-success") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) + return back.redirect("show_protocol", protocol_id=protocol.id) @app.route("/document/print/<int:document_id>") @login_required @@ -1154,10 +1164,10 @@ def delete_document(document): def print_document(document): if not config.PRINTING_ACTIVE: flash("Die Druckfunktion ist nicht aktiviert.", "alert-error") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=document.protocol.id)) + return back.redirect("show_protocol", protocol_id=document.protocol.id) tasks.print_file(document.get_filename(), document.protocol) flash("Das Dokument {} wird gedruckt.".format(document.name), "alert-success") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=document.protocol.id)) + return back.redirect("show_protocol", protocol_id=document.protocol.id) @app.route("/decision/print/<int:decisiondocument_id>") @login_required @@ -1167,12 +1177,13 @@ def print_decision(decisiondocument): user = current_user() if not config.PRINTING_ACTIVE: flash("Die Druckfunktion ist nicht aktiviert.", "alert-error") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=decisiondocument.decision.protocol.id)) + return back.redirect("show_protocol", protocol_id=decisiondocument.decision.protocol.id) tasks.print_file(decisiondocument.get_filename(), decisiondocument.decision.protocol) flash("Das Dokument {} wird gedruckt.".format(decisiondocument.name), "alert-success") - return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=decisiondocument.decision.protocol.id)) + return back.redirect("show_protocol", protocol_id=decisiondocument.decision.protocol.id) @app.route("/errors/list") +@back.anchor @login_required def list_errors(): user = current_user() @@ -1184,6 +1195,7 @@ def list_errors(): return render_template("errors-list.html", errros=errors, errors_table=errors_table) @app.route("/error/show/<int:error_id>") +@back.anchor @login_required @db_lookup(Error) @require_modify_right() @@ -1200,9 +1212,10 @@ def delete_error(error): db.session.delete(error) db.session.commit() flash("Fehler {} gelöscht.".format(name), "alert-success") - return redirect(request.args.get("next") or url_for("list_errors")) + return back.redirect("list_errors") @app.route("/todomails/list") +@back.anchor @login_required def list_todomails(): todomails = sorted(TodoMail.query.all(), key=lambda tm: tm.name.lower()) @@ -1219,7 +1232,7 @@ def new_todomail(): db.session.add(todomail) db.session.commit() flash("Die Todomailzuordnung für {} wurde angelegt.".format(todomail.name), "alert-success") - return redirect(request.args.get("next") or url_for("list_todomails")) + return back.redirect("list_todomails") return render_template("todomail-new.html", form=form) @app.route("/todomail/edit/<int:todomail_id>", methods=["GET", "POST"]) @@ -1231,7 +1244,7 @@ def edit_todomail(todomail): form.populate_obj(todomail) db.session.commit() flash("Die Todo-Mail-Zuordnung wurde geändert.", "alert-success") - return redirect(request.args.get("next") or url_for("list_todomails")) + return back.redirect("list_todomails") return render_template("todomail-edit.html", todomail=todomail, form=form) @app.route("/todomail/delete/<int:todomail_id>") @@ -1242,7 +1255,7 @@ def delete_todomail(todomail): db.session.delete(todomail) db.session.commit() flash("Die Todo-Mail-Zuordnung für {} wurde gelöscht.".format(name), "alert-success") - return redirect(request.args.get("next") or url_for("list_todomails")) + return back.redirect("list_todomails") @app.route("/defaultmeta/new/<int:protocoltype_id>", methods=["GET", "POST"]) @login_required @@ -1256,7 +1269,7 @@ def new_defaultmeta(protocoltype): db.session.add(meta) db.session.commit() flash("Metadatenfeld hinzugefügt.", "alert-success") - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=protocoltype.id)) + return back.redirect("show_type", protocoltype_id=protocoltype.id) return render_template("defaultmeta-new.html", form=form, protocoltype=protocoltype) @app.route("/defaultmeta/edit/<int:defaultmeta_id>", methods=["GET", "POST"]) @@ -1268,7 +1281,7 @@ def edit_defaultmeta(defaultmeta): if form.validate_on_submit(): form.populate_obj(defaultmeta) db.session.commit() - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=defaultmeta.protocoltype.id)) + return back.redirect("show_type", protocoltype_id=defaultmeta.protocoltype.id) return render_template("defaultmeta-edit.html", form=form, defaultmeta=defaultmeta) @app.route("/defaultmeta/delete/<int:defaultmeta_id>") @@ -1282,7 +1295,7 @@ def delete_defaultmeta(defaultmeta): db.session.delete(defaultmeta) db.session.commit() flash("Metadatenfeld '{}' gelöscht.".format(name), "alert-success") - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=type_id)) + return back.redirect("show_type", protocoltype_id=type_id) @app.route("/decisioncategory/new/<int:protocoltype_id>", methods=["GET", "POST"]) @login_required @@ -1296,7 +1309,7 @@ def new_decisioncategory(protocoltype): db.session.add(category) db.session.commit() flash("Beschlusskategorie hinzugefügt.", "alert-success") - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=protocoltype.id)) + return back.redirect("show_type", protocoltype_id=protocoltype.id) return render_template("decisioncategory-new.html", form=form, protocoltype=protocoltype) @app.route("/decisioncategory/edit/<int:decisioncategory_id>", methods=["GET", "POST"]) @@ -1308,7 +1321,7 @@ def edit_decisioncategory(decisioncategory): if form.validate_on_submit(): form.populate_obj(decisioncategory) db.session.commit() - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=decisioncategory.protocoltype.id)) + return back.redirect("show_type", protocoltype_id=decisioncategory.protocoltype.id) return render_template("decisioncategory-edit.html", form=form, decisioncategory=decisioncategory) @app.route("/decisioncategory/delete/<int:decisioncategory_id>") @@ -1322,7 +1335,7 @@ def delete_decisioncategory(decisioncategory): db.session.delete(decisioncategory) db.session.commit() flash("Beschlusskategorie {} gelöscht.".format(name), "alert-success") - return redirect(request.args.get("next") or url_for("show_type", protocoltype_id=type_id)) + return back.redirect("show_type", protocoltype_id=type_id) def create_protocols_feed(protocoltype): if not protocoltype.has_public_anonymous_view_right(): @@ -1467,16 +1480,16 @@ def new_like(): parent = TOP.query.filter_by(id=request.args.get("top_id")).first() if parent is None or not parent.has_public_view_right(user): flash("Missing object to like.", "alert-error") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() if len([like for like in parent.likes if like.who == user.username]) > 0: flash("You have liked this already!", "alert-error") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() like = Like(who=user.username) db.session.add(like) parent.likes.append(like) db.session.commit() flash("Like!", "alert-success") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() @app.route("/login", methods=["GET", "POST"]) @@ -1491,7 +1504,7 @@ def login(): session["auth"] = security_manager.hash_user(user) session.permanent = form.permanent.data flash("Login successful, {}!".format(user.username), "alert-success") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() else: flash("Wrong login data. Try again.", "alert-error") return render_template("login.html", form=form) diff --git a/shared.py b/shared.py index 3e091c4303424a19004383c6715b722aea7564b4..ece29f36fcc7145a5743e00b6957845ea34c5f09 100644 --- a/shared.py +++ b/shared.py @@ -5,6 +5,8 @@ import re from functools import wraps from enum import Enum +import back + import config db = SQLAlchemy() @@ -110,7 +112,7 @@ def login_required(function): if check_login(): return function(*args, **kwargs) else: - return redirect(url_for("login", next=request.url)) + return redirect(url_for("login")) return decorated_function def group_required(group): @@ -121,7 +123,7 @@ def group_required(group): return function(*args, **kwargs) else: flash("You do not have the necessary permissions to view this page.") - return redirect(request.args.get("next") or url_for("index")) + return back.redirect() return decorated_function return decorator diff --git a/templates/document-edit.html b/templates/document-edit.html index 7b1689e7170c53d394d95f91b16606b46ae75d13..d3d30fa7571514901199a50f121cd1c8402cf1c6 100644 --- a/templates/document-edit.html +++ b/templates/document-edit.html @@ -4,6 +4,6 @@ {% block content %} <div class="container"> - {{render_form(form, action_url=url_for("edit_document", document_id=document.id, next=request.args.get("next") or url_for("show_protocol", protocol_id=document.protocol.id)), action_text="Ändern")}} + {{render_form(form, action_url=url_for("edit_document", document_id=document.id), action_text="Ändern")}} </div> {% endblock %} diff --git a/templates/localtop-edit.html b/templates/localtop-edit.html index c320d727b1b248718899be1aa2eadbe66fa517e0..df048b35b5b001172d7e3bc1854cf5b7bc74d25c 100644 --- a/templates/localtop-edit.html +++ b/templates/localtop-edit.html @@ -5,6 +5,6 @@ {% block content %} <div class="container"> <h3>{{localtop.defaulttop.name}}</h3> - {{render_form(form, action_url=url_for("edit_localtop", localtop_id=localtop.id, next=request.args.get("next") or url_for("show_protocol", protocol_id=localtop.protocol.id)), action_text="Ändern", textarea_rows=5)}} + {{render_form(form, action_url=url_for("edit_localtop", localtop_id=localtop.id), action_text="Ändern", textarea_rows=5)}} </div> {% endblock %} diff --git a/templates/top-edit.html b/templates/top-edit.html index 07d56be8f257d106a9e9da490a3e2a266a5286a3..adabf99a3e46b5ceb8d63c988e97dd9b7a8f6e16 100644 --- a/templates/top-edit.html +++ b/templates/top-edit.html @@ -4,6 +4,6 @@ {% block content %} <div class="container"> - {{render_form(form, action_url=url_for("edit_top", top_id=top.id, next=request.args.get("next") or url_for("show_protocol", protocol_id=top.protocol.id)), action_text="Ändern", textarea_rows=5)}} + {{render_form(form, action_url=url_for("edit_top", top_id=top.id), action_text="Ändern", textarea_rows=5)}} </div> {% endblock %}