Browse Source

Switch user permissions to use an enum

Previously, there wasn't any defined list of which permissions were
valid or not. You basically had to look through each model's __acl__
method to see what the possibilities were.

Using an enum will be less convenient when adding new permissions or
changing existing ones (since it will require a database migration), but
it makes it much easier to see what the valid options are, and will
prevent invalid permissions from being set up in the database.
merge-requests/126/merge
Deimos 4 years ago
parent
commit
2e5a2d96bf
  1. 49
      tildes/alembic/versions/28d7ce2c4825_use_enum_for_user_permissions.py
  2. 22
      tildes/tildes/enums.py
  3. 8
      tildes/tildes/models/user/user_permissions.py

49
tildes/alembic/versions/28d7ce2c4825_use_enum_for_user_permissions.py

@ -0,0 +1,49 @@
"""Use enum for user permissions
Revision ID: 28d7ce2c4825
Revises: 82e9801eb2d6
Create Date: 2020-08-05 20:32:51.047215
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "28d7ce2c4825"
down_revision = "82e9801eb2d6"
branch_labels = None
depends_on = None
def upgrade():
op.execute(
"""
create type userpermission as enum(
'comment.remove',
'comment.view_labels',
'topic.edit_by_generic_user',
'topic.edit_link',
'topic.edit_title',
'topic.lock',
'topic.move',
'topic.post',
'topic.remove',
'topic.tag',
'user.ban',
'user.view_removed_posts',
'wiki.edit'
)
"""
)
op.execute(
"""
alter table user_permissions
alter column permission type userpermission using permission::userpermission
"""
)
def downgrade():
op.execute("alter table user_permissions alter column permission type text")
op.execute("drop type userpermission")

22
tildes/tildes/enums.py

@ -290,6 +290,28 @@ class HTMLSanitizationContext(enum.Enum):
USER_BIO = enum.auto()
# Enum for the possible user permissions
# (Using functional API for this one because the values aren't valid Python names)
UserPermission = enum.Enum(
"UserPermission",
[
"comment.remove",
"comment.view_labels",
"topic.edit_by_generic_user",
"topic.edit_link",
"topic.edit_title",
"topic.lock",
"topic.move",
"topic.post",
"topic.remove",
"topic.tag",
"user.ban",
"user.view_removed_posts",
"wiki.edit",
],
)
class UserPermissionType(enum.Enum):
"""Enum for the types of user permissions."""

8
tildes/tildes/models/user/user_permissions.py

@ -3,11 +3,11 @@
"""Contains the UserPermissions class."""
from sqlalchemy import Column, ForeignKey, Integer, Text
from sqlalchemy import Column, ForeignKey, Integer
from sqlalchemy.dialects.postgresql import ENUM
from sqlalchemy.orm import relationship
from tildes.enums import UserPermissionType
from tildes.enums import UserPermission, UserPermissionType
from tildes.models import DatabaseModel
from tildes.models.group import Group
from tildes.models.user import User
@ -21,7 +21,7 @@ class UserPermissions(DatabaseModel):
permission_id: int = Column(Integer, primary_key=True)
user_id: int = Column(Integer, ForeignKey("users.user_id"), nullable=False)
group_id: int = Column(Integer, ForeignKey("groups.group_id"), nullable=True)
permission: str = Column(Text, nullable=False)
permission: UserPermission = Column(ENUM(UserPermission), nullable=False)
permission_type: UserPermissionType = Column(
ENUM(UserPermissionType), nullable=False, server_default="ALLOW"
)
@ -50,6 +50,6 @@ class UserPermissions(DatabaseModel):
if self.permission_type == UserPermissionType.DENY:
principal += "!"
principal += self.permission
principal += str(self.permission.name)
return principal
Loading…
Cancel
Save