flaschengeist/flaschengeist/plugins/users/__init__.py

161 lines
4.8 KiB
Python

"""Users plugin
Provides routes used to manage users
"""
from http.client import NO_CONTENT, CREATED
from flaschengeist.config import config
from flask import Blueprint, request, jsonify, make_response
from werkzeug.exceptions import BadRequest, Forbidden, MethodNotAllowed
from flaschengeist import logger
from flaschengeist.models.user import User
from flaschengeist.plugins import Plugin
from flaschengeist.decorator import login_required, extract_session
from flaschengeist.controller import userController
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, config):
super().__init__(blueprint=users_bp, permissions=[_permission_edit, _permission_delete, _permission_set_roles])
@users_bp.route("/users", methods=["POST"])
def register():
"""Register a new user
Route: ``/users`` | Method: ``POST``
POST-data: Same as `flaschengeist.models.user.User` + ``password?: string``
Returns:
JSON encoded `flaschengeist.models.user.User` or HTTP error
"""
registration = config["users"].get("registration", False)
if not registration or registration not in ["managed", "public"]:
logger.debug("Config for Registration is set to >{}<".format(registration))
raise MethodNotAllowed
if registration == "managed":
extract_session(_permission_register)
data = request.get_json()
if not data:
raise BadRequest
logger.debug("Register new User...")
return make_response(jsonify(userController.register(data)), CREATED)
@users_bp.route("/users", methods=["GET"])
@login_required()
def list_users(current_session):
"""List all existing users
Route: ``/users`` | Method: ``GET``
Args:
current_session: Session sent with Authorization Header
Returns:
JSON encoded array of `flaschengeist.models.user.User` or HTTP error
"""
logger.debug("Retrieve list of all users")
users = userController.get_users()
return jsonify(users)
@users_bp.route("/users/<userid>", methods=["GET"])
@login_required()
def get_user(userid, current_session):
"""Retrieve user by userid
Route: ``/users/<userid>`` | Method: ``GET``
Args:
userid: UserID of user to retrieve
current_session: Session sent with Authorization Header
Returns:
JSON encoded `flaschengeist.models.user.User` or if userid is current user also containing permissions or HTTP error
"""
logger.debug("Get information of user {{ {} }}".format(userid))
user: User = userController.get_user(userid)
serial = user.serialize()
if (userid == current_session._user.userid):
serial['permissions'] = user.get_permissions()
return jsonify(serial)
@users_bp.route("/users/<userid>", methods=["DELETE"])
@login_required(permission=_permission_delete)
def delete_user(userid, current_session):
"""Delete user by userid
Route: ``/users/<userid>`` | Method: ``DELETE``
Args:
userid: UserID of user to retrieve
current_session: Session sent with Authorization Header
Returns:
HTTP-204 or HTTP error
"""
logger.debug("Delete user {{ {} }}".format(userid))
user = userController.get_user(userid)
userController.delete(user)
return "", NO_CONTENT
@users_bp.route("/users/<userid>", methods=["PUT"])
@login_required()
def edit_user(userid, current_session):
"""Modify user by userid
Route: ``/users/<userid>`` | Method: ``PUT``
POST-data: ```{firstname?: string, lastname?: string, display_name?: string, mail?: string,
password?: string, roles?: string[]}```
Args:
userid: UserID of user to retrieve
current_session: Session sent with Authorization Header
Returns:
HTTP-204 or HTTP error
"""
logger.debug("Modify information of user {{ {} }}".format(userid))
user = userController.get_user(userid)
data = request.get_json()
password = None
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 not author.has_permission(_permission_edit):
raise Forbidden
else:
if "password" not in data:
raise BadRequest("Password is missing")
password = data["password"]
for key in ["firstname", "lastname", "display_name", "mail"]:
if key in data:
setattr(user, key, data[key])
if "roles" in data:
if not author.has_permission(_permission_set_roles):
raise Forbidden
userController.set_roles(user, data["roles"])
userController.modify_user(user, password, new_password)
userController.update_user(user)
return "", NO_CONTENT