Skip to content
Snippets Groups Projects
Commit dfe82a15 authored by Robin Sonnabend's avatar Robin Sonnabend
Browse files

Refactored authentication

parent cf8274fb
No related branches found
No related tags found
No related merge requests found
from flask import redirect, flash, request from flask import redirect, flash, request, url_for
from functools import wraps from functools import wraps
from models.database import ALL_MODELS
from shared import db, current_user
ID_KEY = "id" ID_KEY = "id"
KEY_NOT_PRESENT_MESSAGE = "Missing {}_id." KEY_NOT_PRESENT_MESSAGE = "Missing {}_id."
OBJECT_DOES_NOT_EXIST_MESSAGE = "There is no {} with id {}." OBJECT_DOES_NOT_EXIST_MESSAGE = "There is no {} with id {}."
MISSING_VIEW_RIGHT = "Dir fehlenden die nötigen Zugriffsrechte."
def default_redirect(): def default_redirect():
return redirect(request.args.get("next") or url_for("index")) return redirect(request.args.get("next") or url_for("index"))
def login_redirect():
return redirect(request.args.get("next") or url_for("login"))
def db_lookup(*models, check_exists=True): def db_lookup(*models, check_exists=True):
def _decorator(function): def _decorator(function):
@wraps(function) @wraps(function)
def _decorated_function(*args, **kwargs): def _decorated_function(*args, **kwargs):
for model in models: for model in models:
key = model.__object_name__ key = model.__model_name__
id_key = "{}_{}".format(key, ID_KEY) id_key = "{}_{}".format(key, ID_KEY)
if id_key not in kwargs: if id_key not in kwargs:
flash(KEY_NOT_PRESENT_MESSAGE.format(key), "alert-error") flash(KEY_NOT_PRESENT_MESSAGE.format(key), "alert-error")
...@@ -31,3 +39,39 @@ def db_lookup(*models, check_exists=True): ...@@ -31,3 +39,39 @@ def db_lookup(*models, check_exists=True):
return function(*args, **kwargs) return function(*args, **kwargs)
return _decorated_function return _decorated_function
return _decorator return _decorator
def require_right(right, require_exist):
necessary_right_name = "has_{}_right".format(right)
def _decorator(function):
@wraps(function)
def _decorated_function(*args, **kwargs):
user = current_user()
for model in ALL_MODELS:
model_name = model.__model_name__
if model_name in kwargs:
model = kwargs[model_name]
if model is None:
if require_exist:
flash(MISSING_VIEW_RIGHT, "alert-error")
return login_redirect()
else:
continue
necessary_right = getattr(model, necessary_right_name)
if not necessary_right(user):
flash(MISSING_VIEW_RIGHT, "alert-error")
return login_redirect()
return function(*args, **kwargs)
return _decorated_function
return _decorator
def require_public_view_right(require_exist=True):
return require_right("public_view", require_exist)
def require_private_view_right(require_exist=True):
return require_right("private_view", require_exist)
def require_modify_right(require_exist=True):
return require_right("modify", require_exist)
def require_admin_right(require_exist=True):
return require_right("admin", require_exist)
...@@ -18,9 +18,25 @@ from sqlalchemy.ext.hybrid import hybrid_method ...@@ -18,9 +18,25 @@ from sqlalchemy.ext.hybrid import hybrid_method
import config import config
from todostates import make_states from todostates import make_states
class ProtocolType(db.Model): class DatabaseModel(db.Model):
__abstract__ = True
def has_public_view_right(self, user):
print("DBModel")
return self.get_parent().has_public_view_right(user)
def has_private_view_right(self, user):
return self.get_parent().has_private_view_right(user)
def has_modify_right(self, user):
return self.get_parent().has_modify_right(user)
def has_admin_right(self, user):
return self.get_parent().has_admin_right(user)
class ProtocolType(DatabaseModel):
__tablename__ = "protocoltypes" __tablename__ = "protocoltypes"
__object_name__ = "protocoltype" __model_name__ = "protocoltype"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, unique=True) name = db.Column(db.String, unique=True)
short_name = db.Column(db.String, unique=True) short_name = db.Column(db.String, unique=True)
...@@ -91,7 +107,8 @@ class ProtocolType(db.Model): ...@@ -91,7 +107,8 @@ class ProtocolType(db.Model):
def has_public_view_right(self, user): def has_public_view_right(self, user):
return (self.has_public_anonymous_view_right() return (self.has_public_anonymous_view_right()
or (user is not None and self.has_public_authenticated_view_right(user))) or (user is not None and self.has_public_authenticated_view_right(user))
or self.has_admin_right(user))
def has_public_anonymous_view_right(self): def has_public_anonymous_view_right(self):
return (self.is_public return (self.is_public
...@@ -103,10 +120,15 @@ class ProtocolType(db.Model): ...@@ -103,10 +120,15 @@ class ProtocolType(db.Model):
or (self.private_group != "" and self.private_group in user.groups)) or (self.private_group != "" and self.private_group in user.groups))
def has_private_view_right(self, user): def has_private_view_right(self, user):
return (user is not None and self.private_group != "" and self.private_group in user.groups) return ((user is not None
and (self.private_group != "" and self.private_group in user.groups))
or self.has_admin_right(user))
def has_modify_right(self, user): def has_modify_right(self, user):
return (user is not None and self.modify_group != "" and self.modify_group in user.groups) return ((user is not None
and (self.modify_group != "" and self.modify_group in user.groups))
or self.has_admin_right(user))
def has_admin_right(self, user): def has_admin_right(self, user):
return (user is not None and config.ADMIN_GROUP in user.groups) return (user is not None and config.ADMIN_GROUP in user.groups)
...@@ -138,9 +160,9 @@ class ProtocolType(db.Model): ...@@ -138,9 +160,9 @@ class ProtocolType(db.Model):
def get_wiki_infobox_title(self): def get_wiki_infobox_title(self):
return "Vorlage:{}".format(self.get_wiki_infobox()) return "Vorlage:{}".format(self.get_wiki_infobox())
class Protocol(db.Model): class Protocol(DatabaseModel):
__tablename__ = "protocols" __tablename__ = "protocols"
__object_name__ = "protocol" __model_name__ = "protocol"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
protocoltype_id = db.Column(db.Integer, db.ForeignKey("protocoltypes.id")) protocoltype_id = db.Column(db.Integer, db.ForeignKey("protocoltypes.id"))
source = db.Column(db.String) source = db.Column(db.String)
...@@ -173,6 +195,9 @@ class Protocol(db.Model): ...@@ -173,6 +195,9 @@ class Protocol(db.Model):
return "<Protocol(id={}, protocoltype_id={})>".format( return "<Protocol(id={}, protocoltype_id={})>".format(
self.id, self.protocoltype_id) self.id, self.protocoltype_id)
def get_parent(self):
return self.protocoltype
def create_error(self, action, name, description): def create_error(self, action, name, description):
now = datetime.now() now = datetime.now()
return Error(self.id, action, name, now, description) return Error(self.id, action, name, now, description)
...@@ -225,12 +250,6 @@ class Protocol(db.Model): ...@@ -225,12 +250,6 @@ class Protocol(db.Model):
or self.protocoltype.has_private_view_right(user) or self.protocoltype.has_private_view_right(user)
) )
def has_private_view_right(self, user):
return self.protocoltype.has_private_view_right(user)
def has_modify_right(self, user):
return self.protocoltype.has_modify_right(user)
def is_done(self): def is_done(self):
return self.done return self.done
...@@ -303,9 +322,9 @@ def on_protocol_delete(mapper, connection, protocol): ...@@ -303,9 +322,9 @@ def on_protocol_delete(mapper, connection, protocol):
protocol.delete_orphan_todos() protocol.delete_orphan_todos()
class DefaultTOP(db.Model): class DefaultTOP(DatabaseModel):
__tablename__ = "defaulttops" __tablename__ = "defaulttops"
__object_name__ = "defaulttop" __model_name__ = "defaulttop"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
protocoltype_id = db.Column(db.Integer, db.ForeignKey("protocoltypes.id")) protocoltype_id = db.Column(db.Integer, db.ForeignKey("protocoltypes.id"))
name = db.Column(db.String) name = db.Column(db.String)
...@@ -320,12 +339,15 @@ class DefaultTOP(db.Model): ...@@ -320,12 +339,15 @@ class DefaultTOP(db.Model):
return "<DefaultTOP(id={}, protocoltype_id={}, name={}, number={})>".format( return "<DefaultTOP(id={}, protocoltype_id={}, name={}, number={})>".format(
self.id, self.protocoltype_id, self.name, self.number) self.id, self.protocoltype_id, self.name, self.number)
def get_parent(self):
return self.protocoltype
def is_at_end(self): def is_at_end(self):
return self.number > 0 return self.number > 0
class TOP(db.Model): class TOP(DatabaseModel):
__tablename__ = "tops" __tablename__ = "tops"
__object_name__ = "top" __model_name__ = "top"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id")) protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id"))
name = db.Column(db.String) name = db.Column(db.String)
...@@ -344,9 +366,12 @@ class TOP(db.Model): ...@@ -344,9 +366,12 @@ class TOP(db.Model):
return "<TOP(id={}, protocol_id={}, name={}, number={}, planned={})>".format( return "<TOP(id={}, protocol_id={}, name={}, number={}, planned={})>".format(
self.id, self.protocol_id, self.name, self.number, self.planned) self.id, self.protocol_id, self.name, self.number, self.planned)
class Document(db.Model): def get_parent(self):
return self.protocol
class Document(DatabaseModel):
__tablename__ = "documents" __tablename__ = "documents"
__object_name__ = "document" __model_name__ = "document"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id")) protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id"))
name = db.Column(db.String) name = db.Column(db.String)
...@@ -365,6 +390,9 @@ class Document(db.Model): ...@@ -365,6 +390,9 @@ class Document(db.Model):
return "<Document(id={}, protocol_id={}, name={}, filename={}, is_compiled={}, is_private={})>".format( return "<Document(id={}, protocol_id={}, name={}, filename={}, is_compiled={}, is_private={})>".format(
self.id, self.protocol_id, self.name, self.filename, self.is_compiled, self.is_private) self.id, self.protocol_id, self.name, self.filename, self.is_compiled, self.is_private)
def get_parent(self):
return self.protocol
def get_filename(self): def get_filename(self):
return os.path.join(config.DOCUMENTS_PATH, self.filename) return os.path.join(config.DOCUMENTS_PATH, self.filename)
...@@ -379,9 +407,9 @@ def on_document_delete(mapper, connection, document): ...@@ -379,9 +407,9 @@ def on_document_delete(mapper, connection, document):
if os.path.isfile(document_path): if os.path.isfile(document_path):
os.remove(document_path) os.remove(document_path)
class DecisionDocument(db.Model): class DecisionDocument(DatabaseModel):
__tablename__ = "decisiondocuments" __tablename__ = "decisiondocuments"
__object_name__ = "decisiondocument" __model_name__ = "decisiondocument"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
decision_id = db.Column(db.Integer, db.ForeignKey("decisions.id")) decision_id = db.Column(db.Integer, db.ForeignKey("decisions.id"))
name = db.Column(db.String) name = db.Column(db.String)
...@@ -396,6 +424,9 @@ class DecisionDocument(db.Model): ...@@ -396,6 +424,9 @@ class DecisionDocument(db.Model):
return "<DecisionDocument(id={}, decision_id={}, name={}, filename={})>".format( return "<DecisionDocument(id={}, decision_id={}, name={}, filename={})>".format(
self.id, self.decision_id, self.name, self.filename) self.id, self.decision_id, self.name, self.filename)
def get_parent(self):
return self.decision
def get_filename(self): def get_filename(self):
return os.path.join(config.DOCUMENTS_PATH, self.filename) return os.path.join(config.DOCUMENTS_PATH, self.filename)
...@@ -487,9 +518,9 @@ class TodoState(Enum): ...@@ -487,9 +518,9 @@ class TodoState(Enum):
return state, date return state, date
class Todo(db.Model): class Todo(DatabaseModel):
__tablename__ = "todos" __tablename__ = "todos"
__object_name__ = "todo" __model_name__ = "todo"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
protocoltype_id = db.Column(db.Integer, db.ForeignKey("protocoltypes.id")) protocoltype_id = db.Column(db.Integer, db.ForeignKey("protocoltypes.id"))
number = db.Column(db.Integer) number = db.Column(db.Integer)
...@@ -512,6 +543,9 @@ class Todo(db.Model): ...@@ -512,6 +543,9 @@ class Todo(db.Model):
return "<Todo(id={}, number={}, who={}, description={}, state={}, date={})>".format( return "<Todo(id={}, number={}, who={}, description={}, state={}, date={})>".format(
self.id, self.number, self.who, self.description, self.state, self.date) self.id, self.number, self.who, self.description, self.state, self.date)
def get_parent(self):
return self.protocoltype
def is_done(self): def is_done(self):
if self.state.needs_date(): if self.state.needs_date():
if self.state == TodoState.after: if self.state == TodoState.after:
...@@ -581,15 +615,14 @@ class Todo(db.Model): ...@@ -581,15 +615,14 @@ class Todo(db.Model):
parts.append("id {}".format(self.get_id())) parts.append("id {}".format(self.get_id()))
return "[{}]".format(";".join(parts)) return "[{}]".format(";".join(parts))
class TodoProtocolAssociation(DatabaseModel):
class TodoProtocolAssociation(db.Model):
__tablename__ = "todoprotocolassociations" __tablename__ = "todoprotocolassociations"
todo_id = db.Column(db.Integer, db.ForeignKey("todos.id"), primary_key=True) todo_id = db.Column(db.Integer, db.ForeignKey("todos.id"), primary_key=True)
protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id"), primary_key=True) protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id"), primary_key=True)
class Decision(db.Model): class Decision(DatabaseModel):
__tablename__ = "decisions" __tablename__ = "decisions"
__object_name__ = "decision" __model_name__ = "decision"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id")) protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id"))
content = db.Column(db.String) content = db.Column(db.String)
...@@ -604,9 +637,12 @@ class Decision(db.Model): ...@@ -604,9 +637,12 @@ class Decision(db.Model):
return "<Decision(id={}, protocol_id={}, content='{}')>".format( return "<Decision(id={}, protocol_id={}, content='{}')>".format(
self.id, self.protocol_id, self.content) self.id, self.protocol_id, self.content)
class MeetingReminder(db.Model): def get_parent(self):
return self.protocol
class MeetingReminder(DatabaseModel):
__tablename__ = "meetingreminders" __tablename__ = "meetingreminders"
__object_name__ = "meetingreminder" __model_name__ = "meetingreminder"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
protocoltype_id = db.Column(db.Integer, db.ForeignKey("protocoltypes.id")) protocoltype_id = db.Column(db.Integer, db.ForeignKey("protocoltypes.id"))
days_before = db.Column(db.Integer) days_before = db.Column(db.Integer)
...@@ -625,9 +661,12 @@ class MeetingReminder(db.Model): ...@@ -625,9 +661,12 @@ class MeetingReminder(db.Model):
return "<MeetingReminder(id={}, protocoltype_id={}, days_before={}, send_public={}, send_private={})>".format( return "<MeetingReminder(id={}, protocoltype_id={}, days_before={}, send_public={}, send_private={})>".format(
self.id, self.protocoltype_id, self.days_before, self.send_public, self.send_private) self.id, self.protocoltype_id, self.days_before, self.send_public, self.send_private)
class Error(db.Model): def get_parent(self):
return self.protocoltype
class Error(DatabaseModel):
__tablename__ = "errors" __tablename__ = "errors"
__object_name__ = "error" __model_name__ = "error"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id")) protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id"))
action = db.Column(db.String) action = db.Column(db.String)
...@@ -646,15 +685,18 @@ class Error(db.Model): ...@@ -646,15 +685,18 @@ class Error(db.Model):
return "<Error(id={}, protocol_id={}, action={}, name={}, datetime={})>".format( return "<Error(id={}, protocol_id={}, action={}, name={}, datetime={})>".format(
self.id, self.protocol_id, self.action, self.name, self.datetime) self.id, self.protocol_id, self.action, self.name, self.datetime)
def get_parent(self):
return self.protocol
def get_short_description(self): def get_short_description(self):
lines = self.description.splitlines() lines = self.description.splitlines()
if len(lines) <= 4: if len(lines) <= 4:
return "\n".join(lines) return "\n".join(lines)
return "\n".join([*lines[:2], "", *lines[-2:]]) return "\n".join([*lines[:2], "", *lines[-2:]])
class TodoMail(db.Model): class TodoMail(DatabaseModel):
__tablename__ = "todomails" __tablename__ = "todomails"
__object_name__ = "todomail" __model_name__ = "todomail"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, unique=True) name = db.Column(db.String, unique=True)
mail = db.Column(db.String) mail = db.Column(db.String)
...@@ -670,9 +712,9 @@ class TodoMail(db.Model): ...@@ -670,9 +712,9 @@ class TodoMail(db.Model):
def get_formatted_mail(self): def get_formatted_mail(self):
return "{} <{}>".format(self.name, self.mail) return "{} <{}>".format(self.name, self.mail)
class OldTodo(db.Model): class OldTodo(DatabaseModel):
__tablename__ = "oldtodos" __tablename__ = "oldtodos"
__object_name__ = "oldtodo" __model_name__ = "oldtodo"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
old_id = db.Column(db.Integer) old_id = db.Column(db.Integer)
who = db.Column(db.String) who = db.Column(db.String)
...@@ -690,9 +732,9 @@ class OldTodo(db.Model): ...@@ -690,9 +732,9 @@ class OldTodo(db.Model):
"protocol={}".format(self.id, self.old_id, self.who, "protocol={}".format(self.id, self.old_id, self.who,
self.description, self.protocol_key)) self.description, self.protocol_key))
class DefaultMeta(db.Model): class DefaultMeta(DatabaseModel):
__tablename__ = "defaultmetas" __tablename__ = "defaultmetas"
__object_name__ = "defaultmeta" __model_name__ = "defaultmeta"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
protocoltype_id = db.Column(db.Integer, db.ForeignKey("protocoltypes.id")) protocoltype_id = db.Column(db.Integer, db.ForeignKey("protocoltypes.id"))
key = db.Column(db.String) key = db.Column(db.String)
...@@ -707,9 +749,12 @@ class DefaultMeta(db.Model): ...@@ -707,9 +749,12 @@ class DefaultMeta(db.Model):
return ("<DefaultMeta(id={}, protocoltype_id={}, key='{}', " return ("<DefaultMeta(id={}, protocoltype_id={}, key='{}', "
"name='{}')>".format(self.id, self.protocoltype_id, self.key)) "name='{}')>".format(self.id, self.protocoltype_id, self.key))
class Meta(db.Model): def get_parent(self):
return self.protocoltype
class Meta(DatabaseModel):
__tablename__ = "metas" __tablename__ = "metas"
__object_name__ = "meta" __model_name__ = "meta"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id")) protocol_id = db.Column(db.Integer, db.ForeignKey("protocols.id"))
name = db.Column(db.String) name = db.Column(db.String)
...@@ -724,3 +769,11 @@ class Meta(db.Model): ...@@ -724,3 +769,11 @@ class Meta(db.Model):
return "<Meta(id={}, protocoltype_id={}, name={}, value={})>".format( return "<Meta(id={}, protocoltype_id={}, name={}, value={})>".format(
self.id, self.protocoltype_id, self.name, self.value) self.id, self.protocoltype_id, self.name, self.value)
def get_parent(self):
return self.protocol
ALL_MODELS = [
ProtocolType, Protocol, DefaultTOP, TOP, Document, DecisionDocument,
Todo, Decision, MeetingReminder, Error, DefaultMeta, Meta
]
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
{% set has_public_view_right = protocol.has_public_view_right(user) %} {% set has_public_view_right = protocol.has_public_view_right(user) %}
{% set has_private_view_right = protocol.has_private_view_right(user) %} {% set has_private_view_right = protocol.has_private_view_right(user) %}
{% set has_modify_right = protocol.has_modify_right(user) %} {% set has_modify_right = protocol.has_modify_right(user) %}
{% set has_admin_right = protocol.protocoltype.has_admin_right(user) %} {% set has_admin_right = protocol.has_admin_right(user) %}
{% block content %} {% block content %}
<div class="container"> <div class="container">
......
...@@ -174,7 +174,7 @@ class ProtocolTypeTable(SingleValueTable): ...@@ -174,7 +174,7 @@ class ProtocolTypeTable(SingleValueTable):
class DefaultTOPsTable(Table): class DefaultTOPsTable(Table):
def __init__(self, tops, protocoltype=None): def __init__(self, tops, protocoltype=None):
super().__init__("Standard-TOPs", tops, newlink=url_for("new_default_top", type_id=protocoltype.id) if protocoltype is not None else None) super().__init__("Standard-TOPs", tops, newlink=url_for("new_default_top", protocoltype_id=protocoltype.id) if protocoltype is not None else None)
self.protocoltype = protocoltype self.protocoltype = protocoltype
def headers(self): def headers(self):
...@@ -185,10 +185,10 @@ class DefaultTOPsTable(Table): ...@@ -185,10 +185,10 @@ class DefaultTOPsTable(Table):
top.name, top.name,
top.number, top.number,
Table.concat([ Table.concat([
Table.link(url_for("move_default_top", type_id=self.protocoltype.id, top_id=top.id, diff=1), "Runter"), Table.link(url_for("move_default_top", protocoltype_id=self.protocoltype.id, defaulttop_id=top.id, diff=1), "Runter"),
Table.link(url_for("move_default_top", type_id=self.protocoltype.id, top_id=top.id, diff=-1), "Hoch"), Table.link(url_for("move_default_top", protocoltype_id=self.protocoltype.id, defaulttop_id=top.id, diff=-1), "Hoch"),
Table.link(url_for("edit_default_top", type_id=self.protocoltype.id, top_id=top.id), "Ändern"), Table.link(url_for("edit_default_top", protocoltype_id=self.protocoltype.id, defaulttop_id=top.id), "Ändern"),
Table.link(url_for("delete_default_top", type_id=self.protocoltype.id, top_id=top.id), "Löschen", confirm="Bist du dir sicher, dass du den Standard-TOP {} löschen willst?".format(top.name)) Table.link(url_for("delete_default_top", protocoltype_id=self.protocoltype.id, defaulttop_id=top.id), "Löschen", confirm="Bist du dir sicher, dass du den Standard-TOP {} löschen willst?".format(top.name))
]) ])
] ]
...@@ -386,8 +386,8 @@ class DefaultMetasTable(Table): ...@@ -386,8 +386,8 @@ class DefaultMetasTable(Table):
meta.key, meta.key,
] ]
links = [ links = [
Table.link(url_for("edit_defaultmeta", meta_id=meta.id), "Ändern"), Table.link(url_for("edit_defaultmeta", defaultmeta_id=meta.id), "Ändern"),
Table.link(url_for("delete_defaultmeta", meta_id=meta.id, confirm="Bist du dir sicher, dass du das Metadatenfeld {} löschen willst?".format(meta.name)), "Löschen") Table.link(url_for("delete_defaultmeta", defaultmeta_id=meta.id, confirm="Bist du dir sicher, dass du das Metadatenfeld {} löschen willst?".format(meta.name)), "Löschen")
] ]
link_part = [Table.concat(links)] link_part = [Table.concat(links)]
return general_part + link_part return general_part + link_part
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment