1
0
Fork 0
mirror of https://codeberg.org/Mo8it/AdvLabDB.git synced 2024-09-19 18:31:16 +00:00
AdvLabDB/advlabdb/customClasses.py

150 lines
4.5 KiB
Python
Raw Normal View History

2021-07-30 12:20:54 +00:00
from flask import flash, redirect, request, url_for
2021-09-11 18:48:14 +00:00
from flask_admin import AdminIndexView, BaseView
from flask_admin.contrib.sqla import ModelView
2021-06-02 21:43:41 +00:00
from flask_security import current_user
2021-07-13 15:22:15 +00:00
2021-07-30 12:20:54 +00:00
from advlabdb.exceptions import DataBaseException, ModelViewException
2021-11-30 00:36:19 +00:00
from advlabdb.utils import reportBadAttempt
def adminViewIsAccessible():
return current_user.has_role("admin")
2021-07-30 00:03:44 +00:00
def assistantViewIsAccessible():
return current_user.has_role("assistant")
2021-07-30 00:03:44 +00:00
class CustomIndexView(AdminIndexView):
2021-07-01 12:02:23 +00:00
def inaccessible_callback(self, name, **kwargs):
# Redirect to login page if user doesn't have access
return redirect(url_for("security.login", next=request.url))
2021-07-30 00:03:44 +00:00
class SecureAdminIndexView(CustomIndexView):
def is_accessible(self):
return adminViewIsAccessible()
class SecureAssistantIndexView(CustomIndexView):
def is_accessible(self):
return assistantViewIsAccessible()
class CustomModelView(ModelView):
2021-07-01 11:12:43 +00:00
create_modal = True
edit_modal = True
details_modal = True
queryFilter = None
2021-07-29 22:24:10 +00:00
customCreateModel = None
2021-07-01 12:02:23 +00:00
def inaccessible_callback(self, name, **kwargs):
# Redirect to login page if user doesn't have access
return redirect(url_for("security.login", next=request.url))
def get_query(self):
if self.queryFilter:
return super().get_query().filter(self.queryFilter())
else:
return super().get_query()
def get_count_query(self):
if self.queryFilter:
return super().get_count_query().filter(self.queryFilter())
else:
return super().get_count_query()
2021-07-13 15:22:15 +00:00
def handle_view_exception(self, exc):
if type(exc) in (ModelViewException, DataBaseException):
2021-07-13 15:22:15 +00:00
flash(str(exc), "error")
return True
return super().handle_view_exception(exc)
2021-07-29 22:24:10 +00:00
def create_model(self, form):
if not self.customCreateModel:
return super().create_model(form)
else:
try:
model = self.customCreateModel(form)
self.session.add(model)
self.on_model_change(form, model, True)
self.session.commit()
except Exception as ex:
flash(str(ex), "error")
self.session.rollback()
else:
self.after_model_change(form, model, True)
return model
2021-07-30 00:03:44 +00:00
class SecureAdminModelView(CustomModelView):
2021-11-30 00:36:19 +00:00
can_export = True
can_set_page_size = True
can_create = True
can_edit = True
can_delete = True
column_display_actions = True
2021-07-30 00:03:44 +00:00
list_template = "admin_list.html"
create_template = "admin_create.html"
edit_template = "admin_edit.html"
def is_accessible(self):
return adminViewIsAccessible()
class SecureAssistantModelView(CustomModelView):
2021-11-30 00:36:19 +00:00
can_export = False
can_set_page_size = False
can_create = False
can_edit = False
can_delete = False
column_display_actions = False
2021-07-30 00:03:44 +00:00
list_template = "assistant_list.html"
create_template = "assistant_create.html"
edit_template = "assistant_edit.html"
def is_accessible(self):
return assistantViewIsAccessible()
2021-09-11 18:48:14 +00:00
2021-11-30 00:36:19 +00:00
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!")
2021-09-11 18:48:14 +00:00
class SecureAdminBaseView(BaseView):
def is_accessible(self):
return adminViewIsAccessible()