Added Role controller
This commit is contained in:
parent
bf33529bf1
commit
4cd68d7e81
|
@ -58,7 +58,7 @@ class AuthLDAP(modules.Auth):
|
||||||
if 'displayName' in r:
|
if 'displayName' in r:
|
||||||
user.display_name = r['displayName'][0]
|
user.display_name = r['displayName'][0]
|
||||||
for group in self._get_groups(user.uid):
|
for group in self._get_groups(user.uid):
|
||||||
user.add_group(group)
|
user.add_role(group)
|
||||||
|
|
||||||
def _get_groups(self, uid):
|
def _get_groups(self, uid):
|
||||||
groups = []
|
groups = []
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
from flask import Blueprint, request, jsonify
|
||||||
|
from werkzeug.exceptions import NotFound, BadRequest, Forbidden
|
||||||
|
|
||||||
|
from flaschengeist.system.decorator import login_required
|
||||||
|
from flaschengeist.system.controller import roleController
|
||||||
|
|
||||||
|
roles_bp = Blueprint("roles", __name__)
|
||||||
|
permissions = {}
|
||||||
|
|
||||||
|
|
||||||
|
def register():
|
||||||
|
return roles_bp, permissions
|
||||||
|
|
||||||
|
######################################################
|
||||||
|
# Routes #
|
||||||
|
# #
|
||||||
|
# /roles POST: register new #
|
||||||
|
# GET: get all roles #
|
||||||
|
# /roles/permissions GET: get all permissions #
|
||||||
|
# /roles/<rid> GET: get role with rid #
|
||||||
|
# PUT: modify role / permission #
|
||||||
|
# DELETE: remove role #
|
||||||
|
######################################################
|
||||||
|
|
||||||
|
|
||||||
|
@roles_bp.route("/roles", methods=['POST'])
|
||||||
|
@login_required()
|
||||||
|
def __add_role():
|
||||||
|
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(**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/<rid>", 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/<rid>", methods=['PUT'])
|
||||||
|
@login_required()
|
||||||
|
def __edit_role(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"})
|
||||||
|
|
||||||
|
|
||||||
|
@roles_bp.route("/roles/<rid>", methods=['DELETE'])
|
||||||
|
@login_required()
|
||||||
|
def __delete_role(rid, **kwargs):
|
||||||
|
if not roleController.delete_role(rid):
|
||||||
|
raise NotFound
|
||||||
|
|
||||||
|
return jsonify({"ok": "ok"})
|
|
@ -28,6 +28,9 @@ config.read_dict({
|
||||||
'auth': {
|
'auth': {
|
||||||
'enabled': True
|
'enabled': True
|
||||||
},
|
},
|
||||||
|
'roles': {
|
||||||
|
'enabled': True
|
||||||
|
},
|
||||||
'users': {
|
'users': {
|
||||||
'enabled': True
|
'enabled': True
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
from flask import current_app
|
||||||
|
from sqlalchemy.exc import IntegrityError
|
||||||
|
from werkzeug.exceptions import BadRequest
|
||||||
|
|
||||||
|
from flaschengeist.system.models.user import Role, Permission
|
||||||
|
from flaschengeist.system.database import db
|
||||||
|
from flaschengeist import logger
|
||||||
|
|
||||||
|
|
||||||
|
def get_roles():
|
||||||
|
return Role.query.all()
|
||||||
|
|
||||||
|
|
||||||
|
def get_role(rid):
|
||||||
|
return Role.query.get(rid)
|
||||||
|
|
||||||
|
|
||||||
|
def get_permissions():
|
||||||
|
return Permission.query.all()
|
||||||
|
|
||||||
|
|
||||||
|
def update_role(role):
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def set_permissions(role, permissions):
|
||||||
|
for name in permissions:
|
||||||
|
p = Permission.query.filter(Permission.name == name).one_or_none()
|
||||||
|
if not p:
|
||||||
|
raise BadRequest("Invalid permission name >{}<".format(name))
|
||||||
|
role.permissions.append(p)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def create_permissions(permissions):
|
||||||
|
for permission in permissions:
|
||||||
|
if Permission.query.filter(Permission.name == permission).count() > 0:
|
||||||
|
continue
|
||||||
|
p = Permission(name=permission)
|
||||||
|
db.session.add(p)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def create_role(name, permissions=[]):
|
||||||
|
role = Role(name=name)
|
||||||
|
db.session.add(role)
|
||||||
|
set_permissions(role, permissions)
|
||||||
|
return role.id
|
||||||
|
|
||||||
|
|
||||||
|
def delete_role(id):
|
||||||
|
try:
|
||||||
|
num = Role.query.filter(Role.id == id).delete()
|
||||||
|
except IntegrityError:
|
||||||
|
logger.debug("IntegrityError: Role might still be in use", exc_info=True)
|
||||||
|
raise BadRequest("Role still in use")
|
||||||
|
db.session.commit()
|
||||||
|
return num == 1
|
|
@ -5,9 +5,9 @@ from werkzeug.local import LocalProxy
|
||||||
|
|
||||||
logger = LocalProxy(lambda: current_app.logger)
|
logger = LocalProxy(lambda: current_app.logger)
|
||||||
|
|
||||||
association_table = db.Table('user_group',
|
association_table = db.Table('user_x_role',
|
||||||
db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
|
db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
|
||||||
db.Column('group_id', db.Integer, db.ForeignKey('group.id'))
|
db.Column('role_id', db.Integer, db.ForeignKey('role.id'))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class User(db.Model):
|
||||||
firstname = db.Column(db.String(30))
|
firstname = db.Column(db.String(30))
|
||||||
lastname = db.Column(db.String(30))
|
lastname = db.Column(db.String(30))
|
||||||
mail = db.Column(db.String(30))
|
mail = db.Column(db.String(30))
|
||||||
groups = db.relationship("Group", secondary=association_table)
|
roles = db.relationship("Role", secondary=association_table)
|
||||||
sessions = db.relationship("AccessToken", back_populates="user")
|
sessions = db.relationship("AccessToken", back_populates="user")
|
||||||
attributes = db.relationship("UserAttribute", collection_class=attribute_mapped_collection('name'),
|
attributes = db.relationship("UserAttribute", collection_class=attribute_mapped_collection('name'),
|
||||||
cascade="all, delete")
|
cascade="all, delete")
|
||||||
|
@ -42,11 +42,11 @@ class User(db.Model):
|
||||||
else:
|
else:
|
||||||
self.attributes[name] = UserAttribute(name=name, value=value)
|
self.attributes[name] = UserAttribute(name=name, value=value)
|
||||||
|
|
||||||
def add_group(self, name):
|
def add_role(self, name):
|
||||||
r = Group.query.filter_by(name=name).first()
|
r = Role.query.filter_by(name=name).first()
|
||||||
if not r:
|
if not r:
|
||||||
r = Group(name=name)
|
r = Role(name=name)
|
||||||
self.groups.append(r)
|
self.roles.append(r)
|
||||||
|
|
||||||
def update_data(self, data):
|
def update_data(self, data):
|
||||||
logger.debug("update data of user")
|
logger.debug("update data of user")
|
||||||
|
@ -61,6 +61,13 @@ class User(db.Model):
|
||||||
if 'display_name' in data:
|
if 'display_name' in data:
|
||||||
self.display_name = data['display_name']
|
self.display_name = data['display_name']
|
||||||
|
|
||||||
|
def has_permissions(self, permissions):
|
||||||
|
for role in self.roles:
|
||||||
|
for permission in role.permissions:
|
||||||
|
if permission.name in permissions:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
return {
|
return {
|
||||||
# TODO: username should be UID?
|
# TODO: username should be UID?
|
||||||
|
@ -69,29 +76,29 @@ class User(db.Model):
|
||||||
"firstname": self.firstname,
|
"firstname": self.firstname,
|
||||||
"lastname": self.lastname,
|
"lastname": self.lastname,
|
||||||
"mail": self.mail,
|
"mail": self.mail,
|
||||||
"groups": ["user"] + [g.name for g in self.groups]
|
"roles": ["user"] + [r.name for r in self.roles]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class UserAttribute(db.Model):
|
class UserAttribute(db.Model):
|
||||||
__tablename__ = 'userAttribute'
|
__tablename__ = 'user_attribute'
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
user = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
user = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||||
name = db.Column(db.String(30))
|
name = db.Column(db.String(30))
|
||||||
value = db.Column(db.String(192))
|
value = db.Column(db.String(192))
|
||||||
|
|
||||||
|
|
||||||
group_permission_association_table = db.Table('group_permission',
|
role_permission_association_table = db.Table('role_x_permission',
|
||||||
db.Column('group_id', db.Integer, db.ForeignKey('group.id')),
|
db.Column('role_id', db.Integer, db.ForeignKey('role.id')),
|
||||||
db.Column('permission_id', db.Integer, db.ForeignKey('permission.id'))
|
db.Column('permission_id', db.Integer, db.ForeignKey('permission.id'))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Group(db.Model):
|
class Role(db.Model):
|
||||||
__tablename__ = 'group'
|
__tablename__ = 'role'
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
name = db.Column(db.String(30))
|
name = db.Column(db.String(30), unique=True)
|
||||||
permissions = db.relationship("Permission", secondary=group_permission_association_table)
|
permissions = db.relationship("Permission", secondary=role_permission_association_table, cascade="all, delete")
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
@ -100,4 +107,7 @@ class Group(db.Model):
|
||||||
class Permission(db.Model):
|
class Permission(db.Model):
|
||||||
__tablename__ = 'permission'
|
__tablename__ = 'permission'
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
name = db.Column(db.String(30))
|
name = db.Column(db.String(30), unique=True)
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
return self.name
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -18,12 +18,14 @@ setup(
|
||||||
"flask_cors",
|
"flask_cors",
|
||||||
"werkzeug",
|
"werkzeug",
|
||||||
"bjoern",
|
"bjoern",
|
||||||
|
"python-dateutil"
|
||||||
],
|
],
|
||||||
extras_require={"ldap": ["flask_ldapconn", "ldap3"]},
|
extras_require={"ldap": ["flask_ldapconn", "ldap3"]},
|
||||||
entry_points={
|
entry_points={
|
||||||
"flaschengeist.plugin": [
|
"flaschengeist.plugin": [
|
||||||
"auth = flaschengeist.modules.auth:register",
|
"auth = flaschengeist.modules.auth:register",
|
||||||
"users = flaschengeist.modules.users:register",
|
"users = flaschengeist.modules.users:register",
|
||||||
|
"roles = flaschengeist.modules.roles:register",
|
||||||
"schedule = flaschengeist.modules.schedule:register",
|
"schedule = flaschengeist.modules.schedule:register",
|
||||||
],
|
],
|
||||||
"flaschengeist.auth": [
|
"flaschengeist.auth": [
|
||||||
|
|
Loading…
Reference in New Issue