From ec05cde746d449039b9909cad5b310e9e51bcc09 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Fri, 16 Oct 2020 00:37:57 +0200 Subject: [PATCH] Fixed Hooks, use own implementation. Fixed routes. --- flaschengeist/modules/__init__.py | 4 +- flaschengeist/modules/auth/__init__.py | 167 +++++----- flaschengeist/modules/message_mail.py | 22 +- flaschengeist/modules/roles/__init__.py | 116 +++---- flaschengeist/modules/schedule/__init__.py | 309 +++++++++--------- flaschengeist/modules/users/__init__.py | 78 ++--- flaschengeist/readme.md | 15 + .../system/controller/messageController.py | 3 +- flaschengeist/system/hook.py | 20 ++ setup.py | 1 - 10 files changed, 405 insertions(+), 330 deletions(-) create mode 100644 flaschengeist/system/hook.py diff --git a/flaschengeist/modules/__init__.py b/flaschengeist/modules/__init__.py index c594c46..fa0bb92 100644 --- a/flaschengeist/modules/__init__.py +++ b/flaschengeist/modules/__init__.py @@ -1,6 +1,6 @@ -from pyhooks import precall_register +from flaschengeist.system.hook import HookCall -send_message_hook = precall_register("send_message") +send_message_hook = HookCall("send_message") class Plugin: diff --git a/flaschengeist/modules/auth/__init__.py b/flaschengeist/modules/auth/__init__.py index 31218a5..0d57e72 100644 --- a/flaschengeist/modules/auth/__init__.py +++ b/flaschengeist/modules/auth/__init__.py @@ -11,7 +11,7 @@ from werkzeug.local import LocalProxy from flaschengeist import logger from flaschengeist.modules import Plugin from flaschengeist.system.decorator import login_required -from flaschengeist.system.controller import accessTokenController, userController +from flaschengeist.system.controller import accessTokenController, userController, messageController access_controller = LocalProxy(lambda: accessTokenController.AccessTokenController()) auth_bp = Blueprint("auth", __name__) @@ -21,89 +21,96 @@ class AuthRoutePlugin(Plugin): def __init__(self, conf): super().__init__(blueprint=auth_bp) - ################################################# - # Routes # - # # - # /auth POST: login (new token) # - # GET: get all tokens for user # - # /auth/ GET: get lifetime of token # - # PUT: set new lifetime # - # DELETE: logout / delete token # - ################################################# +################################################# +# Routes # +# # +# /auth POST: login (new token) # +# GET: get all tokens for user # +# /auth/ GET: get lifetime of token # +# PUT: set new lifetime # +# DELETE: logout / delete token # +################################################# - @auth_bp.route("/auth", methods=["POST"]) - def _create_token(): - """Login User - Login in User and create an AccessToken for the User. - Requires POST data {'userid': string, 'password': string} - Returns: - A JSON-File with user information and created token or errors - """ - logger.debug("Start log in.") - data = request.get_json() - try: - userid = data["userid"] - password = data["password"] - except KeyError: - raise BadRequest("Missing parameter(s)") +@auth_bp.route("/auth", methods=["POST"]) +def _create_token(): + """Login User - logger.debug("search user {{ {} }} in database".format(userid)) - user = userController.login_user(userid, password) - if not user: - raise Unauthorized - logger.debug("user is {{ {} }}".format(user)) - token = access_controller.create(user, user_agent=request.user_agent) - logger.debug("access token is {{ {} }}".format(token)) - logger.info("User {{ {} }} success login.".format(userid)) + Login in User and create an AccessToken for the User. + Requires POST data {'userid': string, 'password': string} + Returns: + A JSON-File with user information and created token or errors + """ + logger.debug("Start log in.") + data = request.get_json() + try: + userid = data["userid"] + password = data["password"] + except KeyError: + raise BadRequest("Missing parameter(s)") - # Lets cleanup the DB - access_controller.clear_expired() - return jsonify({"user": user, "token": token, "permissions": user.get_permissions()}) + logger.debug("search user {{ {} }} in database".format(userid)) + user = userController.login_user(userid, password) + if not user: + raise Unauthorized + logger.debug("user is {{ {} }}".format(user)) + token = access_controller.create(user, user_agent=request.user_agent) + logger.debug("access token is {{ {} }}".format(token)) + logger.info("User {{ {} }} success login.".format(userid)) - @auth_bp.route("/auth", methods=["GET"]) - @login_required() - def _get_tokens(access_token, **kwargs): - tokens = access_controller.get_users_tokens(access_token.user) - return jsonify(tokens) + # Lets cleanup the DB + access_controller.clear_expired() + return jsonify({"user": user, "token": token, "permissions": user.get_permissions()}) - @auth_bp.route("/auth/", methods=["DELETE"]) - @login_required() - def _delete_token(token, access_token, **kwargs): - logger.debug("Try to delete access token {{ {} }}".format(token)) - token = access_controller.get_token(token, access_token.user) - if not token: - logger.debug("Token not found in database!") - # 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 - access_controller.delete_token(token) - access_controller.clear_expired() + +@auth_bp.route("/auth", methods=["GET"]) +@login_required() +def _get_tokens(access_token, **kwargs): + tokens = access_controller.get_users_tokens(access_token.user) + a = messageController.Message(access_token.user, "Go", "Bar") + messageController.send_message(a) + return jsonify(tokens) + + +@login_required() +@auth_bp.route("/auth/", methods=["DELETE"]) +def _delete_token(token, access_token, **kwargs): + logger.debug("Try to delete access token {{ {} }}".format(token)) + token = access_controller.get_token(token, access_token.user) + if not token: + logger.debug("Token not found in database!") + # 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 + access_controller.delete_token(token) + access_controller.clear_expired() + return jsonify({"ok": "ok"}) + + +@login_required() +@auth_bp.route("/auth/", methods=["GET"]) +def _get_token(token, access_token, **kwargs): + logger.debug("get token {{ {} }}".format(token)) + token = access_controller.get_token(token, access_token.user) + if not token: + # 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(token) + + +@login_required() +@auth_bp.route("/auth/", methods=["PUT"]) +def _set_lifetime(token, access_token, **kwargs): + token = access_controller.get_token(token, access_token.user) + if not token: + # 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 + try: + lifetime = request.get_json()["value"] + logger.debug("set lifetime {{ {} }} to access token {{ {} }}".format(lifetime, token)) + access_controller.set_lifetime(token, lifetime) return jsonify({"ok": "ok"}) - - @auth_bp.route("/auth/", methods=["GET"]) - @login_required() - def _get_token(token, access_token, **kwargs): - logger.debug("get token {{ {} }}".format(token)) - token = access_controller.get_token(token, access_token.user) - if not token: - # 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(token) - - @auth_bp.route("/auth/", methods=["PUT"]) - @login_required() - def _set_lifetime(token, access_token, **kwargs): - token = access_controller.get_token(token, access_token.user) - if not token: - # 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 - try: - lifetime = request.get_json()["value"] - logger.debug("set lifetime {{ {} }} to access token {{ {} }}".format(lifetime, token)) - access_controller.set_lifetime(token, lifetime) - return jsonify({"ok": "ok"}) - except (KeyError, TypeError): - raise BadRequest + except (KeyError, TypeError): + raise BadRequest diff --git a/flaschengeist/modules/message_mail.py b/flaschengeist/modules/message_mail.py index a9fd9e9..cdd06e0 100644 --- a/flaschengeist/modules/message_mail.py +++ b/flaschengeist/modules/message_mail.py @@ -1,6 +1,8 @@ import smtplib from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText +from flaschengeist import logger from flaschengeist.system.models.user import User from flaschengeist.system.controller import userController from flaschengeist.system.controller.messageController import Message @@ -18,9 +20,15 @@ class MailMessagePlugin(Plugin): self.crypt = config["CRYPT"] self.mail = config["MAIL"] - @send_message_hook + @send_message_hook + def dummy_send(msg): + self.send_mail(msg) + def send_mail(self, msg: Message): if isinstance(msg.receiver, User): + if not msg.receiver.mail: + logger.warn("Could not send Mail, mail missing: {}".format(msg.receiver)) + return recipients = [msg.receiver.mail] else: recipients = userController.get_user_by_role(msg.receiver) @@ -29,15 +37,17 @@ class MailMessagePlugin(Plugin): mail["From"] = self.mail mail["To"] = ", ".join(recipients) mail["Subject"] = msg.subject - msg.attach(msg.message) - if not self.smtp: + mail.attach(MIMEText(msg.message)) + if not hasattr(self, "smtp"): self.__connect() - self.smtp.sendmail(self.mail, recipients, msg.as_string()) + self.smtp.sendmail(self.mail, recipients, mail.as_string()) def __connect(self): if self.crypt == "SSL": self.smtp = smtplib.SMTP_SSL(self.server, self.port) - if self.crypt == "STARTTLS": - self.smtp = smtplib.SMTP(self.smtpServer, self.port) + elif self.crypt == "STARTTLS": + self.smtp = smtplib.SMTP(self.server, self.port) self.smtp.starttls() + else: + raise ValueError("Invalid CRYPT given") self.smtp.login(self.user, self.password) diff --git a/flaschengeist/modules/roles/__init__.py b/flaschengeist/modules/roles/__init__.py index ec93bdf..1decdea 100644 --- a/flaschengeist/modules/roles/__init__.py +++ b/flaschengeist/modules/roles/__init__.py @@ -12,67 +12,73 @@ class RolesPlugin(Plugin): def __init__(self, config): super().__init__(config, roles_bp) - ###################################################### - # Routes # - # # - # /roles POST: register new # - # GET: get all roles # - # /roles/permissions GET: get all permissions # - # /roles/ GET: get role with rid # - # PUT: modify role / permission # - # DELETE: remove role # - ###################################################### +###################################################### +# Routes # +# # +# /roles POST: register new # +# GET: get all roles # +# /roles/permissions GET: get all permissions # +# /roles/ GET: get role with rid # +# PUT: modify role / permission # +# DELETE: remove role # +###################################################### - @roles_bp.route("/roles", methods=["POST"]) - @login_required() - def add_role(self): - data = request.get_json() - if not data or "name" not in data: - raise BadRequest - if "permissions" in data: - permissions = data["permissions"] - role = roleController.create_role(data["name"], permissions) - return jsonify({"ok": "ok", "id": role.id}) - @roles_bp.route("/roles", methods=["GET"]) - @login_required() - def list_roles(self, **kwargs): - roles = roleController.get_roles() - return jsonify(roles) +@roles_bp.route("/roles", methods=["POST"]) +@login_required() +def add_role(self): + data = request.get_json() + if not data or "name" not in data: + raise BadRequest + if "permissions" in data: + permissions = data["permissions"] + role = roleController.create_role(data["name"], permissions) + return jsonify({"ok": "ok", "id": role.id}) - @roles_bp.route("/roles/permissions", methods=["GET"]) - @login_required() - def list_permissions(self, **kwargs): - permissions = roleController.get_permissions() - return jsonify(permissions) - @roles_bp.route("/roles/", methods=["GET"]) - @login_required() - def __get_role(self, rid, **kwargs): - role = roleController.get_role(rid) - if role: - return jsonify({"id": role.id, "name": role, "permissions": role.permissions}) +@roles_bp.route("/roles", methods=["GET"]) +@login_required() +def list_roles(**kwargs): + roles = roleController.get_roles() + return jsonify(roles) + + +@roles_bp.route("/roles/permissions", methods=["GET"]) +@login_required() +def list_permissions(**kwargs): + permissions = roleController.get_permissions() + return jsonify(permissions) + + +@roles_bp.route("/roles/", methods=["GET"]) +@login_required() +def __get_role(rid, **kwargs): + role = roleController.get_role(rid) + if role: + return jsonify({"id": role.id, "name": role, "permissions": role.permissions}) + raise NotFound + + +@roles_bp.route("/roles/", methods=["PUT"]) +@login_required() +def __edit_role(rid, **kwargs): + role = roleController.get_role(rid) + if not role: raise NotFound - @roles_bp.route("/roles/", methods=["PUT"]) - @login_required() - def __edit_role(self, rid, **kwargs): - role = roleController.get_role(rid) - if not role: - raise NotFound + data = request.get_json() + if "name" in data: + role.name = data["name"] + if "permissions" in data: + roleController.set_permissions(role, data["permissions"]) + roleController.update_role(role) + return jsonify({"ok": "ok"}) - data = request.get_json() - if "name" in data: - role.name = data["name"] - if "permissions" in data: - roleController.set_permissions(role, data["permissions"]) - roleController.update_role(role) - return jsonify({"ok": "ok"}) - @roles_bp.route("/roles/", methods=["DELETE"]) - @login_required() - def __delete_role(self, rid, **kwargs): - if not roleController.delete_role(rid): - raise NotFound +@roles_bp.route("/roles/", methods=["DELETE"]) +@login_required() +def __delete_role(rid, **kwargs): + if not roleController.delete_role(rid): + raise NotFound - return jsonify({"ok": "ok"}) + return jsonify({"ok": "ok"}) diff --git a/flaschengeist/modules/schedule/__init__.py b/flaschengeist/modules/schedule/__init__.py index 0805329..9527cb2 100644 --- a/flaschengeist/modules/schedule/__init__.py +++ b/flaschengeist/modules/schedule/__init__.py @@ -16,171 +16,184 @@ class SchedulePlugin(Plugin): def __init__(self, config): super().__init__(blueprint=schedule_bp) - #################################################################################### - # Routes # - # # - # /schedule/events POST: create new # - # GET: get all events this month # - # /schedule/events// GET: get events by month / date # - # /// # - # /schedule/events/ GET: get event by ID # - # DELETE: delete specified event # - # PUT: modify specified event # - # /schedule/events//slots GET: get EventSlots of Event # - # POST: add new EventSlot to Event # - # /schedule/events//slots/ PUT: modify EventSlot # - # GET: get specified EventSlot # - # /schedule/events//slots//jobs POST: add User # - # /schedule/eventKinds - # /schedule/eventKinds/ - # PUT: modify user # - # DELETE: remove user # - #################################################################################### +#################################################################################### +# Routes # +# # +# /schedule/events POST: create new # +# GET: get all events this month # +# /schedule/events// GET: get events by month / date # +# /// # +# /schedule/events/ GET: get event by ID # +# DELETE: delete specified event # +# PUT: modify specified event # +# /schedule/events//slots GET: get EventSlots of Event # +# POST: add new EventSlot to Event # +# /schedule/events//slots/ PUT: modify EventSlot # +# GET: get specified EventSlot # +# /schedule/events//slots//jobs POST: add User # +# /schedule/eventKinds +# /schedule/eventKinds/ +# PUT: modify user # +# DELETE: remove user # +#################################################################################### - @schedule_bp.route("/events/", methods=["GET"]) - @login_required() # roles=['schedule_read']) - def __get_event(self, id, **kwargs): - event = eventController.get_event(id) - if not event: - raise NotFound - return jsonify(event) - @schedule_bp.route("/events", methods=["GET"]) - @schedule_bp.route("/events//", methods=["GET"]) - @schedule_bp.route("/events///", methods=["GET"]) - @login_required() # roles=['schedule_read']) - def __get_events(self, year=datetime.now().year, month=datetime.now().month, day=None, **kwrags): - """Get Event objects for specified date (or month or year), - if nothing set then events for current month are returned +@schedule_bp.route("/events/", methods=["GET"]) +@login_required() # roles=['schedule_read']) +def __get_event(self, id, **kwargs): + event = eventController.get_event(id) + if not event: + raise NotFound + return jsonify(event) - Args: - year (int, optional): year to query, defaults to current year - month (int, optional): month to query (if set), defaults to current month - day (int, optional): day to query events for (if set) - **kwrags: contains at least access_token (see flaschengeist.decorator) - Returns: - JSON list containing events found - Raises: - BadRequest: If date is invalid - """ - try: - begin = datetime(year=year, month=month, day=1) - if day: - begin += timedelta(days=day - 1) - end = begin + timedelta(days=1) + +@schedule_bp.route("/events", methods=["GET"]) +@schedule_bp.route("/events//", methods=["GET"]) +@schedule_bp.route("/events///", methods=["GET"]) +@login_required() # roles=['schedule_read']) +def __get_events(year=datetime.now().year, month=datetime.now().month, day=None, **kwargs): + """Get Event objects for specified date (or month or year), + if nothing set then events for current month are returned + + Args: + year (int, optional): year to query, defaults to current year + month (int, optional): month to query (if set), defaults to current month + day (int, optional): day to query events for (if set) + **kwargs: contains at least access_token (see flaschengeist.decorator) + Returns: + JSON list containing events found + Raises: + BadRequest: If date is invalid + """ + try: + begin = datetime(year=year, month=month, day=1) + if day: + begin += timedelta(days=day - 1) + end = begin + timedelta(days=1) + else: + if month == 12: + end = datetime(year=year + 1, month=1, day=1) else: - if month == 12: - end = datetime(year=year + 1, month=1, day=1) - else: - end = datetime(year=year, month=month + 1, day=1) + end = datetime(year=year, month=month + 1, day=1) - events = eventController.get_events(begin, end) - return jsonify(events) - except ValueError: - raise BadRequest("Invalid date given") + events = eventController.get_events(begin, end) + return jsonify(events) + except ValueError: + raise BadRequest("Invalid date given") - @schedule_bp.route("/eventKinds", methods=["POST"]) - @login_required() - def __new_event_kind(self, **kwargs): - data = request.get_json() - if "name" not in data: - raise BadRequest - kind = eventController.create_event_kind(data["name"]) - return jsonify({"ok": "ok", "id": kind.id}) - @schedule_bp.route("/slotKinds", methods=["POST"]) - @login_required() - def __new_slot_kind(self, **kwargs): - data = request.get_json() - if not data or "name" not in data: - raise BadRequest - kind = eventController.create_job_kind(data["name"]) - return jsonify({"ok": "ok", "id": kind.id}) +@schedule_bp.route("/eventKinds", methods=["POST"]) +@login_required() +def __new_event_kind(**kwargs): + data = request.get_json() + if "name" not in data: + raise BadRequest + kind = eventController.create_event_kind(data["name"]) + return jsonify({"ok": "ok", "id": kind.id}) - @schedule_bp.route("/events", methods=["POST"]) - @login_required() - def __new_event(self, **kwargs): - data = request.get_json() - event = eventController.create_event( - begin=parser.isoparse(data["begin"]), - end=parser.isoparse(data["end"]), - description=data["description"], - kind=EventKind.query.get(data["kind"]), - ) - return jsonify({"ok": "ok", "id": event.id}) - @schedule_bp.route("/events/", methods=["DELETE"]) - @login_required() - def __delete_event(self, id, **kwargs): - if not eventController.delete_event(id): - raise NotFound - db.session.commit() - return jsonify({"ok": "ok"}) +@schedule_bp.route("/slotKinds", methods=["POST"]) +@login_required() +def __new_slot_kind(**kwargs): + data = request.get_json() + if not data or "name" not in data: + raise BadRequest + kind = eventController.create_job_kind(data["name"]) + return jsonify({"ok": "ok", "id": kind.id}) - @schedule_bp.route("/eventKinds/", methods=["PUT"]) - @login_required() - def __edit_event_kind(self, id, **kwargs): - data = request.get_json() - if not data or "name" not in data: - raise BadRequest - eventController.rename_event_kind(id, data["name"]) - return jsonify({"ok": "ok"}) - @schedule_bp.route("/events//slots", methods=["GET"]) - @login_required() - def __get_slots(self, event_id, **kwargs): - event = eventController.get_event(event_id) - if not event: - raise NotFound - return jsonify({event.slots}) +@schedule_bp.route("/events", methods=["POST"]) +@login_required() +def __new_event(**kwargs): + data = request.get_json() + event = eventController.create_event( + begin=parser.isoparse(data["begin"]), + end=parser.isoparse(data["end"]), + description=data["description"], + kind=EventKind.query.get(data["kind"]), + ) + return jsonify({"ok": "ok", "id": event.id}) - @schedule_bp.route("/events//slots/", methods=["GET"]) - @login_required() - def __get_slot(self, event_id, slot_id, **kwargs): - slot = eventController.get_event_slot(slot_id, event_id) - if slot: - return jsonify(slot) + +@schedule_bp.route("/events/", methods=["DELETE"]) +@login_required() +def __delete_event(event_id, **kwargs): + if not eventController.delete_event(event_id): raise NotFound + db.session.commit() + return jsonify({"ok": "ok"}) - @schedule_bp.route("/events//slots/", methods=["DELETE"]) - @login_required() - def __delete_slot(self, event_id, slot_id, **kwargs): - if eventController.delete_event_slot(slot_id, event_id): - return jsonify({"ok": "ok"}) + +@schedule_bp.route("/eventKinds/", methods=["PUT"]) +@login_required() +def __edit_event_kind(event_id, **kwargs): + data = request.get_json() + if not data or "name" not in data: + raise BadRequest + eventController.rename_event_kind(event_id, data["name"]) + return jsonify({"ok": "ok"}) + + +@schedule_bp.route("/events//slots", methods=["GET"]) +@login_required() +def __get_slots(event_id, **kwargs): + event = eventController.get_event(event_id) + if not event: raise NotFound + return jsonify({event.slots}) - @schedule_bp.route("/events//slots/", methods=["PUT"]) - @login_required() - def __update_slot(self, event_id, slot_id, **kwargs): - data = request.get_json() - if not data: - raise BadRequest +@schedule_bp.route("/events//slots/", methods=["GET"]) +@login_required() +def __get_slot(event_id, slot_id, **kwargs): + slot = eventController.get_event_slot(slot_id, event_id) + if slot: + return jsonify(slot) + raise NotFound + + +@schedule_bp.route("/events//slots/", methods=["DELETE"]) +@login_required() +def __delete_slot(event_id, slot_id, **kwargs): + if eventController.delete_event_slot(slot_id, event_id): + return jsonify({"ok": "ok"}) + raise NotFound + + +@schedule_bp.route("/events//slots/", methods=["PUT"]) +@login_required() +def __update_slot(event_id, slot_id, **kwargs): + data = request.get_json() + if not data: + raise BadRequest + + for job in data["jobs"]: + eventController.add_job(job.kind, job.user) + if eventController.delete_event_slot(slot_id, event_id): + return jsonify({"ok": "ok"}) + raise NotFound + + +@schedule_bp.route("/events//slots", methods=["POST"]) +@login_required() +def __add_slot(event_id, **kwargs): + event = eventController.get_event(event_id) + if not event: + raise NotFound + data = request.get_json() + attr = {"job_slots": []} + try: + if "start" in data: + attr["start"] = parser.isoparse(data["start"]) + if "end" in data: + attr["end"] = parser.isoparse(data["end"]) for job in data["jobs"]: - eventController.add_job(job.kind, job.user) - if eventController.delete_event_slot(slot_id, event_id): - return jsonify({"ok": "ok"}) - raise NotFound + attr["job_slots"].append({"needed_persons": job["needed_persons"], "kind": job["kind"]}) + except KeyError: + raise BadRequest("Missing data in request") + eventController.add_slot(event, **attr) + return jsonify({"ok": "ok"}) - @schedule_bp.route("/events//slots", methods=["POST"]) - @login_required() - def __add_slot(self, event_id, **kwargs): - event = eventController.get_event(event_id) - if not event: - raise NotFound - data = request.get_json() - attr = {"job_slots": []} - try: - if "start" in data: - attr["start"] = parser.isoparse(data["start"]) - if "end" in data: - attr["end"] = parser.isoparse(data["end"]) - for job in data["jobs"]: - attr["job_slots"].append({"needed_persons": job["needed_persons"], "kind": job["kind"]}) - except KeyError: - raise BadRequest("Missing data in request") - eventController.add_slot(event, **attr) - return jsonify({"ok": "ok"}) - def __edit_event(self): - ... +def __edit_event(): + ... diff --git a/flaschengeist/modules/users/__init__.py b/flaschengeist/modules/users/__init__.py index 5b9fdd4..d168c3d 100644 --- a/flaschengeist/modules/users/__init__.py +++ b/flaschengeist/modules/users/__init__.py @@ -24,45 +24,49 @@ class UsersPlugin(Plugin): # DELETE: remove user # ################################################# - @users_bp.route("/users", methods=["POST"]) - def __registration(self): - logger.debug("Register new User...") - return jsonify({"ok": "ok... well not implemented"}) - @users_bp.route("/users", methods=["GET"]) - @login_required() - def __list_users(self, **kwargs): - logger.debug("Retrieve list of all users") - users = userController.get_users() - return jsonify(users) +@users_bp.route("/users", methods=["POST"]) +def __registration(self): + logger.debug("Register new User...") + return jsonify({"ok": "ok... well not implemented"}) - @users_bp.route("/users/", methods=["GET"]) - @login_required() - def __get_user(self, uid, **kwargs): - logger.debug("Get information of user {{ {} }}".format(uid)) - user = userController.get_user(uid) - if user: - return jsonify(user) + +@users_bp.route("/users", methods=["GET"]) +@login_required() +def __list_users(**kwargs): + logger.debug("Retrieve list of all users") + users = userController.get_users() + return jsonify(users) + + +@users_bp.route("/users/", methods=["GET"]) +@login_required() +def __get_user(uid, **kwargs): + logger.debug("Get information of user {{ {} }}".format(uid)) + user = userController.get_user(uid) + if user: + return jsonify(user) + raise NotFound + + +@users_bp.route("/users/", methods=["PUT"]) +@login_required() +def __edit_user(uid, **kwargs): + logger.debug("Modify information of user {{ {} }}".format(uid)) + user = userController.get_user(uid) + if not user: raise NotFound - @users_bp.route("/users/", methods=["PUT"]) - @login_required() - def __edit_user(self, uid, **kwargs): - logger.debug("Modify information of user {{ {} }}".format(uid)) - user = userController.get_user(uid) - if not user: - raise NotFound + if uid != kwargs["access_token"].user.uid and user.has_permissions(permissions["EDIT_USER"]): + return Forbidden - if uid != kwargs["access_token"].user.uid and user.has_permissions(permissions["EDIT_USER"]): - return Forbidden - - data = request.get_json() - if "password" not in data: - raise BadRequest("Password is missing") - for key in ["firstname", "lastname", "display_name", "mail"]: - if key in data: - setattr(user, key, data[key]) - new_password = data["new_password"] if "new_password" in data else None - userController.modify_user(user, data["password"], new_password) - userController.update_user(user) - return jsonify({"ok": "ok"}) + data = request.get_json() + if "password" not in data: + raise BadRequest("Password is missing") + for key in ["firstname", "lastname", "display_name", "mail"]: + if key in data: + setattr(user, key, data[key]) + new_password = data["new_password"] if "new_password" in data else None + userController.modify_user(user, data["password"], new_password) + userController.update_user(user) + return jsonify({"ok": "ok"}) diff --git a/flaschengeist/readme.md b/flaschengeist/readme.md index d9a2434..e3dc10c 100644 --- a/flaschengeist/readme.md +++ b/flaschengeist/readme.md @@ -28,7 +28,22 @@ or with debug messages: run_flaschengeist --debug ## Development +### Code Style +We enforce you to use PEP 8 code style with a line length of 120 as used by Black. +See also [Black Code Style](https://github.com/psf/black/blob/master/docs/the_black_code_style.md). + +#### Code formatting +We use [Black](https://github.com/psf/black) as the code formatter. + +Installation: + + pip install black +Usage: + + black -l 120 DIRECTORY_OR_FILE + ### Misc +#### Git blame When using `git blame` use this to ignore the code formatting commits: $ git blame FILE.py --ignore-revs-file .git-blame-ignore-revs diff --git a/flaschengeist/system/controller/messageController.py b/flaschengeist/system/controller/messageController.py index 1f064d6..6114aec 100644 --- a/flaschengeist/system/controller/messageController.py +++ b/flaschengeist/system/controller/messageController.py @@ -1,5 +1,6 @@ +from flaschengeist import logger +from flaschengeist.system.hook import Hook from flaschengeist.system.models.user import User, Role -from pyhooks import Hook class Message: diff --git a/flaschengeist/system/hook.py b/flaschengeist/system/hook.py new file mode 100644 index 0000000..729269f --- /dev/null +++ b/flaschengeist/system/hook.py @@ -0,0 +1,20 @@ +_hook_dict = {} + + +class Hook(object): + def __init__(self, function): + self.function = function + + def __call__(self, *args, **kwargs): + if self.function.__name__ in _hook_dict: + _hook_dict[self.function.__name__](*args, **kwargs) + self.function(*args, **kwargs) + + +class HookCall(object): + def __init__(self, name): + self.name = name + + def __call__(self, function): + _hook_dict[self.name] = function + return function \ No newline at end of file diff --git a/setup.py b/setup.py index c0923cf..a7f525f 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,6 @@ setup( "werkzeug", "bjoern", "python-dateutil", - "pyhooks", ], extras_require={"ldap": ["flask_ldapconn", "ldap3"]}, entry_points={