180 lines
9.0 KiB
Python
180 lines
9.0 KiB
Python
|
|
from . import APP_ADMIN, SYS_ADMIN, Application, Role, User, dbauth, Userapp
|
|
from .errors import ApplicationError, AutorisationError
|
|
from flask_login import current_user
|
|
current_user: User
|
|
|
|
session = dbauth.session
|
|
|
|
def check_login(userid: str, password: str):
|
|
"""
|
|
Hier wird ausschließlich nur festgestellt, ob Login und Kennwort vorhanden sind bzw. übereinstimmen.
|
|
alles Weitere muss in den Funktionen erfolgen, die 'check_login' aufrufen.
|
|
"""
|
|
user:User = User.query.filter(User.userid == userid).first()
|
|
if user is None or user.password != password:
|
|
return None
|
|
else:
|
|
return user
|
|
|
|
def get_users():
|
|
"""
|
|
Hier werden derzeit alle User zurückgegeben.
|
|
Allerdings werden die userapps eines Users wie folgt gefiltert:
|
|
|
|
Wenn es sich bei dem current_user um den SysAdmin handelt, wird nichts gefiltert
|
|
|
|
Wenn es sich bei dem current_user um den AppAdmin handelt, werden nur die userapps zurückgegeben, auf die auch
|
|
der current_user Zugriff hat. Außerdem wird die Rolle "SysAdmin" innerhalb der userapp.userapp-roles auch nicht
|
|
mit zurückgegeben
|
|
|
|
Bei allen anderen Arten von Usern werden keine userapps und somit auch keine Rollen zurückgegeben
|
|
"""
|
|
users = []
|
|
user: User
|
|
for user in User.query.order_by(User.userid):
|
|
# Wenn der current_user kein SysAdmin ist, soll diese User auch nicht sehen, dass es einen SysAdmin gibt
|
|
if not current_user.is_SysAdmin() and user.is_SysAdmin():
|
|
continue
|
|
# Wenn innerhalb einer For-Schleife Elemente gelöscht werden, muss auf einer Kopie der
|
|
# Liste iteriert werden, da die For-Schleife sonst mit der Nummerierung durcheinanderkommt, weil während
|
|
# des Durchlaufs Werte durch das remove "verschwinden"
|
|
# Daher wird hier für die For-Schleife mit der Funktion list() eine neue Liste der Origonal-Liste erzeugt
|
|
for userapp in list(user.userapps):
|
|
# Rollen für bestimmte Application, in denen der zurückzugebende User Rollen innehat, sollen nur zurück-
|
|
# gegeben werden, wenn der current_user für diese App SysAdmin oder AppAdmin ist
|
|
if not current_user.has_permission(userapp.application.appid, [APP_ADMIN, SYS_ADMIN]):
|
|
user.userapps.remove(userapp)
|
|
# Wenn der current_user für die Application keine SysAdmin-Rolle hat, soll eine evtl. SysAdmin-Rolle auch
|
|
# nicht zurückgegeben werden
|
|
if not current_user.has_permission(userapp.application.appid, [SYS_ADMIN]):
|
|
for role in list(userapp.userapp_roles): # s.o. wegen remove in for-loop
|
|
if role.roleid == SYS_ADMIN:
|
|
userapp.userapp_roles.remove(role)
|
|
users.append(user)
|
|
return users
|
|
|
|
|
|
def changepassword(userid:str, oldpassword:str, newpassword1:str, newpassword2:str):
|
|
"""
|
|
Die Funktion ändert das Kennwort des Users
|
|
|
|
-userid: string Die Userid (nicht id) des Users
|
|
-oldpassword: string Das bisherige Kennwort des Users
|
|
-newpassword1: string Das neue Kennwort des Users
|
|
-newpassword2: string Die Wiederholung des neuen Kennwort des Users
|
|
"""
|
|
if newpassword1 != newpassword2:
|
|
raise ValueError("Die neuen Kennworte stimmen nicht überein!")
|
|
if newpassword1 is None or newpassword1.strip() == "":
|
|
raise ValueError("Es muss ein neues Kennwort angegeben werden!")
|
|
user:User = User.query.filter(User.userid == userid).first()
|
|
if user is None or user.password != oldpassword:
|
|
raise ValueError("Der angegebene Benutzer existiert nicht oder das alte Kennwort ist falsch")
|
|
user.password = newpassword1
|
|
session.commit()
|
|
return True
|
|
|
|
def updateuser(data):
|
|
"""
|
|
Die User-Daten werden nur geändert, wenn der current_user entweder SysAdmin oder AppAdmin ist
|
|
-data: Dict Ein Dictionary mit den Feldern, die beim User geändert werden sollen
|
|
"""
|
|
if not current_user.has_roles([SYS_ADMIN, APP_ADMIN]):
|
|
raise AutorisationError(allowed_roles=[SYS_ADMIN, APP_ADMIN], user_roles=None)
|
|
currentuser: User = None
|
|
if data["id"] == -1:
|
|
currentuser = User()
|
|
currentuser.id = None
|
|
currentuser.password = ""
|
|
session.add(currentuser)
|
|
else:
|
|
currentuser = User.query.get(data["id"])
|
|
if currentuser is None:
|
|
raise Exception ("404")
|
|
currentuser.username = data["username"]
|
|
currentuser.userid = data["userid"]
|
|
currentuser.email = data["email"]
|
|
currentuser.telefon = data["telefon"]
|
|
session.commit()
|
|
|
|
def deleteusers(userids):
|
|
"""
|
|
Hier werden die User gelöscht, deren userids übergeben werden. Gelöscht werden kann aber nur,
|
|
wenn der current_user entweder SysAdmin oder AppAdmin ist.
|
|
Wenn der zu löschende User Rollen in Applications hat, auf die der AppAdmin keinen Zugriff hat,
|
|
Wird der User ebenfalls nicht gelöscht.
|
|
- userids: string[] eine Liste der userids (nicht id) der User, die gelöscht werden sollen
|
|
"""
|
|
# Wenn er schon mal nirgendwo Sys- oder AppAdmin ist, fliegt er schon mal direkt raus
|
|
if not current_user.has_roles([SYS_ADMIN, APP_ADMIN]):
|
|
raise AutorisationError(allowed_roles=[SYS_ADMIN, APP_ADMIN], user_roles=None)
|
|
# ansonsten: hier dürfen nur die User gelöscht werden, die in denjenigen Apps eine Rolle haben,
|
|
# in dene der current_user entweder SysAdmin aod AppAdmin ist. Wenn der User noch eine Rolle in einer App haben,
|
|
# auf die der current_user keinen Zugriff hat, darf nicht gelöscht werden
|
|
for userid in userids:
|
|
user: User = User.query.filter(User.userid == userid).one()
|
|
if user is not None:
|
|
for userapp in user.userapps:
|
|
currentuser_userapp: Userapp = current_user.get_userapp(userapp.application.appid)
|
|
if currentuser_userapp is None or len(currentuser_userapp.userapp_roles) == 0:
|
|
raise ApplicationError(f"Der Benutzer {user.username} hat noch Rollen in Anwendungen, in denen Sie kein AppAdmin oder SysAdmin sind.",
|
|
"Er kann daher nicht gelöscht werden.",
|
|
"Der komplette Löschvorgang wurde abgebrochen.",
|
|
htmlstatus=404)
|
|
session.delete(user)
|
|
session.commit()
|
|
|
|
def applyuserapprole(data):
|
|
"""
|
|
Hier kann einem Benutzer eine Rolle für eine bestimmte App entzogen oder zugewiesen werden
|
|
|
|
### Parameter
|
|
- data: dict
|
|
- parentuserid: integer
|
|
- Die id (nicht userid) des Users, für den eine Rolle geändert werden soll
|
|
- parantappid: integer
|
|
- Die id (nicht appid) der Application, für die eine Rolle geändert werden soll
|
|
- roleid: integer
|
|
- Die id (nicht roleid) der Rolle, die zugewiesen oder entzogen werden soll
|
|
- ischecked: boolean
|
|
- 'True' bedeutet, dass die Rolle zugewiesen werden soll, 'False' bedeutet, dass die Rolle entzogen werden soll
|
|
"""
|
|
user_id = data['parentuserid']
|
|
app_id = data['parentappid']
|
|
ischecked = data['ischecked']
|
|
role_id = data['roleid']
|
|
|
|
user: User = User.query.get(user_id)
|
|
if user is None:
|
|
raise Exception("Den User gibt es nicht")
|
|
app: Application = Application.query.get(app_id)
|
|
if app is None:
|
|
raise Exception("Die Application gibt es nicht")
|
|
role: Role = Role.query.get(role_id)
|
|
if role is None:
|
|
raise Exception("Die Rolle gibt es nicht")
|
|
|
|
# hier darf nur zugewiesen werden, wenn der current_user entweder SysAdmin ist oder AppAdmin in der App,
|
|
# für die die Rolle geändert wird
|
|
if not current_user.is_SysAdmin() and not current_user.has_permission(app.appid, [APP_ADMIN]):
|
|
raise AutorisationError(allowed_roles=[SYS_ADMIN, APP_ADMIN], user_roles=current_user.get_userapproles(app.appid))
|
|
userapp: Userapp = user.get_userapp_by_id(app_id)
|
|
if userapp is None:
|
|
userapp = Userapp()
|
|
userapp.appid = app_id
|
|
user.userapps.append(userapp)
|
|
userapp_role: Role = userapp.get_role(role_id)
|
|
if userapp_role is None and ischecked:
|
|
userapp.userapp_roles.append(role)
|
|
if userapp_role is not None and not ischecked:
|
|
# eine SysAdmin oder ein AppAdmin kann sich selber nicht die Rolle als SysAdmin oder AppAdmin entziehen
|
|
if current_user.userid == user.userid:
|
|
if ((userapp_role.roleid == APP_ADMIN and current_user.has_permission(app.appid, [APP_ADMIN])) or
|
|
(userapp_role.roleid == SYS_ADMIN and current_user.has_permission(app.appid, [SYS_ADMIN]))):
|
|
raise ApplicationError("Sie können sich nicht selbst die Rolle als AppAdmin entziehen, da Sie dann keinen Zugriff auf das System mehr hätten!")
|
|
userapp.userapp_roles.remove(userapp_role) # remove kann hier einfach so verwendet werden, da nicht über userapp.userapp_roles iteriert wird
|
|
session.commit()
|
|
|
|
|