Merge branch 'pluginify' of groeger-clan.duckdns.org:newgeruecht into pluginify
This commit is contained in:
commit
cf5278d2e2
|
@ -50,7 +50,7 @@ def request_reset(user: User):
|
|||
text = str(config["MESSAGES"]["password_text"]).format(
|
||||
name=user.display_name,
|
||||
username=user.userid,
|
||||
link=f'https://{config["FLASCHENGEIST"]["domain"]}/reset?token={reset.token}'
|
||||
link=f'https://{config["FLASCHENGEIST"]["domain"]}/reset?token={reset.token}',
|
||||
)
|
||||
messageController.send_message(messageController.Message(user, text, subject))
|
||||
|
||||
|
@ -106,7 +106,9 @@ def modify_user(user, password, new_password=None):
|
|||
|
||||
if new_password:
|
||||
logger.debug(f"Password changed for user {user.userid}")
|
||||
subject = str(config["MESSAGES"]["password_changed_subject"]).format(name=user.display_name, username=user.userid)
|
||||
subject = str(config["MESSAGES"]["password_changed_subject"]).format(
|
||||
name=user.display_name, username=user.userid
|
||||
)
|
||||
text = str(config["MESSAGES"]["password_changed_text"]).format(
|
||||
name=user.display_name,
|
||||
username=user.userid,
|
||||
|
@ -185,7 +187,7 @@ def register(data):
|
|||
text = str(config["MESSAGES"]["welcome_text"]).format(
|
||||
name=user.display_name,
|
||||
username=user.userid,
|
||||
password_link=f'https://{config["FLASCHENGEIST"]["domain"]}/reset?token={reset.token}'
|
||||
password_link=f'https://{config["FLASCHENGEIST"]["domain"]}/reset?token={reset.token}',
|
||||
)
|
||||
messageController.send_message(messageController.Message(user, text, subject))
|
||||
|
||||
|
@ -199,3 +201,9 @@ def load_avatar(user: User):
|
|||
def save_avatar(user, avatar):
|
||||
current_app.config["FG_AUTH_BACKEND"].set_avatar(user, avatar)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def persist(user=None):
|
||||
if user:
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
|
|
@ -104,6 +104,7 @@ class _UserAttribute(db.Model, ModelSerializeMixin):
|
|||
|
||||
class _PasswordReset(db.Model):
|
||||
"""Table containing password reset requests"""
|
||||
|
||||
__tablename__ = "password_reset"
|
||||
_user_id: User = db.Column("user", db.Integer, db.ForeignKey("user.id"), primary_key=True)
|
||||
user: User = db.relationship("User", foreign_keys=[_user_id])
|
||||
|
|
|
@ -4,6 +4,8 @@ Extends users plugin with balance functions
|
|||
"""
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from flaschengeist.utils.HTTP import no_content
|
||||
from flask import Blueprint, request, jsonify
|
||||
from werkzeug.exceptions import Forbidden, BadRequest
|
||||
|
||||
|
@ -39,31 +41,41 @@ class BalancePlugin(Plugin):
|
|||
db.create_all()
|
||||
|
||||
|
||||
@balance_bp.route("/users/<userid>/balance/shortcuts", methods=["GET"])
|
||||
@balance_bp.route("/users/<userid>/balance/shortcuts", methods=["GET", "PUT"])
|
||||
@login_required()
|
||||
def get_shortcuts(userid, current_session: Session):
|
||||
"""Get set limit of an user
|
||||
"""Get balance shortcuts of an user
|
||||
|
||||
Route: ``/users/<userid>/balance/limit`` | Method: ``GET``
|
||||
Route: ``/users/<userid>/balance/shortcuts`` | Method: ``GET`` or ``PUT``
|
||||
POST-data: On ``PUT`` json encoded array of floats
|
||||
|
||||
Args:
|
||||
userid: Userid identifying the user
|
||||
current_session: Session sent with Authorization Header
|
||||
|
||||
Returns:
|
||||
JSON object containing the limit (or Null if no limit set) or HTTP error
|
||||
GET: JSON object containing the shortcuts as float array or HTTP error
|
||||
PUT: HTTP-created or HTTP error
|
||||
"""
|
||||
if userid != current_session._user.userid:
|
||||
raise Forbidden
|
||||
|
||||
user = userController.get_user(userid)
|
||||
return jsonify(user.get_attribute("balance_shortcuts", []))
|
||||
if request.method == "GET":
|
||||
return jsonify(user.get_attribute("balance_shortcuts", []))
|
||||
else:
|
||||
data = request.get_json()
|
||||
if not isinstance(data, list) or not all(isinstance(n, (int, float)) for n in data):
|
||||
raise BadRequest
|
||||
user.set_attribute("balance_shortcuts", data)
|
||||
userController.persist()
|
||||
return no_content()
|
||||
|
||||
|
||||
@balance_bp.route("/users/<userid>/balance/limit", methods=["GET"])
|
||||
@login_required()
|
||||
def get_limit(userid, current_session: Session):
|
||||
"""Get set limit of an user
|
||||
"""Get limit of an user
|
||||
|
||||
Route: ``/users/<userid>/balance/limit`` | Method: ``GET``
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ from flaschengeist.config import config
|
|||
from flask import Blueprint, request, jsonify, make_response, Response
|
||||
from werkzeug.exceptions import BadRequest, Forbidden, MethodNotAllowed, NotFound
|
||||
|
||||
from . import permissions
|
||||
from flaschengeist import logger
|
||||
from flaschengeist.models.user import User, _Avatar
|
||||
from flaschengeist.plugins import Plugin
|
||||
|
@ -17,15 +18,11 @@ from flaschengeist.utils.HTTP import created
|
|||
from flaschengeist.utils.datetime import from_iso_format
|
||||
|
||||
users_bp = Blueprint("users", __name__)
|
||||
_permission_edit = "users_edit_other"
|
||||
_permission_set_roles = "users_set_roles"
|
||||
_permission_delete = "users_delete_other"
|
||||
_permission_register = "users_register"
|
||||
|
||||
|
||||
class UsersPlugin(Plugin):
|
||||
def __init__(self, cfg):
|
||||
super().__init__(blueprint=users_bp, permissions=[_permission_edit, _permission_delete, _permission_set_roles])
|
||||
super().__init__(blueprint=users_bp, permissions=permissions.permissions)
|
||||
|
||||
|
||||
@users_bp.route("/users", methods=["POST"])
|
||||
|
@ -46,7 +43,7 @@ def register():
|
|||
logger.debug("Config for Registration is set to >{}<".format(registration))
|
||||
raise MethodNotAllowed
|
||||
if registration == "managed":
|
||||
extract_session(_permission_register)
|
||||
extract_session(permissions.REGISTER)
|
||||
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
|
@ -114,7 +111,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(_permission_edit):
|
||||
if userid != current_session._user.userid and not current_session._user.has_permission(permissions.EDIT):
|
||||
raise Forbidden
|
||||
|
||||
file = request.files.get("file")
|
||||
|
@ -129,7 +126,7 @@ def set_avatar(userid, current_session):
|
|||
|
||||
|
||||
@users_bp.route("/users/<userid>", methods=["DELETE"])
|
||||
@login_required(permission=_permission_delete)
|
||||
@login_required(permission=permissions.DELETE)
|
||||
def delete_user(userid, current_session):
|
||||
"""Delete user by userid
|
||||
|
||||
|
@ -175,7 +172,7 @@ def edit_user(userid, current_session):
|
|||
author = user
|
||||
if userid != current_session._user.userid:
|
||||
author = current_session._user
|
||||
if not author.has_permission(_permission_edit):
|
||||
if not author.has_permission(permissions.EDIT):
|
||||
raise Forbidden
|
||||
else:
|
||||
if "password" not in data:
|
||||
|
@ -190,7 +187,7 @@ def edit_user(userid, current_session):
|
|||
|
||||
if "roles" in data:
|
||||
roles = set(data["roles"])
|
||||
if not author.has_permission(_permission_set_roles):
|
||||
if not author.has_permission(permissions.SET_ROLES):
|
||||
if len(roles) != len(user.roles) or set(user.roles) != roles:
|
||||
raise Forbidden
|
||||
else:
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
EDIT = "users_edit_other"
|
||||
"""Can edit other users"""
|
||||
|
||||
SET_ROLES = "users_set_roles"
|
||||
"""Can assign roles to users"""
|
||||
|
||||
DELETE = "users_delete"
|
||||
"""Can delete users"""
|
||||
|
||||
REGISTER = "users_register"
|
||||
"""Can register new users"""
|
||||
|
||||
permissions = [value for key, value in globals().items() if not key.startswith("_")]
|
Loading…
Reference in New Issue