Skip to content

Commit 06fce94

Browse files
committed
Replace #get with #default and don't require explicit initial configuration anymore
1 parent 669a046 commit 06fce94

File tree

8 files changed

+37
-33
lines changed

8 files changed

+37
-33
lines changed

lib/secure_headers.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def header_hash_for(request)
166166
# name - the name of the previously configured override.
167167
def use_secure_headers_override(request, name)
168168
config = config_for(request)
169-
config.apply_override(name)
169+
config.override(name)
170170
override_secure_headers_request_config(request, config)
171171
end
172172

@@ -195,7 +195,7 @@ def content_security_policy_style_nonce(request)
195195
# Falls back to the global config
196196
def config_for(request, prevent_dup = false)
197197
config = request.env[SECURE_HEADERS_CONFIG] ||
198-
Configuration.get
198+
Configuration.default
199199

200200

201201
# Global configs are frozen, per-request configs are not. When we're not

lib/secure_headers/configuration.rb

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module SecureHeaders
55
class Configuration
66
DEFAULT_CONFIG = :default
77
NOOP_OVERRIDE = "secure_headers_noop_override"
8-
class NotYetConfiguredError < StandardError; end
8+
class AlreadyConfiguredError < StandardError; end
99
class IllegalPolicyModificationError < StandardError; end
1010
class << self
1111
# Public: Set the global default configuration.
@@ -14,6 +14,18 @@ class << self
1414
#
1515
# Returns the newly created config.
1616
def default(&block)
17+
if defined?(@default_config) && !block_given?
18+
return @default_config
19+
else
20+
configure(&block)
21+
end
22+
end
23+
24+
def configure(&block)
25+
if defined?(@default_config)
26+
raise AlreadyConfiguredError, "Policy already configured"
27+
end
28+
1729
# Define a built-in override that clears all configuration options and
1830
# results in no security headers being set.
1931
override(NOOP_OVERRIDE) do |config|
@@ -26,12 +38,6 @@ def default(&block)
2638
new_config.validate_config!
2739
@default_config = new_config
2840
end
29-
alias_method :configure, :default
30-
31-
def get
32-
raise NotYetConfiguredError, "Default policy not yet supplied" unless @default_config
33-
@default_config
34-
end
3541

3642
# Public: create a named configuration that overrides the default config.
3743
#
@@ -170,7 +176,7 @@ def dup
170176
# Public: Apply a named override to the current config
171177
#
172178
# Returns self
173-
def apply_override(name)
179+
def override(name = nil, &block)
174180
if override = self.class.overrides(name)
175181
instance_eval(&override)
176182
else

spec/lib/secure_headers/configuration_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ module SecureHeaders
55
describe Configuration do
66
before(:each) do
77
reset_config
8-
Configuration.default
98
end
109

1110
it "has a default config" do
1211
expect(Configuration.default).to_not be_nil
1312
end
1413

1514
it "has an 'noop' override" do
15+
Configuration.default
1616
expect(Configuration.overrides(Configuration::NOOP_OVERRIDE)).to_not be_nil
1717
end
1818

@@ -41,7 +41,7 @@ module SecureHeaders
4141
config.cookies = OPT_OUT
4242
end
4343

44-
config = Configuration.get
44+
config = Configuration.default
4545
expect(config.cookies).to eq(OPT_OUT)
4646
end
4747

@@ -50,7 +50,7 @@ module SecureHeaders
5050
config.cookies = {httponly: true, secure: true, samesite: {lax: false}}
5151
end
5252

53-
config = Configuration.get
53+
config = Configuration.default
5454
expect(config.cookies).to eq({httponly: true, secure: true, samesite: {lax: false}})
5555
end
5656
end

spec/lib/secure_headers/headers/policy_management_spec.rb

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33

