diff --git a/advlabdb/customClasses.py b/advlabdb/customClasses.py index af10a17..a822562 100644 --- a/advlabdb/customClasses.py +++ b/advlabdb/customClasses.py @@ -4,6 +4,7 @@ from flask_admin.contrib.sqla import ModelView from flask_security import current_user from advlabdb.exceptions import DataBaseException, ModelViewException +from advlabdb.utils import reportBadAttempt def adminViewIsAccessible(): @@ -31,9 +32,6 @@ class SecureAssistantIndexView(CustomIndexView): class CustomModelView(ModelView): - can_export = True - can_set_page_size = True - create_modal = True edit_modal = True details_modal = True @@ -87,6 +85,14 @@ class CustomModelView(ModelView): class SecureAdminModelView(CustomModelView): + can_export = True + can_set_page_size = True + + can_create = True + can_edit = True + can_delete = True + column_display_actions = True + list_template = "admin_list.html" create_template = "admin_create.html" edit_template = "admin_edit.html" @@ -96,6 +102,14 @@ class SecureAdminModelView(CustomModelView): class SecureAssistantModelView(CustomModelView): + can_export = False + can_set_page_size = False + + can_create = False + can_edit = False + can_delete = False + column_display_actions = False + list_template = "assistant_list.html" create_template = "assistant_create.html" edit_template = "assistant_edit.html" @@ -103,6 +117,32 @@ class SecureAssistantModelView(CustomModelView): def is_accessible(self): return assistantViewIsAccessible() + def queryFilter(self): + """ + A default filter has to be implemented to restrict assistants read/write access. + See on_model_change! + """ + raise ModelViewException("Not implemented!") + + def on_model_change(self, form, model, is_created): + """ + This method is NOT ALLOWED TO BE (completely) OVERWRITTEN! + This method uses the filter returned by queryFilter (which has to be implemented!) to prevent assistants + from modifing models not listed on their view by sending a POST request with a different id. + You can extend this method by implementing a custom on_model_change and then calling super().on_model_change within it. + """ + if is_created: + reportBadAttempt("An assistant tried to create a model!") + raise ModelViewException("Assistants can not create models!") + + if model not in self.get_query(): + reportBadAttempt("An assistant tried to change a model not in his filter!") + raise ModelViewException("Unauthorized action!") + + def on_model_delete(self, model): + reportBadAttempt("An assistant tried to delete a model!") + raise ModelViewException("Assistants can not delete models!") + class SecureAdminBaseView(BaseView): def is_accessible(self): diff --git a/advlabdb/utils.py b/advlabdb/utils.py index 0a31115..63c50d0 100644 --- a/advlabdb/utils.py +++ b/advlabdb/utils.py @@ -63,3 +63,7 @@ def initActiveSemesterMenuLinks(space): ) space.add_link(MenuLink(name="Logout", url=url_for("security.logout"))) + + +def reportBadAttempt(message): + print("BAD ATTEMPT:", message) # TODO: Log