Skip to content

Commit

Permalink
Unwrap sensitive values in error messages
Browse files Browse the repository at this point in the history
When sensitive values are compared and do not match, the produce error
message does not help for debugging:

```
  1) postgresql::server::role with Password Datatype Sensitive[String] has alter role for "test" user with password as ****
     Failure/Error:
       is_expected.to contain_postgresql_psql('ALTER ROLE test ENCRYPTED PASSWORD ****')
         .with('command'     => sensitive('ALTER ROLE "test" ENCRYPTED PASSWORD \'new-pa$s\''),
               'sensitive'   => 'true',
               'unless'      => sensitive("SELECT 1 FROM pg_shadow WHERE usename = 'test' AND passwd = 'new-pa$s'"),
               'port'        => '5432')

       expected that the catalogue would contain Postgresql_psql[ALTER ROLE test ENCRYPTED PASSWORD ****] with command set to Sensitive("ALTER ROLE \"test\" ENCRYPTED PASSWORD 'new-pa$s'") but it is set to #<Sensitive [value redacted]>, and parameter unless set to Sensitive("SELECT 1 FROM pg_shadow WHERE usename = 'test' AND passwd = 'new-pa$s'") but it is set to #<Sensitive [value redacted]>
       Diff:
         <The diff is empty, are your objects producing identical `#inspect` output?>
     # ./spec/defines/server/role_spec.rb:56:in `block (3 levels) in <top (required)>'
     # /usr/home/romain/.gem/ruby/3.0/bin/rspec:25:in `load'
     # /usr/home/romain/.gem/ruby/3.0/bin/rspec:25:in `<main>'
```

With this change, the sensitive values are unwrapped and allow to spot
the missing unwraps in unit tests:

```
  1) postgresql::server::role with Password Datatype Sensitive[String] has alter role for "test" user with password as ****
     Failure/Error:
       is_expected.to contain_postgresql_psql('ALTER ROLE test ENCRYPTED PASSWORD ****')
         .with('command'     => sensitive('ALTER ROLE "test" ENCRYPTED PASSWORD \'new-pa$s\''),
               'sensitive'   => 'true',
               'unless'      => sensitive("SELECT 1 FROM pg_shadow WHERE usename = 'test' AND passwd = 'new-pa$s'"),
               'port'        => '5432')

       expected that the catalogue would contain Postgresql_psql[ALTER ROLE test ENCRYPTED PASSWORD ****] with command set to Sensitive("ALTER ROLE \"test\" ENCRYPTED PASSWORD 'new-pa$s'") but it is set to Sensitive("ALTER ROLE \"test\" ENCRYPTED PASSWORD 'Sensitive [value redacted]'"), and parameter unless set to Sensitive("SELECT 1 FROM pg_shadow WHERE usename = 'test' AND passwd = 'new-pa$s'") but it is set to Sensitive("SELECT 1 FROM pg_shadow WHERE usename = 'test' AND passwd = 'Sensitive [value redacted]'")
       Diff:

       @@ -1,4 +1,4 @@
       -Sensitive("ALTER ROLE \"test\" ENCRYPTED PASSWORD 'new-pa$s'")
       +Sensitive("ALTER ROLE \"test\" ENCRYPTED PASSWORD 'Sensitive [value redacted]'")

       -Sensitive("SELECT 1 FROM pg_shadow WHERE usename = 'test' AND passwd = 'new-pa$s'")
       +Sensitive("SELECT 1 FROM pg_shadow WHERE usename = 'test' AND passwd = 'Sensitive [value redacted]'")
```
  • Loading branch information
smortex committed Oct 13, 2023
1 parent 537d1a6 commit b9dde53
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/rspec-puppet/matchers/parameter_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def matches?(resource)
actual = resource[@parameter]
expected = @value

actual = RSpec::Puppet::Sensitive.new(actual.unwrap) if actual.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)

# Puppet flattens an array with a single value into just the value and
# this can cause confusion when testing as people expect when you put
# an array in, you'll get an array out.
Expand Down
5 changes: 5 additions & 0 deletions lib/rspec-puppet/sensitive.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ def inspect
"Sensitive(#{@value.inspect})"
end

# @return the unwrapped value (needed to show diff)
def to_s
inspect
end

# Check for equality with another value.
# If compared to Puppet Sensitive type, it compares the wrapped values.

Expand Down
29 changes: 29 additions & 0 deletions spec/unit/matchers/parameter_matcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,34 @@
expect(subject.matches?(foo_parameter: nil)).to be(false)
end
end

context 'with sensitive("foo") expected' do
subject do
described_class.new(:foo_parameter, RSpec::Puppet::Sensitive.new('foo'), :should)
end

it 'matches sensitive("foo")' do
expect(subject.matches?(foo_parameter: RSpec::Puppet::Sensitive.new('foo'))).to be(true)
expect(subject.errors.size).to eq(0)
end

it 'does not match sensitive("bar")' do
expect(subject.matches?(foo_parameter: RSpec::Puppet::Sensitive.new('bar'))).to be(false)
expect(subject.errors.size).to eq(1)
expect(subject.errors[0].message).to eq('foo_parameter set to Sensitive("foo") but it is set to Sensitive("bar")')
end

it 'does not matches "foo"' do
expect(subject.matches?(foo_parameter: 'foo')).to be(false)
expect(subject.errors.size).to eq(1)
expect(subject.errors[0].message).to eq('foo_parameter set to Sensitive("foo") but it is set to "foo"')
end

it 'does not matches "Sensitive [value redacted]"' do
expect(subject.matches?(foo_parameter: 'Sensitive [value redacted]')).to be(false)
expect(subject.errors.size).to eq(1)
expect(subject.errors[0].message).to eq('foo_parameter set to Sensitive("foo") but it is set to "Sensitive [value redacted]"')
end
end
end
end

0 comments on commit b9dde53

Please sign in to comment.