diff --git a/flaschengeist/controller/sessionController.py b/flaschengeist/controller/sessionController.py index a3e08f8..4cae005 100644 --- a/flaschengeist/controller/sessionController.py +++ b/flaschengeist/controller/sessionController.py @@ -31,7 +31,7 @@ def validate_token(token, user_agent, permission): if session.expires >= datetime.now(timezone.utc) and ( session.browser == user_agent.browser and session.platform == user_agent.platform ): - if not permission or session._user.has_permission(permission): + if not permission or session.user_.has_permission(permission): session.refresh() db.session.commit() return session @@ -58,7 +58,7 @@ def create(user, user_agent=None) -> Session: token_str = secrets.token_hex(16) session = Session( token=token_str, - _user=user, + user_=user, lifetime=lifetime, browser=user_agent.browser, platform=user_agent.platform, @@ -83,13 +83,13 @@ def get_session(token, owner=None): Session: Token object identified by given token string """ session = Session.query.filter(Session.token == token).one_or_none() - if session and (owner and owner != session._user): + if session and (owner and owner != session.user_): raise Forbidden return session def get_users_sessions(user): - return Session.query.filter(Session._user == user) + return Session.query.filter(Session.user_ == user) def delete_sessions(user): @@ -98,7 +98,7 @@ def delete_sessions(user): Args: user (User): User to delete all sessions for """ - Session.query.filter(Session._user_id == user._id).delete() + Session.query.filter(Session.user_.id_ == user.id_).delete() db.session.commit() diff --git a/flaschengeist/controller/userController.py b/flaschengeist/controller/userController.py index 111db65..a84b795 100644 --- a/flaschengeist/controller/userController.py +++ b/flaschengeist/controller/userController.py @@ -14,9 +14,9 @@ from flaschengeist.controller import messageController, sessionController def _generate_password_reset(user): """Generate a password reset link for the user""" - reset = _PasswordReset.query.get(user._id) + reset = _PasswordReset.query.get(user.id_) if not reset: - reset = _PasswordReset(_user_id=user._id) + reset = _PasswordReset(_user_id=user.id_) db.session.add(reset) expires = datetime.now(tz=timezone.utc) diff --git a/flaschengeist/models/session.py b/flaschengeist/models/session.py index c170ad6..7822804 100644 --- a/flaschengeist/models/session.py +++ b/flaschengeist/models/session.py @@ -27,12 +27,12 @@ class Session(db.Model, ModelSerializeMixin): userid: str = "" _id = db.Column("id", db.Integer, primary_key=True) - _user: User = db.relationship("User", back_populates="_sessions") _user_id = db.Column("user_id", db.Integer, db.ForeignKey("user.id")) + user_: User = db.relationship("User", back_populates="sessions_") @property def userid(self): - return self._user.userid + return self.user_.userid def refresh(self): """Update the Timestamp diff --git a/flaschengeist/models/user.py b/flaschengeist/models/user.py index 6e23e4b..4118120 100644 --- a/flaschengeist/models/user.py +++ b/flaschengeist/models/user.py @@ -62,9 +62,10 @@ class User(db.Model, ModelSerializeMixin): permissions: Optional[list[str]] = None avatar_url: Optional[str] = "" + id_ = db.Column("id", db.Integer, primary_key=True) roles_: list[Role] = db.relationship("Role", secondary=association_table, cascade="save-update, merge") - _id = db.Column("id", db.Integer, primary_key=True) - _sessions = db.relationship("Session", back_populates="_user") + sessions_ = db.relationship("Session", back_populates="user_") + _attributes = db.relationship( "_UserAttribute", collection_class=attribute_mapped_collection("name"), cascade="all, delete" ) diff --git a/flaschengeist/plugins/auth/__init__.py b/flaschengeist/plugins/auth/__init__.py index 07b00c4..f2289f0 100644 --- a/flaschengeist/plugins/auth/__init__.py +++ b/flaschengeist/plugins/auth/__init__.py @@ -62,7 +62,7 @@ def get_sessions(current_session, **kwargs): Returns: A JSON array of `flaschengeist.models.session.Session` or HTTP error """ - sessions = sessionController.get_users_sessions(current_session._user) + sessions = sessionController.get_users_sessions(current_session.user_) return jsonify(sessions) @@ -77,7 +77,7 @@ def delete_session(token, current_session, **kwargs): 200 Status (empty) or HTTP error """ logger.debug("Try to delete access token {{ {} }}".format(token)) - session = sessionController.get_session(token, current_session._user) + session = sessionController.get_session(token, current_session.user_) if not session: logger.debug("Token not found in database!") # Return 403 error, so that users can not bruteforce tokens @@ -103,7 +103,7 @@ def get_session(token, current_session, **kwargs): JSON encoded `flaschengeist.models.session.Session` or HTTP error """ logger.debug("get token {{ {} }}".format(token)) - session = sessionController.get_session(token, current_session._user) + session = sessionController.get_session(token, current_session.user_) if not session: # Return 403 error, so that users can not bruteforce tokens # Valid tokens from other users and invalid tokens now are looking the same @@ -127,7 +127,7 @@ def set_lifetime(token, current_session, **kwargs): Returns: HTTP-204 or HTTP error """ - session = sessionController.get_session(token, current_session._user) + session = sessionController.get_session(token, current_session.user_) if not session: # Return 403 error, so that users can not bruteforce tokens # Valid tokens from other users and invalid tokens now are looking the same @@ -136,7 +136,7 @@ def set_lifetime(token, current_session, **kwargs): lifetime = request.get_json()["value"] logger.debug(f"set lifetime >{lifetime}< to access token >{token}<") sessionController.set_lifetime(session, lifetime) - return jsonify(sessionController.get_session(token, current_session._user)) + return jsonify(sessionController.get_session(token, current_session.user_)) except (KeyError, TypeError): raise BadRequest @@ -156,12 +156,12 @@ def get_assocd_user(token, current_session, **kwargs): JSON encoded `flaschengeist.models.user.User` or HTTP error """ logger.debug("get token {{ {} }}".format(token)) - session = sessionController.get_session(token, current_session._user) + session = sessionController.get_session(token, current_session.user_) if not session: # Return 403 error, so that users can not bruteforce tokens # Valid tokens from other users and invalid tokens now are looking the same raise Forbidden - return jsonify(session._user) + return jsonify(session.user_) @auth_bp.route("/auth/reset", methods=["POST"]) diff --git a/flaschengeist/plugins/balance/__init__.py b/flaschengeist/plugins/balance/__init__.py index edaa2a4..fc424bb 100644 --- a/flaschengeist/plugins/balance/__init__.py +++ b/flaschengeist/plugins/balance/__init__.py @@ -67,7 +67,7 @@ def get_shortcuts(userid, current_session: Session): GET: JSON object containing the shortcuts as float array or HTTP error PUT: HTTP-created or HTTP error """ - if userid != current_session._user.userid: + if userid != current_session.user_.userid: raise Forbidden user = userController.get_user(userid) @@ -98,8 +98,8 @@ def get_limit(userid, current_session: Session): JSON object containing the limit (or Null if no limit set) or HTTP error """ user = userController.get_user(userid) - if (user != current_session._user and not current_session._user.has_permission(permissions.SET_LIMIT)) or ( - user == current_session._user and not user.has_permission(permissions.SHOW) + if (user != current_session.user_ and not current_session.user_.has_permission(permissions.SET_LIMIT)) or ( + user == current_session.user_ and not user.has_permission(permissions.SHOW) ): raise Forbidden @@ -148,7 +148,7 @@ def get_balance(userid, current_session: Session): Returns: JSON object containing credit, debit and balance or HTTP error """ - if userid != current_session._user.userid and not current_session._user.has_permission(permissions.SHOW_OTHER): + if userid != current_session.user_.userid and not current_session.user_.has_permission(permissions.SHOW_OTHER): raise Forbidden # Might raise NotFound @@ -187,7 +187,7 @@ def get_transactions(userid, current_session: Session): Returns: JSON Object {transactions: Transaction[], count?: number} or HTTP error """ - if userid != current_session._user.userid and not current_session._user.has_permission(permissions.SHOW_OTHER): + if userid != current_session.user_.userid and not current_session.user_.has_permission(permissions.SHOW_OTHER): raise Forbidden # Might raise NotFound @@ -253,19 +253,19 @@ def change_balance(userid, current_session: Session): if sender == user: raise BadRequest - if (sender == current_session._user and sender.has_permission(permissions.SEND)) or ( - sender != current_session._user and current_session._user.has_permission(permissions.SEND_OTHER) + if (sender == current_session.user_ and sender.has_permission(permissions.SEND)) or ( + sender != current_session.user_ and current_session.user_.has_permission(permissions.SEND_OTHER) ): - return HTTP.created(balance_controller.send(sender, user, amount, current_session._user)) + return HTTP.created(balance_controller.send(sender, user, amount, current_session.user_)) elif ( amount < 0 and ( - (user == current_session._user and user.has_permission(permissions.DEBIT_OWN)) - or current_session._user.has_permission(permissions.DEBIT) + (user == current_session.user_ and user.has_permission(permissions.DEBIT_OWN)) + or current_session.user_.has_permission(permissions.DEBIT) ) - ) or (amount > 0 and current_session._user.has_permission(permissions.CREDIT)): - return HTTP.created(balance_controller.change_balance(user, data["amount"], current_session._user)) + ) or (amount > 0 and current_session.user_.has_permission(permissions.CREDIT)): + return HTTP.created(balance_controller.change_balance(user, data["amount"], current_session.user_)) raise Forbidden @@ -286,11 +286,11 @@ def reverse_transaction(transaction_id, current_session: Session): """ transaction = balance_controller.get_transaction(transaction_id) - if current_session._user.has_permission(permissions.REVERSAL) or ( - transaction.sender_ == current_session._user + if current_session.user_.has_permission(permissions.REVERSAL) or ( + transaction.sender_ == current_session.user_ and (datetime.now(tz=timezone.utc) - transaction.time).total_seconds() < 10 ): - reversal = balance_controller.reverse_transaction(transaction, current_session._user) + reversal = balance_controller.reverse_transaction(transaction, current_session.user_) return HTTP.created(reversal) raise Forbidden diff --git a/flaschengeist/plugins/balance/models.py b/flaschengeist/plugins/balance/models.py index 41c3520..be504aa 100644 --- a/flaschengeist/plugins/balance/models.py +++ b/flaschengeist/plugins/balance/models.py @@ -20,13 +20,13 @@ class Transaction(db.Model, ModelSerializeMixin): id: int = db.Column("id", db.Integer, primary_key=True) time: datetime = db.Column(UtcDateTime, nullable=False, default=UtcDateTime.current_utc) amount: float = db.Column(db.Numeric(precision=5, scale=2, asdecimal=False), nullable=False) - reversal_id: int = db.Column(db.Integer, db.ForeignKey("balance_transaction.id")) + reversal_id: Optional[int] = db.Column(db.Integer, db.ForeignKey("balance_transaction.id")) # Dummy properties used for JSON serialization (userid instead of full user) - sender_id: Optional[str] = "" - receiver_id: Optional[str] = "" - author_id: Optional[str] = "" - original_id: Optional[int] = -1 + author_id: Optional[str] = None + sender_id: Optional[str] = None + original_id: Optional[int] = None + receiver_id: Optional[str] = None # Not exported relationships just in backend only sender_: User = db.relationship("User", foreign_keys=[_sender_id]) @@ -40,7 +40,7 @@ class Transaction(db.Model, ModelSerializeMixin): @sender_id.expression def sender_id(cls): - return db.select([User.userid]).where(cls._sender_id == User._id).as_scalar() + return db.select([User.userid]).where(cls._sender_id == User.id_).as_scalar() @hybrid_property def receiver_id(self): @@ -48,7 +48,7 @@ class Transaction(db.Model, ModelSerializeMixin): @receiver_id.expression def receiver_id(cls): - return db.select([User.userid]).where(cls._receiver_id == User._id).as_scalar() + return db.select([User.userid]).where(cls._receiver_id == User.id_).as_scalar() @property def author_id(self): diff --git a/flaschengeist/plugins/pricelist/__init__.py b/flaschengeist/plugins/pricelist/__init__.py index b015e85..de9eb35 100644 --- a/flaschengeist/plugins/pricelist/__init__.py +++ b/flaschengeist/plugins/pricelist/__init__.py @@ -241,7 +241,7 @@ def get_columns(userid, current_session: Session): GET: JSON object containing the shortcuts as float array or HTTP error PUT: HTTP-created or HTTP error """ - if userid != current_session._user.userid: + if userid != current_session.user_.userid: raise Forbidden user = userController.get_user(userid) diff --git a/flaschengeist/plugins/schedule/__init__.py b/flaschengeist/plugins/schedule/__init__.py index d21b4f3..a2e3ec0 100644 --- a/flaschengeist/plugins/schedule/__init__.py +++ b/flaschengeist/plugins/schedule/__init__.py @@ -388,15 +388,15 @@ def update_job(event_id, job_id, current_session: Session): if not data: raise BadRequest - if ("user" not in data or len(data) > 1) and not current_session._user.has_permission(permissions.EDIT): + if ("user" not in data or len(data) > 1) and not current_session.user_.has_permission(permissions.EDIT): raise Forbidden if "user" in data: try: user = userController.get_user(data["user"]["userid"]) value = data["user"]["value"] - if (user == current_session._user and not user.has_permission(permissions.ASSIGN)) or ( - user != current_session._user and not current_session._user.has_permission(permissions.ASSIGN_OTHER) + if (user == current_session.user_ and not user.has_permission(permissions.ASSIGN)) or ( + user != current_session.user_ and not current_session.user_.has_permission(permissions.ASSIGN_OTHER) ): raise Forbidden event_controller.assign_to_job(job, user, value) diff --git a/flaschengeist/plugins/users/__init__.py b/flaschengeist/plugins/users/__init__.py index 02e565e..277aca1 100644 --- a/flaschengeist/plugins/users/__init__.py +++ b/flaschengeist/plugins/users/__init__.py @@ -92,7 +92,7 @@ def get_user(userid, current_session): logger.debug("Get information of user {{ {} }}".format(userid)) user: User = userController.get_user(userid) serial = user.serialize() - if userid == current_session._user.userid: + if userid == current_session.user_.userid: serial["permissions"] = user.get_permissions() return jsonify(serial) @@ -113,7 +113,7 @@ def get_avatar(userid): @login_required() def set_avatar(userid, current_session): user = userController.get_user(userid) - if userid != current_session._user.userid and not current_session._user.has_permission(permissions.EDIT): + if userid != current_session.user_.userid and not current_session.user_.has_permission(permissions.EDIT): raise Forbidden file = request.files.get("file") @@ -172,8 +172,8 @@ def edit_user(userid, current_session): new_password = data["new_password"] if "new_password" in data else None author = user - if userid != current_session._user.userid: - author = current_session._user + if userid != current_session.user_.userid: + author = current_session.user_ if not author.has_permission(permissions.EDIT): raise Forbidden else: