Added some permissions, reworked permission system.
This commit is contained in:
parent
ba0c76a727
commit
d3a2b40834
|
@ -18,10 +18,7 @@ class Plugin:
|
|||
pass
|
||||
|
||||
def serialize(self):
|
||||
return {
|
||||
"version": self.version,
|
||||
"permissions": self.permissions
|
||||
}
|
||||
return {"version": self.version, "permissions": self.permissions}
|
||||
|
||||
|
||||
class AuthPlugin(Plugin):
|
||||
|
@ -38,9 +35,9 @@ class AuthPlugin(Plugin):
|
|||
|
||||
def update_user(self, user):
|
||||
"""If backend is using external data, then update this user instance with external data
|
||||
|
||||
Args:
|
||||
user: User object
|
||||
)
|
||||
Args:
|
||||
user: User object
|
||||
"""
|
||||
pass
|
||||
|
||||
|
@ -57,3 +54,12 @@ class AuthPlugin(Plugin):
|
|||
Error: Other errors if backend went mad (are not handled and will result in a 500 error)
|
||||
"""
|
||||
raise NotImplemented
|
||||
|
||||
def delete_user(self, user):
|
||||
"""If backend is using (writeable) external data, then delete the user from external database.
|
||||
|
||||
Args:
|
||||
user: User object
|
||||
|
||||
"""
|
||||
pass
|
||||
|
|
|
@ -6,12 +6,13 @@ from flaschengeist.system.decorator import login_required
|
|||
from flaschengeist.system.controller import roleController
|
||||
|
||||
roles_bp = Blueprint("roles", __name__)
|
||||
roles_permission = "roles_edit"
|
||||
_permission_edit = "roles_edit"
|
||||
_permission_delete = "roles_delete"
|
||||
|
||||
|
||||
class RolesPlugin(Plugin):
|
||||
def __init__(self, config):
|
||||
super().__init__(config, roles_bp, permissions=[roles_permission])
|
||||
super().__init__(config, roles_bp, permissions=[_permission_edit, _permission_delete])
|
||||
|
||||
|
||||
######################################################
|
||||
|
@ -27,7 +28,7 @@ class RolesPlugin(Plugin):
|
|||
|
||||
|
||||
@roles_bp.route("/roles", methods=["POST"])
|
||||
@login_required(permissions=[roles_permission])
|
||||
@login_required(permission=_permission_edit)
|
||||
def add_role(**kwargs):
|
||||
data = request.get_json()
|
||||
if not data or "name" not in data:
|
||||
|
@ -41,7 +42,7 @@ def add_role(**kwargs):
|
|||
@roles_bp.route("/roles", methods=["GET"])
|
||||
@login_required()
|
||||
def list_roles(**kwargs):
|
||||
roles = roleController.get_roles()
|
||||
roles = roleController.get_all()
|
||||
return jsonify(roles)
|
||||
|
||||
|
||||
|
@ -55,18 +56,16 @@ def list_permissions(**kwargs):
|
|||
@roles_bp.route("/roles/<rid>", methods=["GET"])
|
||||
@login_required()
|
||||
def __get_role(rid, **kwargs):
|
||||
role = roleController.get_role(rid)
|
||||
role = roleController.get(rid)
|
||||
if role:
|
||||
return jsonify({"id": role.id, "name": role, "permissions": role.permissions})
|
||||
raise NotFound
|
||||
|
||||
|
||||
@roles_bp.route("/roles/<rid>", methods=["PUT"])
|
||||
@login_required(permissions=[roles_permission])
|
||||
@login_required(permission=_permission_edit)
|
||||
def __edit_role(rid, **kwargs):
|
||||
role = roleController.get_role(rid)
|
||||
if not role:
|
||||
raise NotFound
|
||||
role = roleController.get(rid)
|
||||
|
||||
data = request.get_json()
|
||||
if "name" in data:
|
||||
|
@ -78,9 +77,9 @@ def __edit_role(rid, **kwargs):
|
|||
|
||||
|
||||
@roles_bp.route("/roles/<rid>", methods=["DELETE"])
|
||||
@login_required(permissions=[roles_permission])
|
||||
@login_required(permission=_permission_delete)
|
||||
def __delete_role(rid, **kwargs):
|
||||
if not roleController.delete_role(rid):
|
||||
raise NotFound
|
||||
role = roleController.get(rid)
|
||||
roleController.delete(role)
|
||||
|
||||
return jsonify({"ok": "ok"})
|
||||
|
|
|
@ -10,13 +10,25 @@ from flaschengeist.system.decorator import login_required
|
|||
from flaschengeist.system.controller import eventController
|
||||
|
||||
schedule_bp = Blueprint("schedule", __name__, url_prefix="/schedule")
|
||||
schedule_perms = {"EDIT_EVENT": "schedule_edit_event",
|
||||
"NEW_EVENT": "schedule_create_event"}
|
||||
_permission_edit_type = "schedule_edit_type"
|
||||
_permission_edit = "schedule_edit"
|
||||
_permission_create = "schedule_create"
|
||||
_permission_delete = "schedule_delete"
|
||||
_permission_assign = "schedule_assign_other"
|
||||
|
||||
|
||||
class SchedulePlugin(Plugin):
|
||||
def __init__(self, config):
|
||||
super().__init__(blueprint=schedule_bp, permissions=schedule_perms.values())
|
||||
super().__init__(
|
||||
blueprint=schedule_bp,
|
||||
permissions=[
|
||||
_permission_create,
|
||||
_permission_edit,
|
||||
_permission_edit_type,
|
||||
_permission_delete,
|
||||
_permission_assign,
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
####################################################################################
|
||||
|
@ -41,10 +53,10 @@ class SchedulePlugin(Plugin):
|
|||
####################################################################################
|
||||
|
||||
|
||||
@schedule_bp.route("/events/<int:id>", methods=["GET"])
|
||||
@schedule_bp.route("/events/<int:eid>", methods=["GET"])
|
||||
@login_required()
|
||||
def __get_event(id, **kwargs):
|
||||
event = eventController.get_event(id)
|
||||
def __get_event(eid, **kwargs):
|
||||
event = eventController.get_event(eid)
|
||||
if not event:
|
||||
raise NotFound
|
||||
return jsonify(event)
|
||||
|
@ -86,7 +98,7 @@ def __get_events(year=datetime.now().year, month=datetime.now().month, day=None,
|
|||
|
||||
|
||||
@schedule_bp.route("/eventKinds", methods=["POST"])
|
||||
@login_required()
|
||||
@login_required(permission=_permission_edit_type)
|
||||
def __new_event_kind(**kwargs):
|
||||
data = request.get_json()
|
||||
if "name" not in data:
|
||||
|
@ -96,7 +108,7 @@ def __new_event_kind(**kwargs):
|
|||
|
||||
|
||||
@schedule_bp.route("/slotKinds", methods=["POST"])
|
||||
@login_required()
|
||||
@login_required(permission=_permission_edit_type)
|
||||
def __new_slot_kind(**kwargs):
|
||||
data = request.get_json()
|
||||
if not data or "name" not in data:
|
||||
|
@ -106,7 +118,7 @@ def __new_slot_kind(**kwargs):
|
|||
|
||||
|
||||
@schedule_bp.route("/events", methods=["POST"])
|
||||
@login_required(permissions=[schedule_perms["NEW_EVENT"]])
|
||||
@login_required(permission=_permission_create)
|
||||
def __new_event(**kwargs):
|
||||
data = request.get_json()
|
||||
event = eventController.create_event(
|
||||
|
@ -119,7 +131,7 @@ def __new_event(**kwargs):
|
|||
|
||||
|
||||
@schedule_bp.route("/events/<int:event_id>", methods=["DELETE"])
|
||||
@login_required(permissions=[schedule_perms["EDIT_EVENT"]])
|
||||
@login_required(permission=_permission_delete)
|
||||
def __delete_event(event_id, **kwargs):
|
||||
if not eventController.delete_event(event_id):
|
||||
raise NotFound
|
||||
|
@ -128,7 +140,7 @@ def __delete_event(event_id, **kwargs):
|
|||
|
||||
|
||||
@schedule_bp.route("/eventKinds/<int:event_id>", methods=["PUT"])
|
||||
@login_required()
|
||||
@login_required(permission=_permission_edit_type)
|
||||
def __edit_event_kind(event_id, **kwargs):
|
||||
data = request.get_json()
|
||||
if not data or "name" not in data:
|
||||
|
@ -156,7 +168,7 @@ def __get_slot(event_id, slot_id, **kwargs):
|
|||
|
||||
|
||||
@schedule_bp.route("/events/<int:event_id>/slots/<int:slot_id>", methods=["DELETE"])
|
||||
@login_required()
|
||||
@login_required(permission=_permission_delete)
|
||||
def __delete_slot(event_id, slot_id, **kwargs):
|
||||
if eventController.delete_event_slot(slot_id, event_id):
|
||||
return jsonify({"ok": "ok"})
|
||||
|
@ -164,7 +176,7 @@ def __delete_slot(event_id, slot_id, **kwargs):
|
|||
|
||||
|
||||
@schedule_bp.route("/events/<int:event_id>/slots/<int:slot_id>", methods=["PUT"])
|
||||
@login_required()
|
||||
@login_required(permission=_permission_edit)
|
||||
def __update_slot(event_id, slot_id, **kwargs):
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
|
@ -178,7 +190,7 @@ def __update_slot(event_id, slot_id, **kwargs):
|
|||
|
||||
|
||||
@schedule_bp.route("/events/<int:event_id>/slots", methods=["POST"])
|
||||
@login_required()
|
||||
@login_required(permission=_permission_edit)
|
||||
def __add_slot(event_id, **kwargs):
|
||||
event = eventController.get_event(event_id)
|
||||
if not event:
|
||||
|
|
|
@ -7,12 +7,13 @@ from flaschengeist.system.decorator import login_required
|
|||
from flaschengeist.system.controller import userController
|
||||
|
||||
users_bp = Blueprint("users", __name__)
|
||||
users_perm = "users_edit_other"
|
||||
_permission_edit = "users_edit_other"
|
||||
_permission_delete = "users_delete_other"
|
||||
|
||||
|
||||
class UsersPlugin(Plugin):
|
||||
def __init__(self, config):
|
||||
super().__init__(blueprint=users_bp, permissions=[users_perm])
|
||||
super().__init__(blueprint=users_bp, permissions=[_permission_edit, _permission_delete])
|
||||
|
||||
#################################################
|
||||
# Routes #
|
||||
|
@ -49,15 +50,22 @@ def __get_user(uid, **kwargs):
|
|||
raise NotFound
|
||||
|
||||
|
||||
@users_bp.route("/users/<uid>", methods=["DELETE"])
|
||||
@login_required(permission=_permission_delete)
|
||||
def __delete_user(uid, **kwargs):
|
||||
logger.debug("Delete user {{ {} }}".format(uid))
|
||||
user = userController.get_user(uid)
|
||||
userController.delete(user)
|
||||
return jsonify({"ok": "ok"})
|
||||
|
||||
|
||||
@users_bp.route("/users/<uid>", 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
|
||||
|
||||
if uid != kwargs["access_token"].user.userid and user.has_permissions([users_perm]):
|
||||
if uid != kwargs["access_token"].user.userid and user.has_permission(_permission_edit):
|
||||
return Forbidden
|
||||
|
||||
data = request.get_json()
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
from sqlalchemy.exc import IntegrityError
|
||||
from werkzeug.exceptions import BadRequest
|
||||
from werkzeug.exceptions import BadRequest, NotFound
|
||||
|
||||
from flaschengeist.system.models.user import Role, Permission
|
||||
from flaschengeist.system.database import db
|
||||
from flaschengeist import logger
|
||||
|
||||
|
||||
def get_roles():
|
||||
def get_all():
|
||||
return Role.query.all()
|
||||
|
||||
|
||||
def get_role(rid):
|
||||
return Role.query.get(rid)
|
||||
def get(rid):
|
||||
role = Role.query.get(rid).one_or_none()
|
||||
if not role:
|
||||
raise NotFound
|
||||
|
||||
|
||||
def get_permissions():
|
||||
|
@ -47,9 +49,9 @@ def create_role(name, permissions=[]):
|
|||
return role.id
|
||||
|
||||
|
||||
def delete_role(id):
|
||||
def delete(role):
|
||||
try:
|
||||
num = Role.query.filter(Role.id == id).delete()
|
||||
num = Role.query.filter(Role.id == role.id).delete()
|
||||
except IntegrityError:
|
||||
logger.debug("IntegrityError: Role might still be in use", exc_info=True)
|
||||
raise BadRequest("Role still in use")
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from flask import current_app
|
||||
from werkzeug.exceptions import NotFound
|
||||
|
||||
from flaschengeist.system.models.user import User, Role
|
||||
from flaschengeist.system.database import db
|
||||
|
@ -51,4 +52,13 @@ def get_user_by_role(role: Role):
|
|||
|
||||
|
||||
def get_user(uid):
|
||||
return User.query.filter(User.userid == uid).one_or_none()
|
||||
user = User.query.filter(User.userid == uid).one_or_none()
|
||||
if not user:
|
||||
raise NotFound
|
||||
return user
|
||||
|
||||
|
||||
def delete(user):
|
||||
current_app.config["FG_AUTH_BACKEND"].delete_user(user)
|
||||
db.session.delete(user)
|
||||
db.session.commit()
|
||||
|
|
|
@ -6,12 +6,12 @@ from flaschengeist import logger
|
|||
from flaschengeist.system.controller import sessionController
|
||||
|
||||
|
||||
def login_required(permissions=None):
|
||||
def login_required(permission=None):
|
||||
def wrap(func):
|
||||
@wraps(func)
|
||||
def wrapped_f(*args, **kwargs):
|
||||
token = list(filter(None, request.headers.get("Authorization").split(" ")))[-1]
|
||||
access_token = sessionController.validate_token(token, request.user_agent, permissions)
|
||||
access_token = sessionController.validate_token(token, request.user_agent, permission)
|
||||
if access_token:
|
||||
kwargs["access_token"] = access_token
|
||||
logger.debug("token {{ {} }} is valid".format(token))
|
||||
|
@ -19,5 +19,7 @@ def login_required(permissions=None):
|
|||
else:
|
||||
logger.info("token {{ {} }} is not valid".format(token))
|
||||
raise Unauthorized
|
||||
|
||||
return wrapped_f
|
||||
|
||||
return wrap
|
||||
|
|
|
@ -45,15 +45,19 @@ class Event(db.Model, ModelSerializeMixin):
|
|||
|
||||
class Job(db.Model, ModelSerializeMixin):
|
||||
__tablename__ = "job"
|
||||
_user: User = db.relationship("User")
|
||||
# user: str = column_property(_user.userid)
|
||||
user: str = None
|
||||
value: float = db.Column(db.Numeric(precision=3, scale=2))
|
||||
|
||||
_id = db.Column("id", db.Integer, primary_key=True)
|
||||
_user_id = db.Column("user_id", db.Integer, db.ForeignKey("user.id"))
|
||||
_user: User = db.relationship("User")
|
||||
_slot_id = db.Column("slot_id", db.Integer, db.ForeignKey("job_slot.id"))
|
||||
_slot = db.relationship("JobSlot")
|
||||
|
||||
@property
|
||||
def user(self):
|
||||
return self._user.userid
|
||||
|
||||
|
||||
class JobKind(db.Model, ModelSerializeMixin):
|
||||
__tablename__ = "job_kind"
|
||||
|
|
Loading…
Reference in New Issue