diff --git a/CHANGES.md b/CHANGES.md index 1dac4cd..e8eaf32 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,9 @@ +### 2.2.0 (2017-08-31) + +* [#46](https://github.com/square/rails-auth/pull/46) + Add linting for YAML acl checks (i.e. prevent duplicate keys) + ([@cgthornt]) + ### 2.1.3 (2017-08-04) * [#44](https://github.com/square/rails-auth/pull/44) diff --git a/lib/rails/auth/acl.rb b/lib/rails/auth/acl.rb index e6d7a2f..bad3b61 100644 --- a/lib/rails/auth/acl.rb +++ b/lib/rails/auth/acl.rb @@ -17,6 +17,15 @@ class ACL # @param [String] :yaml serialized YAML to load an ACL from def self.from_yaml(yaml, **args) require "yaml" + require "yamllint" + + linter = YamlLint::Linter.new + linter.check_stream(StringIO.new(yaml)) + if linter.errors? + # Always in the format of {"" => ["msg1", "msg2", ...]} + msg = linter.errors[""].join(", ") + raise ParseError, "ACL lint failed: #{msg}" + end new(YAML.load(yaml), **args) end diff --git a/lib/rails/auth/version.rb b/lib/rails/auth/version.rb index 9b846bb..de5e78b 100644 --- a/lib/rails/auth/version.rb +++ b/lib/rails/auth/version.rb @@ -3,6 +3,6 @@ module Rails # Pluggable authentication and authorization for Rack/Rails module Auth - VERSION = "2.1.3".freeze + VERSION = "2.2.0".freeze end end diff --git a/rails-auth.gemspec b/rails-auth.gemspec index 368f050..a96d4d5 100644 --- a/rails-auth.gemspec +++ b/rails-auth.gemspec @@ -28,6 +28,7 @@ Gem::Specification.new do |spec| spec.required_ruby_version = ">= 2.0.0" spec.add_runtime_dependency "rack" + spec.add_runtime_dependency "yamllint", "~> 0.0.9" spec.add_development_dependency "bundler", "~> 1.10" spec.add_development_dependency "rake", "~> 10.0" diff --git a/spec/fixtures/example_invalid_acl.yml b/spec/fixtures/example_invalid_acl.yml new file mode 100644 index 0000000..66958aa --- /dev/null +++ b/spec/fixtures/example_invalid_acl.yml @@ -0,0 +1,7 @@ +--- +- resources: + - method: ALL + method: POST + path: /foo/bar/.* + - path: /foo/bar + path: /bar diff --git a/spec/rails/auth/acl_spec.rb b/spec/rails/auth/acl_spec.rb index 3bde83c..599c864 100644 --- a/spec/rails/auth/acl_spec.rb +++ b/spec/rails/auth/acl_spec.rb @@ -31,4 +31,17 @@ expect(resources.first.path).to eq %r{\A/foo/bar/.*\z} end end + + describe ".from_yaml" do + subject { example_acl } + + context "when given an invalid YAML file" do + let(:example_config) { fixture_path("example_invalid_acl.yml").read } + + it "raises an error" do + expect { subject }.to raise_error Rails::Auth::ParseError, + 'ACL lint failed: The same key is defined more than once: 0.resources.0.method, The same key is defined more than once: 0.resources.1.path' + end + end + end end