diff --git a/app/models/priv.py b/app/models/priv.py index 765e59c..2977227 100644 --- a/app/models/priv.py +++ b/app/models/priv.py @@ -47,6 +47,9 @@ class Group(db.Model): members = db.relationship('Member', secondary=lambda: GroupMember, back_populates='groups') + # Other fields populated automatically through relations: + # list of privileges + def __init__(self, name, css, descr): self.name = name self.css = css @@ -59,7 +62,7 @@ class Group(db.Model): * Group privileges """ - for gp in GroupPrivilege.query.filter_by(gid=self.id).all(): + for gp in self.privileges: db.session.delete(gp) db.session.commit() @@ -67,8 +70,7 @@ class Group(db.Model): db.session.commit() def privs(self): - gps = GroupPrivilege.query.filter_by(gid=self.id).all() - return sorted(gp.priv for gp in gps) + return sorted(gp.priv for gp in self.privileges) def __repr__(self): return f'' @@ -79,15 +81,17 @@ GroupMember = db.Table('group_member', db.Model.metadata, db.Column('gid', db.Integer, db.ForeignKey('group.id')), db.Column('uid', db.Integer, db.ForeignKey('member.id'))) - -# Many-to-many relationship for privileges granted to groups +# GroupPrivilege: A list of privileges for groups, materialized as a table class GroupPrivilege(db.Model): __tablename__ = 'group_privilege' id = db.Column(db.Integer, primary_key=True) - gid = db.Column(db.Integer, db.ForeignKey('group.id')) + group_id = db.Column(db.Integer, db.ForeignKey('group.id')) + group = db.relationship('Group', backref='privileges', + foreign_keys=group_id) + priv = db.Column(db.String(64)) def __init__(self, group, priv): - self.gid = group.id + self.group = group self.priv = priv diff --git a/app/models/user.py b/app/models/user.py index afe88a5..7a50a24 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -210,10 +210,10 @@ class Member(User): """Check whether the member has the specified privilege.""" if priv in self.special_privs: return True - return db.session.query(Group, GroupPrivilege).filter( - Group.id.in_([g.id for g in self.groups]), - GroupPrivilege.gid==Group.id, - GroupPrivilege.priv==priv).first() is not None + for g in self.groups: + if priv in g.privs(): + return True + return False def special_privileges(self): """List member's special privileges.""" diff --git a/master.py b/master.py index 6a79f4c..e0b9a7d 100755 --- a/master.py +++ b/master.py @@ -78,11 +78,11 @@ def update_groups(): # Update an existing group if g is not None: changes = (g.css != css) or (g.description != descr) or \ - (set(g.privs()) != set(privs)) + (set(g.privs) != set(privs)) g.css = css g.description = descr - for gpriv in GroupPrivilege.query.filter_by(gid=g.id): + for gpriv in g.privs: db.session.delete(gpriv) for priv in privs: db.session.add(GroupPrivilege(g, priv)) diff --git a/migrations/versions/fcf53f1a14e3_relate_groups_with_their_privileges_.py b/migrations/versions/fcf53f1a14e3_relate_groups_with_their_privileges_.py new file mode 100644 index 0000000..36f4205 --- /dev/null +++ b/migrations/versions/fcf53f1a14e3_relate_groups_with_their_privileges_.py @@ -0,0 +1,25 @@ +"""relate groups with their privileges through a relationship + +Revision ID: fcf53f1a14e3 +Revises: 44fbbb1fd537 +Create Date: 2022-05-12 19:43:04.436448 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'fcf53f1a14e3' +down_revision = '44fbbb1fd537' +branch_labels = None +depends_on = None + + +def upgrade(): + # Actually modified by hand for once - Lephe' + op.alter_column('group_privilege', 'gid', new_column_name='group_id') + + +def downgrade(): + op.alter_column('group_privilege', 'group_id', new_column_name='gid')