Merge branch 'pluginify' of groeger-clan.duckdns.org:newgeruecht into pluginify

This commit is contained in:
Tim Gröger 2021-01-22 14:25:49 +01:00
commit cf5278d2e2
5 changed files with 50 additions and 19 deletions

View File

@ -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()

View File

@ -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])

View File

@ -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)
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``

View File

@ -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:

View File

@ -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("_")]