Compare commits

..

No commits in common. "d0674e8876c21a53ab97e7aebfaf622097eae54a" and "593b8546a2905f6b67e59e8812dd7b09f598d0f1" have entirely different histories.

5 changed files with 16 additions and 53 deletions

View File

@ -1,6 +1,5 @@
import secrets
from io import BytesIO
from sqlalchemy import exc
from flask import current_app
from datetime import datetime, timedelta, timezone
from flask.helpers import send_file
@ -169,34 +168,11 @@ def find_user(uid_mail):
return user
@Hook
def delete_user(user: User):
def delete(user):
"""Delete given user"""
# First let the backend delete the user, as this might fail
current_app.config["FG_AUTH_BACKEND"].delete_user(user)
# Clear all easy relationships
user.avatar_ = None
user._attributes.clear()
user.roles_.clear()
user.sessions_.clear()
user.reset_requests_.clear()
db.session.commit()
try:
# Delete the user
db.session.delete(user)
db.session.commit()
except exc.IntegrityError:
logger.error("Delete of user failed, there might be ForeignKey contraits from disabled plugins", exec_info=True)
# Remove at least all personal data
user.userid = f"__deleted_user__{user.id_}"
user.display_name = "DELETED USER"
user.firstname = ""
user.lastname = ""
user.birthday = None
user.mail = None
db.session.commit()
def register(data):

View File

@ -5,9 +5,10 @@ from typing import Optional
from datetime import date, datetime
from sqlalchemy.orm.collections import attribute_mapped_collection
from flaschengeist.models.image import Image
from ..database import db
from . import ModelSerializeMixin, UtcDateTime, Serial
from .image import Image
association_table = db.Table(
@ -62,21 +63,16 @@ class User(db.Model, ModelSerializeMixin):
roles: list[str] = []
permissions: Optional[list[str]] = None
# Protected stuff for backend use only
id_ = db.Column("id", Serial, primary_key=True)
roles_: list[Role] = db.relationship("Role", secondary=association_table, cascade="save-update, merge")
sessions_: list["Session"] = db.relationship(
"Session", back_populates="user_", cascade="all, delete, delete-orphan"
)
sessions_ = db.relationship("Session", back_populates="user_")
avatar_: Optional[Image] = db.relationship("Image", cascade="all, delete, delete-orphan", single_parent=True)
reset_requests_: list["_PasswordReset"] = db.relationship("_PasswordReset", cascade="all, delete, delete-orphan")
# Private stuff for internal use
_avatar_id = db.Column("avatar", Serial, db.ForeignKey("image.id"))
_attributes = db.relationship(
"_UserAttribute",
collection_class=attribute_mapped_collection("name"),
cascade="all, delete, delete-orphan",
cascade="all, delete",
)
@property
@ -121,7 +117,7 @@ class _PasswordReset(db.Model):
__tablename__ = "password_reset"
_user_id: User = db.Column("user", Serial, db.ForeignKey("user.id"), primary_key=True)
user: User = db.relationship("User", back_populates="reset_requests_", foreign_keys=[_user_id])
user: User = db.relationship("User", foreign_keys=[_user_id])
token: str = db.Column(db.String(32))
expires: datetime = db.Column(UtcDateTime)

View File

@ -27,11 +27,6 @@ before_update_user = HookBefore("update_user")
Args:
user: User object
"""
before_delete_user = HookBefore("delete_user")
"""Hook decorator,this is called before an user gets deleted.
Args:
user: User object
"""
class Plugin:

View File

@ -6,7 +6,8 @@ Flaschengeist database (as User attribute)
import os
import hashlib
import binascii
from werkzeug.exceptions import BadRequest
from werkzeug.exceptions import BadRequest, NotFound
from flaschengeist.plugins import AuthPlugin
from flaschengeist.models.user import User, Role, Permission
from flaschengeist.database import db
@ -17,8 +18,6 @@ class AuthPlain(AuthPlugin):
def post_install(self):
if User.query.first() is None:
logger.info("Installing admin user")
role = Role.query.filter(Role.name == "Superuser").first()
if role is None:
role = Role(name="Superuser", permissions=Permission.query.all())
admin = User(
userid="admin",

View File

@ -2,17 +2,18 @@
Provides routes used to manage users
"""
from io import BytesIO
from http.client import NO_CONTENT, CREATED
from flask import Blueprint, request, jsonify, make_response
from flask import Blueprint, request, jsonify, make_response, Response, send_file
from werkzeug.exceptions import BadRequest, Forbidden, MethodNotAllowed, NotFound
from . import permissions
from flaschengeist import logger
from flaschengeist.config import config
from flaschengeist.plugins import Plugin
from flaschengeist.models.user import User
from flaschengeist.models.user import User, _Avatar
from flaschengeist.utils.decorators import login_required, extract_session, headers
from flaschengeist.controller import userController
from flaschengeist.controller import userController, imageController as image_controller
from flaschengeist.utils.HTTP import created, no_content
from flaschengeist.utils.datetime import from_iso_format
@ -22,10 +23,6 @@ class UsersPlugin(Plugin):
blueprint = Blueprint(name, __name__)
permissions = permissions.permissions
def install(self):
userController.install()
return super().install()
@UsersPlugin.blueprint.route("/users", methods=["POST"])
def register():
@ -147,7 +144,7 @@ def delete_avatar(userid, current_session):
if userid != current_session.user_.userid and not current_session.user_.has_permission(permissions.EDIT):
raise Forbidden
userController.delete_avatar(user)
return no_content()
return "", NO_CONTENT
@UsersPlugin.blueprint.route("/users/<userid>", methods=["DELETE"])
@ -166,8 +163,8 @@ def delete_user(userid, current_session):
"""
logger.debug("Delete user {{ {} }}".format(userid))
user = userController.get_user(userid)
userController.delete_user(user)
return no_content()
userController.delete(user)
return "", NO_CONTENT
@UsersPlugin.blueprint.route("/users/<userid>", methods=["PUT"])
@ -220,7 +217,7 @@ def edit_user(userid, current_session):
userController.modify_user(user, password, new_password)
userController.update_user(user)
return no_content()
return "", NO_CONTENT
@UsersPlugin.blueprint.route("/notifications", methods=["GET"])