Merge "Rationalise code for filtering private Boards and Worklists"

This commit is contained in:
Zuul 2019-06-09 14:46:13 +00:00 committed by Gerrit Code Review
commit 1919d5414a
2 changed files with 37 additions and 70 deletions

View File

@ -446,64 +446,35 @@ def filter_private_worklists(query, current_user, hide_lanes=True):
are lanes in a board. are lanes in a board.
""" """
# Alias all the things we're joining, in case they've been # Lanes inherit board permissions and ignore their own, so need to be
# joined already. # handled separately. If we're not hiding all lanes from the result,
board_worklists = aliased(models.BoardWorklist, # these two queries are combined at the end.
name="worklist_boardworklists") lanes = query.filter(models.Worklist.boards.any())
boards = aliased(models.Board, name="worklist_boards") lists = query.filter(~models.Worklist.boards.any())
board_permissions = aliased(models.board_permissions,
name="worklist_boardpermissions")
worklist_permissions = aliased(models.worklist_permissions,
name="worklist_worklistpermissions")
permissions = aliased(models.Permission, name="worklist_permissions")
user_permissions = aliased(models.user_permissions,
name="worklist_userpermissions")
users = aliased(models.User, name="worklist_users")
# Worklists permissions must be inherited from the board which
# contains the list (if any). To handle this we split the query
# into the lists which are in boards (`lanes`) and those which
# aren't (`lists`). We then either hide the lanes entirely or
# unify the two queries.
lanes = query.join(
(board_worklists, models.Worklist.id == board_worklists.list_id))
lanes = (lanes
.outerjoin((boards, boards.id == board_worklists.board_id))
.outerjoin((board_permissions,
boards.id == board_permissions.c.board_id))
.outerjoin((permissions,
permissions.id == board_permissions.c.permission_id))
.outerjoin((user_permissions,
permissions.id == user_permissions.c.permission_id))
.outerjoin((users, user_permissions.c.user_id == users.id)))
lists = query.outerjoin(
(board_worklists, models.Worklist.id == board_worklists.list_id))
lists = (lists.filter(board_worklists.board_id.is_(None))
.outerjoin((worklist_permissions,
models.Worklist.id == worklist_permissions.c.worklist_id))
.outerjoin((permissions,
permissions.id == worklist_permissions.c.permission_id))
.outerjoin((user_permissions,
user_permissions.c.permission_id == permissions.id))
.outerjoin((users, user_permissions.c.user_id == users.id)))
if current_user: if current_user:
if not hide_lanes: if not hide_lanes:
# This removes any worklists that are related only to boards
# that the user doesn't have permission to see.
lanes = lanes.filter( lanes = lanes.filter(
or_( models.Worklist.boards.any(
and_( or_(
users.id == current_user, models.Board.permissions.any(
boards.private == true() models.Permission.users.any(
), models.User.id == current_user
boards.private == false() )
),
models.Board.private == false(),
models.Board.id.is_(None)
)
) )
) )
lists = lists.filter( lists = lists.filter(
or_( or_(
and_( models.Worklist.permissions.any(
users.id == current_user, models.Permission.users.any(
models.Worklist.private == true() models.User.id == current_user
)
), ),
models.Worklist.private == false(), models.Worklist.private == false(),
models.Worklist.id.is_(None) models.Worklist.id.is_(None)
@ -511,7 +482,16 @@ def filter_private_worklists(query, current_user, hide_lanes=True):
) )
else: else:
if not hide_lanes: if not hide_lanes:
lanes = lanes.filter(boards.private == false()) # This removes any worklists that are related to only private
# boards
lanes = lanes.filter(
models.Worklist.boards.any(
or_(
models.Board.private == false(),
models.Board.id.is_(None)
)
)
)
lists = lists.filter( lists = lists.filter(
or_( or_(
models.Worklist.private == false(), models.Worklist.private == false(),
@ -531,28 +511,13 @@ def filter_private_boards(query, current_user):
:param current_user: The ID of the user requesting the result. :param current_user: The ID of the user requesting the result.
""" """
board_permissions = aliased(models.board_permissions,
name="board_boardpermissions")
permissions = aliased(models.Permission, name="board_permissions")
user_permissions = aliased(models.user_permissions,
name="board_userpermissions")
users = aliased(models.User, name="board_users")
query = (query
.outerjoin((board_permissions,
models.Board.id == board_permissions.c.board_id))
.outerjoin((permissions,
board_permissions.c.permission_id == permissions.id))
.outerjoin((user_permissions,
permissions.id == user_permissions.c.permission_id))
.outerjoin((users, user_permissions.c.user_id == users.id)))
if current_user: if current_user:
query = query.filter( query = query.filter(
or_( or_(
and_( models.Board.permissions.any(
users.id == current_user, models.Permission.users.any(
models.Board.private == true() models.User.id == current_user
)
), ),
models.Board.private == false(), models.Board.private == false(),
models.Board.id.is_(None) models.Board.id.is_(None)

View File

@ -614,6 +614,8 @@ class Worklist(FullText, ModelBuilder, Base):
automatic = Column(Boolean, default=False) automatic = Column(Boolean, default=False)
filters = relationship(WorklistFilter) filters = relationship(WorklistFilter)
permissions = relationship("Permission", secondary="worklist_permissions") permissions = relationship("Permission", secondary="worklist_permissions")
boards = relationship("Board", secondary="board_worklists",
backref="worklists")
_public_fields = ["id", "title", "creator_id", "project_id", _public_fields = ["id", "title", "creator_id", "project_id",
"permission_id", "private", "archived", "automatic"] "permission_id", "private", "archived", "automatic"]