2018-11-30 08:51:45 -06:00
|
|
|
# frozen_string_literal: true
|
|
|
|
class ContentSecurityPolicy
|
|
|
|
module Extension
|
|
|
|
extend self
|
|
|
|
|
|
|
|
def site_setting_extension
|
|
|
|
{ script_src: SiteSetting.content_security_policy_script_src.split('|') }
|
|
|
|
end
|
|
|
|
|
|
|
|
def plugin_extensions
|
|
|
|
[].tap do |extensions|
|
|
|
|
Discourse.plugins.each do |plugin|
|
|
|
|
extensions.concat(plugin.csp_extensions) if plugin.enabled?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
THEME_SETTING = 'extend_content_security_policy'
|
|
|
|
|
2019-02-11 06:32:04 -06:00
|
|
|
def theme_extensions(theme_ids)
|
|
|
|
key = "theme_extensions_#{Theme.transform_ids(theme_ids).join(',')}"
|
|
|
|
cache[key] ||= find_theme_extensions(theme_ids)
|
2018-11-30 08:51:45 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
def clear_theme_extensions_cache!
|
2019-02-11 06:32:04 -06:00
|
|
|
cache.clear
|
2018-11-30 08:51:45 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def cache
|
|
|
|
@cache ||= DistributedCache.new('csp_extensions')
|
|
|
|
end
|
|
|
|
|
2019-02-11 06:32:04 -06:00
|
|
|
def find_theme_extensions(theme_ids)
|
2018-11-30 08:51:45 -06:00
|
|
|
extensions = []
|
|
|
|
|
2019-02-11 06:32:04 -06:00
|
|
|
Theme.where(id: Theme.transform_ids(theme_ids)).find_each do |theme|
|
2018-11-30 08:51:45 -06:00
|
|
|
theme.cached_settings.each do |setting, value|
|
|
|
|
extensions << build_theme_extension(value) if setting.to_s == THEME_SETTING
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
extensions
|
|
|
|
end
|
|
|
|
|
|
|
|
def build_theme_extension(raw)
|
|
|
|
{}.tap do |extension|
|
|
|
|
raw.split('|').each do |entry|
|
|
|
|
directive, source = entry.split(':', 2).map(&:strip)
|
|
|
|
|
|
|
|
extension[directive] ||= []
|
|
|
|
extension[directive] << source
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|