0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-09 21:45:25 +08:00
discourse/plugins/discourse-assign/lib/discourse_assign/assignment_permissions.rb
Mark VanLandingham 2aaa6a5ca3
FEATURE: Add category-level assignment permissions (#40412)
Previously, assignment permissions only came from the global
`assign_allowed_on_groups` site setting.

This change lets categories grant assignment permission to additional
groups, keeping assignment controls and assignee suggestions scoped to
the relevant category.
2026-06-08 09:59:40 -05:00

114 lines
3 KiB
Ruby
Vendored

# frozen_string_literal: true
module DiscourseAssign
module AssignmentPermissions
CATEGORY_ADDITIONAL_ASSIGN_ALLOWED_GROUPS = "additional_assign_allowed_on_groups"
class << self
def allowed_user_ids_for_target(target)
ids = Set.new(admin_user_ids)
ids.merge(user_ids_in_groups(global_group_ids))
ids.merge(user_ids_in_groups(scoped_group_ids_for_category(category_id_for(target))))
ids.to_a
end
def allowed_group_ids_for_target(user, target)
ids = Set.new(Group.assignable(user).pluck(:id))
ids.merge(scoped_group_ids_for_category(category_id_for(target)))
ids.to_a
end
def assign_allowed_groups_for_target(user, target)
Group.visible_groups(user).where(
id: global_group_ids | scoped_group_ids_for_category(category_id_for(target)),
)
end
def assign_allowed_groups_for_user(user)
group_ids =
if user&.guardian&.can_assign_globally?
global_group_ids | all_scoped_group_ids
else
global_group_ids | scoped_group_ids_for_user(user)
end
Group.visible_groups(user).where(id: group_ids)
end
def assignable_user_ids_for_user(user)
group_ids =
if user&.guardian&.can_assign_globally?
global_group_ids | all_scoped_group_ids
else
global_group_ids | scoped_group_ids_for_user(user)
end
(admin_user_ids | user_ids_in_groups(group_ids)).uniq
end
def all_assign_allowed_group_ids
global_group_ids | all_scoped_group_ids
end
def category_id_for(target)
case target
when Topic
target.category_id
when Post
target.topic&.category_id
else
nil
end
end
def global_group_ids
SiteSetting.assign_allowed_on_groups_map
end
def all_scoped_group_ids
CategoryCustomField
.where(name: CATEGORY_ADDITIONAL_ASSIGN_ALLOWED_GROUPS)
.pluck(:value)
.flat_map { |value| group_ids_from_value(value) }
.uniq
end
def scoped_group_ids_for_user(user)
return [] if user.blank?
all_scoped_group_ids & group_ids_for(user)
end
def scoped_group_ids_for_category(category_id)
return [] if category_id.blank?
group_ids_from_value(
CategoryCustomField.where(
category_id:,
name: CATEGORY_ADDITIONAL_ASSIGN_ALLOWED_GROUPS,
).pick(:value),
)
end
private
def group_ids_for(user)
user.group_ids
end
def admin_user_ids
User.human_users.admins.pluck(:id)
end
def user_ids_in_groups(group_ids)
return [] if group_ids.blank?
GroupUser.where(group_id: group_ids).pluck(:user_id)
end
def group_ids_from_value(value)
value.to_s.split("|").map(&:to_i).reject(&:zero?)
end
end
end
end