forked from mastodon/mastodon
-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract class from CSP configuration/initialization (mastodon#26905)
- Loading branch information
1 parent
2e6bf60
commit eae5c73
Showing
3 changed files
with
192 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# frozen_string_literal: true | ||
|
||
class ContentSecurityPolicy | ||
def base_host | ||
Rails.configuration.x.web_domain | ||
end | ||
|
||
def assets_host | ||
url_from_configured_asset_host || url_from_base_host | ||
end | ||
|
||
def media_host | ||
cdn_host_value || assets_host | ||
end | ||
|
||
private | ||
|
||
def url_from_configured_asset_host | ||
Rails.configuration.action_controller.asset_host | ||
end | ||
|
||
def cdn_host_value | ||
s3_alias_host || s3_cloudfront_host || azure_alias_host || s3_hostname_host | ||
end | ||
|
||
def url_from_base_host | ||
host_to_url(base_host) | ||
end | ||
|
||
def host_to_url(host_string) | ||
uri_from_configuration_and_string(host_string) if host_string.present? | ||
end | ||
|
||
def s3_alias_host | ||
host_to_url ENV.fetch('S3_ALIAS_HOST', nil) | ||
end | ||
|
||
def s3_cloudfront_host | ||
host_to_url ENV.fetch('S3_CLOUDFRONT_HOST', nil) | ||
end | ||
|
||
def azure_alias_host | ||
host_to_url ENV.fetch('AZURE_ALIAS_HOST', nil) | ||
end | ||
|
||
def s3_hostname_host | ||
host_to_url ENV.fetch('S3_HOSTNAME', nil) | ||
end | ||
|
||
def uri_from_configuration_and_string(host_string) | ||
Addressable::URI.parse("#{host_protocol}://#{host_string}").tap do |uri| | ||
uri.path += '/' unless uri.path.blank? || uri.path.end_with?('/') | ||
end.to_s | ||
end | ||
|
||
def host_protocol | ||
Rails.configuration.x.use_https ? 'https' : 'http' | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
|
||
describe ContentSecurityPolicy do | ||
subject { described_class.new } | ||
|
||
around do |example| | ||
original_asset_host = Rails.configuration.action_controller.asset_host | ||
original_web_domain = Rails.configuration.x.web_domain | ||
original_use_https = Rails.configuration.x.use_https | ||
example.run | ||
Rails.configuration.action_controller.asset_host = original_asset_host | ||
Rails.configuration.x.web_domain = original_web_domain | ||
Rails.configuration.x.use_https = original_use_https | ||
end | ||
|
||
describe '#base_host' do | ||
before { Rails.configuration.x.web_domain = 'host.example' } | ||
|
||
it 'returns the configured value for the web domain' do | ||
expect(subject.base_host).to eq 'host.example' | ||
end | ||
end | ||
|
||
describe '#assets_host' do | ||
context 'when asset_host is not configured' do | ||
before { Rails.configuration.action_controller.asset_host = nil } | ||
|
||
context 'with a configured web domain' do | ||
before { Rails.configuration.x.web_domain = 'host.example' } | ||
|
||
context 'when use_https is enabled' do | ||
before { Rails.configuration.x.use_https = true } | ||
|
||
it 'returns value from base host with https protocol' do | ||
expect(subject.assets_host).to eq 'https://host.example' | ||
end | ||
end | ||
|
||
context 'when use_https is disabled' do | ||
before { Rails.configuration.x.use_https = false } | ||
|
||
it 'returns value from base host with http protocol' do | ||
expect(subject.assets_host).to eq 'http://host.example' | ||
end | ||
end | ||
end | ||
end | ||
|
||
context 'when asset_host is configured' do | ||
before do | ||
Rails.configuration.action_controller.asset_host = 'https://assets.host.example' | ||
end | ||
|
||
it 'returns full value from configured host' do | ||
expect(subject.assets_host).to eq 'https://assets.host.example' | ||
end | ||
end | ||
end | ||
|
||
describe '#media_host' do | ||
context 'when there is no configured CDN' do | ||
it 'defaults to using the assets_host value' do | ||
expect(subject.media_host).to eq(subject.assets_host) | ||
end | ||
end | ||
|
||
context 'when an S3 alias host is configured' do | ||
around do |example| | ||
ClimateControl.modify S3_ALIAS_HOST: 'asset-host.s3-alias.example' do | ||
example.run | ||
end | ||
end | ||
|
||
it 'uses the s3 alias host value' do | ||
expect(subject.media_host).to eq 'https://asset-host.s3-alias.example' | ||
end | ||
end | ||
|
||
context 'when an S3 alias host with a trailing path is configured' do | ||
around do |example| | ||
ClimateControl.modify S3_ALIAS_HOST: 'asset-host.s3-alias.example/pathname' do | ||
example.run | ||
end | ||
end | ||
|
||
it 'uses the s3 alias host value and preserves the path' do | ||
expect(subject.media_host).to eq 'https://asset-host.s3-alias.example/pathname/' | ||
end | ||
end | ||
|
||
context 'when an S3 cloudfront host is configured' do | ||
around do |example| | ||
ClimateControl.modify S3_CLOUDFRONT_HOST: 'asset-host.s3-cloudfront.example' do | ||
example.run | ||
end | ||
end | ||
|
||
it 'uses the s3 cloudfront host value' do | ||
expect(subject.media_host).to eq 'https://asset-host.s3-cloudfront.example' | ||
end | ||
end | ||
|
||
context 'when an azure alias host is configured' do | ||
around do |example| | ||
ClimateControl.modify AZURE_ALIAS_HOST: 'asset-host.azure-alias.example' do | ||
example.run | ||
end | ||
end | ||
|
||
it 'uses the azure alias host value' do | ||
expect(subject.media_host).to eq 'https://asset-host.azure-alias.example' | ||
end | ||
end | ||
|
||
context 'when s3_enabled is configured' do | ||
around do |example| | ||
ClimateControl.modify S3_ENABLED: 'true', S3_HOSTNAME: 'asset-host.s3.example' do | ||
example.run | ||
end | ||
end | ||
|
||
it 'uses the s3 hostname host value' do | ||
expect(subject.media_host).to eq 'https://asset-host.s3.example' | ||
end | ||
end | ||
end | ||
end |