44
module SecureHeaders
55
describe PolicyManagement do
6+
before(:each) do
7+
reset_config
8+
end
9+
610
let (:default_opts) do
711
{
812
default_src: %w(https:),
@@ -164,7 +168,7 @@ module SecureHeaders
164168
script_src: %w('self'),
165169
}
166170
end
167-
combined_config = ContentSecurityPolicy.combine_policies(Configuration.get.csp.to_h, style_src: %w(anothercdn.com))
171+
combined_config = ContentSecurityPolicy.combine_policies(Configuration.default.csp.to_h, style_src: %w(anothercdn.com))
168172
csp = ContentSecurityPolicy.new(combined_config)
169173
expect(csp.name).to eq(ContentSecurityPolicyConfig::HEADER_NAME)
170174
expect(csp.value).to eq("default-src https:; script-src 'self'; style-src https: anothercdn.com")
@@ -179,7 +183,7 @@ module SecureHeaders
179183
}.freeze
180184
end
181185
report_uri = "https://report-uri.io/asdf"
182-
combined_config = ContentSecurityPolicy.combine_policies(Configuration.get.csp.to_h, report_uri: [report_uri])
186+
combined_config = ContentSecurityPolicy.combine_policies(Configuration.default.csp.to_h, report_uri: [report_uri])
183187
csp = ContentSecurityPolicy.new(combined_config, USER_AGENTS[:firefox])
184188
expect(csp.value).to include("report-uri #{report_uri}")
185189
end
@@ -195,7 +199,7 @@ module SecureHeaders
195199
non_default_source_additions = ContentSecurityPolicy::NON_FETCH_SOURCES.each_with_object({}) do |directive, hash|
196200
hash[directive] = %w("http://example.org)
197201
end
198-
combined_config = ContentSecurityPolicy.combine_policies(Configuration.get.csp.to_h, non_default_source_additions)
202+
combined_config = ContentSecurityPolicy.combine_policies(Configuration.default.csp.to_h, non_default_source_additions)
199203

200204
ContentSecurityPolicy::NON_FETCH_SOURCES.each do |directive|
201205
expect(combined_config[directive]).to eq(%w("http://example.org))
@@ -210,7 +214,7 @@ module SecureHeaders
210214
report_only: false
211215
}
212216
end
213-
combined_config = ContentSecurityPolicy.combine_policies(Configuration.get.csp.to_h, report_only: true)
217+
combined_config = ContentSecurityPolicy.combine_policies(Configuration.default.csp.to_h, report_only: true)
214218
csp = ContentSecurityPolicy.new(combined_config, USER_AGENTS[:firefox])
215219
expect(csp.name).to eq(ContentSecurityPolicyReportOnlyConfig::HEADER_NAME)
216220
end
@@ -223,7 +227,7 @@ module SecureHeaders
223227
block_all_mixed_content: false
224228
}
225229
end
226-
combined_config = ContentSecurityPolicy.combine_policies(Configuration.get.csp.to_h, block_all_mixed_content: true)
230+
combined_config = ContentSecurityPolicy.combine_policies(Configuration.default.csp.to_h, block_all_mixed_content: true)
227231
csp = ContentSecurityPolicy.new(combined_config)
228232
expect(csp.value).to eq("default-src https:; block-all-mixed-content; script-src 'self'")
229233
end
@@ -233,7 +237,7 @@ module SecureHeaders
233237
config.csp = OPT_OUT
234238
end
235239
expect do
236-
ContentSecurityPolicy.combine_policies(Configuration.get.csp.to_h, script_src: %w(anothercdn.com))
240+
ContentSecurityPolicy.combine_policies(Configuration.default.csp.to_h, script_src: %w(anothercdn.com))
237241
end.to raise_error(ContentSecurityPolicyConfigError)
238242
end
239243
end

spec/lib/secure_headers/middleware_spec.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ module SecureHeaders
1111

1212
before(:each) do
1313
reset_config
14-
Configuration.default
1514
end
1615

1716
it "warns if the hpkp report-uri host is the same as the current host" do

spec/lib/secure_headers/view_helpers_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ module SecureHeaders
105105
let(:filename) { "app/views/asdfs/index.html.erb" }
106106

107107
before(:all) do
108+
reset_config
108109
Configuration.default do |config|
109110
config.csp = {
110111
default_src: %w('self'),

spec/lib/secure_headers_spec.rb

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,6 @@ module SecureHeaders
99

1010
let(:request) { Rack::Request.new("HTTP_X_FORWARDED_SSL" => "on") }
1111

12-
it "raises a NotYetConfiguredError if default has not been set" do
13-
expect do
14-
SecureHeaders.header_hash_for(request)
15-
end.to raise_error(Configuration::NotYetConfiguredError)
16-
end
17-
18-
it "raises a NotYetConfiguredError if trying to opt-out of unconfigured headers" do
19-
expect do
20-
SecureHeaders.opt_out_of_header(request, :csp)
21-
end.to raise_error(Configuration::NotYetConfiguredError)
22-
end
23-
2412
it "raises and ArgumentError when referencing an override that has not been set" do
2513
expect do
2614
Configuration.default
@@ -364,6 +352,7 @@ module SecureHeaders
364352
end
365353

366354
it "sets identical values when the configs are the same" do
355+
reset_config
367356
Configuration.default do |config|
368357
config.csp = {
369358
default_src: %w('self'),
@@ -381,6 +370,7 @@ module SecureHeaders
381370
end
382371

383372
it "sets different headers when the configs are different" do
373+
reset_config
384374
Configuration.default do |config|
385375
config.csp = {
386376
default_src: %w('self'),
@@ -395,6 +385,7 @@ module SecureHeaders
395385
end
396386

397387
it "allows you to opt-out of enforced CSP" do
388+
reset_config
398389
Configuration.default do |config|
399390
config.csp = SecureHeaders::OPT_OUT
400391
config.csp_report_only = {
@@ -452,6 +443,7 @@ module SecureHeaders
452443

453444
context "when inferring which config to modify" do
454445
it "updates the enforced header when configured" do
446+
reset_config
455447
Configuration.default do |config|
456448
config.csp = {
457449
default_src: %w('self'),
@@ -466,6 +458,7 @@ module SecureHeaders
466458
end
467459

468460
it "updates the report only header when configured" do
461+
reset_config
469462
Configuration.default do |config|
470463
config.csp = OPT_OUT
471464
config.csp_report_only = {
@@ -481,6 +474,7 @@ module SecureHeaders
481474
end
482475

483476
it "updates both headers if both are configured" do
477+
reset_config
484478
Configuration.default do |config|
485479
config.csp = {
486480
default_src: %w(enforced.com),

spec/spec_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ module SecureHeaders
4444
class Configuration
4545
class << self
4646
def clear_default_config
47-
@default_config = nil
47+
remove_instance_variable(:@default_config) if defined?(@default_config)
4848
end
4949
end
5050
end

0 commit comments

Comments
 (0)