mirror of
https://github.com/discourse/discourse.git
synced 2026-08-04 10:39:43 +08:00
Further following on from bee1be8599,
this brings greater parity between theme settings and site settings.
This commit adds a new `disallowed_groups` field to theme and component
settings, which allows theme authors to specify groups that cannot be
selected
by admins for a particular list type or object group type setting.
This is useful for cases where the group-based setting isn't usable
for a group like e.g. anonymous_users, no point allowing them for
a setting that requires a user to be logged in to take effect.
c.f.
https://meta.discourse.org/t/granular-group-based-permissions-for-anonymous-and-logged-in-users/402273/18?u=martin
### List groups
With `disallowed_groups: "4|5"` specified (`logged_in_users` &
`anonymous_users`)
<img width="734" height="450" alt="image"
src="https://github.com/user-attachments/assets/ed8d7338-65fa-44e6-8dce-7073a87076e6"
/>
### Object groups
With `disallowed_groups: "4|5"` specified (`logged_in_users` &
`anonymous_users`)
<img width="696" height="725" alt="image"
src="https://github.com/user-attachments/assets/1a9103d4-cf44-4038-9d62-3838cb779b49"
/>
93 lines
2.5 KiB
Ruby
Vendored
93 lines
2.5 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
class ThemeSettingsManager::Objects < ThemeSettingsManager
|
|
def self.extract_value_from_row(row)
|
|
row.json_value
|
|
end
|
|
|
|
def default
|
|
hydrate_uploads(@default.map(&:deep_stringify_keys))
|
|
end
|
|
|
|
def value
|
|
has_record? ? hydrate_uploads(db_record.json_value) : default
|
|
end
|
|
|
|
def value=(objects)
|
|
objects = JSON.parse(objects) if objects.is_a?(::String)
|
|
objects = remove_disallowed_groups(objects)
|
|
ensure_is_valid_value!(objects)
|
|
objects = SchemaSettingsObjectValidator.normalize_uploads(schema:, objects:)
|
|
record = has_record? ? update_record!(json_value: objects) : create_record!(json_value: objects)
|
|
theme.reload
|
|
record.json_value
|
|
end
|
|
|
|
def schema
|
|
@opts[:schema]
|
|
end
|
|
|
|
def hydrate_uploads(objects)
|
|
SchemaSettingsObjectValidator.hydrate_uploads(schema:, objects:, cdn: true)
|
|
end
|
|
|
|
def remove_disallowed_groups(objects)
|
|
return objects if objects.blank?
|
|
|
|
remove_disallowed_groups_from_objects(objects.deep_dup, schema[:properties])
|
|
end
|
|
|
|
def categories(guardian)
|
|
category_ids = Set.new
|
|
|
|
value.each do |theme_setting_object|
|
|
category_ids.merge(
|
|
SchemaSettingsObjectValidator.new(
|
|
schema:,
|
|
object: theme_setting_object,
|
|
).property_values_of_type("categories"),
|
|
)
|
|
end
|
|
|
|
return [] if category_ids.empty?
|
|
|
|
Category.secured(guardian).where(id: category_ids)
|
|
end
|
|
|
|
private
|
|
|
|
def remove_disallowed_groups_from_objects(objects, properties)
|
|
objects.each do |object|
|
|
properties.each do |property_name, property_attributes|
|
|
key = object_key(object, property_name)
|
|
next if key.nil?
|
|
|
|
case property_attributes[:type]
|
|
when "groups"
|
|
next if property_attributes[:disallowed_groups].blank?
|
|
|
|
disallowed_ids = property_attributes[:disallowed_groups].to_s.split("|").map(&:to_i)
|
|
object[key] = Array(object[key]).reject { |id| disallowed_ids.include?(id) }
|
|
when "objects"
|
|
nested_objects = object[key]
|
|
if nested_objects.is_a?(Array)
|
|
remove_disallowed_groups_from_objects(
|
|
nested_objects,
|
|
property_attributes[:schema][:properties],
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
objects
|
|
end
|
|
|
|
def object_key(object, property_name)
|
|
string_key = property_name.to_s
|
|
return string_key if object.key?(string_key)
|
|
|
|
symbol_key = property_name.to_sym
|
|
symbol_key if object.key?(symbol_key)
|
|
end
|
|
end
|