diff --git a/app/models/priv.py b/app/models/priv.py index ff96ae4..765e59c 100644 --- a/app/models/priv.py +++ b/app/models/priv.py @@ -16,16 +16,18 @@ class SpecialPrivilege(db.Model): id = db.Column(db.Integer, primary_key=True) # Member that is granted the privilege - mid = db.Column(db.Integer, db.ForeignKey('member.id'), index=True) + member_id = db.Column(db.Integer, db.ForeignKey('member.id'), index=True) + member = db.relationship('Member', backref="special_privs", + foreign_keys=member_id) # Privilege name priv = db.Column(db.String(64)) def __init__(self, member, priv): - self.mid = member.id + self.member = member self.priv = priv def __repr__(self): - return f'' + return f'' # Group: User group, corresponds to a community role and a set of privileges diff --git a/app/models/user.py b/app/models/user.py index 0f80594..afe88a5 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -139,6 +139,7 @@ class Member(User): # Other fields populated automatically through relations: + # List of special privileges # List of unseen notifications (of type Notification) # Polls created by the member (of class Poll) @@ -194,7 +195,7 @@ class Member(User): Deletes the user, but not the posts; use either transfer_posts() or delete_posts() before calling this. """ - for sp in SpecialPrivilege.query.filter_by(mid=self.id).all(): + for sp in self.special_privs: db.session.delete(sp) self.trophies = [] @@ -207,7 +208,7 @@ class Member(User): def priv(self, priv): """Check whether the member has the specified privilege.""" - if SpecialPrivilege.query.filter_by(mid=self.id, priv=priv).first(): + 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]), @@ -216,8 +217,7 @@ class Member(User): def special_privileges(self): """List member's special privileges.""" - sp = SpecialPrivilege.query.filter_by(mid=self.id).all() - return sorted(row.priv for row in sp) + return sorted(self.special_privs) def can_access_forum(self, forum): """Whether this member can read the forum's contents.""" diff --git a/app/routes/admin/groups.py b/app/routes/admin/groups.py index 3c2ff3d..3315fdf 100644 --- a/app/routes/admin/groups.py +++ b/app/routes/admin/groups.py @@ -15,7 +15,7 @@ def adm_groups(): # Users with either groups or special privileges users_groups = Member.query.join(GroupMember) users_special = Member.query \ - .join(SpecialPrivilege, Member.id == SpecialPrivilege.mid) + .join(SpecialPrivilege, Member.id == SpecialPrivilege.member_id) users = users_groups.union(users_special) users = sorted(users, key = lambda x: x.name) diff --git a/migrations/versions/44fbbb1fd537_special_privileges_as_a_relationship.py b/migrations/versions/44fbbb1fd537_special_privileges_as_a_relationship.py new file mode 100644 index 0000000..4b7761c --- /dev/null +++ b/migrations/versions/44fbbb1fd537_special_privileges_as_a_relationship.py @@ -0,0 +1,38 @@ +"""special privileges as a relationship + +Revision ID: 44fbbb1fd537 +Revises: 72df33816b21 +Create Date: 2022-05-12 19:15:15.592896 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '44fbbb1fd537' +down_revision = '72df33816b21' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('special_privilege', sa.Column('member_id', sa.Integer(), nullable=True)) + op.drop_index('ix_special_privilege_mid', table_name='special_privilege') + op.create_index(op.f('ix_special_privilege_member_id'), 'special_privilege', ['member_id'], unique=False) + op.drop_constraint('special_privilege_mid_fkey', 'special_privilege', type_='foreignkey') + op.create_foreign_key(None, 'special_privilege', 'member', ['member_id'], ['id']) + op.drop_column('special_privilege', 'mid') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('special_privilege', sa.Column('mid', sa.INTEGER(), autoincrement=False, nullable=True)) + op.drop_constraint(None, 'special_privilege', type_='foreignkey') + op.create_foreign_key('special_privilege_mid_fkey', 'special_privilege', 'member', ['mid'], ['id']) + op.drop_index(op.f('ix_special_privilege_member_id'), table_name='special_privilege') + op.create_index('ix_special_privilege_mid', 'special_privilege', ['mid'], unique=False) + op.drop_column('special_privilege', 'member_id') + # ### end Alembic commands ###