class SwfAssetsController < ApplicationController
	# We're very careful with what content is allowed to load. This is because
	# asset movies run arbitrary JS, and, while we generally trust content from
	# Neopets.com, let's not be *allowing* movie JS to do whatever it wants! This
	# is a good default security stance, even if we don't foresee an attack.
	content_security_policy do |policy|
		policy.sandbox "allow-scripts"
		policy.default_src "none"

		policy.img_src -> {
			src_list(
				helpers.image_url("favicon.png"),
				@swf_asset.image_url,
				*@swf_asset.canvas_movie_sprite_urls,

				# For images, `images.neopets.com` is a generally safe host to load
				# from (shouldn't be a vulnerable site or exfiltration vector), and
				# doing this can help make this header a *lot* shorter, which helps
				# our nginx reverse proxy (and probably some clients) handle it. (For
				# example, see asset `667993` for "Engulfed in Flames Effect".)
				hosts: ["https://images.neopets.com"],
			)
		}

		policy.script_src -> {
			src_list(
				helpers.javascript_url("easeljs.min"),
				helpers.javascript_url("tweenjs.min"),
				helpers.javascript_url("swf_assets/show"),
				@swf_asset.canvas_movie_library_url,
			)
		}

		policy.style_src -> {
			src_list(
				helpers.stylesheet_url("swf_assets/show"),
			)
		}
	end

	def show
		@swf_asset = SwfAsset.find params[:id]
		render layout: nil
	end

	private

	def src_list(*urls, hosts: [])
		urls.
			# Ignore any `nil`s that might arise
			filter(&:present?).
			# Remove query strings from URLs (they're invalid in CSPs)
			map { |url| url.sub(/\?.*\z/, "") }.
			# For the given `hosts`, remove all their specific URLs, and just list
			# the host itself.
			reject { |url| hosts.any? { |h| url.start_with? h } } + hosts
	end
end