Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raise on override defined config #436

Merged
merged 5 commits into from
Mar 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/named_overrides_and_appends.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Named Appends

Named Appends are blocks of code that can be reused and composed during requests. e.g. If a certain partial is rendered conditionally, and the csp needs to be adjusted for that partial, you can create a named append for that situation. The value returned by the block will be passed into `append_content_security_policy_directives`. The current request object is passed as an argument to the block for even more flexibility.
Named Appends are blocks of code that can be reused and composed during requests. e.g. If a certain partial is rendered conditionally, and the csp needs to be adjusted for that partial, you can create a named append for that situation. The value returned by the block will be passed into `append_content_security_policy_directives`. The current request object is passed as an argument to the block for even more flexibility. Reusing a configuration name is not allowed and will throw an exception.

```ruby
def show
Expand Down Expand Up @@ -91,6 +91,8 @@ class MyController < ApplicationController
end
```

Reusing a configuration name is not allowed and will throw an exception.

By default, a no-op configuration is provided. No headers will be set when this default override is used.

```ruby
Expand Down
11 changes: 11 additions & 0 deletions lib/secure_headers/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ def default(&block)
def override(name, &block)
@overrides ||= {}
raise "Provide a configuration block" unless block_given?
if named_append_or_override_exists?(name)
raise AlreadyConfiguredError, "Configuration already exists"
end
@overrides[name] = block
end

Expand All @@ -59,6 +62,9 @@ def named_appends(name)
def named_append(name, &block)
@appends ||= {}
raise "Provide a configuration block" unless block_given?
if named_append_or_override_exists?(name)
raise AlreadyConfiguredError, "Configuration already exists"
end
@appends[name] = block
end

Expand All @@ -68,6 +74,11 @@ def dup

private

def named_append_or_override_exists?(name)
(defined?(@appends) && @appends.key?(name)) ||
(defined?(@overrides) && @overrides.key?(name))
end

# Public: perform a basic deep dup. The shallow copy provided by dup/clone
# can lead to modifying parent objects.
def deep_copy(config)
Expand Down
54 changes: 54 additions & 0 deletions spec/lib/secure_headers/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,60 @@ module SecureHeaders
expect(Configuration.overrides(:test_override)).to_not be_nil
end

describe "#override" do
it "raises on configuring an existing override" do
set_override = Proc.new {
Configuration.override(:test_override) do |config|
config.x_frame_options = "DENY"
end
}

set_override.call

expect { set_override.call }
.to raise_error(Configuration::AlreadyConfiguredError, "Configuration already exists")
end

it "raises when a named append with the given name exists" do
Configuration.named_append(:test_override) do |config|
config.x_frame_options = "DENY"
end

expect do
Configuration.override(:test_override) do |config|
config.x_frame_options = "SAMEORIGIN"
end
end.to raise_error(Configuration::AlreadyConfiguredError, "Configuration already exists")
end
end

describe "#named_append" do
it "raises on configuring an existing append" do
set_override = Proc.new {
Configuration.named_append(:test_override) do |config|
config.x_frame_options = "DENY"
end
}

set_override.call

expect { set_override.call }
.to raise_error(Configuration::AlreadyConfiguredError, "Configuration already exists")
end

it "raises when an override with the given name exists" do
Configuration.override(:test_override) do |config|
config.x_frame_options = "DENY"
end

expect do
Configuration.named_append(:test_override) do |config|
config.x_frame_options = "SAMEORIGIN"
end
end.to raise_error(Configuration::AlreadyConfiguredError, "Configuration already exists")
end
end

it "deprecates the secure_cookies configuration" do
expect {
Configuration.default do |config|
Expand Down
10 changes: 10 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,20 @@ class << self
def clear_default_config
remove_instance_variable(:@default_config) if defined?(@default_config)
end

def clear_overrides
remove_instance_variable(:@overrides) if defined?(@overrides)
end

def clear_appends
remove_instance_variable(:@appends) if defined?(@appends)
end
end
end
end

def reset_config
SecureHeaders::Configuration.clear_default_config
SecureHeaders::Configuration.clear_overrides
SecureHeaders::Configuration.clear_appends
end